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
+ relocate.c \
+ dwarf_form_relocatable.c dwarf_lineaddr_relocatable.c
if MAINTAINER_MODE
BUILT_SOURCES = $(srcdir)/known-dwarf.h
--- /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>
+
+
+int
+dwarf_form_relocatable (attr, sym, name, addend)
+ Dwarf_Attribute *attr;
+ GElf_Sym *sym;
+ const char **name;
+ GElf_Sxword *addend;
+{
+ if (attr == NULL)
+ return -1;
+
+ int width;
+ switch (attr->form)
+ {
+ default:
+ return ((addend != NULL && INTUSE(dwarf_formsdata) (attr, addend)) ? -1
+ : __libdw_relocatable (attr->cu->dbg, IDX_last, NULL, 0,
+ sym, name, addend, 0));
+
+ 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);
+}
--- /dev/null
+/* Return relocatable line address.
+ Copyright (C) 2010 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2004.
+
+ 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"
+
+
+int
+dwarf_lineaddr_relocatable (line, sym, name, addend)
+ Dwarf_Line *line;
+ GElf_Sym *sym;
+ const char **name;
+ GElf_Sxword *addend;
+{
+ 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);
+}
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.
+ 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);
+
+/* Like dwarf_lineaddr, but as described above. */
+extern int dwarf_lineaddr_relocatable (Dwarf_Line *line,
+ GElf_Sym *sym, const char **name,
+ GElf_Sxword *addend);
+
+
/* Get abbreviation at given offset for given DIE. */
extern Dwarf_Abbrev *dwarf_getabbrev (Dwarf_Die *die, Dwarf_Off offset,
size_t *lengthp);
dwarf_next_unit;
dwarf_offdie_types;
} ELFUTILS_0.146;
+
+ELFUTILS_0.149 {
+ global:
+ dwarf_form_relocatable;
+ dwarf_lineaddr_relocatable;
+} ELFUTILS_0.148;
ret, sec_ret, size);
}
+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)
+ __nonnull_attribute__ (1) internal_function;
+
+
static inline size_t
cu_sec_idx (struct Dwarf_CU *cu)
{
*val = addend;
return result;
}
+\f
+int
+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)
+{
+ struct dwarf_section_reloc *const r = dbg->relocate->sectionrel[sec_idx];
+ int symndx;
+ int result = relocatable_datum (dbg, sec_idx, r, valp, width,
+ &symndx, addend);
+ if (result == 0)
+ {
+ if (sym != NULL)
+ *sym = (GElf_Sym) { .st_shndx = SHN_ABS };
+ if (name != NULL)
+ *name = NULL;
+ if (addend != NULL)
+ *addend = offset + (width == 8
+ ? read_8ubyte_unaligned (dbg, valp)
+ : read_4ubyte_unaligned (dbg, valp));
+ }
+ else if (likely (result > 0))
+ {
+ GElf_Sym sym_mem;
+ GElf_Word shndx;
+ if (sym == NULL)
+ sym = &sym_mem;
+ result = reloc_getsym (r, symndx, sym, &shndx);
+ if (likely (result > 0))
+ {
+ if (name != NULL)
+ {
+ if (sym->st_name == 0)
+ *name = NULL;
+ else if (unlikely (sym->st_name >= r->symstrdata->d_size))
+ {
+ __libdw_seterrno (DWARF_E_RELBADSYM);
+ return -1;
+ }
+ else
+ *name = (const char *) r->symstrdata->d_buf + sym->st_name;
+ }
+ if (addend != NULL)
+ *addend += offset;
+ result = (sym->st_shndx < SHN_LORESERVE ? sym->st_shndx
+ : sym->st_shndx == SHN_XINDEX ? shndx : SHN_UNDEF);
+ }
+ }
+
+ return result;
+}