From: Mark Wielaard Date: Fri, 5 Dec 2025 15:13:32 +0000 (+0100) Subject: libdw: Make sure to get .eh_frame_hdr with .eh_frame in getcfi_shdr X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Fusers%2Fmark%2Ftry-getcfi_shdr;p=thirdparty%2Felfutils.git libdw: Make sure to get .eh_frame_hdr with .eh_frame in getcfi_shdr If we find a .eh_frame section we want to make sure to also get the search table section .eh_frame_hdr. Otherwise lookups will be very slow. Only create a Dwarf_CFI without a search table as a last resort. * libdw/dwarf_getcfi_elf.c (getcfi_shdr): Keep iterating through the shdrs till both .eh_frame and .eh_frame_hdr are found. Check both aren't SHT_NOBITS. Suggested-by: Shimin Guo Signed-off-by: Mark Wielaard --- diff --git a/libdw/dwarf_getcfi_elf.c b/libdw/dwarf_getcfi_elf.c index c0e3cadd..5b510653 100644 --- a/libdw/dwarf_getcfi_elf.c +++ b/libdw/dwarf_getcfi_elf.c @@ -281,6 +281,8 @@ getcfi_shdr (Elf *elf, const GElf_Ehdr *ehdr) if (shstrndx != 0) { + Elf_Scn *eh_scn = NULL; + GElf_Shdr eh_shdr_mem; Elf_Scn *hdr_scn = NULL; GElf_Addr hdr_vaddr = 0; Elf_Scn *scn = NULL; @@ -295,18 +297,38 @@ getcfi_shdr (Elf *elf, const GElf_Ehdr *ehdr) continue; if (!strcmp (name, ".eh_frame_hdr")) { - hdr_scn = scn; - hdr_vaddr = shdr->sh_addr; + if (shdr->sh_type != SHT_NOBITS) + { + hdr_scn = scn; + hdr_vaddr = shdr->sh_addr; + + if (eh_scn != NULL) + return getcfi_scn_eh_frame (elf, ehdr, + eh_scn, &eh_shdr_mem, + hdr_scn, hdr_vaddr); + } } else if (!strcmp (name, ".eh_frame")) { if (shdr->sh_type != SHT_NOBITS) - return getcfi_scn_eh_frame (elf, ehdr, scn, shdr, - hdr_scn, hdr_vaddr); - else - return NULL; + { + eh_scn = scn; + eh_shdr_mem = *shdr; + + if (hdr_scn != NULL) + return getcfi_scn_eh_frame (elf, ehdr, + eh_scn, &eh_shdr_mem, + hdr_scn, hdr_vaddr); + } } } + + /* .eh_frame without .eh_frame_hdr will be slow, might want to + generate our own search table? */ + if (eh_scn != NULL) + return getcfi_scn_eh_frame (elf, ehdr, + eh_scn, &eh_shdr_mem, + NULL, 0); } return (void *) -1l;