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 80 81 82 83 84 85 86 87 88 89 90 91
|
(**************************************************************************)
(* *)
(* OCaml *)
(* *)
(* Xavier Leroy, projet Gallium, INRIA Paris *)
(* *)
(* Copyright 2015 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. *)
(* *)
(**************************************************************************)
(* Copy a bytecode executable, removing debugging information and possibly
dynlink information and #! header from the copy.
*)
open Misc
let remove_header = ref false
let remove_DBUG = ref true
let remove_CRCS = ref false
let remove_section (s : Bytesections.Name.t) =
match s with
| DBUG -> !remove_DBUG
| CRCS -> !remove_CRCS
| RNTM -> !remove_header
| _ -> false
let stripdebug infile outfile =
let ic = open_in_bin infile in
let toc = Bytesections.read_toc ic in
let oc =
open_out_gen [Open_wronly; Open_creat; Open_trunc; Open_binary] 0o777
outfile in
if not !remove_header then begin
(* Copy header up to first section *)
seek_in ic 0;
let header_length = Bytesections.pos_first_section toc in
copy_file_chunk ic oc header_length
end;
(* Copy each section except DBUG and CRCS *)
let toc_writer = Bytesections.init_record oc in
List.iter
(fun {Bytesections.name; pos; len} ->
if not (remove_section name) then begin
seek_in ic pos;
copy_file_chunk ic oc len;
Bytesections.record toc_writer name
end
)
(Bytesections.all toc);
(* Rewrite the toc and trailer *)
Bytesections.write_toc_and_trailer toc_writer;
(* Done *)
close_in ic;
close_out oc
let options = [
"-remove-header", Arg.Set remove_header,
"remove the header that calls ocamlrun automatically";
"-keep-header", Arg.Clear remove_header,
"preserve the header that calls ocamlrun automatically (default)";
"-remove-debug", Arg.Set remove_DBUG,
"remove all debugging information (default)";
"-keep-debug", Arg.Clear remove_DBUG,
"preserve all debugging information";
"-remove-dynlink", Arg.Set remove_CRCS,
"remove the data needed for dynamic code loading";
"-keep-dynlink", Arg.Clear remove_CRCS,
"preserve the data needed for dynamic code loading (default)";
"-all", Arg.Unit (fun () -> remove_header := true; remove_DBUG := true;
remove_CRCS := true),
"remove header, debugging info, and dynamic code loading info"
]
let usage =
"Usage: stripdebug [options] <input file> <output file>\n\
Options are:"
let main() =
let anon = ref [] in
Arg.parse options (fun x -> anon := x :: !anon) usage;
match !anon with
| [output; input] -> stripdebug input output
| _ -> Arg.usage options usage; exit 2
let _ = main()
|