diff --git a/dwarf/.keep b/dwarf/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/dwarf/modify_debug_section.c b/dwarf/modify_debug_section.c new file mode 100644 index 0000000000000000000000000000000000000000..0616b63804018ac84d13fcabe87da60016387dd4 --- /dev/null +++ b/dwarf/modify_debug_section.c @@ -0,0 +1,203 @@ +#include /* for printf */ +#include /* for free() */ +#include /* for memcmp() */ +#include "dwarf.h" +#include "libdwarf.h" +#include "dwarf_base_types.h" +#include "dwarf_opaque.h" +#include "dwarf_die_deliv.h" + +#include "modify_debug_section.h" + +#define TRUE 1 +#define FALSE 0 + +// the value of offse to be increase +static long ChangeOffset; +// .debug_info section offset (from the beginning elf file) +static unsigned long DiSecOff; + +// char* cu_2_file[100] = {"", "banana", "orange"}; +char* cu_2_elf_idx[100]; +// memset(cu_2_file, 0, sizeof(cu_2_file)); +// elf file paths before sysboost combine +static char** elf_paths[100]; +static unsigned int elf_num; + +int _get_cu_num(char* path){ + Dwarf_Debug dbg = df_init(path); + int cu_num = 0; + while (get_first_die_of_next_cu(dbg, NULL, NULL) == DW_DLV_OK) { + cu_2_elf_path[] + cu_num++; + } + dwarf_finish(dbg); + return cu_num; +} + +void load_raw_file_info(char** paths, len){ + for (int i=0; idi_cu_context->cc_dbg; + Dwarf_Off ret_offset = (die->di_debug_ptr - dbg->de_debug_info.dss_data); + Dwarf_Byte_Ptr die_info_end = + _dwarf_calculate_info_section_end_ptr(die->di_cu_context); + Dwarf_Byte_Ptr info_ptr = die->di_debug_ptr; + Dwarf_Error* error; + int sum = 0; + + Dwarf_Unsigned ignore_this = 0; + Dwarf_Unsigned len = 0; + int lres = dwarf_decode_leb128((char *)info_ptr, + &len,&ignore_this,(char *)die_info_end); + info_ptr += len; + + for (int i = 0; i < die->di_abbrev_list->abl_abbrev_count; ++i) { + Dwarf_Unsigned attr_form = die->di_abbrev_list->abl_form[i]; + Dwarf_Unsigned sov = 0; + + if (attr_form != DW_FORM_implicit_const) { + Dwarf_Unsigned sov = 0; + int vres = 0; + + vres = _dwarf_get_size_of_val(dbg, attr_form, + die->di_cu_context->cc_version_stamp, + die->di_cu_context->cc_address_size, + info_ptr, + die->di_cu_context->cc_length_size, + &sov, + die_info_end, + error); + info_ptr += sov; + + die->di_abbrev_list[i]; + + // DO SOMTHING !!!!! START + if (die->di_abbrev_list->abl_attr[i] == DW_AT_low_pc) + printf("[low]"); + // // if DW_FORM_line_strp, change abl value to new .debug_line_str offset + if (die->di_abbrev_list->abl_form[i] == DW_FORM_line_strp){ + unsigned char offset = info_ptr-sov-dbg->de_debug_info.dss_data; + printf("DW_FORM_line_strp"); + } + // DO SOMTHING !!!!! END + // offset = sum+ret_offset+1 or info_ptr-sov-dbg->de_debug_info.dss_data + printf("%d: %d, sov is %ld, sum is %ld, final: %x, %x\n",i, attr_form, sov, sum, sum+ret_offset+1, info_ptr-sov-dbg->de_debug_info.dss_data); + sum += sov; + } + } +} + + +void traverse_cu(Dwarf_Debug dbg) +{ + int res = 0; + int is_info = TRUE; + Dwarf_Error error = 0; + + Dwarf_Die first_die; + do { + res = get_first_die_of_next_cu(dbg, &first_die, error); + traverse_die(first_die); + } while (res == DW_DLV_OK); +} + +void get_first_die_of_next_cu(Dwarf_Debug dbg, Dwarf_Die* caller_ret_die, Dwarf_Error * error) +{ + int res = 0; + int is_info = TRUE; + res = dwarf_next_cu_header_d(dbg, is_info, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL,&error); + + if (res != DW_DLV_OK) { + printf("dwarf_next_cu_header_d ERROR\n", error); + return res; + } + + res = dwarf_siblingof_b(dbg, NULL, is_info, caller_ret_die, error); + if (res != DW_DLV_OK) { + printf("dwarf_siblingof_b ERROR\n", error); + } + return res; +} + +int traverse_die(Dwarf_Die parent_die, Dwarf_Error * error) +{ + // DO SOMETHING + get_low_pc_key_val(parent_die); + + Dwarf_Die* stack[20]; + Dwarf_Die son_die; + int res = 0; + + res = dwarf_child(parent_die, &son_die, error); + + // dgb right? + Dwarf_Debug dbg = parent_die->di_cu_context->cc_dbg; + while (res == DW_DLV_OK) { + traverse_die(son_die, error); + res = dwarf_siblingof_b(dbg, son_die, TRUE, &son_die, error); + } + if (res == DW_DLV_NO_ENTRY) { + // no more child + return DW_DLV_OK; + } else { + printf("dwarf_child or dwarf_siblingof_b ERROR\n", error); + return res; + } +} + +Dwarf_Debug df_init(const char *path) +{ + static char true_pathbuf[FILENAME_MAX]; + unsigned tpathlen = FILENAME_MAX; + Dwarf_Handler errhand = 0; + Dwarf_Ptr errarg = 0; + Dwarf_Error error = 0; + Dwarf_Debug dbg = 0; + unsigned groupnumber = DW_GROUPNUMBER_ANY; + int res = 0; + + res = dwarf_init_path(path,true_pathbuf, + tpathlen,groupnumber,errhand, + errarg,&dbg, &error); + Dwarf_Die first_die; + + return dbg; +} + +int main(){ + char *path = "/home/brook/out/static/nobel.static"; + // char *path = "/home/sysboost/nobel.rto"; + ChangeOffset = 0x550000; + DiSecOff = get_debug_info_section_offset(path); + Dwarf_Debug dbg = df_init(path); + traverse_cu(dbg); + dwarf_finish(dbg); + return 0; +} diff --git a/dwarf/test_get_section_info.c b/dwarf/test_get_section_info.c new file mode 100644 index 0000000000000000000000000000000000000000..6f63b6f6d881860b798a6956326a4d7e9850d3f9 --- /dev/null +++ b/dwarf/test_get_section_info.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include + +struct sh_data { + unsigned int sh_size; + unsigned int sh_offset; +}; + +int get_section_info(const char* filename, struct sh_data** data, int* count) { + int fd = popen(filename, O_RDONLY); + if (fd < 0) { + printf("Failed to open file: %s\n", filename); + return -1; + } + + Elf* elf = elf_begin(fd, ELF_C_READ, NULL); + if (elf == NULL) { + printf("Failed to read ELF file: %s\n", filename); + close(fd); + return -1; + } + + int shnum; + if (elf_getshnum(elf, &shnum) != 0) { + printf("Failed to get section header count: %s\n", elf_errmsg(-1)); + elf_end(elf); + close(fd); + return -1; + } + + struct sh_data* section_data = (struct sh_data*)malloc(shnum * sizeof(struct sh_data)); + if (section_data == NULL) { + printf("Failed to allocate memory for section data.\n"); + elf_end(elf); + close(fd); + return -1; + } + + memset(section_data, 0, shnum * sizeof(struct sh_data)); + + Elf_Scn* scn = NULL; + while ((scn = elf_nextscn(elf, scn)) != NULL) { + GElf_Shdr shdr; + if (gelf_getshdr(scn, &shdr) != &shdr) { + printf("Failed to get section header: %s\n", elf_errmsg(-1)); + free(section_data); + elf_end(elf); + close(fd); + return -1; + } + + const char* name = elf_strptr(elf, elf_getshdrstrndx(elf), shdr.sh_name); + if (name == NULL) { + printf("Failed to get section name: %s\n", elf_errmsg(-1)); + free(section_data); + elf_end(elf); + close(fd); + return -1; + } + + int index = elf_ndxscn(scn); + section_data[index].sh_size = shdr.sh_size; + section_data[index].sh_offset = shdr.sh_offset; + } + + elf_end(elf); + close(fd); + + *data = section_data; + *count = shnum; + + return 0; +} + +int main(int argc, char** argv) { + if (argc != 2) { + printf("Usage: %s \n", argv[0]); + return 1; + } + + struct sh_data* section_data; + int count; + if (get_section_info(argv[1], §ion_data, &count) != 0) { + printf("Failed to get section info.\n"); + return 1; + } + + printf("Section info for %s:\n", argv[1]); + for (int i = 0; i < count; i++) { + printf("%s: size=%u, offset=%u\n", elf_strptr(elf, elf_getshdrstrndx(elf), i), section_data[i].sh_size, section_data[i].sh_offset); + } + + free(section_data); + return 0; +} +// void main(){} \ No newline at end of file diff --git a/dwarf/test_write.c b/dwarf/test_write.c new file mode 100644 index 0000000000000000000000000000000000000000..0bbd67956adcebcca6d42c271418c5faf96e5ac8 --- /dev/null +++ b/dwarf/test_write.c @@ -0,0 +1,71 @@ +#include +#include + +unsigned int r_debug_info_start = 0x00435f5b; +unsigned int r_debug_info_offsets[] = {0x448c, 0x9d, 0}; // == raw binary .debug_info size +unsigned int r_debug_abbrev_offsets[] = {0x443, 0x80, 0}; // get by rto abbrev== raw binary .debug_abbrev size +// Abbrev Offset length 4 in aarch64 + +FILE* open_rto(char* file_name) +{ + // todo how to open to make fseek fast + FILE *file = fopen(file_name, "rb+"); + if (file == NULL) { + printf("FAIL OPEN"); + return NULL; + } + return file; +} + +void _print_old_value(FILE *file, int offset, int len) +{ + fseek(file, offset, SEEK_SET); + char buffer[len]; + size_t bytesRead = fread(buffer, 1, len, file); + if (bytesRead > 0) { + printf("at %d: ", offset); + for (size_t i = 0; i < bytesRead; ++i) { + printf("%lx", buffer[i]); + } + printf(" -> "); + } else { + printf("FAIL to READ\n"); + } +} + +void modify(FILE *file, int offset, int len, void* newValue) +{ + _print_old_value(file, offset, len); + fseek(file, offset, SEEK_SET); + for (size_t i = 0; i < len; ++i) { + printf("%x", *(char *)(newValue+i)); + } + printf("\n"); + fwrite(newValue, len, 1, file); +} + +void modify_debug_info_abbrev_offset(FILE *file, unsigned int debug_info_start, unsigned int debug_info_offsets[], unsigned int debug_abbrev_offsets[]) +{ + const unsigned int FILE_COUNT = 3; + const unsigned int ABBREV_OFFSET_LEN = 4; + const unsigned int ABBREV_OFFSET_OFFSET = 8; + unsigned int di_offset = debug_info_start + ABBREV_OFFSET_OFFSET; + unsigned int da_offset = 0x0; + for (int i = 1; i < FILE_COUNT; i++) { + di_offset += debug_info_offsets[i-1]; + da_offset += debug_abbrev_offsets[i-1]; + printf("change at %lx to %lx\n", di_offset, da_offset); + modify(file, di_offset, ABBREV_OFFSET_LEN, &da_offset); + } +} + +void test_modify_debug_info_abbrev_offset(){ + FILE *file = open_rto("/home/sysboost/nobel.rto"); + modify_debug_info_abbrev_offset(file, r_debug_info_start, r_debug_info_offsets, r_debug_abbrev_offsets); +} +int main() { + // FILE *file = open_rto("test_write.txt"); + // modify(file, 1, 2, "xy"); + test_modify_debug_info_abbrev_offset(); + return 0; +} diff --git a/meson.build b/meson.build index 7a3c6e16045f05f4aacfc612c2c1d3893e0a5f2a..05f2a67cb99ff43f57bb9cb430094fb27b9f73a7 100644 --- a/meson.build +++ b/meson.build @@ -4,7 +4,7 @@ project('SYSBOOST', 'C', version: run_command(find_program('cat', 'more'), files('VERSION'), check: true).stdout().strip(), license: 'MulanPSL', default_options: [ - 'buildtype=release', + 'buildtype=debug', 'default_library=static', 'warning_level=2', ], @@ -35,4 +35,4 @@ lk_args = [] subdir('src') # build tests -subdir('tests') \ No newline at end of file +subdir('tests') diff --git a/src/elf_link_common.c b/src/elf_link_common.c index 190ad6a3b6d174f58ac7cb18d5830f84a56c62bf..ab21c44f5cd4a2fe88b35ea0c3f8c2c2cd163cdd 100644 --- a/src/elf_link_common.c +++ b/src/elf_link_common.c @@ -123,6 +123,9 @@ static char *needed_sections[] = { ".symtab", ".strtab", ".shstrtab", + ".debug_info", + ".debug_line", + ".debug_str", }; #define NEEDED_SECTIONS_LEN (sizeof(needed_sections) / sizeof(needed_sections[0])) @@ -590,9 +593,11 @@ static unsigned long _get_new_elf_addr(elf_link_t *elf_link, elf_file_t *src_ef, for (int i = 0; i < len; i++) { sec_rel = &sec_rels[i]; + // sec_rel is a section in the same file as src_ef if (sec_rel->src_ef != src_ef) { continue; } + // old addr is between source section if (addr < sec_rel->src_sec->sh_addr || addr > sec_rel->src_sec->sh_addr + sec_rel->src_sec->sh_size) { continue; } @@ -602,7 +607,12 @@ static unsigned long _get_new_elf_addr(elf_link_t *elf_link, elf_file_t *src_ef, } // section like .symtab has no addr if (!(sec_rel->src_sec->sh_flags & SHF_ALLOC)) { - continue; + char *name = elf_get_section_name(src_ef, sec_rel->src_sec); + if (strncmp(name, ".debug_info", 11) == 0) { + printf("new addr found: %s", name); + } else { + continue; + } } // .tbss has the same offset as .init_array, e.g. // [22] .tbss NOBITS 00000000007ffd18 005ffd18 @@ -626,13 +636,21 @@ static unsigned long _get_new_elf_addr(elf_link_t *elf_link, elf_file_t *src_ef, if (found) { // out elf must be pic tmp = (addr - sec_rel->src_sec->sh_addr) + (unsigned long)sec_rel->dst_mem_addr; - if (sec_rel->src_sec->sh_addr == 0) { - si_log_set_global_level(SI_LOG_LEVEL_DEBUG); - show_sec_mapping(elf_link); - SI_LOG_DEBUG("dst_file_offset %lx dst_sec->sh_offset %lx dst_sec->sh_addr %lx src_sec->sh_addr %lx\n", - sec_rel->dst_file_offset, sec_rel->dst_sec->sh_offset, sec_rel->dst_sec->sh_addr, sec_rel->src_sec->sh_addr); - si_panic("%s %lx %lx\n", src_ef->file_name, addr, tmp); - } + char *name = elf_get_section_name(src_ef, sec_rel->src_sec); + printf("nnamee: %s ", name); + printf("addr %lx, sec_rel->src_sec->sh_addr %lx, sec_rel->dst_mem_addr %lx\n", + addr, sec_rel->src_sec->sh_addr, sec_rel->dst_mem_addr); + // if (sec_rel->src_sec->sh_addr == 0) { + // si_log_set_global_level(SI_LOG_LEVEL_DEBUG); + // show_sec_mapping(elf_link); + // char *name = elf_get_section_name(src_ef, sec_rel->src_sec); + // printf("nnamee: %s", name); + // printf("dst_file_offset %lx dst_sec->sh_offset %lx dst_sec->sh_addr %lx src_sec->sh_addr %lx\n", + // sec_rel->dst_file_offset, sec_rel->dst_sec->sh_offset, sec_rel->dst_sec->sh_addr, sec_rel->src_sec->sh_addr); + // SI_LOG_DEBUG("dst_file_offset %lx dst_sec->sh_offset %lx dst_sec->sh_addr %lx src_sec->sh_addr %lx\n", + // sec_rel->dst_file_offset, sec_rel->dst_sec->sh_offset, sec_rel->dst_sec->sh_addr, sec_rel->src_sec->sh_addr); + // si_panic("%s %lx %lx\n", src_ef->file_name, addr, tmp); + // } return tmp; } diff --git a/src/elf_link_elf.c b/src/elf_link_elf.c index 0e9a1d7939d04a445a62eba7fbc72b21ad83f508..f27c839bd4a34dab0962040c3a9eb0489d88178c 100644 --- a/src/elf_link_elf.c +++ b/src/elf_link_elf.c @@ -584,6 +584,36 @@ static void modify_tls_segment(elf_link_t *elf_link) modify_segment(elf_link, out_ef->tls_Phdr, ".tdata", ".tbss"); } +static void write_debug_info(elf_link_t *elf_link) +{ + // unsigned int start = 0; + // Elf64_Phdr *p; + // elf_file_t *out_ef = &elf_link->out_ef; + merge_debug_sections(elf_link); + + unsigned int start = elf_align_file_segment(elf_link); + printf("start: %d", start); + + // elf_align_file_segment(elf_link); + // printf(p); + // p = out_ef->debug_info_Phdr; + // p->p_offset = start; + // p->p_vaddr = start; + // p->p_paddr = start; + // p->p_filesz = elf_link->next_file_offset - start; + // p->p_memsz = p->p_filesz; +} + +// static void write_debug_line(elf_link_t *elf_link) +// { +// merge_debug_sections(elf_link); + +// unsigned int start = elf_align_file_segment(elf_link); +// printf("start: %d", start); + +// elf_align_file_segment(elf_link); +// } + // .tdata .init_array .fini_array .dynamic .got .got.plt .data .bss static void write_data(elf_link_t *elf_link) { @@ -1401,6 +1431,9 @@ static void elf_link_write_sections(elf_link_t *elf_link) // .shstrtab write_shstrtab(elf_link); + write_debug_info(elf_link); + + // write_debug_line(elf_link); /* * .comment is useless, it's used to hold comments about the generated ELF * (details such as compiler version and execution platform). diff --git a/src/elf_read_elf.c b/src/elf_read_elf.c index 612400811e860f6c28e52b37d401c451177f449f..eba2b5cd7e7bb55b4ecaa0f5f9a5b3b16c5dd191 100644 --- a/src/elf_read_elf.c +++ b/src/elf_read_elf.c @@ -36,6 +36,7 @@ #endif #define DEBUG_SEC_PRE_NAME ".debug_" +#define RELA_DEBUG_SEC_PRE_NAME ".rela.debug_" #define BUILD_ID_LEN 40 #define ELF_VERSION_NR_LOCAL 0 @@ -477,6 +478,36 @@ bool elf_is_debug_section(elf_file_t *ef, Elf64_Shdr *sechdr) return false; } +bool elf_is_rela_debug_section(elf_file_t *ef, Elf64_Shdr *sechdr) +{ + char *name = NULL; + + name = ef->shstrtab_data + sechdr->sh_name; + if (strncmp(name, RELA_DEBUG_SEC_PRE_NAME, sizeof(RELA_DEBUG_SEC_PRE_NAME) - 1) == 0) { + return true; + } + + return false; +} + +bool debug_info_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec) +{ + char *name = elf_get_section_name(ef, sec); + return strcmp(name, ".debug_info") == 0; +} + +bool debug_line_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec) +{ + char *name = elf_get_section_name(ef, sec); + return strcmp(name, ".debug_line") == 0; +} + +bool debug_str_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec) +{ + char *name = elf_get_section_name(ef, sec); + return strcmp(name, ".debug_str") == 0; +} + // text | rodata | got | data | bss bool elf_is_same_area(const elf_file_t *ef, const Elf64_Shdr *a, const Elf64_Shdr *b) { diff --git a/src/elf_read_elf.h b/src/elf_read_elf.h index 29a3426f51042008137b1bb096de4a38779a337d..dab2cb4dbe4715466b020a0a879508100bd1b8de 100644 --- a/src/elf_read_elf.h +++ b/src/elf_read_elf.h @@ -350,6 +350,10 @@ bool got_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec); bool rwdata_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec); bool bss_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec); bool elf_is_debug_section(elf_file_t *ef, Elf64_Shdr *sechdr); +bool elf_is_rela_debug_section(elf_file_t *ef, Elf64_Shdr *sechdr); +bool debug_info_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec); +bool debug_line_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec); +bool debug_str_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec); bool elf_is_same_area(const elf_file_t *ef, const Elf64_Shdr *a, const Elf64_Shdr *b); // ELF diff --git a/src/elf_relocation.c b/src/elf_relocation.c index b40004f3aefdbd42c11d2b60e9ed731e8e2c356c..8cffd8abec289c1108d5965c0b568cabc944aad7 100644 --- a/src/elf_relocation.c +++ b/src/elf_relocation.c @@ -85,15 +85,23 @@ static void modify_local_call_ef(elf_link_t *elf_link, elf_file_t *ef) unsigned int shnum = ef->hdr->e_shnum; unsigned int i; Elf64_Shdr *sec = NULL; - + char *name; for (i = 1; i < shnum; i++) { sec = &sechdrs[i]; // rela sec is not alloc and sh_info is alloc sec, .rela.text // sh_info for SHT_SYMTAB is the first non-local symbol index if (sechdrs[i].sh_type != SHT_RELA || !is_rela_for_A(ef, sec)) { - continue; + name = elf_get_section_name(ef, sec); + if (strncmp(name, ".rela.debug_info", 16) == 0) { + bool kkk = is_rela_for_A(ef, sec); + printf("###.rela.debug_info: %d, %d\n", i, kkk); + } else { + continue; + } } + name = elf_get_section_name(ef, sec); + printf("%d: %s\n", i, name); modify_local_call_sec(elf_link, ef, sec); } } diff --git a/src/elf_relocation_aarch64.c b/src/elf_relocation_aarch64.c index 96584b1314b29b05d612151e781685b0c23326bc..58eaa32871b97198597c22b08d8c284eb154e8b0 100644 --- a/src/elf_relocation_aarch64.c +++ b/src/elf_relocation_aarch64.c @@ -784,6 +784,7 @@ int modify_local_call_rela(elf_link_t *elf_link, elf_file_t *ef, Elf64_Rela *rel // TLS (thread local storage) use 4 rela modify_tls_insn(elf_link, ef, rela, sym); return SKIP_THREE_RELA; + case R_AARCH64_ABS32: case R_AARCH64_ABS64: old_addr = sym->st_value + rela->r_addend; new_addr = get_new_addr_by_old_addr(elf_link, ef, old_addr); diff --git a/src/elf_write_elf.c b/src/elf_write_elf.c index 7d5e4ad07fc27d11877bd94179860471fe0d5623..2495864fd8f6fdbcccda233797f95d956805e343 100644 --- a/src/elf_write_elf.c +++ b/src/elf_write_elf.c @@ -287,7 +287,7 @@ static void record_rela_arr(elf_link_t *elf_link, elf_file_t *ef, Elf64_Shdr *se } } -static unsigned long elf_get_sh_size(elf_link_t *elf_link, Elf64_Shdr *tmp_sec) +static unsigned long elf_get_sh_size(elf_link_t *elf_link, Elf64_Shdr *tmp_sec) { if (tmp_sec->sh_flags & SHF_ALLOC) { // .text .bss @@ -329,7 +329,7 @@ static Elf64_Shdr *elf_merge_section(elf_link_t *elf_link, Elf64_Shdr *tmp_sec, elf_file_t *main_ef = get_main_ef(elf_link); tmp_sec->sh_offset = elf_align_file(elf_link, tmp_sec->sh_addralign); - tmp_sec->sh_addr = elf_link->next_mem_addr; + tmp_sec->sh_addr = elf_link->next_mem_addr; SI_LOG_DEBUG("section %s at 0x%lx\n", name, tmp_sec->sh_offset); // libc .dynsym .dynstr need put first, so version section no change @@ -402,12 +402,28 @@ static void append_section(elf_link_t *elf_link, Elf64_Shdr *dst_sec, elf_file_t // first in section to dst section if (dst_sec->sh_offset == 0) { dst_sec->sh_offset = elf_link->next_file_offset; - dst_sec->sh_addr = elf_link->next_mem_addr; + if (elf_is_debug_section(ef, dst_sec) || elf_is_rela_debug_section(ef, dst_sec)) { + dst_sec->sh_addr = 0; + } + else { + dst_sec->sh_addr = elf_link->next_mem_addr; + } } write_elf_file_section(elf_link, ef, sec, dst_sec); } +// static inline bool elf_is_debug_section(elf_file_t *ef, Elf64_Shdr *sec) +// { +// name = elf_get_section_name(ef, sec); +// if (strncmp(name, ".rela.debug_info", 16) == 0) { +// if (strcmp(name, ".gnu.hash") == 0) { +// return true; +// } + +// return false; +// } + static void merge_section(elf_link_t *elf_link, Elf64_Shdr *dst_sec, elf_file_t *ef, Elf64_Shdr *sec) { // in append_section, the first section need change this @@ -467,6 +483,13 @@ static void merge_filter_section(elf_link_t *elf_link, Elf64_Shdr *dst_sec, elf_ } } +// static void merge_filter_debug_info_section(elf_link_t *elf_link, char *sec_name, section_filter_func filter) +// { +// elf_file_t *ef = &elf_link->in_efs[1]; +// sec = elf_find_section_by_name(ef, name); +// Elf64_Shdr *dst_sec add_tmp_section(elf_link, ef, sec); +// } + static void merge_filter_sections(elf_link_t *elf_link, char *sec_name, section_filter_func filter) { elf_file_t *ef = NULL; @@ -483,14 +506,23 @@ static void merge_filter_sections(elf_link_t *elf_link, char *sec_name, section_ // do with all in ELFs for (int i = 0; i < count; i++) { + // if (strcmp(sec_name, ".debug_info") == 0 && i == 0) + // continue; ef = &elf_link->in_efs[i]; merge_filter_section(elf_link, dst_sec, ef, filter); } - dst_sec->sh_size = elf_link->next_mem_addr - dst_sec->sh_addr; + dst_sec->sh_size = elf_get_sh_size(elf_link, dst_sec); SI_LOG_DEBUG("section %-20s %08lx %08lx %06lx\n", sec_name, dst_sec->sh_addr, dst_sec->sh_offset, dst_sec->sh_size); } +void merge_debug_sections(elf_link_t *elf_link) +{ + merge_filter_sections(elf_link, ".debug_info", debug_info_section_filter); + merge_filter_sections(elf_link, ".debug_line", debug_line_section_filter); + merge_filter_sections(elf_link, ".debug_str", debug_line_section_filter); +} + void merge_text_sections(elf_link_t *elf_link) { merge_filter_sections(elf_link, ".text", text_section_filter); diff --git a/src/elf_write_elf.h b/src/elf_write_elf.h index 0d9e005188be98c75ada962ee6d959c920838e9a..97761cc6cdd4c8f5fe64d551695072a0002f99de 100644 --- a/src/elf_write_elf.h +++ b/src/elf_write_elf.h @@ -38,6 +38,7 @@ unsigned int elf_align_file_section(elf_link_t *elf_link, Elf64_Shdr *sec, bool // write section void copy_from_old_elf(elf_link_t *elf_link); +void merge_debug_sections(elf_link_t *elf_link); void merge_text_sections(elf_link_t *elf_link); void merge_rodata_sections(elf_link_t *elf_link); void merge_data_relro_sections(elf_link_t *elf_link);