diff options
Diffstat (limited to 'libdw')
| -rw-r--r-- | libdw/ChangeLog | 25 | ||||
| -rw-r--r-- | libdw/dwarf_begin_elf.c | 27 | ||||
| -rw-r--r-- | libdw/dwarf_getabbrev.c | 2 | ||||
| -rw-r--r-- | libdw/dwarf_getaranges.c | 4 | ||||
| -rw-r--r-- | libdw/dwarf_hasattr.c | 4 | ||||
| -rw-r--r-- | libdw/libdw_alloc.c | 1 |
6 files changed, 51 insertions, 12 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index da7ed9d0..ebe002cd 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,28 @@ +2018-09-13 Mark Wielaard <[email protected]> + + * 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 <[email protected]> + + * dwarf_getabbrev.c (__libdw_getabbrev): Continue until both name + and form are zero. + * dwarf_hasattr.c (dwarf_hasattr): Stop when both name and form + are zero. + +2018-08-18 Mark Wielaard <[email protected]> + + * dwarf_getaranges.c (dwarf_getaranges.c): Make sure there is enough + data to read the address and segment size. + +2018-07-04 Ross Burton <[email protected]> + + * libdw_alloc.c: Remove error.h include. + 2018-06-28 Mark Wielaard <[email protected]> * dwarf_next_cfi.c (dwarf_next_cfi): Check whether length is zero. 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) { diff --git a/libdw/dwarf_getabbrev.c b/libdw/dwarf_getabbrev.c index 988d12c2..6a7e981b 100644 --- a/libdw/dwarf_getabbrev.c +++ b/libdw/dwarf_getabbrev.c @@ -140,7 +140,7 @@ __libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset, get_sleb128 (formval, abbrevp, end); } } - while (attrname != 0 && attrform != 0); + while (attrname != 0 || attrform != 0); /* Return the length to the caller if she asked for it. */ if (lengthp != NULL) diff --git a/libdw/dwarf_getaranges.c b/libdw/dwarf_getaranges.c index bff9c860..de5b81ba 100644 --- a/libdw/dwarf_getaranges.c +++ b/libdw/dwarf_getaranges.c @@ -148,6 +148,10 @@ dwarf_getaranges (Dwarf *dbg, Dwarf_Aranges **aranges, size_t *naranges) length_bytes, &offset, IDX_debug_info, 4)) goto fail; + /* Next up two bytes for address and segment size. */ + if (readp + 2 > readendp) + goto invalid; + unsigned int address_size = *readp++; if (unlikely (address_size != 4 && address_size != 8)) goto invalid; diff --git a/libdw/dwarf_hasattr.c b/libdw/dwarf_hasattr.c index 90053b13..eca08394 100644 --- a/libdw/dwarf_hasattr.c +++ b/libdw/dwarf_hasattr.c @@ -60,8 +60,8 @@ dwarf_hasattr (Dwarf_Die *die, unsigned int search_name) unsigned int attr_form; get_uleb128_unchecked (attr_form, attrp); - /* We can stop if we found the attribute with value zero. */ - if (attr_name == 0 || attr_form == 0) + /* We can stop if we found the end of the attribute list. */ + if (attr_name == 0 && attr_form == 0) return 0; if (attr_name == search_name) diff --git a/libdw/libdw_alloc.c b/libdw/libdw_alloc.c index d6af23a2..f1e08714 100644 --- a/libdw/libdw_alloc.c +++ b/libdw/libdw_alloc.c @@ -31,7 +31,6 @@ # include <config.h> #endif -#include <error.h> #include <errno.h> #include <stdlib.h> #include "libdwP.h" |
