diff --git a/DwarfSynth.mlpack b/DwarfSynth.mlpack index 1eeb434..aae7cdc 100644 --- a/DwarfSynth.mlpack +++ b/DwarfSynth.mlpack @@ -5,3 +5,5 @@ Regs OnlyUnwind Simplest Frontend +PreCBinding + diff --git a/DwarfSynth/Main.ml b/DwarfSynth/Main.ml index 877cd18..c9f4ff5 100644 --- a/DwarfSynth/Main.ml +++ b/DwarfSynth/Main.ml @@ -2,4 +2,9 @@ open Std let main outfile proj = let pre_dwarf = Simplest.of_proj proj in - Format.printf "%a" Frontend.pp_pre_dwarf_readelf pre_dwarf + Format.printf "%a" Frontend.pp_pre_dwarf_readelf pre_dwarf; + let pre_c_dwarf = PreCBinding.convert_pre_c pre_dwarf in + let fd = open_out_bin "tmp.marshal" in + Marshal.to_channel fd pre_c_dwarf [] + + diff --git a/DwarfSynth/PreCBinding.ml b/DwarfSynth/PreCBinding.ml index 546b87b..a315536 100644 --- a/DwarfSynth/PreCBinding.ml +++ b/DwarfSynth/PreCBinding.ml @@ -20,6 +20,10 @@ type pre_c_pre_dwarf = { fdes: pre_c_pre_dwarf_fde array } +(* OCAML -> C conversion *) + +(* external write_dwarf : string -> pre_c_pre_dwarf -> int = "caml__write_dwarf" *) + (* ========================================================================= *) (** Empty default value for `pre_c_pre_dwarf_entry` *) diff --git a/DwarfSynth/c_bindings/Makefile b/DwarfSynth/c_bindings/Makefile index 28d6c78..02047a6 100644 --- a/DwarfSynth/c_bindings/Makefile +++ b/DwarfSynth/c_bindings/Makefile @@ -1,15 +1,23 @@ CDEFINE = -CFLAGS = -Wall -Wextra -std=c11 -O2 -g $(CDEFINE) +CFLAGS = -Wall -Wextra -std=c11 -O2 -g $(CDEFINE) -I/home/zappa/.opam/bap/lib/ocaml LIBDWARFW_DIR=../../libdwarfw/build -CLIBS = -L$(LIBDWARFW_DIR) -Wl,-rpath,$(LIBDWARFW_DIR) -lelf -ldwarf -ldwarfw +CLIBS = -L$(LIBDWARFW_DIR) -Wl,-rpath,$(LIBDWARFW_DIR) -lz -lelf -ldwarf -ldwarfw +OCAMLCLIBS = -ccopt -L$(LIBDWARFW_DIR) -ccopt -Wl,-rpath,$(LIBDWARFW_DIR) -cclib -lz -cclib -lelf -cclib -ldwarf -cclib -ldwarfw -all: test_dw.bin + +all: test_dw.bin ml_dwarf_write.bin test_%.bin: test_%.o dwarf_write.o - gcc $(CFLAGS) $(CLIBS) $^ -o $@ + gcc $(CFLAGS) $^ /usr/lib/x86_64-linux-gnu/libelf.a $(CLIBS) -o $@ %.o: %.c gcc $(CFLAGS) -c $< -o $@ +ml_dwarf_write.bin: ml_dwarf_write.ml dwarf_write_stubs.c dwarf_write.o + ocamlopt -c dwarf_write_stubs.c + ocamlopt -o ml_dwarf_write.bin ml_dwarf_write.ml dwarf_write_stubs.o dwarf_write.o $(OCAMLCLIBS) + clean: - rm -f *.o test_*.bin + rm -f *.o *.bin + +.PRECIOUS: %.o diff --git a/DwarfSynth/c_bindings/dwarf_write.h b/DwarfSynth/c_bindings/dwarf_write.h index f060433..3230e44 100644 --- a/DwarfSynth/c_bindings/dwarf_write.h +++ b/DwarfSynth/c_bindings/dwarf_write.h @@ -10,7 +10,7 @@ #include "../../libdwarfw/include/dwarfw.h" -#include +#include #include #include #include diff --git a/DwarfSynth/c_bindings/dwarf_write_stubs.c b/DwarfSynth/c_bindings/dwarf_write_stubs.c new file mode 100644 index 0000000..7f66615 --- /dev/null +++ b/DwarfSynth/c_bindings/dwarf_write_stubs.c @@ -0,0 +1,161 @@ +#include "dwarf_write.h" + +#include + +#include +#include +#include +#include + +/* dump functions */ + +void dump_pre_dwarf_entry(struct pre_dwarf_entry e) { + printf(" %lx %d + %lld\n", e.location, e.cfa_offset_reg, e.cfa_offset); +} + +void dump_pre_dwarf_fde(struct pre_dwarf_fde f) { + printf("%ld\n", f.num); + printf("%lx %lx\n", f.initial_location, f.end_location); + for (int i=0; i < f.num; i++) + dump_pre_dwarf_entry(f.entries[i]); +} + +void dump_pre_dwarf (struct pre_dwarf p) { + printf("num_fde: %ld \n", p.num_fde); + for (int i=0; i < p.num_fde; i++) { + dump_pre_dwarf_fde(p.fdes[i]); + } +} + +void margin (int n) + { while (n-- > 0) printf("."); return; } + +void print_block (value v,int m) +{ + int size, i; + margin(m); + if (Is_long(v)) + { printf("immediate value (%ld)\n", Long_val(v)); return; }; + printf ("memory block: size=%d - ", size=Wosize_val(v)); + switch (Tag_val(v)) + { + case Closure_tag : + printf("closure with %d free variables\n", size-1); + margin(m+4); printf("code pointer: %p\n",Code_val(v)) ; + for (i=1;i=No_scan_tag) { printf("unknown tag"); break; }; + printf("structured block (tag=%d):\n",Tag_val(v)); + for (i=0;ilocation = convert_addr_t(Field(oc_pde, 0)); + pde->cfa_offset = convert_offset_t(Field(oc_pde, 1)); + pde->cfa_offset_reg = convert_reg_t(Field(oc_pde, 2)); + + return pde; +} + +struct pre_dwarf_fde convert_pre_dwarf_fde(value oc_pre_dwarf_fde) { + + struct pre_dwarf_fde * pre_dwarf_fde = malloc(sizeof(struct pre_dwarf_fde)); + + CAMLparam1(oc_pre_dwarf_fde); + + pre_dwarf_fde->num = Int_val(Field(oc_pre_dwarf_fde,0)); + pre_dwarf_fde->initial_location = int64_of_value (Field(oc_pre_dwarf_fde,1)); + pre_dwarf_fde->end_location = int64_of_value(Field(oc_pre_dwarf_fde,2)); + + // FZ: is num the correct size? we can also read the size from the array. + + pre_dwarf_fde->entries = malloc(sizeof(struct pre_dwarf_entry) * pre_dwarf_fde->num); + + for (unsigned int i=0; i < pre_dwarf_fde->num; i++) + pre_dwarf_fde->entries[i] = *convert_pre_dwarf_entry(Field(Field(oc_pre_dwarf_fde,4),i)); + + return *pre_dwarf_fde; +} + +struct pre_dwarf * convert_pre_dwarf(value oc_pre_dwarf) { + struct pre_dwarf * pre_dwarf = malloc(sizeof(struct pre_dwarf)); + + pre_dwarf->num_fde = (size_t) Int_val(Field(oc_pre_dwarf,0)); + + //array + + pre_dwarf->fdes = malloc(sizeof(struct pre_dwarf_fde) * pre_dwarf->num_fde); + for (unsigned int i=0; i < pre_dwarf->num_fde; i++) { + pre_dwarf->fdes[i] = convert_pre_dwarf_fde(Field(Field(oc_pre_dwarf,1),i)); + } + return pre_dwarf; +} + +// OCaml type: string -> pre_c_dwarf -> int +value caml_write_dwarf (value oc_obj_path, value oc_pre_dwarf) { + + char *obj_path; + struct pre_dwarf *pre_dwarf; + + CAMLparam2(oc_obj_path, oc_pre_dwarf); + + // inspect_block(oc_pre_dwarf); + + obj_path = String_val(oc_obj_path); + + pre_dwarf = convert_pre_dwarf(oc_pre_dwarf); + + dump_pre_dwarf(*pre_dwarf); + + CAMLreturn(write_dwarf(obj_path, pre_dwarf)); +} diff --git a/DwarfSynth/c_bindings/ml_dwarf_write.ml b/DwarfSynth/c_bindings/ml_dwarf_write.ml new file mode 100644 index 0000000..ec21a7f --- /dev/null +++ b/DwarfSynth/c_bindings/ml_dwarf_write.ml @@ -0,0 +1,47 @@ +(* copy here as quick hack / restructure the file directory *) + +type pre_c_pre_dwarf_entry = { + location: int64; + cfa_offset: int64; + cfa_offset_reg: int +} + +type pre_c_pre_dwarf_fde = { + num: int; + initial_location: int64; + end_location: int64; + name: string; + entries: pre_c_pre_dwarf_entry array +} + +type pre_c_pre_dwarf = { + num_fde: int; + fdes: pre_c_pre_dwarf_fde array +} + +let dump_pre_c_pre_dwarf_entry e = + Printf.printf " %8Lx %d+%Ld \n" e.location e.cfa_offset_reg e.cfa_offset + +let dump_pre_c_pre_dwarf_fde f = + Printf.printf "%s %Lx %Lx\n" f.name f.initial_location f.end_location; + for i = 0 to Array.length f.entries - 1 do + dump_pre_c_pre_dwarf_entry f.entries.(i) + done + + +let dump_pre_c_pre_dwarf p = + for i = 0 to Array.length p.fdes - 1 do + dump_pre_c_pre_dwarf_fde p.fdes.(i) + done + + +external write_dwarf : string -> pre_c_pre_dwarf -> int = "caml_write_dwarf" + +(* use: ml_dwarf_write *) + +let _ = + let fd = open_in_bin Sys.argv.(1) in + let pre_c_dwarf = ((Marshal.from_channel fd): pre_c_pre_dwarf) in + dump_pre_c_pre_dwarf pre_c_dwarf; + write_dwarf Sys.argv.(2) pre_c_dwarf + diff --git a/Makefile b/Makefile index 7d9b915..9a80d49 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -OCAMLBUILD=bapbuild +OCAMLBUILD=bapbuild -no-hygiene BAPBUNDLE=bapbundle ROOT_MODULE=dwarfsynth diff --git a/_tags b/_tags index 251debe..d6c64b1 100644 --- a/_tags +++ b/_tags @@ -7,3 +7,4 @@ true: bin_annot : for-pack(DwarfSynth) : for-pack(DwarfSynth) : for-pack(DwarfSynth) +: for-pack(DwarfSynth)