(**************************************************************************) (* *) (* 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] \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()