summaryrefslogtreecommitdiff
path: root/tools/dumpobj.ml
diff options
context:
space:
mode:
Diffstat (limited to 'tools/dumpobj.ml')
-rw-r--r--tools/dumpobj.ml534
1 files changed, 0 insertions, 534 deletions
diff --git a/tools/dumpobj.ml b/tools/dumpobj.ml
deleted file mode 100644
index 5a6fa6d4ea..0000000000
--- a/tools/dumpobj.ml
+++ /dev/null
@@ -1,534 +0,0 @@
-(***********************************************************************)
-(* *)
-(* Objective Caml *)
-(* *)
-(* 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 Q Public License version 1.0. *)
-(* *)
-(***********************************************************************)
-
-(* $Id$ *)
-
-(* Disassembler for executable and .cmo object files *)
-
-open Obj
-open Printf
-open Config
-open Asttypes
-open Lambda
-open Emitcode
-open Opcodes
-open Instruct
-open Opnames
-
-(* Read signed and unsigned integers *)
-
-let inputu ic =
- let b1 = input_byte ic in
- let b2 = input_byte ic in
- let b3 = input_byte ic in
- let b4 = input_byte ic in
- (b4 lsl 24) + (b3 lsl 16) + (b2 lsl 8) + b1
-
-let inputs ic =
- let b1 = input_byte ic in
- let b2 = input_byte ic in
- let b3 = input_byte ic in
- let b4 = input_byte ic in
- let b4' = if b4 >= 128 then b4-256 else b4 in
- (b4' lsl 24) + (b3 lsl 16) + (b2 lsl 8) + b1
-
-(* Global variables *)
-
-type global_table_entry =
- Empty
- | Global of Ident.t
- | Constant of Obj.t
-
-let start = ref 0 (* Position of beg. of code *)
-let reloc = ref ([] : (reloc_info * int) list) (* Relocation table *)
-let globals = ref ([||] : global_table_entry array) (* Global map *)
-let primitives = ref ([||] : string array) (* Table of primitives *)
-let objfile = ref false (* true if dumping a .cmo *)
-
-(* Events (indexed by PC) *)
-
-let event_table = (Hashtbl.create 253 : (int, debug_event) Hashtbl.t)
-
-let relocate_event orig ev =
- ev.ev_pos <- orig + ev.ev_pos;
- match ev.ev_repr with
- Event_parent repr -> repr := ev.ev_pos
- | _ -> ()
-
-let record_events orig evl =
- List.iter
- (fun ev ->
- relocate_event orig ev;
- Hashtbl.add event_table ev.ev_pos ev)
- evl
-
-(* Print a structured constant *)
-
-let print_float f =
- if String.contains f '.'
- then printf "%s" f
- else printf "%s." f
-;;
-
-let rec print_struct_const = function
- Const_base(Const_int i) -> printf "%d" i
- | Const_base(Const_float f) -> print_float f
- | Const_base(Const_string s) -> printf "%S" s
- | Const_base(Const_char c) -> printf "%C" c
- | Const_base(Const_int32 i) -> printf "%ldl" i
- | Const_base(Const_nativeint i) -> printf "%ndn" i
- | Const_base(Const_int64 i) -> printf "%LdL" i
- | Const_pointer n -> printf "%da" n
- | Const_block(tag, args) ->
- printf "<%d>" tag;
- begin match args with
- [] -> ()
- | [a1] ->
- printf "("; print_struct_const a1; printf ")"
- | a1::al ->
- printf "("; print_struct_const a1;
- List.iter (fun a -> printf ", "; print_struct_const a) al;
- printf ")"
- end
- | Const_float_array a ->
- printf "[|";
- List.iter (fun f -> print_float f; printf "; ") a;
- printf "|]"
-
-(* Print an obj *)
-
-let rec print_obj x =
- if Obj.is_block x then begin
- match Obj.tag x with
- 252 -> (* string *)
- printf "%S" (Obj.magic x : string)
- | 253 -> (* float *)
- printf "%.12g" (Obj.magic x : float)
- | 254 -> (* float array *)
- let a = (Obj.magic x : float array) in
- printf "[|";
- for i = 0 to Array.length a - 1 do
- if i > 0 then printf ", ";
- printf "%.12g" a.(i)
- done;
- printf "|]"
- | _ ->
- printf "<%d>" (Obj.tag x);
- begin match Obj.size x with
- 0 -> ()
- | 1 ->
- printf "("; print_obj (Obj.field x 0); printf ")"
- | n ->
- printf "("; print_obj (Obj.field x 0);
- for i = 1 to n - 1 do
- printf ", "; print_obj (Obj.field x i)
- done;
- printf ")"
- end
- end else
- printf "%d" (Obj.magic x : int)
-
-(* Current position in input file *)
-
-let currpos ic =
- pos_in ic - !start
-
-(* Access in the relocation table *)
-
-let rec rassoc key = function
- [] -> raise Not_found
- | (a,b) :: l -> if b = key then a else rassoc key l
-
-let find_reloc ic =
- rassoc (pos_in ic - !start) !reloc
-
-(* Symbolic printing of global names, etc *)
-
-let print_getglobal_name ic =
- if !objfile then begin
- begin try
- match find_reloc ic with
- Reloc_getglobal id -> print_string (Ident.name id)
- | Reloc_literal sc -> print_struct_const sc
- | _ -> print_string "<wrong reloc>"
- with Not_found ->
- print_string "<no reloc>"
- end;
- ignore (inputu ic);
- end
- else begin
- let n = inputu ic in
- if n >= Array.length !globals || n < 0
- then print_string "<global table overflow>"
- else match !globals.(n) with
- Global id -> print_string(Ident.name id)
- | Constant obj -> print_obj obj
- | _ -> print_string "???"
- end
-
-let print_setglobal_name ic =
- if !objfile then begin
- begin try
- match find_reloc ic with
- Reloc_setglobal id -> print_string (Ident.name id)
- | _ -> print_string "<wrong reloc>"
- with Not_found ->
- print_string "<no reloc>"
- end;
- ignore (inputu ic);
- end
- else begin
- let n = inputu ic in
- if n >= Array.length !globals || n < 0
- then print_string "<global table overflow>"
- else match !globals.(n) with
- Global id -> print_string(Ident.name id)
- | _ -> print_string "???"
- end
-
-let print_primitive ic =
- if !objfile then begin
- begin try
- match find_reloc ic with
- Reloc_primitive s -> print_string s
- | _ -> print_string "<wrong reloc>"
- with Not_found ->
- print_string "<no reloc>"
- end;
- ignore (inputu ic);
- end
- else begin
- let n = inputu ic in
- if n >= Array.length !primitives || n < 0
- then print_int n
- else print_string !primitives.(n)
- end
-
-(* Disassemble one instruction *)
-
-let currpc ic =
- currpos ic / 4
-
-type shape =
- | Nothing
- | Uint
- | Sint
- | Uint_Uint
- | Disp
- | Uint_Disp
- | Sint_Disp
- | Getglobal
- | Getglobal_Uint
- | Setglobal
- | Primitive
- | Uint_Primitive
- | Switch
- | Closurerec
-;;
-
-let op_shapes = [
- opACC0, Nothing;
- opACC1, Nothing;
- opACC2, Nothing;
- opACC3, Nothing;
- opACC4, Nothing;
- opACC5, Nothing;
- opACC6, Nothing;
- opACC7, Nothing;
- opACC, Uint;
- opPUSH, Nothing;
- opPUSHACC0, Nothing;
- opPUSHACC1, Nothing;
- opPUSHACC2, Nothing;
- opPUSHACC3, Nothing;
- opPUSHACC4, Nothing;
- opPUSHACC5, Nothing;
- opPUSHACC6, Nothing;
- opPUSHACC7, Nothing;
- opPUSHACC, Uint;
- opPOP, Uint;
- opASSIGN, Uint;
- opENVACC1, Nothing;
- opENVACC2, Nothing;
- opENVACC3, Nothing;
- opENVACC4, Nothing;
- opENVACC, Uint;
- opPUSHENVACC1, Nothing;
- opPUSHENVACC2, Nothing;
- opPUSHENVACC3, Nothing;
- opPUSHENVACC4, Nothing;
- opPUSHENVACC, Uint;
- opPUSH_RETADDR, Disp;
- opAPPLY, Uint;
- opAPPLY1, Nothing;
- opAPPLY2, Nothing;
- opAPPLY3, Nothing;
- opAPPTERM, Uint_Uint;
- opAPPTERM1, Uint;
- opAPPTERM2, Uint;
- opAPPTERM3, Uint;
- opRETURN, Uint;
- opRESTART, Nothing;
- opGRAB, Uint;
- opCLOSURE, Uint_Disp;
- opCLOSUREREC, Closurerec;
- opOFFSETCLOSUREM2, Nothing;
- opOFFSETCLOSURE0, Nothing;
- opOFFSETCLOSURE2, Nothing;
- opOFFSETCLOSURE, Sint; (* was Uint *)
- opPUSHOFFSETCLOSUREM2, Nothing;
- opPUSHOFFSETCLOSURE0, Nothing;
- opPUSHOFFSETCLOSURE2, Nothing;
- opPUSHOFFSETCLOSURE, Sint; (* was Nothing *)
- opGETGLOBAL, Getglobal;
- opPUSHGETGLOBAL, Getglobal;
- opGETGLOBALFIELD, Getglobal_Uint;
- opPUSHGETGLOBALFIELD, Getglobal_Uint;
- opSETGLOBAL, Setglobal;
- opATOM0, Nothing;
- opATOM, Uint;
- opPUSHATOM0, Nothing;
- opPUSHATOM, Uint;
- opMAKEBLOCK, Uint_Uint;
- opMAKEBLOCK1, Uint;
- opMAKEBLOCK2, Uint;
- opMAKEBLOCK3, Uint;
- opMAKEFLOATBLOCK, Uint;
- opGETFIELD0, Nothing;
- opGETFIELD1, Nothing;
- opGETFIELD2, Nothing;
- opGETFIELD3, Nothing;
- opGETFIELD, Uint;
- opGETFLOATFIELD, Uint;
- opSETFIELD0, Nothing;
- opSETFIELD1, Nothing;
- opSETFIELD2, Nothing;
- opSETFIELD3, Nothing;
- opSETFIELD, Uint;
- opSETFLOATFIELD, Uint;
- opVECTLENGTH, Nothing;
- opGETVECTITEM, Nothing;
- opSETVECTITEM, Nothing;
- opGETSTRINGCHAR, Nothing;
- opSETSTRINGCHAR, Nothing;
- opBRANCH, Disp;
- opBRANCHIF, Disp;
- opBRANCHIFNOT, Disp;
- opSWITCH, Switch;
- opBOOLNOT, Nothing;
- opPUSHTRAP, Disp;
- opPOPTRAP, Nothing;
- opRAISE, Nothing;
- opCHECK_SIGNALS, Nothing;
- opC_CALL1, Primitive;
- opC_CALL2, Primitive;
- opC_CALL3, Primitive;
- opC_CALL4, Primitive;
- opC_CALL5, Primitive;
- opC_CALLN, Uint_Primitive;
- opCONST0, Nothing;
- opCONST1, Nothing;
- opCONST2, Nothing;
- opCONST3, Nothing;
- opCONSTINT, Sint;
- opPUSHCONST0, Nothing;
- opPUSHCONST1, Nothing;
- opPUSHCONST2, Nothing;
- opPUSHCONST3, Nothing;
- opPUSHCONSTINT, Sint;
- opNEGINT, Nothing;
- opADDINT, Nothing;
- opSUBINT, Nothing;
- opMULINT, Nothing;
- opDIVINT, Nothing;
- opMODINT, Nothing;
- opANDINT, Nothing;
- opORINT, Nothing;
- opXORINT, Nothing;
- opLSLINT, Nothing;
- opLSRINT, Nothing;
- opASRINT, Nothing;
- opEQ, Nothing;
- opNEQ, Nothing;
- opLTINT, Nothing;
- opLEINT, Nothing;
- opGTINT, Nothing;
- opGEINT, Nothing;
- opOFFSETINT, Sint;
- opOFFSETREF, Sint;
- opISINT, Nothing;
- opGETMETHOD, Nothing;
- opBEQ, Sint_Disp;
- opBNEQ, Sint_Disp;
- opBLTINT, Sint_Disp;
- opBLEINT, Sint_Disp;
- opBGTINT, Sint_Disp;
- opBGEINT, Sint_Disp;
- opULTINT, Nothing;
- opUGEINT, Nothing;
- opBULTINT, Uint_Disp;
- opBUGEINT, Uint_Disp;
- opSTOP, Nothing;
- opEVENT, Nothing;
- opBREAK, Nothing;
-];;
-
-let print_event ev =
- printf "File \"%s\", line %d, character %d:\n" ev.ev_char.Lexing.pos_fname
- ev.ev_char.Lexing.pos_lnum
- (ev.ev_char.Lexing.pos_cnum - ev.ev_char.Lexing.pos_bol)
-
-let print_instr ic =
- let pos = currpos ic in
- List.iter print_event (Hashtbl.find_all event_table pos);
- printf "%8d " (pos / 4);
- let op = inputu ic in
- if op >= Array.length names_of_instructions || op < 0
- then (print_string "*** unknown opcode : "; print_int op)
- else print_string names_of_instructions.(op);
- print_string " ";
- begin try match List.assoc op op_shapes with
- | Uint -> print_int (inputu ic)
- | Sint -> print_int (inputs ic)
- | Uint_Uint
- -> print_int (inputu ic); print_string ", "; print_int (inputu ic)
- | Disp -> let p = currpc ic in print_int (p + inputs ic)
- | Uint_Disp
- -> print_int (inputu ic); print_string ", ";
- let p = currpc ic in print_int (p + inputs ic)
- | Sint_Disp
- -> print_int (inputs ic); print_string ", ";
- let p = currpc ic in print_int (p + inputs ic)
- | Getglobal -> print_getglobal_name ic
- | Getglobal_Uint
- -> print_getglobal_name ic; print_string ", "; print_int (inputu ic)
- | Setglobal -> print_setglobal_name ic
- | Primitive -> print_primitive ic
- | Uint_Primitive
- -> print_int(inputu ic); print_string ", "; print_primitive ic
- | Switch
- -> let n = inputu ic in
- let orig = currpc ic in
- for i = 0 to (n land 0xFFFF) - 1 do
- print_string "\n int "; print_int i; print_string " -> ";
- print_int(orig + inputs ic);
- done;
- for i = 0 to (n lsr 16) - 1 do
- print_string "\n tag "; print_int i; print_string " -> ";
- print_int(orig + inputs ic);
- done;
- | Closurerec
- -> let nfuncs = inputu ic in
- let nvars = inputu ic in
- let orig = currpc ic in
- print_int nvars;
- for i = 0 to nfuncs - 1 do
- print_string ", ";
- print_int (orig + inputu ic);
- done;
- | Nothing -> ()
- with Not_found -> print_string "(unknown arguments)"
- end;
- print_string "\n";
-;;
-
-(* Disassemble a block of code *)
-
-let print_code ic len =
- start := pos_in ic;
- let stop = !start + len in
- while pos_in ic < stop do print_instr ic done
-
-(* Dump relocation info *)
-
-let print_reloc (info, pos) =
- printf " %d (%d) " pos (pos/4);
- match info with
- Reloc_literal sc -> print_struct_const sc; printf "\n"
- | Reloc_getglobal id -> printf "require %s\n" (Ident.name id)
- | Reloc_setglobal id -> printf "provide %s\n" (Ident.name id)
- | Reloc_primitive s -> printf "prim %s\n" s
-
-(* Print a .cmo file *)
-
-let dump_obj filename ic =
- let buffer = String.create (String.length cmo_magic_number) in
- really_input ic buffer 0 (String.length cmo_magic_number);
- if buffer <> cmo_magic_number then begin
- prerr_endline "Not an object file"; exit 2
- end;
- let cu_pos = input_binary_int ic in
- seek_in ic cu_pos;
- let cu = (input_value ic : compilation_unit) in
- reloc := cu.cu_reloc;
- if cu.cu_debug > 0 then begin
- seek_in ic cu.cu_debug;
- let evl = (input_value ic : debug_event list) in
- record_events 0 evl
- end;
- seek_in ic cu.cu_pos;
- print_code ic cu.cu_codesize
-
-(* Read the primitive table from an executable *)
-
-let read_primitive_table ic len =
- let p = String.create len in
- really_input ic p 0 len;
- let rec split beg cur =
- if cur >= len then []
- else if p.[cur] = '\000' then
- String.sub p beg (cur - beg) :: split (cur + 1) (cur + 1)
- else
- split beg (cur + 1) in
- Array.of_list(split 0 0)
-
-(* Print an executable file *)
-
-let dump_exe ic =
- Bytesections.read_toc ic;
- let prim_size = Bytesections.seek_section ic "PRIM" in
- primitives := read_primitive_table ic prim_size;
- ignore(Bytesections.seek_section ic "DATA");
- let init_data = (input_value ic : Obj.t array) in
- globals := Array.create (Array.length init_data) Empty;
- for i = 0 to Array.length init_data - 1 do
- !globals.(i) <- Constant (init_data.(i))
- done;
- ignore(Bytesections.seek_section ic "SYMB");
- let (_, sym_table) = (input_value ic : int * (Ident.t, int) Tbl.t) in
- Tbl.iter (fun id pos -> !globals.(pos) <- Global id) sym_table;
- begin try
- ignore (Bytesections.seek_section ic "DBUG");
- let num_eventlists = input_binary_int ic in
- for i = 1 to num_eventlists do
- let orig = input_binary_int ic in
- let evl = (input_value ic : debug_event list) in
- record_events orig evl
- done
- with Not_found -> ()
- end;
- let code_size = Bytesections.seek_section ic "CODE" in
- print_code ic code_size
-
-let main() =
- for i = 1 to Array.length Sys.argv - 1 do
- let ic = open_in_bin Sys.argv.(i) in
- begin try
- objfile := false; dump_exe ic
- with Bytesections.Bad_magic_number ->
- objfile := true; seek_in ic 0; dump_obj (Sys.argv.(i)) ic
- end;
- close_in ic
- done;
- exit 0
-
-let _ = Printexc.catch main (); exit 0