blob: a8ad126dd6d0b11d4b6771341d1592dc4e2fe63b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
(**************************************************************************)
(* *)
(* OCaml *)
(* *)
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 1996 Institut National de Recherche en Informatique et *)
(* en Automatique. *)
(* *)
(* All rights reserved. This file is distributed under the terms of *)
(* the GNU Lesser General Public License version 2.1, with the *)
(* special exception on linking described in the file LICENSE. *)
(* *)
(**************************************************************************)
(* "Expunge" a toplevel by removing compiler modules from the global map.
Usage: expunge <source file> <dest file> <names of modules to keep> *)
open Misc
module String = Misc.Stdlib.String
let is_exn =
let h = Hashtbl.create 64 in
Array.iter (fun n -> Hashtbl.add h n ()) Runtimedef.builtin_exceptions;
Hashtbl.mem h
let to_keep = ref String.Set.empty
let negate = Sys.argv.(3) = "-v"
let keep =
if negate then fun name -> is_exn name || not (String.Set.mem name !to_keep)
else fun name -> is_exn name || (String.Set.mem name !to_keep)
let expunge_map tbl =
Symtable.filter_global_map (fun id -> keep (Ident.name id)) tbl
let expunge_crcs tbl =
List.filter (fun (unit, _crc) -> keep unit) tbl
let main () =
let input_name = Sys.argv.(1) in
let output_name = Sys.argv.(2) in
for i = (if negate then 4 else 3) to Array.length Sys.argv - 1 do
to_keep := String.Set.add (String.capitalize_ascii Sys.argv.(i)) !to_keep
done;
let ic = open_in_bin input_name in
let toc = Bytesections.read_toc ic in
seek_in ic 0;
let oc =
open_out_gen [Open_wronly; Open_creat; Open_trunc; Open_binary] 0o777
output_name in
let first_pos = Bytesections.pos_first_section toc in
(* Copy the file up to the first section as is *)
copy_file_chunk ic oc first_pos;
(* Copy each section, modifying the symbol section in passing *)
let toc_writer = Bytesections.init_record oc in
List.iter
(fun {Bytesections.name; pos; len} ->
seek_in ic pos;
begin match name with
SYMB ->
let global_map : Symtable.global_map = input_value ic in
output_value oc (expunge_map global_map)
| CRCS ->
let crcs : (string * Digest.t option) list = input_value ic in
output_value oc (expunge_crcs crcs)
| _ ->
copy_file_chunk ic oc len
end;
Bytesections.record toc_writer name)
(Bytesections.all toc);
(* Rewrite the toc and trailer *)
Bytesections.write_toc_and_trailer toc_writer;
(* Done *)
close_in ic;
close_out oc
let _ = main (); exit 0
|