From 5b533a52bb9e4e9a1a10e99724ca3e5a697d5203 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 29 Jun 2010 00:21:10 -0700 Subject: [PATCH] Add dwarf_getsrc_relocatable. --- libdw/ChangeLog | 16 +++-- libdw/Makefile.am | 2 +- libdw/dwarf_getsrc_die.c | 3 +- libdw/dwarf_relocatable_info.c | 107 ++++++++++++--------------------- libdw/libdw.h | 5 ++ libdw/libdw.map | 1 + libdw/libdwP.h | 1 + 7 files changed, 62 insertions(+), 73 deletions(-) diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 70e46a16e..023621f49 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,4 +1,12 @@ -2010-06-28 Roland McGrath +2010-06-29 Roland McGrath + + * dwarf_getsrc_relocatable.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.h: Declare it. + * libdw.map (ELFUTILS_0.149): Add it. + + * dwarf_getsrc_die.c: Add INTDEF. + * libdwP.h: Add INTDECL. * libdwP.h (struct Dwarf_Lines_s): Change reloc member to int pointer. * dwarf_getsrclines.c (struct linelist): Add reloc/symndx/shndx members. @@ -15,9 +23,9 @@ * libdw.h (Dwarf_Relocatable): Use uint8_t for sec and form members. Add symndx member. - * dwarf_relocatable_info.c (relocatable_form): Take new arg SYMNDX. - If VALP is null, use SYMNDX instead of looking for a reloc. - (dwarf_relocatable_info): Update caller. + * dwarf_relocatable_info.c: Update RELOC with non-null valp to + one with a null valp, symndx set, and adjust section-relative. + If RELOC->valp is already null, use cached symndx. 2010-06-24 Roland McGrath diff --git a/libdw/Makefile.am b/libdw/Makefile.am index e77ea5f4c..719d1d580 100644 --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@ -88,7 +88,7 @@ libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \ relocate.c dwarf_relocatable_info.c \ dwarf_form_relocatable.c dwarf_line_relocatable.c \ dwarf_ranges_relocatable.c dwarf_getlocation_relocatable.c \ - dwarf_haspc_relocatable.c + dwarf_haspc_relocatable.c dwarf_getsrc_relocatable.c if MAINTAINER_MODE BUILT_SOURCES = $(srcdir)/known-dwarf.h diff --git a/libdw/dwarf_getsrc_die.c b/libdw/dwarf_getsrc_die.c index 96aa41fdc..f82ed5bfd 100644 --- a/libdw/dwarf_getsrc_die.c +++ b/libdw/dwarf_getsrc_die.c @@ -1,5 +1,5 @@ /* Find line information for address. - Copyright (C) 2004, 2005 Red Hat, Inc. + Copyright (C) 2004-2010 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper , 2004. @@ -97,3 +97,4 @@ dwarf_getsrc_die (Dwarf_Die *cudie, Dwarf_Addr addr) __libdw_seterrno (DWARF_E_ADDR_OUTOFRANGE); return NULL; } +INTDEF (dwarf_getsrc_die) diff --git a/libdw/dwarf_relocatable_info.c b/libdw/dwarf_relocatable_info.c index f4260e772..37868f627 100644 --- a/libdw/dwarf_relocatable_info.c +++ b/libdw/dwarf_relocatable_info.c @@ -55,32 +55,33 @@ #include -static int -relocatable_form (struct Dwarf_CU *cu, - uint_fast8_t sec_idx, - uint_fast8_t form, - const unsigned char *valp, - int symndx, - Dwarf_Addr adjust, - GElf_Sym *sym, const char **name, - GElf_Sxword *addend, const char **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; + int width; - switch (form) + switch (reloc->form) { default: /* This can't be relocatable. */ if (addend != NULL) { - if (valp == NULL) + if (reloc->valp == NULL) *addend = 0; else { Dwarf_Attribute attr = { - .cu = cu, - .form = form, - .valp = (unsigned char *) valp + .cu = reloc->cu, + .form = reloc->form, + .valp = (unsigned char *) reloc->valp }; if (INTUSE(dwarf_formsdata) (&attr, addend)) return -1; @@ -88,7 +89,7 @@ relocatable_form (struct Dwarf_CU *cu, } noreloc: if (addend != NULL) - *addend += adjust; + *addend += reloc->adjust; if (sym != NULL) *sym = (GElf_Sym) { .st_shndx = SHN_ABS }; if (name != NULL) @@ -98,7 +99,7 @@ relocatable_form (struct Dwarf_CU *cu, return 0; case DW_FORM_addr: - width = cu->address_size; + width = reloc->cu->address_size; break; case DW_FORM_data4: @@ -110,29 +111,43 @@ relocatable_form (struct Dwarf_CU *cu, break; } - if (valp != NULL) + GElf_Sxword adjust = 0; + if (reloc->valp != NULL) { - int result = __libdw_relocatable (cu->dbg, sec_idx, valp, width, - &symndx, addend); + int result = __libdw_relocatable (reloc->cu->dbg, reloc->sec, + reloc->valp, width, + &reloc->symndx, &adjust); if (unlikely (result < 0)) return result; if (result == 0) - goto noreloc; + { + reloc->valp = NULL; + reloc->adjust += adjust; + goto noreloc; + } } - struct dwarf_section_reloc *r = cu->dbg->relocate->sectionrel[sec_idx]; + struct dwarf_section_reloc *const r + = reloc->cu->dbg->relocate->sectionrel[reloc->sec]; GElf_Sym sym_mem; GElf_Word shndx; if (sym == NULL) sym = &sym_mem; if (unlikely (gelf_getsymshndx (r->symdata, r->symxndxdata, - symndx, sym, &shndx) == NULL)) + reloc->symndx, sym, &shndx) == NULL)) { __libdw_seterrno (DWARF_E_RELBADSYM); return -1; } + if (reloc->valp != NULL) + { + /* Turn the adjustment into a section-relative address. */ + reloc->valp = NULL; + reloc->adjust += sym->st_value + adjust; + } + if (name != NULL) { if (sym->st_name == 0) @@ -147,14 +162,9 @@ relocatable_form (struct Dwarf_CU *cu, } if (addend != NULL) - { - if (valp == NULL) - /* The ADJUST value was already section-relative, so we have to - remove the st_value portion of it. */ - *addend = adjust - sym->st_value; - else - *addend += adjust; - } + /* The adjustment is already section-relative, so we have to + remove the st_value portion of it. */ + *addend = reloc->adjust - sym->st_value; int result = (sym->st_shndx < SHN_LORESERVE ? sym->st_shndx : sym->st_shndx == SHN_XINDEX ? shndx : SHN_UNDEF); @@ -174,41 +184,4 @@ relocatable_form (struct Dwarf_CU *cu, return result; } - - -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->symndx, reloc->adjust, - sym, name, addend, secname); -} INTDEF (dwarf_relocatable_info) - -#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 c359e10f2..2eaf95a27 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -626,6 +626,11 @@ extern int dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, /* Get source for address in CU. */ extern Dwarf_Line *dwarf_getsrc_die (Dwarf_Die *cudie, Dwarf_Addr addr); +/* Get source for relocatable address in CU. */ +extern Dwarf_Line *dwarf_getsrc_relocatable (Dwarf_Die *cudie, + Dwarf_Relocatable *reloc) + __nonnull_attribute__ (2); + /* Get source for file and line number. */ extern int dwarf_getsrc_file (Dwarf *dbg, const char *fname, int line, int col, Dwarf_Line ***srcsp, size_t *nsrcs) diff --git a/libdw/libdw.map b/libdw/libdw.map index ff3638ea9..86505b4bd 100644 --- a/libdw/libdw.map +++ b/libdw/libdw.map @@ -251,6 +251,7 @@ ELFUTILS_0.148 { ELFUTILS_0.149 { global: dwarf_form_relocatable; + dwarf_getsrc_relocatable; dwarf_line_relocatable; dwarf_getlocation_relocatable; dwarf_haspc_relocatable; diff --git a/libdw/libdwP.h b/libdw/libdwP.h index f2886028c..3633a28af 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -679,6 +679,7 @@ INTDECL (dwarf_getarangeinfo) INTDECL (dwarf_getaranges) INTDECL (dwarf_getsrcfiles) INTDECL (dwarf_getsrclines) +INTDECL (dwarf_getsrc_die) INTDECL (dwarf_hasattr) INTDECL (dwarf_haschildren) INTDECL (dwarf_haspc) -- 2.47.2