From 828abdf495b260bd9db80a3782aeafb2bc4dd247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Bastian?= Date: Sun, 23 Dec 2018 15:36:24 +0100 Subject: [PATCH] Remove relocation data in dwarf_write --- DwarfSynth/PreCBinding.ml | 4 +-- DwarfSynth/c_bindings/.gitignore | 3 +++ DwarfSynth/c_bindings/Makefile | 15 +++++++++++ DwarfSynth/c_bindings/dwarf_write.c | 41 ++++++++++++++++++++++------- DwarfSynth/c_bindings/dwarf_write.h | 5 ++++ DwarfSynth/c_bindings/test_dw.c | 18 +++++++++++++ 6 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 DwarfSynth/c_bindings/.gitignore create mode 100644 DwarfSynth/c_bindings/Makefile create mode 100644 DwarfSynth/c_bindings/test_dw.c diff --git a/DwarfSynth/PreCBinding.ml b/DwarfSynth/PreCBinding.ml index 6d5ca99..546b87b 100644 --- a/DwarfSynth/PreCBinding.ml +++ b/DwarfSynth/PreCBinding.ml @@ -68,9 +68,9 @@ let convert_pre_c_entries entries : pre_c_pre_dwarf_entry array = (fun loc entry _ -> convert_pre_c_entry loc entry) entries empty_entry -let convert_pre_c_fde name entry num : pre_c_pre_dwarf_fde = +let convert_pre_c_fde name entry id : pre_c_pre_dwarf_fde = { - num = num; + num = AddrMap.cardinal entry.cfa_changes_fde; initial_location = entry.beg_pos; end_location = entry.end_pos; name = name; diff --git a/DwarfSynth/c_bindings/.gitignore b/DwarfSynth/c_bindings/.gitignore new file mode 100644 index 0000000..09d4d6b --- /dev/null +++ b/DwarfSynth/c_bindings/.gitignore @@ -0,0 +1,3 @@ +*.o +*.bin +*.bck diff --git a/DwarfSynth/c_bindings/Makefile b/DwarfSynth/c_bindings/Makefile new file mode 100644 index 0000000..28d6c78 --- /dev/null +++ b/DwarfSynth/c_bindings/Makefile @@ -0,0 +1,15 @@ +CDEFINE = +CFLAGS = -Wall -Wextra -std=c11 -O2 -g $(CDEFINE) +LIBDWARFW_DIR=../../libdwarfw/build +CLIBS = -L$(LIBDWARFW_DIR) -Wl,-rpath,$(LIBDWARFW_DIR) -lelf -ldwarf -ldwarfw + +all: test_dw.bin + +test_%.bin: test_%.o dwarf_write.o + gcc $(CFLAGS) $(CLIBS) $^ -o $@ + +%.o: %.c + gcc $(CFLAGS) -c $< -o $@ + +clean: + rm -f *.o test_*.bin diff --git a/DwarfSynth/c_bindings/dwarf_write.c b/DwarfSynth/c_bindings/dwarf_write.c index 40de7cb..fe84671 100644 --- a/DwarfSynth/c_bindings/dwarf_write.c +++ b/DwarfSynth/c_bindings/dwarf_write.c @@ -6,6 +6,7 @@ #include "dwarf_write.h" + struct internal_state { Elf *elf; }; @@ -255,10 +256,11 @@ static int write_all_fde_instructions(struct dwarfw_fde *fde, } static int process_section(struct internal_state* state, - struct pre_dwarf* pre_dwarf, Elf_Scn *s, FILE *f, size_t *written, - FILE *rela_f) + struct pre_dwarf* pre_dwarf, Elf_Scn *s, FILE *f, size_t *written /*, + FILE *rela_f */) { size_t shndx = elf_ndxscn(s); + fprintf(stderr, "Processing section %lu\n", shndx); //D GElf_Sym text_sym; int text_sym_idx = find_section_symbol(state->elf, shndx, &text_sym); @@ -267,6 +269,12 @@ static int process_section(struct internal_state* state, return 1; } + GElf_Shdr shdr; + gelf_getshdr(s, &shdr); + uintptr_t s_addr = shdr.sh_addr, + s_endaddr = shdr.sh_addr + shdr.sh_size; + + struct dwarfw_cie cie = { .version = 1, .augmentation = "zR", @@ -274,7 +282,7 @@ static int process_section(struct internal_state* state, .data_alignment = -8, .return_address_register = 16, .augmentation_data = { - .pointer_encoding = DW_EH_PE_sdata4 | DW_EH_PE_pcrel, + .pointer_encoding = DW_EH_PE_sdata4 /* | DW_EH_PE_pcrel */, }, }; @@ -289,6 +297,14 @@ static int process_section(struct internal_state* state, for (size_t fde_id = 0; fde_id < pre_dwarf->num_fde; ++fde_id) { struct pre_dwarf_fde* cur_fde = &(pre_dwarf->fdes[fde_id]); + if(!(s_addr <= cur_fde->initial_location + && cur_fde->end_location < s_endaddr)) + // The fde is not included in this section + { + continue; + } + fprintf(stderr, "FDE %lu belongs to this section\n", cur_fde->num); //D + struct dwarfw_fde fde = { .cie = &cie, .initial_location = cur_fde->initial_location, @@ -317,16 +333,17 @@ static int process_section(struct internal_state* state, fde.instructions = instr_buf; fde.cie_pointer = *written; - GElf_Rela initial_position_rela; - if (!(n = dwarfw_fde_write(&fde, &initial_position_rela, f))) { + /* GElf_Rela initial_position_rela; */ + if (!(n = dwarfw_fde_write(&fde, /*&initial_position_rela*/NULL, f))) { fprintf(stderr, "dwarfw_fde_write() failed\n"); return -1; } - initial_position_rela.r_offset += *written; + /* initial_position_rela.r_offset += *written; */ *written += n; free(instr_buf); // r_offset and r_addend have already been populated by dwarfw_fde_write + /* initial_position_rela.r_info = GELF_R_INFO(text_sym_idx, ELF32_R_TYPE(initial_position_rela.r_info)); @@ -334,6 +351,7 @@ static int process_section(struct internal_state* state, fprintf(stderr, "can't write rela\n"); return 1; } + */ } return 0; @@ -382,6 +400,7 @@ int write_dwarf(char* objname, struct pre_dwarf* pre_dwarf) { return 1; } + /* char *rela_buf; size_t rela_len; FILE *rela_f = open_memstream(&rela_buf, &rela_len); @@ -389,6 +408,7 @@ int write_dwarf(char* objname, struct pre_dwarf* pre_dwarf) { fprintf(stderr, "open_memstream() failed\n"); return 1; } + */ size_t written = 0; for (size_t i = 0; i < sections_num; ++i) { @@ -406,13 +426,12 @@ int write_dwarf(char* objname, struct pre_dwarf* pre_dwarf) { continue; } - if (process_section(&state, pre_dwarf, s, f, &written, rela_f)) { + if (process_section(&state, pre_dwarf, s, f, &written /*, rela_f*/)) { return 1; } } - fclose(f); - fclose(rela_f); + /* fclose(rela_f); */ // Create the .eh_frame section Elf_Scn *scn = create_debug_frame_section(elf, ".eh_frame", buf, len); @@ -421,6 +440,7 @@ int write_dwarf(char* objname, struct pre_dwarf* pre_dwarf) { return 1; } + /* // Create the .eh_frame.rela section Elf_Scn *rela = create_rela_section(elf, ".rela.eh_frame", scn, rela_buf, rela_len); @@ -428,6 +448,7 @@ int write_dwarf(char* objname, struct pre_dwarf* pre_dwarf) { fprintf(stderr, "create_rela_section() failed\n"); return 1; } + */ // Write the modified ELF object elf_flagelf(elf, ELF_C_SET, ELF_F_DIRTY); @@ -437,7 +458,7 @@ int write_dwarf(char* objname, struct pre_dwarf* pre_dwarf) { } free(buf); - free(rela_buf); + /* free(rela_buf); */ elf_end(elf); close(fd); diff --git a/DwarfSynth/c_bindings/dwarf_write.h b/DwarfSynth/c_bindings/dwarf_write.h index da38ba5..f060433 100644 --- a/DwarfSynth/c_bindings/dwarf_write.h +++ b/DwarfSynth/c_bindings/dwarf_write.h @@ -6,6 +6,8 @@ #pragma once +#define _XOPEN_SOURCE 700 + #include "../../libdwarfw/include/dwarfw.h" #include @@ -52,3 +54,6 @@ struct pre_dwarf { size_t num_fde; struct pre_dwarf_fde* fdes; }; + +/// Writes the provided `pre_dwarf` as DWARF in the ELF file at `obj_path` +int write_dwarf(char* obj_path, struct pre_dwarf* pre_dwarf); diff --git a/DwarfSynth/c_bindings/test_dw.c b/DwarfSynth/c_bindings/test_dw.c new file mode 100644 index 0000000..071e23c --- /dev/null +++ b/DwarfSynth/c_bindings/test_dw.c @@ -0,0 +1,18 @@ +#include +#include +#include "dwarf_write.h" + +int main() { + struct pre_dwarf_entry entries[3] = { + { 0x1300, DW_REG_RSP, 8 }, + { 0x1310, DW_REG_RSP, 16 }, + { 0x1340, DW_REG_RSP, 8 } + }; + struct pre_dwarf_fde fde = { + 3, entries, 0x1300, 0x1342 + }; + struct pre_dwarf dwarf_data = {1, &fde}; + + write_dwarf("test.bin", &dwarf_data); + return 0; +}