From 2d16c7988d7036522bc0d7efcc5a513b89612376 Mon Sep 17 00:00:00 2001 From: taoyuxiang Date: Tue, 26 Dec 2023 10:01:39 +0800 Subject: [PATCH 1/2] add .debug_line merge .debug_loclists .debugrnglists(not modify) can show source file in gdb now --- Makefile | 4 + src/elfmerge/elf_link_common.c | 2 + src/elfmerge/elf_link_elf.c | 306 +++++++++++++++++++++++++++++++++ src/elfmerge/elf_read_elf.c | 12 ++ src/elfmerge/elf_read_elf.h | 2 + src/elfmerge/elf_write_elf.c | 2 + 6 files changed, 328 insertions(+) diff --git a/Makefile b/Makefile index d0ac455..2f4289e 100644 --- a/Makefile +++ b/Makefile @@ -48,6 +48,10 @@ install: xz -k $(BUILD_DIR)/src/static_template/sysboost_static_template mv -f $(BUILD_DIR)/src/static_template/sysboost_static_template.xz /usr/lib/relocation/ +# .debug_* in sysboost_static_template and sysboost_static_template.relocation are not same, need sync +sync_tmp: + xz -k build/src/static_template/sysboost_static_template -c > /usr/lib/relocation/sysboost_static_template.relocation + test: sysboostd install clear ./tests/test_sysboostd.py diff --git a/src/elfmerge/elf_link_common.c b/src/elfmerge/elf_link_common.c index ee2a8fa..ba69174 100644 --- a/src/elfmerge/elf_link_common.c +++ b/src/elfmerge/elf_link_common.c @@ -128,6 +128,8 @@ static char *needed_sections[] = { ".debug_str", ".debug_line_str", ".debug_abbrev", + ".debug_loclists", + ".debug_rnglists" }; #define NEEDED_SECTIONS_LEN (sizeof(needed_sections) / sizeof(needed_sections[0])) diff --git a/src/elfmerge/elf_link_elf.c b/src/elfmerge/elf_link_elf.c index 778f55e..5f2cd81 100644 --- a/src/elfmerge/elf_link_elf.c +++ b/src/elfmerge/elf_link_elf.c @@ -1435,6 +1435,9 @@ struct dwarf_bias_info { uint64_t text; uint64_t debug_str; uint64_t debug_line_str; + uint64_t debug_line; + uint64_t debug_loclists; + uint64_t debug_rnglists; }; int dwarf_modify_di_abbrev(Dwarf_Die die, void *di_ptr, struct dwarf_bias_info *bias_info) @@ -1498,15 +1501,33 @@ int dwarf_modify_di_abbrev(Dwarf_Die die, void *di_ptr, struct dwarf_bias_info * case DW_FORM_data8: /* no need to modify */ break; + // A 2-byte length followed by 0 to 65,535 contiguous information bytes case DW_FORM_block2: + // Immediately in the debugging information entry itself case DW_FORM_string: + case DW_FORM_sdata: + // todo DW_FORM_ref_addr??? case DW_FORM_ref4: case DW_FORM_implicit_const: + // DW_AT_location...??? case DW_FORM_exprloc: case DW_FORM_flag_present: + // DW_AT_stmt_list: debug_line, ... more case DW_FORM_sec_offset: /* TODO */ + switch (die->di_abbrev_list->abl_attr[i]){ + case DW_AT_stmt_list: + *dst_ptr += bias_info->debug_line; + break; + // case DW_AT_ranges: + // *dst_ptr += bias_info->debug_rnglists; + // break; + // case DW_AT_location: + // case DW_AT_GNU_locviews: + // *dst_ptr += bias_info->debug_loclists; + // break; + } break; case DW_FORM_block4: case DW_FORM_block: @@ -1606,6 +1627,12 @@ void prep_bias_info(elf_link_t *elf_link, elf_file_t *ef, struct dwarf_bias_info elf_find_section_by_name(get_out_ef(elf_link), ".debug_str")->sh_offset; unsigned long dls_base_offset = elf_find_section_by_name(get_out_ef(elf_link), ".debug_line_str")->sh_offset; + unsigned long dl_base_offset = + elf_find_section_by_name(get_out_ef(elf_link), ".debug_line")->sh_offset; + unsigned long dll_base_offset = + elf_find_section_by_name(get_out_ef(elf_link), ".debug_loclists")->sh_offset; + unsigned long drl_base_offset = + elf_find_section_by_name(get_out_ef(elf_link), ".debug_rnglists")->sh_offset; Elf64_Shdr *text_sec = elf_find_section_by_name(ef, ".init"); unsigned long text_addr = get_new_addr_by_old_addr( @@ -1619,10 +1646,25 @@ void prep_bias_info(elf_link_t *elf_link, elf_file_t *ef, struct dwarf_bias_info unsigned long dls_offset = get_new_offset_by_old_offset( elf_link, ef, dls_sec->sh_offset ); + Elf64_Shdr *dl_sec = elf_find_section_by_name(ef, ".debug_line"); + unsigned long dl_offset = get_new_offset_by_old_offset( + elf_link, ef, dl_sec->sh_offset + ); + Elf64_Shdr *dll_sec = elf_find_section_by_name(ef, ".debug_loclists"); + unsigned long dll_offset = get_new_offset_by_old_offset( + elf_link, ef, dll_sec->sh_offset + ); + Elf64_Shdr *drl_sec = elf_find_section_by_name(ef, ".debug_rnglists"); + unsigned long drl_offset = get_new_offset_by_old_offset( + elf_link, ef, drl_sec->sh_offset + ); bias_info->text = text_addr - text_base_addr; bias_info->debug_str = ds_offset - ds_base_offset; bias_info->debug_line_str = dls_offset - dls_base_offset; + bias_info->debug_line = dl_offset - dl_base_offset; + bias_info->debug_loclists = dll_offset - dll_base_offset; + bias_info->debug_rnglists = drl_offset - drl_base_offset; SI_LOG_DEBUG("%s, text: %lx, debug_str: %lx, debug_line_str: %lx\n", ef->file_name, bias_info->text, bias_info->debug_str, bias_info->debug_line_str); @@ -1630,6 +1672,267 @@ void prep_bias_info(elf_link_t *elf_link, elf_file_t *ef, struct dwarf_bias_info text_addr, text_base_addr); } +void skip_leb128(unsigned char** data){ + printf(".(%p,%02x)", (void*)*data, **data&0xff); + while (**data & 0x80) { + ++*data; + printf("(%p,%02x)", (void*)*data, **data&0xff); + } + ++*data; + printf("-(%p,%02x)", (void*)*data, **data&0xff); +} + +unsigned long read_skip_leb128(unsigned char** data) { + unsigned long result = 0; + unsigned int shift = 0; + unsigned char byte; + + do { + byte = **data; + ++*data; + result |= (byte & 0x7f) << shift; + shift += 7; + } while (byte & 0x80); + + return result; +} + +void process_extended_line_op( + // unsigned char * start, + unsigned char ** data, + struct dwarf_bias_info *bias_info + ) +{ + // *data++; + // LEB128 is mentioned in the document, but use byte actually, because max op_code is 0x80 + unsigned long len = read_skip_leb128(data); + unsigned char op_code = **data; + // printf("(%lx)", **data); + ++*data; + // printf("(%lx)", **data); + printf("[%x]:len:%lx", op_code, len); + uint32_t *dst_ptr = (uint32_t *)*data; + switch (op_code) { + case DW_LNE_end_sequence: + printf ("DW_LNE_end_sequence\n"); + break; + case DW_LNE_set_address: + *dst_ptr += bias_info->text; + // printf("(%lx)", **data); + // unsigned long *addr = (unsigned long*) *data; + printf("=== %lx, %lx \n", (unsigned long) *data, bias_info->text); + break; + case DW_LNE_define_file: + //The DW_LNE_define_file operation defined in earlier versions of DWARF is deprecated 5 in DWARF Version 5. + printf ("DW_LNE_define_file\n"); + break; + + case DW_LNE_set_discriminator: + // set dir path? no need to modify? + // skip_leb128(data); + printf ("set Discriminator\n"); + break; + + /* HP extensions. */ + case DW_LNE_HP_negate_is_UV_update: + printf ("DW_LNE_HP_negate_is_UV_update\n"); + break; + case DW_LNE_HP_push_context: + printf ("DW_LNE_HP_push_context\n"); + break; + case DW_LNE_HP_pop_context: + printf ("DW_LNE_HP_pop_context\n"); + break; + case DW_LNE_HP_set_file_line_column: + printf ("DW_LNE_HP_set_file_line_column\n"); + break; + case DW_LNE_HP_set_routine_name: + printf ("DW_LNE_HP_set_routine_name\n"); + break; + case DW_LNE_HP_set_sequence: + printf ("DW_LNE_HP_set_sequence\n"); + break; + case DW_LNE_HP_negate_post_semantics: + printf ("DW_LNE_HP_negate_post_semantics\n"); + break; + case DW_LNE_HP_negate_function_exit: + printf ("DW_LNE_HP_negate_function_exit\n"); + break; + case DW_LNE_HP_negate_front_end_logical: + printf ("DW_LNE_HP_negate_front_end_logical\n"); + break; + case DW_LNE_HP_define_proc: + printf ("DW_LNE_HP_define_proc\n"); + break; + // case DW_LNE_HP_source_file_correlation: + // // no common? raise error if occur + // break; + + default: + { + printf("UNKNOWN extended_line_op ERROR\n"); + exit(1); + } + } + *data += len - 1; +} + +static void modify_line_number_statement( + unsigned char ** data, unsigned char *start, unsigned char *end, + struct dwarf_bias_info *bias_info) +{ + // int cu_line_offset = 0x1b5; + // unsigned char *start = *data - cu_line_offset; + while (*data < end){ //ptr < end + unsigned char op_code; + printf("%lx ", *data-start); + op_code = **data; + ++*data; + printf("OP[%x]:", op_code); + switch (op_code) + { + // DW_LNS_extended_op + case 0: + process_extended_line_op(data, bias_info); + // if (*(unsigned short*)*data == 0x0101){ + // *data += 0x2; + // printf("DW_LNE_end_sequence\n"); + // return 0; + // } + // else { + // process_extended_line_op(data); + // } + break; + case DW_LNS_copy: + printf("DW_LNS_copy\n"); + break; + case DW_LNS_advance_pc: + printf("DW_LNS_advance_pc\n"); + skip_leb128(data); + break; + case DW_LNS_advance_line: + printf("DW_LNS_advance_line\n"); + /* + [0x00000bcc] Extended opcode 1: End of Sequence + + [0x00000bcf] Set column to 1 bb1 OP[3]:DW_LNS_advance_line +.(0xffff8bc19baf,a7)(0xffff8bc19bb0,71)-(0xffff8bc19bb1,4a)bb4 OP[4a]:Sp_op 61 +*/ + skip_leb128(data); + break; + case DW_LNS_set_file: + printf("\n"); + skip_leb128(data); + break; + case DW_LNS_set_column: + skip_leb128(data); + printf("DW_LNS_set_column: skip\n"); + break; + case DW_LNS_negate_stmt: + printf("DW_LNS_negate_stmt\n"); + break; + case DW_LNS_set_basic_block: + printf("DW_LNS_set_basic_block\n"); + break; + case DW_LNS_const_add_pc: + printf("\n"); + break; + case DW_LNS_fixed_advance_pc: + printf("\n"); + // nead process, but this op only use in few machine + break; + case DW_LNS_set_prologue_end: + printf("\n"); + break; + case DW_LNS_set_epilogue_begin: + printf("\n"); + break; + case DW_LNS_set_isa: + skip_leb128(data); + break; + + default: + printf("Sp_op %d\n", (op_code-13)); + // printf("NT YT\n"); + // exit(2); + } + // return 0; + } +} + +void modify_cu_debug_line(unsigned char ** data, struct dwarf_bias_info *bias_info, unsigned char *start)//, int cu_num) +{ + // unsigned int cu_dl_len = *(int *)data; + unsigned char *end = *(int *)*data + *data + 0x4; + printf("\n***modify_cu_debug_line***%ld***\n", end - start); + // skip_header(data); + *data += 0x12; + // skip_opcodes(data); + *data += 0xc; + // unsigned long dt_count = read_skip_dir_table_count(data); + // 0x01011f + *data += 0x3; + unsigned long dt_count = read_skip_leb128(data); + // print_dt(data, dt_count); + for (unsigned long i =0; i < dt_count; i++){ + printf("%ld,%x:%x\n", i, *(unsigned int*)*data, *(unsigned int*)*data); + uint32_t *dst_ptr = (uint32_t *)*data; + *dst_ptr += bias_info->debug_line_str; + // **data += bias_info->debug_line_str; + *data += 4; + } + // unsigned long ft_count = read_skip_file_name_table_count(data); + // 0201 1f02 0f + *data += 0x5; + unsigned long ft_count = read_skip_leb128(data); + // print_ft(data, ft_count); + for (unsigned long i =0; i< ft_count; i++){ + printf("%ld,%x:%x\n", i, *(unsigned int*)*data, *(unsigned int*)*data); + // **data += bias_info->debug_line_str; + uint32_t *dst_ptr = (uint32_t *)*data; + *dst_ptr += bias_info->debug_line_str; + *data += 4; + skip_leb128(data); + } + modify_line_number_statement(data, start, end, bias_info); + // exit(1); +} + +int modify_debug_line(elf_link_t *elf_link) +{ + elf_file_t *ef; + char *temp_path; + struct dwarf_bias_info bias_info; + + foreach_infile(elf_link, ef) { + Elf64_Shdr *dl_sec = elf_find_section_by_name(ef, ".debug_line"); + unsigned long dst_offset = get_new_offset_by_old_offset( + elf_link, ef, dl_sec->sh_offset + ); + void *dl_ptr = get_out_ef(elf_link)->data + dst_offset; + unsigned char *start = dl_ptr; + prep_bias_info(elf_link, ef, &bias_info); + + temp_path = temp_get_file_name(ef->file_name); + Dwarf_Debug dbg = dwarf_init(temp_path); + if (!dbg) + si_panic("dwarf_init fail, file: %s\n", temp_path); + + int res = 0; + Dwarf_Die first_die; + for (;;) { + res = dwarf_get_first_die_of_next_cu(dbg, &first_die); + if (res == DW_DLV_NO_ENTRY) { + /* no entry */ + break; + } + modify_cu_debug_line((unsigned char **)&dl_ptr, &bias_info, start); + } + dwarf_finish(dbg); + } + return 0; +} + int modify_debug_info(elf_link_t *elf_link) { elf_file_t *ef; @@ -1654,10 +1957,13 @@ int modify_debug_info(elf_link_t *elf_link) return 0; } + static void modify_debug(elf_link_t *elf_link) { modify_debug_info_abbrev_offset(elf_link); modify_debug_info(elf_link); + modify_debug_line(elf_link); + // todo modify_debug_list(elf_link); } /* debug modify end */ diff --git a/src/elfmerge/elf_read_elf.c b/src/elfmerge/elf_read_elf.c index d27f1bf..5e2d2f8 100644 --- a/src/elfmerge/elf_read_elf.c +++ b/src/elfmerge/elf_read_elf.c @@ -523,6 +523,18 @@ bool debug_line_str_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec) return strcmp(name, ".debug_line_str") == 0; } +bool debug_loclists_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec) +{ + char *name = elf_get_section_name(ef, sec); + return strcmp(name, ".debug_loclists") == 0; +} + +bool debug_rnglists_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec) +{ + char *name = elf_get_section_name(ef, sec); + return strcmp(name, ".debug_rnglists") == 0; +} + bool debug_abbrev_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec) { char *name = elf_get_section_name(ef, sec); diff --git a/src/elfmerge/elf_read_elf.h b/src/elfmerge/elf_read_elf.h index 98b7476..b2885bb 100644 --- a/src/elfmerge/elf_read_elf.h +++ b/src/elfmerge/elf_read_elf.h @@ -360,6 +360,8 @@ 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 debug_line_str_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec); bool debug_abbrev_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec); +bool debug_loclists_section_filter(const elf_file_t *ef, const Elf64_Shdr *sec); +bool debug_rnglists_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/elfmerge/elf_write_elf.c b/src/elfmerge/elf_write_elf.c index 9b9d6a7..bb197bb 100644 --- a/src/elfmerge/elf_write_elf.c +++ b/src/elfmerge/elf_write_elf.c @@ -516,6 +516,8 @@ void merge_debug_sections(elf_link_t *elf_link) merge_filter_sections(elf_link, ".debug_line", debug_line_section_filter); merge_filter_sections(elf_link, ".debug_str", debug_str_section_filter); merge_filter_sections(elf_link, ".debug_line_str", debug_line_str_section_filter); + merge_filter_sections(elf_link, ".debug_loclists", debug_loclists_section_filter); + merge_filter_sections(elf_link, ".debug_rnglists", debug_rnglists_section_filter); } void merge_text_sections(elf_link_t *elf_link) -- Gitee From 1e9297585921c4f7f01eacfaecda1d2baddb4fc0 Mon Sep 17 00:00:00 2001 From: t30002884 Date: Mon, 8 Jan 2024 20:24:43 +0800 Subject: [PATCH 2/2] add line loclist rnglist --- src/elfmerge/elf_link_elf.c | 744 +++++++++++++++++++++++------------- 1 file changed, 469 insertions(+), 275 deletions(-) diff --git a/src/elfmerge/elf_link_elf.c b/src/elfmerge/elf_link_elf.c index 5f2cd81..c5b730a 100644 --- a/src/elfmerge/elf_link_elf.c +++ b/src/elfmerge/elf_link_elf.c @@ -1001,7 +1001,7 @@ static int sym_cmp_func(const void *src_sym_a_, const void *src_sym_b_) } static inline Elf64_Addr get_symbol_new_value(elf_link_t *elf_link, elf_file_t *ef, - Elf64_Sym *sym, char *name) + Elf64_Sym *sym, char *name) { if (elf_is_symbol_type_section(sym)) { // section may be delete in out ef, so section symbol can not get new value @@ -1041,7 +1041,7 @@ static inline Elf64_Addr get_symbol_new_value(elf_link_t *elf_link, elf_file_t * } static inline Elf32_Section get_symbol_new_section(elf_link_t *elf_link, elf_file_t *ef, - Elf64_Sym *sym) + Elf64_Sym *sym) { Elf64_Section shndx = sym->st_shndx; @@ -1052,7 +1052,7 @@ static inline Elf32_Section get_symbol_new_section(elf_link_t *elf_link, elf_fil } static inline Elf64_Word get_symbol_new_name(elf_link_t *elf_link, elf_file_t *ef, - Elf64_Sym *sym, Elf64_Word sh_link) + Elf64_Sym *sym, Elf64_Word sh_link) { Elf64_Word name = sym->st_name; Elf64_Shdr *strtab = &ef->sechdrs[sh_link]; @@ -1431,6 +1431,14 @@ int dwarf_get_first_die_of_next_cu(Dwarf_Debug dbg, Dwarf_Die* first_die) return ret; } +// location view pair info in .debug_loc +#define MAX_LVP_NUM 20000 +struct lvp_info { + uint64_t num; //=0 + uint64_t start[MAX_LVP_NUM]; + uint64_t end[MAX_LVP_NUM]; +}; + struct dwarf_bias_info { uint64_t text; uint64_t debug_str; @@ -1438,6 +1446,8 @@ struct dwarf_bias_info { uint64_t debug_line; uint64_t debug_loclists; uint64_t debug_rnglists; + + struct lvp_info lvp; }; int dwarf_modify_di_abbrev(Dwarf_Die die, void *di_ptr, struct dwarf_bias_info *bias_info) @@ -1463,7 +1473,6 @@ int dwarf_modify_di_abbrev(Dwarf_Die die, void *di_ptr, struct dwarf_bias_info * Dwarf_Unsigned sov = 0; int ret; - /* todo test if this is needed */ if (attr_form == DW_FORM_implicit_const) { continue; } @@ -1491,9 +1500,26 @@ int dwarf_modify_di_abbrev(Dwarf_Die die, void *di_ptr, struct dwarf_bias_info * break; case DW_FORM_strp: *dst_ptr += bias_info->debug_str; - // printf("offset: %lx, *abbrev_ptr: %x *dst_ptr: %x\n", - // (abbrev_ptr - di_base), - // *(uint32_t *)abbrev_ptr, *dst_ptr); + break; + case DW_FORM_sec_offset: + switch (die->di_abbrev_list->abl_attr[i]){ + case DW_AT_stmt_list: + *dst_ptr += bias_info->debug_line; + break; + case DW_AT_location: + bias_info->lvp.end[bias_info->lvp.num] = *dst_ptr; + *dst_ptr += bias_info->debug_loclists; + break; + case DW_AT_GNU_locviews: + bias_info->lvp.start[bias_info->lvp.num] = *dst_ptr; + *dst_ptr += bias_info->debug_loclists; + bias_info->lvp.num++; + break; + // todo .debug_rnglist + case DW_AT_ranges: + *dst_ptr += bias_info->debug_rnglists; + break; + } break; case DW_FORM_data1: case DW_FORM_data2: @@ -1511,24 +1537,14 @@ int dwarf_modify_di_abbrev(Dwarf_Die die, void *di_ptr, struct dwarf_bias_info * case DW_FORM_ref4: case DW_FORM_implicit_const: // DW_AT_location...??? - case DW_FORM_exprloc: case DW_FORM_flag_present: - // DW_AT_stmt_list: debug_line, ... more - case DW_FORM_sec_offset: - /* TODO */ - switch (die->di_abbrev_list->abl_attr[i]){ - case DW_AT_stmt_list: - *dst_ptr += bias_info->debug_line; - break; - // case DW_AT_ranges: - // *dst_ptr += bias_info->debug_rnglists; - // break; - // case DW_AT_location: - // case DW_AT_GNU_locviews: - // *dst_ptr += bias_info->debug_loclists; - // break; - } break; + case DW_FORM_exprloc: + case DW_AT_location: + // 0a03 0903 need reloc, 02 01 03 dont? + + break; + case DW_FORM_block4: case DW_FORM_block: case DW_FORM_block1: @@ -1573,7 +1589,7 @@ int dwarf_modify_di_abbrev(Dwarf_Die die, void *di_ptr, struct dwarf_bias_info * } int dwarf_traverse_die(Dwarf_Debug dbg, Dwarf_Die parent_die, - void *di_ptr, struct dwarf_bias_info *bias_info) + void *di_ptr, struct dwarf_bias_info *bias_info) { Dwarf_Die son_die; int res; @@ -1618,284 +1634,163 @@ char *temp_get_file_name(char *name) return result; } -void prep_bias_info(elf_link_t *elf_link, elf_file_t *ef, struct dwarf_bias_info *bias_info) -{ - /* .text starts from .init */ - unsigned long text_base_addr = - elf_find_section_by_name(ef, ".init")->sh_addr; - unsigned long ds_base_offset = - elf_find_section_by_name(get_out_ef(elf_link), ".debug_str")->sh_offset; - unsigned long dls_base_offset = - elf_find_section_by_name(get_out_ef(elf_link), ".debug_line_str")->sh_offset; - unsigned long dl_base_offset = - elf_find_section_by_name(get_out_ef(elf_link), ".debug_line")->sh_offset; - unsigned long dll_base_offset = - elf_find_section_by_name(get_out_ef(elf_link), ".debug_loclists")->sh_offset; - unsigned long drl_base_offset = - elf_find_section_by_name(get_out_ef(elf_link), ".debug_rnglists")->sh_offset; - - Elf64_Shdr *text_sec = elf_find_section_by_name(ef, ".init"); - unsigned long text_addr = get_new_addr_by_old_addr( - elf_link, ef, text_sec->sh_addr - ); - Elf64_Shdr *ds_sec = elf_find_section_by_name(ef, ".debug_str"); - unsigned long ds_offset = get_new_offset_by_old_offset( - elf_link, ef, ds_sec->sh_offset - ); - Elf64_Shdr *dls_sec = elf_find_section_by_name(ef, ".debug_line_str"); - unsigned long dls_offset = get_new_offset_by_old_offset( - elf_link, ef, dls_sec->sh_offset - ); - Elf64_Shdr *dl_sec = elf_find_section_by_name(ef, ".debug_line"); - unsigned long dl_offset = get_new_offset_by_old_offset( - elf_link, ef, dl_sec->sh_offset - ); - Elf64_Shdr *dll_sec = elf_find_section_by_name(ef, ".debug_loclists"); - unsigned long dll_offset = get_new_offset_by_old_offset( - elf_link, ef, dll_sec->sh_offset - ); - Elf64_Shdr *drl_sec = elf_find_section_by_name(ef, ".debug_rnglists"); - unsigned long drl_offset = get_new_offset_by_old_offset( - elf_link, ef, drl_sec->sh_offset +#define INIT ".init" +#define DEBUG_STR ".debug_str" +#define DEBUG_LINE_STR ".debug_line_str" +#define DEBUG_LINE ".debug_line" +#define DEBUG_LOCLISTS ".debug_loclists" +#define DEBUG_RNGLISTS ".debug_rnglists" + +uint64_t get_ef_sec_bias(elf_link_t *elf_link, elf_file_t *ef, char *sec_name) +{ + unsigned long d_base_offset = + elf_find_section_by_name(get_out_ef(elf_link), sec_name)->sh_offset; + Elf64_Shdr *d_sec = elf_find_section_by_name(ef, ".debug_str"); + unsigned long d_offset = get_new_offset_by_old_offset( + elf_link, ef, d_sec->sh_offset ); + return d_offset - d_base_offset; +} + +struct dwarf_bias_info* init_prep_bias_info(elf_link_t *elf_link) +{ + struct dwarf_bias_info* dbi = + (struct dwarf_bias_info*)malloc(elf_link->in_ef_nr * sizeof(struct dwarf_bias_info)); + for (unsigned int i=0; i < elf_link->in_ef_nr; i++) { + unsigned long text_base_addr = elf_find_section_by_name(&elf_link->in_efs[i], INIT)->sh_addr; + Elf64_Shdr *text_sec = elf_find_section_by_name(&elf_link->in_efs[i], INIT); + unsigned long text_addr = get_new_addr_by_old_addr(elf_link, &elf_link->in_efs[i], text_sec->sh_addr); + dbi[i].text = text_addr - text_base_addr; - bias_info->text = text_addr - text_base_addr; - bias_info->debug_str = ds_offset - ds_base_offset; - bias_info->debug_line_str = dls_offset - dls_base_offset; - bias_info->debug_line = dl_offset - dl_base_offset; - bias_info->debug_loclists = dll_offset - dll_base_offset; - bias_info->debug_rnglists = drl_offset - drl_base_offset; - SI_LOG_DEBUG("%s, text: %lx, debug_str: %lx, debug_line_str: %lx\n", - ef->file_name, - bias_info->text, bias_info->debug_str, bias_info->debug_line_str); - SI_LOG_DEBUG("text_addr: %lx, out_text_base_addr: %lx\n", - text_addr, text_base_addr); -} - -void skip_leb128(unsigned char** data){ - printf(".(%p,%02x)", (void*)*data, **data&0xff); + dbi[i].debug_str = get_ef_sec_bias(elf_link, &elf_link->in_efs[i], DEBUG_STR); + dbi[i].debug_line_str = get_ef_sec_bias(elf_link, &elf_link->in_efs[i], DEBUG_LINE_STR); + dbi[i].debug_line = get_ef_sec_bias(elf_link, &elf_link->in_efs[i], DEBUG_LINE); + dbi[i].debug_loclists = get_ef_sec_bias(elf_link, &elf_link->in_efs[i], DEBUG_LOCLISTS); + dbi[i].debug_rnglists = get_ef_sec_bias(elf_link, &elf_link->in_efs[i], DEBUG_RNGLISTS); + dbi[i].lvp.num = 0; + } + return dbi; +} + +void skip_leb128(uint8_t** data){ while (**data & 0x80) { ++*data; - printf("(%p,%02x)", (void*)*data, **data&0xff); } ++*data; - printf("-(%p,%02x)", (void*)*data, **data&0xff); } -unsigned long read_skip_leb128(unsigned char** data) { - unsigned long result = 0; - unsigned int shift = 0; - unsigned char byte; +uint64_t read_skip_leb128(uint8_t** data) { + uint64_t result = 0; + uint64_t shift = 0; + uint8_t byte; do { - byte = **data; - ++*data; - result |= (byte & 0x7f) << shift; - shift += 7; + byte = **data; + ++*data; + result |= (byte & 0x7f) << shift; + shift += 7; } while (byte & 0x80); return result; } -void process_extended_line_op( - // unsigned char * start, - unsigned char ** data, - struct dwarf_bias_info *bias_info - ) +void process_extended_line_op(uint8_t ** data, + struct dwarf_bias_info *bias_info) { - // *data++; - // LEB128 is mentioned in the document, but use byte actually, because max op_code is 0x80 + // LEB128 is mentioned in the document, + // but use byte actually, because max op_code is 0x80 unsigned long len = read_skip_leb128(data); - unsigned char op_code = **data; - // printf("(%lx)", **data); + uint8_t op_code = **data; ++*data; - // printf("(%lx)", **data); - printf("[%x]:len:%lx", op_code, len); - uint32_t *dst_ptr = (uint32_t *)*data; + uint64_t *dst_ptr = (uint64_t*)*data; switch (op_code) { - case DW_LNE_end_sequence: - printf ("DW_LNE_end_sequence\n"); - break; - case DW_LNE_set_address: - *dst_ptr += bias_info->text; - // printf("(%lx)", **data); - // unsigned long *addr = (unsigned long*) *data; - printf("=== %lx, %lx \n", (unsigned long) *data, bias_info->text); - break; - case DW_LNE_define_file: - //The DW_LNE_define_file operation defined in earlier versions of DWARF is deprecated 5 in DWARF Version 5. - printf ("DW_LNE_define_file\n"); - break; - - case DW_LNE_set_discriminator: - // set dir path? no need to modify? - // skip_leb128(data); - printf ("set Discriminator\n"); - break; - - /* HP extensions. */ - case DW_LNE_HP_negate_is_UV_update: - printf ("DW_LNE_HP_negate_is_UV_update\n"); - break; - case DW_LNE_HP_push_context: - printf ("DW_LNE_HP_push_context\n"); - break; - case DW_LNE_HP_pop_context: - printf ("DW_LNE_HP_pop_context\n"); - break; - case DW_LNE_HP_set_file_line_column: - printf ("DW_LNE_HP_set_file_line_column\n"); - break; - case DW_LNE_HP_set_routine_name: - printf ("DW_LNE_HP_set_routine_name\n"); - break; - case DW_LNE_HP_set_sequence: - printf ("DW_LNE_HP_set_sequence\n"); - break; - case DW_LNE_HP_negate_post_semantics: - printf ("DW_LNE_HP_negate_post_semantics\n"); - break; - case DW_LNE_HP_negate_function_exit: - printf ("DW_LNE_HP_negate_function_exit\n"); - break; - case DW_LNE_HP_negate_front_end_logical: - printf ("DW_LNE_HP_negate_front_end_logical\n"); - break; - case DW_LNE_HP_define_proc: - printf ("DW_LNE_HP_define_proc\n"); - break; - // case DW_LNE_HP_source_file_correlation: - // // no common? raise error if occur - // break; - - default: - { - printf("UNKNOWN extended_line_op ERROR\n"); - exit(1); - } + case DW_LNE_set_address: + *dst_ptr += bias_info->text; + break; + case DW_LNE_end_sequence: + case DW_LNE_define_file: + case DW_LNE_set_discriminator: + case DW_LNE_HP_negate_is_UV_update: + case DW_LNE_HP_push_context: + case DW_LNE_HP_pop_context: + case DW_LNE_HP_set_file_line_column: + case DW_LNE_HP_set_routine_name: + case DW_LNE_HP_set_sequence: + case DW_LNE_HP_negate_post_semantics: + case DW_LNE_HP_negate_function_exit: + case DW_LNE_HP_negate_front_end_logical: + case DW_LNE_HP_define_proc: + break; + default: + si_panic("unknown extended_line_op 0x%x\n", op_code); + break; } *data += len - 1; } -static void modify_line_number_statement( - unsigned char ** data, unsigned char *start, unsigned char *end, +void modify_line_number_statement( + uint8_t **data, uint8_t *end, struct dwarf_bias_info *bias_info) { - // int cu_line_offset = 0x1b5; - // unsigned char *start = *data - cu_line_offset; - while (*data < end){ //ptr < end - unsigned char op_code; - printf("%lx ", *data-start); - op_code = **data; - ++*data; - printf("OP[%x]:", op_code); - switch (op_code) - { - // DW_LNS_extended_op - case 0: - process_extended_line_op(data, bias_info); - // if (*(unsigned short*)*data == 0x0101){ - // *data += 0x2; - // printf("DW_LNE_end_sequence\n"); - // return 0; - // } - // else { - // process_extended_line_op(data); - // } - break; - case DW_LNS_copy: - printf("DW_LNS_copy\n"); - break; - case DW_LNS_advance_pc: - printf("DW_LNS_advance_pc\n"); - skip_leb128(data); - break; - case DW_LNS_advance_line: - printf("DW_LNS_advance_line\n"); - /* - [0x00000bcc] Extended opcode 1: End of Sequence - - [0x00000bcf] Set column to 1 bb1 OP[3]:DW_LNS_advance_line -.(0xffff8bc19baf,a7)(0xffff8bc19bb0,71)-(0xffff8bc19bb1,4a)bb4 OP[4a]:Sp_op 61 -*/ - skip_leb128(data); - break; - case DW_LNS_set_file: - printf("\n"); - skip_leb128(data); - break; - case DW_LNS_set_column: - skip_leb128(data); - printf("DW_LNS_set_column: skip\n"); - break; - case DW_LNS_negate_stmt: - printf("DW_LNS_negate_stmt\n"); - break; - case DW_LNS_set_basic_block: - printf("DW_LNS_set_basic_block\n"); - break; - case DW_LNS_const_add_pc: - printf("\n"); - break; - case DW_LNS_fixed_advance_pc: - printf("\n"); - // nead process, but this op only use in few machine - break; - case DW_LNS_set_prologue_end: - printf("\n"); - break; - case DW_LNS_set_epilogue_begin: - printf("\n"); - break; - case DW_LNS_set_isa: - skip_leb128(data); - break; - - default: - printf("Sp_op %d\n", (op_code-13)); - // printf("NT YT\n"); - // exit(2); - } - // return 0; + while (*data < end) { + uint8_t op_code = *(uint8_t*)*data; + ++*data; + switch (op_code) + { + // DW_LNS_extended_op + case 0: + process_extended_line_op(data, bias_info); + break; + case DW_LNS_advance_pc: + case DW_LNS_advance_line: + case DW_LNS_set_file: + case DW_LNS_set_column: + case DW_LNS_set_isa: + skip_leb128((uint8_t**)data); + break; + case DW_LNS_copy: + case DW_LNS_negate_stmt: + case DW_LNS_set_basic_block: + case DW_LNS_const_add_pc: + case DW_LNS_fixed_advance_pc: + case DW_LNS_set_prologue_end: + case DW_LNS_set_epilogue_begin: + break; + default: + // si_panic("unknown line_op 0x%x\n", op_code); + break; + } } } -void modify_cu_debug_line(unsigned char ** data, struct dwarf_bias_info *bias_info, unsigned char *start)//, int cu_num) +void modify_cu_debug_line(uint8_t **data, struct dwarf_bias_info *bias_info) { - // unsigned int cu_dl_len = *(int *)data; - unsigned char *end = *(int *)*data + *data + 0x4; - printf("\n***modify_cu_debug_line***%ld***\n", end - start); - // skip_header(data); + // in the.debug_line, the length of CU is recorded at the 4-byte starting with CU, plus 0x4 + uint8_t *end = *data + *(uint32_t *)*data + 0x4; + // skip_header; *data += 0x12; - // skip_opcodes(data); + // skip_opcodes; todo may be different in some binary *data += 0xc; // unsigned long dt_count = read_skip_dir_table_count(data); // 0x01011f *data += 0x3; - unsigned long dt_count = read_skip_leb128(data); + uint64_t dt_count = read_skip_leb128(data); // print_dt(data, dt_count); - for (unsigned long i =0; i < dt_count; i++){ - printf("%ld,%x:%x\n", i, *(unsigned int*)*data, *(unsigned int*)*data); + for (uint64_t i =0; i < dt_count; i++) { uint32_t *dst_ptr = (uint32_t *)*data; *dst_ptr += bias_info->debug_line_str; - // **data += bias_info->debug_line_str; - *data += 4; + *data += 0x4; } - // unsigned long ft_count = read_skip_file_name_table_count(data); // 0201 1f02 0f *data += 0x5; - unsigned long ft_count = read_skip_leb128(data); - // print_ft(data, ft_count); - for (unsigned long i =0; i< ft_count; i++){ - printf("%ld,%x:%x\n", i, *(unsigned int*)*data, *(unsigned int*)*data); - // **data += bias_info->debug_line_str; + uint64_t ft_count = read_skip_leb128(data); + for (uint64_t i =0; i< ft_count; i++){ uint32_t *dst_ptr = (uint32_t *)*data; *dst_ptr += bias_info->debug_line_str; - *data += 4; + *data += 0x4; skip_leb128(data); } - modify_line_number_statement(data, start, end, bias_info); - // exit(1); + modify_line_number_statement(data, end, bias_info); } int modify_debug_line(elf_link_t *elf_link) @@ -1905,13 +1800,11 @@ int modify_debug_line(elf_link_t *elf_link) struct dwarf_bias_info bias_info; foreach_infile(elf_link, ef) { - Elf64_Shdr *dl_sec = elf_find_section_by_name(ef, ".debug_line"); + Elf64_Shdr *dl_sec = elf_find_section_by_name(ef, DEBUG_LINE); unsigned long dst_offset = get_new_offset_by_old_offset( elf_link, ef, dl_sec->sh_offset ); - void *dl_ptr = get_out_ef(elf_link)->data + dst_offset; - unsigned char *start = dl_ptr; - prep_bias_info(elf_link, ef, &bias_info); + uint8_t *dl_ptr = get_out_ef(elf_link)->data + dst_offset; temp_path = temp_get_file_name(ef->file_name); Dwarf_Debug dbg = dwarf_init(temp_path); @@ -1926,44 +1819,345 @@ int modify_debug_line(elf_link_t *elf_link) /* no entry */ break; } - modify_cu_debug_line((unsigned char **)&dl_ptr, &bias_info, start); + modify_cu_debug_line((unsigned char **)&dl_ptr, &bias_info); } dwarf_finish(dbg); } return 0; } -int modify_debug_info(elf_link_t *elf_link) + +unsigned int decode_count_loc_desc(elf_link_t *elf_link, elf_file_t *ef, uint8_t *optr, unsigned long cld_len) { + unsigned int extra_skip = 0; + uint8_t *end_ptr = optr + cld_len; + while (optr < end_ptr){ + uint8_t op = *optr++; + switch (op) + { + case DW_OP_addr: { + uint64_t *_addr = (uint64_t*)optr; + *_addr = get_new_offset_by_old_offset(elf_link, ef, *_addr); + optr += 8; + // skip_leb128((unsigned char **)&optr); + // optr += read_skip_leb128((unsigned char **)&optr); + break; + } + case DW_OP_deref: + case DW_OP_dup: + case DW_OP_drop: + case DW_OP_over: + case DW_OP_swap: + case DW_OP_rot: + case DW_OP_xderef: + case DW_OP_abs: + case DW_OP_and: + case DW_OP_div: + case DW_OP_minus: + case DW_OP_mod: + case DW_OP_mul: + case DW_OP_neg: + case DW_OP_not: + case DW_OP_or: + case DW_OP_plus: + case DW_OP_shl: + case DW_OP_shr: + case DW_OP_shra: + case DW_OP_xor: + case DW_OP_eq: + case DW_OP_ge: + case DW_OP_gt: + case DW_OP_le: + case DW_OP_lt: + case DW_OP_ne: + case DW_OP_lit0: + case DW_OP_lit1: + case DW_OP_lit2: + case DW_OP_lit3: + case DW_OP_lit4: + case DW_OP_lit5: + case DW_OP_lit6: + case DW_OP_lit7: + case DW_OP_lit8: + case DW_OP_lit9: + case DW_OP_lit10: + case DW_OP_lit11: + case DW_OP_lit12: + case DW_OP_lit13: + case DW_OP_lit14: + case DW_OP_lit15: + case DW_OP_lit16: + case DW_OP_lit17: + case DW_OP_lit18: + case DW_OP_lit19: + case DW_OP_lit20: + case DW_OP_lit21: + case DW_OP_lit22: + case DW_OP_lit23: + case DW_OP_lit24: + case DW_OP_lit25: + case DW_OP_lit26: + case DW_OP_lit27: + case DW_OP_lit28: + case DW_OP_lit29: + case DW_OP_lit30: + case DW_OP_lit31: + case DW_OP_reg0: + case DW_OP_reg1: + case DW_OP_reg2: + case DW_OP_reg3: + case DW_OP_reg4: + case DW_OP_reg5: + case DW_OP_reg6: + case DW_OP_reg7: + case DW_OP_reg8: + case DW_OP_reg9: + case DW_OP_reg10: + case DW_OP_reg11: + case DW_OP_reg12: + case DW_OP_reg13: + case DW_OP_reg14: + case DW_OP_reg15: + case DW_OP_reg16: + case DW_OP_reg17: + case DW_OP_reg18: + case DW_OP_reg19: + case DW_OP_reg20: + case DW_OP_reg21: + case DW_OP_reg22: + case DW_OP_reg23: + case DW_OP_reg24: + case DW_OP_reg25: + case DW_OP_reg26: + case DW_OP_reg27: + case DW_OP_reg28: + case DW_OP_reg29: + case DW_OP_reg30: + case DW_OP_reg31: + case DW_OP_nop: + case DW_OP_form_tls_address: + case DW_OP_call_frame_cfa: + case DW_OP_GNU_push_tls_address: + case DW_OP_GNU_uninit: + case DW_OP_HP_is_value: + case DW_OP_HP_fltconst4: + case DW_OP_HP_fltconst8: + case DW_OP_HP_mod_range: + case DW_OP_HP_unmod_range: + case DW_OP_HP_tls: + case DW_OP_PGI_omp_thread_num: + break; + case DW_OP_const1u: + case DW_OP_const1s: + case DW_OP_pick: + case DW_OP_deref_size: + case DW_OP_xderef_size: + optr += 1; + break; + case DW_OP_const2u: + case DW_OP_const2s: + case DW_OP_bra: + case DW_OP_skip: + optr += 2; + break; + case DW_OP_const4u: + case DW_OP_const4s: + case DW_OP_GNU_parameter_ref: + optr += 4; + break; + case DW_OP_const8u: + case DW_OP_const8s: + optr += 8; + break; + case DW_OP_constu: + case DW_OP_consts: + case DW_OP_breg0: + case DW_OP_breg1: + case DW_OP_breg2: + case DW_OP_breg3: + case DW_OP_breg4: + case DW_OP_breg5: + case DW_OP_breg6: + case DW_OP_breg7: + case DW_OP_breg8: + case DW_OP_breg9: + case DW_OP_breg10: + case DW_OP_breg11: + case DW_OP_breg12: + case DW_OP_breg13: + case DW_OP_breg14: + case DW_OP_breg15: + case DW_OP_breg16: + case DW_OP_breg17: + case DW_OP_breg18: + case DW_OP_breg19: + case DW_OP_breg20: + case DW_OP_breg21: + case DW_OP_breg22: + case DW_OP_breg23: + case DW_OP_breg24: + case DW_OP_breg25: + case DW_OP_breg26: + case DW_OP_breg27: + case DW_OP_breg28: + case DW_OP_breg29: + case DW_OP_breg30: + case DW_OP_breg31: + case DW_OP_regx: + case DW_OP_fbreg: + case DW_OP_piece: + case DW_OP_convert: + case DW_OP_GNU_convert: + skip_leb128(&optr); + break; + case DW_OP_bregx: + case DW_OP_bit_piece: + skip_leb128(&optr); + skip_leb128(&optr); + break; + case DW_OP_implicit_value: + optr += read_skip_leb128((unsigned char **)&optr); + break; + case DW_OP_implicit_pointer: + case DW_OP_GNU_implicit_pointer: + // not support dwarf_version -1 2 + // todo why 00 00 at end 目前只出现在末尾, 且有多余00 00 , 搞清楚为什么 + return 0; + skip_leb128(&optr); + optr += 2; + extra_skip += 2; + break; + case DW_OP_entry_value: + case DW_OP_GNU_entry_value: { + unsigned long sub_cld_len = read_skip_leb128(&optr); + decode_count_loc_desc(elf_link, ef, optr, sub_cld_len); + optr += sub_cld_len; + break; + } + case DW_OP_push_object_address: + case DW_OP_call2: + case DW_OP_call4: + case DW_OP_call_ref: + si_panic("old dwarf version 2,3 not support\n"); + break; + case DW_OP_GNU_encoded_addr: + case DW_OP_const_type: + case DW_OP_GNU_const_type: + case DW_OP_regval_type: + case DW_OP_GNU_regval_type: + case DW_OP_deref_type: + case DW_OP_GNU_deref_type: + case DW_OP_reinterpret: + case DW_OP_GNU_reinterpret: + case DW_OP_GNU_addr_index: + case DW_OP_GNU_const_index: + case DW_OP_GNU_variable_value: + // todo may need support + si_panic("not support\n"); + break; + default: + si_panic("OPOP not support\n"); + // if (op >= DW_OP_lo_user + // && op <= DW_OP_hi_user) + // printf (_("(User defined location op 0x%x)"), op); + // else + // printf (_("(Unknown location op 0x%x)"), op); + // /* No way to tell where the next op is, so just bail. */ + // return need_frame_base; + } + } + return extra_skip; +} + +void modify_debug_loclists(elf_link_t *elf_link, struct dwarf_bias_info* dbi) { - elf_file_t *ef; char *temp_path; - struct dwarf_bias_info bias_info; - foreach_infile(elf_link, ef) { - Elf64_Shdr *di_sec = elf_find_section_by_name(ef, ".debug_info"); + for (unsigned int fi=0; fiin_ef_nr; fi++) { + Elf64_Shdr *dll_sec = elf_find_section_by_name(&elf_link->in_efs[fi], DEBUG_LOCLISTS); unsigned long dst_offset = get_new_offset_by_old_offset( - elf_link, ef, di_sec->sh_offset + elf_link, &elf_link->in_efs[fi], dll_sec->sh_offset + ); + uint8_t *start = get_out_ef(elf_link)->data + dst_offset; + + temp_path = temp_get_file_name(elf_link->in_efs[fi].file_name); + Dwarf_Debug dbg = dwarf_init(temp_path); + if (!dbg) + si_panic("dwarf_init fail, file: %s\n", temp_path); + + for (uint64_t i= 0; i < dbi[fi].lvp.num; i++){ + uint8_t *dll_ptr = start + dbi[fi].lvp.end[i]; + bool end_mark = false; + while (!end_mark) { + uint8_t lle = *dll_ptr++; + switch (lle) { + case DW_LLE_end_of_list: + end_mark = true; + break; + case DW_LLE_base_address: { + uint64_t *_addr = (uint64_t*)dll_ptr; + *_addr = get_new_offset_by_old_offset(elf_link, &elf_link->in_efs[fi], *_addr); + dll_ptr += 8; + break; + } + case DW_LLE_offset_pair: { + skip_leb128(&dll_ptr); + skip_leb128(&dll_ptr); + // uint64_t cld_len = read_skip_leb128(&dll_ptr); + // unsigned int extra_skip = decode_count_loc_desc(elf_link, ef, dll_ptr, cld_len); + // dll_ptr += cld_len; + // dll_ptr += extra_skip; + dll_ptr += read_skip_leb128(&dll_ptr); + break; + } + case DW_LLE_start_length: { + uint64_t *_addr = (uint64_t*)dll_ptr; + *_addr = get_new_offset_by_old_offset(elf_link, &elf_link->in_efs[fi], *_addr); + dll_ptr += 8; + skip_leb128(&dll_ptr); + // unsigned long cld_len = read_skip_leb128((unsigned char **)&dll_ptr); + // unsigned int extra_skip = decode_count_loc_desc(elf_link, ef, dll_ptr, cld_len); + // dll_ptr += cld_len; + // dll_ptr += extra_skip; + dll_ptr += read_skip_leb128(&dll_ptr); + break; + } + default: + si_panic("unknown lle 0x%x\n", lle); + return; + } + } + } + } +} +int modify_debug_info(elf_link_t *elf_link, struct dwarf_bias_info* dbi) +{ + char *temp_path; + + for (unsigned int i=0; iin_ef_nr; i++) { + Elf64_Shdr *di_sec = elf_find_section_by_name(&elf_link->in_efs[i], ".debug_info"); + unsigned long dst_offset = get_new_offset_by_old_offset( + elf_link, &elf_link->in_efs[i], di_sec->sh_offset ); void *di_ptr = get_out_ef(elf_link)->data + dst_offset; - prep_bias_info(elf_link, ef, &bias_info); - temp_path = temp_get_file_name(ef->file_name); + temp_path = temp_get_file_name(elf_link->in_efs[i].file_name); Dwarf_Debug dbg = dwarf_init(temp_path); if (!dbg) si_panic("dwarf_init fail, file: %s\n", temp_path); - dwarf_traverse_cu(dbg, di_ptr, &bias_info); + dwarf_traverse_cu(dbg, di_ptr, &dbi[i]); dwarf_finish(dbg); } return 0; } - static void modify_debug(elf_link_t *elf_link) { modify_debug_info_abbrev_offset(elf_link); - modify_debug_info(elf_link); + struct dwarf_bias_info* dbi = init_prep_bias_info(elf_link); + modify_debug_info(elf_link, dbi); + modify_debug_loclists(elf_link, dbi); modify_debug_line(elf_link); - // todo modify_debug_list(elf_link); + free(dbi); } /* debug modify end */ -- Gitee