summaryrefslogtreecommitdiffstats
path: root/libdw
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2018-08-04 22:34:32 +0200
committerMark Wielaard <mark@klomp.org>2018-09-14 00:20:49 +0200
commitb14633d41673bb1903c887cb9ffd55fe700c4eb1 (patch)
treedcd91404f2f7ad1b57189864470abe40d5cd5c3c /libdw
parent583d106753e805e75a6cbfeab79aa2965e042f69 (diff)
libdw: dwarf_begin_elf should use elf_getshdrstrndx to get section names.
dwarf_begin_elf used the Ehdr e_shstrndx to get the shdr string table section. This does not work for ELF files with more than SHN_LORESERVE sections. Use elf_getshdrstrndx, and don't pass around the ehdr. Add a simple testcase that fails before the patch because dwarf_begin return an error. Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'libdw')
-rw-r--r--libdw/ChangeLog9
-rw-r--r--libdw/dwarf_begin_elf.c27
2 files changed, 28 insertions, 8 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 7cb25923..ebe002cd 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,12 @@
+2018-09-13 Mark Wielaard <mark@klomp.org>
+
+ * dwarf_begin_elf.c (check_section): Drop ehdr argument, add and
+ use shstrndx argument.
+ (global_read): Likewise.
+ (scngrp_read): Likewise.
+ (dwarf_begin_elf): Call elf_getshdrstrndx. Pass shstrndx to
+ global_read or scngrp_read.
+
2018-08-18 Mark Wielaard <mark@klomp.org>
* dwarf_getabbrev.c (__libdw_getabbrev): Continue until both name
diff --git a/libdw/dwarf_begin_elf.c b/libdw/dwarf_begin_elf.c
index 184a6dc9..38c8f5c6 100644
--- a/libdw/dwarf_begin_elf.c
+++ b/libdw/dwarf_begin_elf.c
@@ -71,7 +71,7 @@ static const char dwarf_scnnames[IDX_last][19] =
#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
static Dwarf *
-check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
+check_section (Dwarf *result, size_t shstrndx, Elf_Scn *scn, bool inscngrp)
{
GElf_Shdr shdr_mem;
GElf_Shdr *shdr;
@@ -101,7 +101,7 @@ check_section (Dwarf *result, GElf_Ehdr *ehdr, Elf_Scn *scn, bool inscngrp)
/* We recognize the DWARF section by their names. This is not very
safe and stable but the best we can do. */
- const char *scnname = elf_strptr (result->elf, ehdr->e_shstrndx,
+ const char *scnname = elf_strptr (result->elf, shstrndx,
shdr->sh_name);
if (scnname == NULL)
{
@@ -302,19 +302,19 @@ valid_p (Dwarf *result)
static Dwarf *
-global_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr)
+global_read (Dwarf *result, Elf *elf, size_t shstrndx)
{
Elf_Scn *scn = NULL;
while (result != NULL && (scn = elf_nextscn (elf, scn)) != NULL)
- result = check_section (result, ehdr, scn, false);
+ result = check_section (result, shstrndx, scn, false);
return valid_p (result);
}
static Dwarf *
-scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
+scngrp_read (Dwarf *result, Elf *elf, size_t shstrndx, Elf_Scn *scngrp)
{
GElf_Shdr shdr_mem;
GElf_Shdr *shdr = gelf_getshdr (scngrp, &shdr_mem);
@@ -363,7 +363,7 @@ scngrp_read (Dwarf *result, Elf *elf, GElf_Ehdr *ehdr, Elf_Scn *scngrp)
return NULL;
}
- result = check_section (result, ehdr, scn, true);
+ result = check_section (result, shstrndx, scn, true);
if (result == NULL)
break;
}
@@ -425,15 +425,26 @@ dwarf_begin_elf (Elf *elf, Dwarf_Cmd cmd, Elf_Scn *scngrp)
if (cmd == DWARF_C_READ || cmd == DWARF_C_RDWR)
{
+ /* All sections are recognized by name, so pass the section header
+ string index along to easily get the section names. */
+ size_t shstrndx;
+ if (elf_getshdrstrndx (elf, &shstrndx) != 0)
+ {
+ Dwarf_Sig8_Hash_free (&result->sig8_hash);
+ __libdw_seterrno (DWARF_E_INVALID_ELF);
+ free (result);
+ return NULL;
+ }
+
/* If the caller provides a section group we get the DWARF
sections only from this setion group. Otherwise we search
for the first section with the required name. Further
sections with the name are ignored. The DWARF specification
does not really say this is allowed. */
if (scngrp == NULL)
- return global_read (result, elf, ehdr);
+ return global_read (result, elf, shstrndx);
else
- return scngrp_read (result, elf, ehdr, scngrp);
+ return scngrp_read (result, elf, shstrndx, scngrp);
}
else if (cmd == DWARF_C_WRITE)
{