From: Roland McGrath Date: Tue, 22 Jun 2010 23:51:53 +0000 (-0700) Subject: Rejigger relocatable libdw interface. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7f60f9f8a8955aaf7e9bc4fbaa530bdfbcb658b4;p=thirdparty%2Felfutils.git Rejigger relocatable libdw interface. --- diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 2fdc8bd90..18afa6825 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,5 +1,15 @@ 2010-06-22 Roland McGrath + * libdw.h (Dwarf_Relocatable): New type. Declare three new functions. + * dwarf_relocatable_info.c: New file. + * dwarf_form_relocatable.c: New file. + * dwarf_line_relocatable.c: New file. + * Makefile.am (libdw_a_SOURCES): Add them. + * libdw.map (ELFUTILS_0.149): New set; add those. + + * relocate.c (__libdw_relocatable): New function. + * libdwP.h: Declare it. + * dwarf_getsrclines.c: Fix signed comparison warning in extended opcode parsing. @@ -12,14 +22,6 @@ 2010-06-21 Roland McGrath - * relocate.c (__libdw_relocatable): New function. - * libdwP.h: Declare it. - * dwarf_form_relocatable.c: New file. - * dwarf_lineaddr_relocatable.c: New file. - * Makefile.am (libdw_a_SOURCES): Add them. - * libdw.map (ELFUTILS_0.149): New set; add those. - * libdw.h: Declare them. - * libdwP.h (struct Dwarf_Line_s): Replace files with cu. (struct Dwarf_Lines_s): New member reloc. * dwarf_linesrc.c: Update usage. diff --git a/libdw/Makefile.am b/libdw/Makefile.am index 067eec0d1..146d7f442 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -85,8 +85,8 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ dwarf_cfi_addrframe.c \ dwarf_getcfi.c dwarf_getcfi_elf.c dwarf_cfi_end.c \ dwarf_aggregate_size.c \ - relocate.c \ - dwarf_form_relocatable.c dwarf_lineaddr_relocatable.c + relocate.c dwarf_relocatable_info.c \ + dwarf_form_relocatable.c dwarf_line_relocatable.c if MAINTAINER_MODE BUILT_SOURCES = $(srcdir)/known-dwarf.h diff --git a/libdw/dwarf_form_relocatable.c b/libdw/dwarf_form_relocatable.c index 588694c3c..3b2dc9c2d 100644 --- a/libdw/dwarf_form_relocatable.c +++ b/libdw/dwarf_form_relocatable.c @@ -56,37 +56,18 @@ int -dwarf_form_relocatable (attr, sym, name, addend, secname) +dwarf_form_relocatable (attr, reloc) Dwarf_Attribute *attr; - GElf_Sym *sym; - const char **name; - GElf_Sxword *addend; - const char **secname; + Dwarf_Relocatable *reloc; { if (attr == NULL) return -1; - int width; - switch (attr->form) + *reloc = (Dwarf_Relocatable) { - default: - return ((addend != NULL && INTUSE(dwarf_formsdata) (attr, addend)) ? -1 - : __libdw_relocatable (attr->cu->dbg, IDX_last, NULL, 0, - sym, name, addend, 0, secname)); + .sec = cu_sec_idx (attr->cu), .form = attr->form, + .cu = attr->cu, .valp = attr->valp, + }; - case DW_FORM_addr: - width = attr->cu->address_size; - break; - - case DW_FORM_data4: - width = 4; - break; - - case DW_FORM_data8: - width = 8; - break; - } - - return __libdw_relocatable (attr->cu->dbg, cu_sec_idx (attr->cu), - attr->valp, width, sym, name, addend, 0, secname); + return 0; } diff --git a/libdw/dwarf_lineaddr_relocatable.c b/libdw/dwarf_line_relocatable.c similarity index 87% rename from libdw/dwarf_lineaddr_relocatable.c rename to libdw/dwarf_line_relocatable.c index c47ac6ef4..a57422e96 100644 --- a/libdw/dwarf_lineaddr_relocatable.c +++ b/libdw/dwarf_line_relocatable.c @@ -52,23 +52,25 @@ #endif #include "libdwP.h" +#include int -dwarf_lineaddr_relocatable (line, sym, name, addend, secname) +dwarf_line_relocatable (line, reloc) Dwarf_Line *line; - GElf_Sym *sym; - const char **name; - GElf_Sxword *addend; - const char **secname; + Dwarf_Relocatable *reloc; { if (line == NULL) return -1; - return __libdw_relocatable (line->cu->dbg, IDX_debug_line, - line->cu->lines->reloc == NULL ? NULL - : line->cu->lines->reloc[line - - line->cu->lines->info], - line->cu->address_size, sym, name, addend, - line->addr, secname); + *reloc = (Dwarf_Relocatable) + { + .sec = IDX_debug_line, .form = DW_FORM_addr, + .cu = line->cu, + .valp = (line->cu->lines->reloc == NULL ? NULL + : line->cu->lines->reloc[line - line->cu->lines->info]), + .adjust = line->addr + }; + + return 0; } diff --git a/libdw/dwarf_relocatable_info.c b/libdw/dwarf_relocatable_info.c new file mode 100644 index 000000000..67b28f512 --- /dev/null +++ b/libdw/dwarf_relocatable_info.c @@ -0,0 +1,140 @@ +/* Return relocatable address from attribute. + Copyright (C) 2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + In addition, as a special exception, Red Hat, Inc. gives You the + additional right to link the code of Red Hat elfutils with code licensed + under any Open Source Initiative certified open source license + (http://www.opensource.org/licenses/index.php) which requires the + distribution of source code with any binary distribution and to + distribute linked combinations of the two. Non-GPL Code permitted under + this exception must only link to the code of Red Hat elfutils through + those well defined interfaces identified in the file named EXCEPTION + found in the source code files (the "Approved Interfaces"). The files + of Non-GPL Code may instantiate templates or use macros or inline + functions from the Approved Interfaces without causing the resulting + work to be covered by the GNU General Public License. Only Red Hat, + Inc. may make changes or additions to the list of Approved Interfaces. + Red Hat's grant of this exception is conditioned upon your not adding + any new exceptions. If you wish to add a new Approved Interface or + exception, please contact Red Hat. You must obey the GNU General Public + License in all respects for all of the Red Hat elfutils code and other + code used in conjunction with Red Hat elfutils except the Non-GPL Code + covered by this exception. If you modify this file, you may extend this + exception to your version of the file, but you are not obligated to do + so. If you do not wish to provide this exception without modification, + you must delete this exception statement from your version and license + this file solely under the GPL without exception. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libdwP.h" +#include + +static int +relocatable_form (struct Dwarf_CU *cu, + unsigned int sec_idx, + unsigned int form, + const unsigned char *valp, + Dwarf_Addr adjust, + GElf_Sym *sym, const char **name, + GElf_Sxword *addend, const char **secname) +{ + int width; + switch (form) + { + default: + /* This can't be relocatable. We'll let __libdw_relocatable + fill in the SHN_ABS indicator for the constant 0 base. */ + if (addend != NULL) + { + Dwarf_Attribute attr = + { + .cu = cu, + .form = form, + .valp = (unsigned char *) valp + }; + if (INTUSE(dwarf_formsdata) (&attr, addend)) + return -1; + *addend += adjust; + addend = NULL; + } + width = 0; + valp = NULL; + break; + + case DW_FORM_addr: + width = cu->address_size; + break; + + case DW_FORM_data4: + width = 4; + break; + + case DW_FORM_data8: + width = 8; + break; + } + + return __libdw_relocatable (cu->dbg, sec_idx, valp, width, + sym, name, addend, adjust, secname); +} + +int +dwarf_relocatable_info (reloc, sym, name, addend, secname) + Dwarf_Relocatable *reloc; + GElf_Sym *sym; + const char **name; + GElf_Sxword *addend; + const char **secname; +{ + if (reloc == NULL) + return -1; + + return relocatable_form (reloc->cu, reloc->sec, + reloc->form, reloc->valp, reloc->adjust, + sym, name, addend, secname); +} + +#if 0 +/* Shorthand for dwarf_relocatable_info(dwarf_form_relocatable). */ + +int +dwarf_form_relocatable_info (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; + + return relocatable_form (attr->cu, cu_sec_idx (attr->cu), + attr->form, attr->valp, 0, + sym, name, addend, secname); +} +#endif diff --git a/libdw/libdw.h b/libdw/libdw.h index 2726fac43..f55be48a4 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -137,6 +137,7 @@ struct Dwarf_CU; /* Macro information. */ typedef struct Dwarf_Macro_s Dwarf_Macro; + /* Attribute representation. */ typedef struct { @@ -147,6 +148,17 @@ typedef struct } Dwarf_Attribute; +/* Relocatable address representation. */ +typedef struct +{ + unsigned int sec; + unsigned int form; + const unsigned char *valp; + struct Dwarf_CU *cu; + Dwarf_Addr adjust; +} Dwarf_Relocatable; + + /* Data block representation. */ typedef struct { @@ -445,6 +457,11 @@ extern int dwarf_formsdata (Dwarf_Attribute *attr, Dwarf_Sword *return_uval) extern int dwarf_formaddr (Dwarf_Attribute *attr, Dwarf_Addr *return_addr) __nonnull_attribute__ (2); +/* Return relocatable address represented by attribute. */ +extern int dwarf_form_relocatable (Dwarf_Attribute *attr, + Dwarf_Relocatable *return_reloc) + __nonnull_attribute__ (2); + /* This function is deprecated. Always use dwarf_formref_die instead. Return reference offset represented by attribute. */ extern int dwarf_formref (Dwarf_Attribute *attr, Dwarf_Off *return_offset) @@ -512,38 +529,32 @@ extern int dwarf_arrayorder (Dwarf_Die *die); extern int dwarf_srclang (Dwarf_Die *die); -/* Relocatable address access functions. +/* 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 +/* A Dwarf_Relocatable represents an address that might require + relocation in an ET_REL file. Return the relocation details for + that address. Returns -1 for errors. If successful, fills 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). + 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. + 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, +extern int dwarf_relocatable_info (Dwarf_Relocatable *reloc, GElf_Sym *sym, const char **name, 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, - const char **secname); - /* Get abbreviation at given offset for given DIE. */ extern Dwarf_Abbrev *dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset, @@ -611,6 +622,9 @@ extern int dwarf_getsrc_file (Dwarf *dbg, const char *fname, int line, int col, /* Return line address. */ extern int dwarf_lineaddr (Dwarf_Line *line, Dwarf_Addr *addrp); +/* Return line address in relocatable form. */ +extern int dwarf_line_relocatable (Dwarf_Line *line, Dwarf_Relocatable *relocp); + /* Return line VLIW operation index. */ extern int dwarf_lineop_index (Dwarf_Line *line, unsigned int *op_indexp); diff --git a/libdw/libdw.map b/libdw/libdw.map index d3d51af3e..ff530702e 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -253,5 +253,6 @@ ELFUTILS_0.148 { ELFUTILS_0.149 { global: dwarf_form_relocatable; - dwarf_lineaddr_relocatable; + dwarf_line_relocatable; + dwarf_relocatable_info; } ELFUTILS_0.148; diff --git a/libdw/relocate.c b/libdw/relocate.c index 1a27a71aa..195687390 100644 --- a/libdw/relocate.c +++ b/libdw/relocate.c @@ -552,8 +552,9 @@ __libdw_relocatable (Dwarf *dbg, int sec_idx, GElf_Sym *sym, const char **name, GElf_Sxword *addend, GElf_Sxword offset, const char **secname) { - struct dwarf_section_reloc *const r - = dbg->relocate != NULL ? dbg->relocate->sectionrel[sec_idx] : NULL; + struct dwarf_section_reloc *const r = ((valp != NULL && dbg->relocate != NULL) + ? dbg->relocate->sectionrel[sec_idx] + : NULL); int symndx; int result = relocatable_datum (dbg, sec_idx, r, valp, width, &symndx, addend);