diff options
author | emaste <emaste@FreeBSD.org> | 2016-05-20 17:24:34 +0000 |
---|---|---|
committer | emaste <emaste@FreeBSD.org> | 2016-05-20 17:24:34 +0000 |
commit | e1afa8a66332bcb42ea042ec5dfb59de5b33ee08 (patch) | |
tree | 53f16cf467b740bb55f778ee1a5c3b117e43c2e0 /contrib/elftoolchain/libdwarf | |
parent | 1860a225caf7329b3bc2038750624b9d0b47139a (diff) | |
parent | db27a04d331bc804aa12a4a70e9e0d939f3773c0 (diff) | |
download | FreeBSD-src-e1afa8a66332bcb42ea042ec5dfb59de5b33ee08.zip FreeBSD-src-e1afa8a66332bcb42ea042ec5dfb59de5b33ee08.tar.gz |
Update to ELF Tool Chain r3475
Improvements include:
* Add support for reporting and handling a number of new constants in
various tools, including:
* CloudABI OSABI
* DT_TLSDESC_*
* i386, MIPS, SPARC and amd64 relocations
* C++ demangler bug fixes
* Man page updates
* Improved input validation in several tools
This update also reduces diffs against upstream as a number of fixes
included in upstream were previously cherry-picked into FreeBSD.
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'contrib/elftoolchain/libdwarf')
-rw-r--r-- | contrib/elftoolchain/libdwarf/libdwarf_abbrev.c | 6 | ||||
-rw-r--r-- | contrib/elftoolchain/libdwarf/libdwarf_elf_init.c | 102 |
2 files changed, 67 insertions, 41 deletions
diff --git a/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c b/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c index abcc2fd..9e4b6ab 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_abbrev.c @@ -27,7 +27,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_abbrev.c 3136 2014-12-24 16:04:38Z kaiwang27 $"); +ELFTC_VCSID("$Id: libdwarf_abbrev.c 3420 2016-02-27 02:14:05Z emaste $"); int _dwarf_abbrev_add(Dwarf_CU cu, uint64_t entry, uint64_t tag, uint8_t children, @@ -115,9 +115,7 @@ _dwarf_abbrev_parse(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Unsigned *offset, assert(abp != NULL); ds = _dwarf_find_section(dbg, ".debug_abbrev"); - assert(ds != NULL); - - if (*offset >= ds->ds_size) + if (ds == NULL || *offset >= ds->ds_size) return (DW_DLE_NO_ENTRY); aboff = *offset; diff --git a/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c b/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c index 5ab6ffc..bd68afc 100644 --- a/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c +++ b/contrib/elftoolchain/libdwarf/libdwarf_elf_init.c @@ -26,7 +26,7 @@ #include "_libdwarf.h" -ELFTC_VCSID("$Id: libdwarf_elf_init.c 3161 2015-02-15 21:43:36Z emaste $"); +ELFTC_VCSID("$Id: libdwarf_elf_init.c 3475 2016-05-18 18:11:26Z emaste $"); static const char *debug_name[] = { ".debug_abbrev", @@ -50,55 +50,81 @@ static const char *debug_name[] = { }; static void -_dwarf_elf_write_reloc(Dwarf_Debug dbg, Elf_Data *symtab_data, int endian, - void *buf, uint64_t offset, GElf_Xword r_info, GElf_Sxword r_addend, - int is_rel) +_dwarf_elf_apply_rel_reloc(Dwarf_Debug dbg, void *buf, uint64_t bufsize, + Elf_Data *rel_data, Elf_Data *symtab_data, int endian) { + Dwarf_Unsigned type; + GElf_Rel rel; GElf_Sym sym; - int size; + size_t symndx; + uint64_t offset; + uint64_t addend; + int size, j; + + j = 0; + while (gelf_getrel(rel_data, j++, &rel) != NULL) { + symndx = GELF_R_SYM(rel.r_info); + type = GELF_R_TYPE(rel.r_info); + + if (gelf_getsym(symtab_data, symndx, &sym) == NULL) + continue; + + size = _dwarf_get_reloc_size(dbg, type); + if (size == 0) + continue; /* Unknown or non-absolute relocation. */ - if (gelf_getsym(symtab_data, GELF_R_SYM(r_info), &sym) == NULL) - return; - if ((size = _dwarf_get_reloc_size(dbg, GELF_R_TYPE(r_info))) == 0) - return; /* Unknown or non-absolute relocation. */ - if (is_rel) { - uint64_t roffset = offset; + offset = rel.r_offset; + if (offset + size >= bufsize) + continue; + + if (endian == ELFDATA2MSB) + addend = _dwarf_read_msb(buf, &offset, size); + else + addend = _dwarf_read_lsb(buf, &offset, size); + offset = rel.r_offset; if (endian == ELFDATA2MSB) - r_addend = _dwarf_read_msb(buf, &roffset, size); + _dwarf_write_msb(buf, &offset, sym.st_value + addend, + size); else - r_addend = _dwarf_read_lsb(buf, &roffset, size); + _dwarf_write_lsb(buf, &offset, sym.st_value + addend, + size); } - if (endian == ELFDATA2MSB) - _dwarf_write_msb(buf, &offset, sym.st_value + r_addend, size); - else - _dwarf_write_lsb(buf, &offset, sym.st_value + r_addend, size); } static void -_dwarf_elf_apply_rel_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data, - Elf_Data *symtab_data, int endian) +_dwarf_elf_apply_rela_reloc(Dwarf_Debug dbg, void *buf, uint64_t bufsize, + Elf_Data *rel_data, Elf_Data *symtab_data, int endian) { - GElf_Rel rel; - int j; + Dwarf_Unsigned type; + GElf_Rela rela; + GElf_Sym sym; + size_t symndx; + uint64_t offset; + int size, j; j = 0; - while (gelf_getrel(rel_data, j++, &rel) != NULL) - _dwarf_elf_write_reloc(dbg, symtab_data, endian, buf, - rel.r_offset, rel.r_info, 0, 1); -} + while (gelf_getrela(rel_data, j++, &rela) != NULL) { + symndx = GELF_R_SYM(rela.r_info); + type = GELF_R_TYPE(rela.r_info); -static void -_dwarf_elf_apply_rela_reloc(Dwarf_Debug dbg, void *buf, Elf_Data *rel_data, - Elf_Data *symtab_data, int endian) -{ - GElf_Rela rela; - int j; + if (gelf_getsym(symtab_data, symndx, &sym) == NULL) + continue; - j = 0; - while (gelf_getrela(rel_data, j++, &rela) != NULL) - _dwarf_elf_write_reloc(dbg, symtab_data, endian, buf, - rela.r_offset, rela.r_info, rela.r_addend, 0); + offset = rela.r_offset; + size = _dwarf_get_reloc_size(dbg, type); + if (size == 0) + continue; /* Unknown or non-absolute relocation. */ + if (offset + size >= bufsize) + continue; + + if (endian == ELFDATA2MSB) + _dwarf_write_msb(buf, &offset, + sym.st_value + rela.r_addend, size); + else + _dwarf_write_lsb(buf, &offset, + sym.st_value + rela.r_addend, size); + } } static int @@ -150,10 +176,12 @@ _dwarf_elf_relocate(Dwarf_Debug dbg, Elf *elf, Dwarf_Elf_Data *ed, size_t shndx, memcpy(ed->ed_alloc, ed->ed_data->d_buf, ed->ed_data->d_size); if (sh.sh_type == SHT_REL) - _dwarf_elf_apply_rel_reloc(dbg, ed->ed_alloc, + _dwarf_elf_apply_rel_reloc(dbg, + ed->ed_alloc, ed->ed_data->d_size, rel, symtab_data, eh.e_ident[EI_DATA]); else - _dwarf_elf_apply_rela_reloc(dbg, ed->ed_alloc, + _dwarf_elf_apply_rela_reloc(dbg, + ed->ed_alloc, ed->ed_data->d_size, rel, symtab_data, eh.e_ident[EI_DATA]); return (DW_DLE_NONE); |