Hi Mark,
On Fri, Dec 5, 2025 at 10:27 AM Mark Wielaard <[email protected]> wrote:
>
> 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.
>
> https://sourceware.org/bugzilla/show_bug.cgi?id=33658
>
> Suggested-by: Shimin Guo <[email protected]>
> Signed-off-by: Mark Wielaard <[email protected]>
LGTM.
Aaron
> ---
> libdw/dwarf_getcfi_elf.c | 34 ++++++++++++++++++++++++++++------
> 1 file changed, 28 insertions(+), 6 deletions(-)
>
> diff --git a/libdw/dwarf_getcfi_elf.c b/libdw/dwarf_getcfi_elf.c
> index c0e3cadd2489..5b5106537688 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;
> --
> 2.52.0
>