Skip to content

Instantly share code, notes, and snippets.

@dbuenzli
Last active October 15, 2019 16:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dbuenzli/0b773f4a4dd9f7a35f30cd9b671e48c5 to your computer and use it in GitHub Desktop.
Save dbuenzli/0b773f4a4dd9f7a35f30cd9b671e48c5 to your computer and use it in GitHub Desktop.
Read cma/cmxa/cmxs link metadata
(*
ocamlfind ocamlopt -o readmeta -linkpkg \
-package dynlink,compiler-libs.optcomp,compiler-libs.bytecomp readmeta.ml
*)
let read_cma ic =
let lib =
let toc_pos = input_binary_int ic in
seek_in ic toc_pos;
(input_value ic : Cmo_format.library)
in
Printf.printf "ccobjs: %s\nccopts: %s\ndllibs: %s\n%!"
(String.concat " " lib.Cmo_format.lib_ccobjs)
(String.concat " " lib.Cmo_format.lib_ccopts)
(String.concat " " lib.Cmo_format.lib_dllibs)
let read_cmxa ic =
let lib = (input_value ic : Cmx_format.library_infos) in
Printf.printf "ccobjs: %s\nccopts: %s\n"
(String.concat " " lib.Cmx_format.lib_ccobjs)
(String.concat " " lib.Cmx_format.lib_ccopts)
type handle
external ndl_open : string -> bool -> handle * Cmxs_format.dynheader
= "caml_natdynlink_open"
let read_cmxs file =
let _, dynh = ndl_open file false in
let unit_name d = d.Cmxs_format.dynu_name in
let units = List.map unit_name dynh.Cmxs_format.dynu_units in
Printf.printf "units: %s" (String.concat " " units)
let read_meta file =
if Filename.extension file = ".cmxs" then read_cmxs file else
let ic = open_in_bin file in
try
let len = String.length Config.cma_magic_number in
let magic = really_input_string ic len in
begin match magic with
| m when String.equal m Config.cma_magic_number -> read_cma ic
| m when String.equal m Config.cmxa_magic_number -> read_cmxa ic
| m -> raise (Sys_error ("unknown magic number " ^ m))
end;
close_in ic
with
| e -> close_in_noerr ic; raise e
let main () =
try
if Array.length Sys.argv <> 2
then (Printf.eprintf "Usage: readmeta CM[X]A\n"; exit 1)
else (read_meta Sys.argv.(1); exit 0)
with
| Sys_error e -> Printf.eprintf "%s: %s" Sys.argv.(1) e; exit 1
let () = if !Sys.interactive then () else main ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment