From 854de8b8bd4e28a305546a57b70c505a78f52529 Mon Sep 17 00:00:00 2001 From: mephi42 Date: Fri, 18 Oct 2019 11:14:28 +0200 Subject: [PATCH 1/3] Do not skip segments of type SEG_CODE --- src/dwarfexport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 src/dwarfexport.cpp diff --git a/src/dwarfexport.cpp b/src/dwarfexport.cpp old mode 100644 new mode 100755 index 77d3088..5f860a6 --- a/src/dwarfexport.cpp +++ b/src/dwarfexport.cpp @@ -724,7 +724,7 @@ void add_debug_info(std::shared_ptr info, // Only consider EXEC segments // TODO: Skip plt/got? - if (!(seg->perm & SEGPERM_EXEC)) { + if (!(seg->perm & SEGPERM_EXEC) && seg->type != SEG_CODE) { dwarfexport_log("Segment #", segn, " is not executable. Skipping."); continue; } From 8846a7c2f424661bb973fb1f7f583ca05660c13a Mon Sep 17 00:00:00 2001 From: mephi42 Date: Wed, 14 Oct 2020 20:46:15 +0200 Subject: [PATCH 2/3] Skip segments without functions --- src/dwarfexport.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/dwarfexport.cpp b/src/dwarfexport.cpp index 5f860a6..b24fd62 100755 --- a/src/dwarfexport.cpp +++ b/src/dwarfexport.cpp @@ -740,7 +740,8 @@ void add_debug_info(std::shared_ptr info, f = get_next_func(seg->startEA); if (f == nullptr) { - dwarfexport_error("get_next_func() failed"); + dwarfexport_log("Skipping ", lsegname, " because it has no functions"); + continue; } } From db9d4d41eef9592134931649512cf95510ca7093 Mon Sep 17 00:00:00 2001 From: mephi42 Date: Wed, 14 Oct 2020 22:43:51 +0200 Subject: [PATCH 3/3] Allow overlapping sections --- src/dwarfgen.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) mode change 100644 => 100755 src/dwarfgen.cpp diff --git a/src/dwarfgen.cpp b/src/dwarfgen.cpp old mode 100644 new mode 100755 index 34cc8e9..7910bea --- a/src/dwarfgen.cpp +++ b/src/dwarfgen.cpp @@ -144,7 +144,7 @@ std::shared_ptr generate_dwarf_object(const Options &options) { } static Elf_Scn *get_last_section(Elf *elf) { - std::size_t count, max_offset = 0; + std::size_t count, max_offset = 0, max_size = 0; GElf_Shdr shdr; Elf_Scn *last_scn; @@ -156,9 +156,14 @@ static Elf_Scn *get_last_section(Elf *elf) { if (!gelf_getshdr(scn, &shdr)) { dwarfexport_error("elf_getshdr() failed: ", elf_errmsg(-1)); } - if (shdr.sh_offset > max_offset) { + if (shdr.sh_type == SHT_NOBITS) { + continue; + } + if (shdr.sh_offset > max_offset || + (shdr.sh_offset == max_offset && shdr.sh_size > max_size)) { last_scn = scn; max_offset = shdr.sh_offset; + max_size = shdr.sh_size; } } return last_scn; @@ -243,6 +248,34 @@ static void add_debug_section_data(std::shared_ptr info) { } } +static void log_elf(Elf *elf) { + GElf_Ehdr ehdr; + int scn_index; + Elf_Scn *scn; + GElf_Shdr shdr; + + if (gelf_getehdr(elf, &ehdr) != &ehdr) + dwarfexport_error("gelf_getehdr() failed: ", elf_errmsg(-1)); + + for (scn_index = 1; scn_index < ehdr.e_shnum; scn_index++) { + if ((scn = elf_getscn(elf, scn_index)) == NULL) + dwarfexport_error("getshdr() failed: ", elf_errmsg(-1)); + if (gelf_getshdr(scn, &shdr) != &shdr) + dwarfexport_error("getshdr() failed: ", elf_errmsg(-1)); + dwarfexport_log("Section #", scn_index, + ": sh_name=", shdr.sh_name, + ", sh_type=", shdr.sh_type, + ", sh_flags=", shdr.sh_flags, + ", sh_addr=", shdr.sh_addr, + ", sh_offset=", shdr.sh_offset, + ", sh_size=", shdr.sh_size, + ", sh_link=", shdr.sh_link, + ", sh_info=", shdr.sh_info, + ", sh_addralign=", shdr.sh_addralign, + ", sh_entsize=", shdr.sh_entsize); + } +} + static void generate_copy_with_dbg_info(std::shared_ptr info, const std::string &src, const std::string &dst) { @@ -284,10 +317,10 @@ static void generate_copy_with_dbg_info(std::shared_ptr info, info->elf = elf_out; - /* Some compilers produce binaries with non-adjacent sections, so - * we cannot use the automatic layout. Suppress it and use the exact + /* Some compilers produce binaries with non-adjacent or overlapping sections, + * so we cannot use the automatic layout. Suppress it and use the exact * layout from the input. */ - if (elf_flagelf(elf_out, ELF_C_SET, ELF_F_LAYOUT) == 0) + if (elf_flagelf(elf_out, ELF_C_SET, ELF_F_LAYOUT | ELF_F_LAYOUT_OVERLAP) == 0) dwarfexport_error("elf_flagelf failed: ", elf_errmsg(-1)); if (gelf_getehdr(elf_out, &ehdr_out) != &ehdr_out) @@ -346,8 +379,14 @@ static void generate_copy_with_dbg_info(std::shared_ptr info, dwarfexport_error("gelf_update_shdr() failed: ", elf_errmsg(-1)); } + dwarfexport_log("After copying the original sections:"); + log_elf(elf_out); + add_debug_section_data(info); + dwarfexport_log("After adding the debug sections:"); + log_elf(elf_out); + // Get the current last section (to fix section header and string table loc) auto last_scn = get_last_section(elf_out); GElf_Shdr last_shdr; @@ -374,6 +413,9 @@ static void generate_copy_with_dbg_info(std::shared_ptr info, if (gelf_update_ehdr(elf_out, &ehdr_out) == 0) dwarfexport_error("gelf_update_ehdr() failed: ", elf_errmsg(-1)); + dwarfexport_log("After fixing various offsets:"); + log_elf(elf_out); + if (elf_update(elf_out, ELF_C_WRITE) < 0) dwarfexport_error("elf_update() failed: ", elf_errmsg(-1));