2010-06-22 Roland McGrath <roland@redhat.com>
+ * 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.
2010-06-21 Roland McGrath <roland@redhat.com>
- * 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.
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
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;
}
#endif
#include "libdwP.h"
+#include <dwarf.h>
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;
}
--- /dev/null
+/* 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
+ <http://www.openinventionnetwork.com>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwP.h"
+#include <dwarf.h>
+
+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
/* Macro information. */
typedef struct Dwarf_Macro_s Dwarf_Macro;
+
/* Attribute representation. */
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
{
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)
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,
/* 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);
ELFUTILS_0.149 {
global:
dwarf_form_relocatable;
- dwarf_lineaddr_relocatable;
+ dwarf_line_relocatable;
+ dwarf_relocatable_info;
} ELFUTILS_0.148;
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);