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
>

Reply via email to