From: Roland McGrath Date: Mon, 21 Jun 2010 10:43:50 +0000 (-0700) Subject: Fetch section name in relocatable calls. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=64f5748595d2cf911764a3262fc8777ff8bc6227;p=thirdparty%2Felfutils.git Fetch section name in relocatable calls. --- diff --git a/libdw/dwarf_form_relocatable.c b/libdw/dwarf_form_relocatable.c index f01b1375a..588694c3c 100644 --- a/libdw/dwarf_form_relocatable.c +++ b/libdw/dwarf_form_relocatable.c @@ -56,11 +56,12 @@ int -dwarf_form_relocatable (attr, sym, name, addend) +dwarf_form_relocatable (attr, sym, name, addend, secname) Dwarf_Attribute *attr; GElf_Sym *sym; const char **name; GElf_Sxword *addend; + const char **secname; { if (attr == NULL) return -1; @@ -71,7 +72,7 @@ dwarf_form_relocatable (attr, sym, name, addend) default: return ((addend != NULL && INTUSE(dwarf_formsdata) (attr, addend)) ? -1 : __libdw_relocatable (attr->cu->dbg, IDX_last, NULL, 0, - sym, name, addend, 0)); + sym, name, addend, 0, secname)); case DW_FORM_addr: width = attr->cu->address_size; @@ -87,5 +88,5 @@ dwarf_form_relocatable (attr, sym, name, addend) } return __libdw_relocatable (attr->cu->dbg, cu_sec_idx (attr->cu), - attr->valp, width, sym, name, addend, 0); + attr->valp, width, sym, name, addend, 0, secname); } diff --git a/libdw/dwarf_lineaddr_relocatable.c b/libdw/dwarf_lineaddr_relocatable.c index 2b4a7a67f..c47ac6ef4 100644 --- a/libdw/dwarf_lineaddr_relocatable.c +++ b/libdw/dwarf_lineaddr_relocatable.c @@ -55,11 +55,12 @@ int -dwarf_lineaddr_relocatable (line, sym, name, addend) +dwarf_lineaddr_relocatable (line, sym, name, addend, secname) Dwarf_Line *line; GElf_Sym *sym; const char **name; GElf_Sxword *addend; + const char **secname; { if (line == NULL) return -1; @@ -69,5 +70,5 @@ dwarf_lineaddr_relocatable (line, sym, name, addend) : line->cu->lines->reloc[line - line->cu->lines->info], line->cu->address_size, sym, name, addend, - line->addr); + line->addr, secname); } diff --git a/libdw/libdw.h b/libdw/libdw.h index 0ba51972a..2726fac43 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -515,26 +515,34 @@ extern int dwarf_srclang (Dwarf_Die *die); /* Relocatable address access functions. These retrieve an address that might require relocation in an ET_REL - file. They return -1 for errors. If successful, they fill in SYM (if - not null) with the ELF symbol describing the address fetched. If NAME - is not null, it is filled with the symbol name, or with NULL if there is - no named symbol involved. If ADDEND is not null, it is filled with the - offset relative to that symbol. If the symbol refers to a normal - section, the return value is that section index (which might be above - SHN_LORESERVE). If the symbol does not refer to a normal section, - the return value is zero and SYM->st_shndx has a special SHN_* value. + file. They return -1 for errors. If successful, they fill in SYM + (if not null) with the ELF symbol describing the address fetched. + + If the symbol refers to a normal section, the return value is that + section index (which might be above SHN_LORESERVE). If the symbol + does not refer to a normal section, the return value is zero and + SYM->st_shndx has a special SHN_* value. If SECNAME is not null, it + is filled with the name of the symbol's section if available, or NULL + if not available (or for a special st_shndx). + + If NAME is not null, it is filled with the symbol name, or with NULL + if there is no named symbol involved. If ADDEND is not null, it is + filled with the offset relative to that symbol. + An address that required no relocation appears as a SHN_ABS symbol with st_value 0 and the whole address in the addend. */ /* Like dwarf_formaddr, but as described above. */ extern int dwarf_form_relocatable (Dwarf_Attribute *attr, GElf_Sym *sym, const char **name, - GElf_Sxword *addend); + GElf_Sxword *addend, + const char **secname); /* Like dwarf_lineaddr, but as described above. */ extern int dwarf_lineaddr_relocatable (Dwarf_Line *line, GElf_Sym *sym, const char **name, - GElf_Sxword *addend); + GElf_Sxword *addend, + const char **secname); /* Get abbreviation at given offset for given DIE. */ diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 60ca016bf..017920e9a 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -622,7 +622,8 @@ __libdw_read_offset (Dwarf *dbg, extern int __libdw_relocatable (Dwarf *dbg, int sec_idx, const unsigned char *valp, unsigned int width, GElf_Sym *sym, const char **name, - GElf_Sxword *addend, GElf_Sxword offset) + GElf_Sxword *addend, GElf_Sxword offset, + const char **secname) __nonnull_attribute__ (1) internal_function; diff --git a/libdw/relocate.c b/libdw/relocate.c index 27a05eff9..298042acb 100644 --- a/libdw/relocate.c +++ b/libdw/relocate.c @@ -550,7 +550,7 @@ internal_function __libdw_relocatable (Dwarf *dbg, int sec_idx, const unsigned char *valp, unsigned int width, GElf_Sym *sym, const char **name, GElf_Sxword *addend, - GElf_Sxword offset) + GElf_Sxword offset, const char **secname) { struct dwarf_section_reloc *const r = dbg->relocate->sectionrel[sec_idx]; int symndx; @@ -566,6 +566,8 @@ __libdw_relocatable (Dwarf *dbg, int sec_idx, *addend = offset + (width == 8 ? read_8ubyte_unaligned (dbg, valp) : read_4ubyte_unaligned (dbg, valp)); + if (secname != NULL) + *secname = NULL; } else if (likely (result > 0)) { @@ -592,6 +594,18 @@ __libdw_relocatable (Dwarf *dbg, int sec_idx, *addend += offset; result = (sym->st_shndx < SHN_LORESERVE ? sym->st_shndx : sym->st_shndx == SHN_XINDEX ? shndx : SHN_UNDEF); + if (secname != NULL) + { + Elf *symelf = ((Elf_Data_Scn *) r->symdata)->s->elf; + size_t shstrndx; + GElf_Shdr shdr; + if (result == 0 + || elf_getshdrstrndx (symelf, &shstrndx) < 0 + || gelf_getshdr (elf_getscn (symelf, result), &shdr) == NULL) + *secname = NULL; + else + *secname = elf_strptr (symelf, shstrndx, shdr.sh_name); + } } }