From: Roland McGrath Date: Wed, 5 Jan 2011 18:53:26 +0000 (-0800) Subject: Merge branch 'master' into roland/relocate X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2167f54e91fec095b5dd443432687e1d253033dd;p=thirdparty%2Felfutils.git Merge branch 'master' into roland/relocate Conflicts: libdw/Makefile.am libdw/libdw.h libdw/libdw.map libdwfl/dwfl_lineinfo.c libdwfl/dwfl_module_getdwarf.c libdwfl/libdwflP.h --- 2167f54e91fec095b5dd443432687e1d253033dd diff --cc backends/ChangeLog index 7031ba34e,7865338fb..7e6f32b34 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@@ -1,26 -1,8 +1,31 @@@ + 2010-11-08 Roland McGrath + + * i386_retval.c (loc_intreg): Typo fix. + Reported by Thorsten Glaser . + +2010-06-20 Roland McGrath + + * alpha_init.c: Replace reloc_simple_type with reloc_simple_types. + * arm_init.c: Likewise. + * i386_init.c: Likewise. + * ia64_init.c: Likewise. + * PPC64_init.c: Likewise. + * ppc_init.c: Likewise. + * s390_init.c: Likewise. + * sh_init.c: Likewise. + * sparc_init.c: Likewise. + * x86_64_init.c: Likewise. + * alpha_symbol.c: Likewise. + * arm_symbol.c: Likewise. + * i386_symbol.c: Likewise. + * ia64_symbol.c: Likewise. + * ppc64_symbol.c: Likewise. + * ppc_symbol.c: Likewise. + * s390_symbol.c: Likewise. + * sh_symbol.c: Likewise. + * sparc_symbol.c: Likewise. + * x86_64_symbol.c: Likewise. + 2010-04-10 Matt Fleming * sh_corenote.c: New file. diff --cc libdw/ChangeLog index e76d97d26,8ec74857f..bcb535aee --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@@ -1,80 -1,35 +1,112 @@@ + 2010-10-13 Roland McGrath + + * dwarf.h: Add DW_LANG_Go. + + 2010-10-05 Roland McGrath + + * dwarf_getaranges.c: Use malloc rather than alloca, + since the total number of elements can be quite huge. + + 2010-07-26 Roland McGrath + + * dwarf_getlocation_implicit_pointer.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.map (ELFUTILS_0.149): New set. + Add dwarf_getlocation_implicit_pointer. + * libdw.h: Declare it. + + * dwarf_offdie.c (do_offdie): Renamed to __libdw_offdie, made global. + (dwarf_offdie, dwarf_offdie_types): Update callers. + * libdwP.h: Declare it. + + * dwarf.h: Add DW_OP_GNU_implicit_pointer. + * dwarf_getlocation.c (__libdw_intern_expression): Handle it. + + 2010-08-24 Roland McGrath + + * libdw.map (ELFUTILS_0.149): New set. Add dwfl_dwarf_line. + + 2010-07-27 Roland McGrath + + * dwarf_formref_die.c: Fix sig8 hash insertion. + +2010-06-30 Roland McGrath + + * dwarf_getlocation_relocatable_addr.c: New file. + * Makefile.am (libdw_a_SOURCES): Add it. + * libdw.map (ELFUTILS_0.149): Add it. + * libdw.h: Declare it. + + * dwarf_getlocation.c (__libdw_intern_expression): New flag argument. + When set, handle relocatable DW_OP_addr. + (__libdw_getlocation): Likewise, pass it through. + (dwarf_getlocation, dwarf_getlocation_addr): Update callers. + * dwarf_frame_register.c: Likewise. + * dwarf_frame_cfa.c: Likewise. + * dwarf_getlocation_relocatable.c: Likewise. + * libdwP.h: Update decls. + + * relocate.c (digest_one_reloc, digest_relocs): Track r_offset values + and don't bother sorting if they were already sorted. + + * relocate.c (digest_relocs, compare_digested_reloc): Use qsort on an + array of pointers, not structs. + +2010-06-29 Roland McGrath + + * libdwP.h (dwarf_file_reloc): Remove resolve_symbol member, + add dwflmod member instead. + * relocate.h: Declare __libdwfl_relocate_setup and + __libdwfl_relocate_symbol. + * relocate.c (noresolve_symbol): Removed. + (__libdw_relocate_begin): Initialize dwflmod instead of resolve_symbol. + (__libdw_relocate_shndx): Removed, now in libdwfl. + (digest_relocs): Call __libdwfl_relocate_setup. + (__libdw_relocate_address): Call __libdwfl_relocate_symbol. + + * dwarf_lineaddr.c: Add INTDEF. + * libdwP.h: Add INTDECL. + + * 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. + (compare_lines): Sort by shndx before line.addr. + (dwarf_getsrclines): Resolve relocatable addresses to a symndx and + section-relative address. + * dwarf_line_relocatable.c: Initialize symndx instead of valp. + * dwarf_lineaddr.c: Use __libdw_relocate_shndx + + * relocate.c (__libdw_relocatable_getsym): New function. + (__libdw_relocate_address, __libdw_relocate_offset): Call it. + (__libdw_relocate_shndx): New function. + * relocate.h: Declare them. + + * libdw.h (Dwarf_Relocatable): Use uint8_t for sec and form members. + Add symndx member. + * 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 + + * encoded-value.h (encoded_value_size): Replace E_IDENT parameter + with ADDRESS_SIZE. + (read_encoded_value): Update caller. + * fde.c (binary_search_fde): Likewise. + * dwarf_next_cfi.c: Likewise. + * cfi.h (struct dwarf_cie): New member address_size. + (CFI_ADDRSIZE): New macro. + * cie.c (intern_new_cie): Initialize and use CIE->address_size. + (canonicalize_encoding): New function. + (intern_new_cie): Call it, do both FDE and LSDA encodings. + 2010-06-23 Roland McGrath * cfi.c (dwarf_cfi_validate_fde): Function removed. diff --cc libdw/Makefile.am index 35a0fd8d0,598bdd1ff..1888151ae --- a/libdw/Makefile.am +++ b/libdw/Makefile.am @@@ -1,6 -1,6 +1,6 @@@ ## Process this file with automake to create Makefile.in ## --## Copyright (C) 2002-2010 Red Hat, Inc. ++## Copyright (C) 2002-2011 Red Hat, Inc. ## This file is part of Red Hat elfutils. ## ## Red Hat elfutils is free software; you can redistribute it and/or modify @@@ -84,12 -84,7 +84,12 @@@ libdw_a_SOURCES = dwarf_begin.c dwarf_b dwarf_frame_info.c dwarf_frame_cfa.c dwarf_frame_register.c \ dwarf_cfi_addrframe.c \ dwarf_getcfi.c dwarf_getcfi_elf.c dwarf_cfi_end.c \ - dwarf_aggregate_size.c \ - dwarf_aggregate_size.c dwarf_getlocation_implicit_pointer.c ++ dwarf_aggregate_size.c dwarf_getlocation_implicit_pointer.c \ + relocate.c dwarf_relocatable_info.c \ + dwarf_form_relocatable.c dwarf_line_relocatable.c \ + dwarf_ranges_relocatable.c dwarf_getlocation_relocatable.c \ + dwarf_getlocation_relocatable_addr.c \ + dwarf_haspc_relocatable.c dwarf_getsrc_relocatable.c if MAINTAINER_MODE BUILT_SOURCES = $(srcdir)/known-dwarf.h diff --cc libdw/libdw.h index 75dcd142b,d36238ed7..b98835a25 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@@ -1,5 -1,5 +1,5 @@@ /* Interfaces for libdw. -- Copyright (C) 2002-2010 Red Hat, Inc. ++ Copyright (C) 2002-2011 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@@ -736,14 -659,16 +736,24 @@@ extern int dwarf_getlocation_implicit_v Dwarf_Block *return_block) __nonnull_attribute__ (2, 3); + /* Return the attribute indicated by a DW_OP_GNU_implicit_pointer operation. + The OP pointer must point into an expression that dwarf_getlocation + or dwarf_getlocation_addr has returned given the same ATTR. + The result is the DW_AT_location or DW_AT_const_value attribute + of the OP->number DIE. */ + extern int dwarf_getlocation_implicit_pointer (Dwarf_Attribute *attr, + const Dwarf_Op *op, + Dwarf_Attribute *result) + __nonnull_attribute__ (2, 3); + +/* Return the relocatable form of a DW_OP_addr operation. The OP pointer + must point into an expression that dwarf_getlocation_relocatable has + returned given the same ATTR. */ +extern int dwarf_getlocation_relocatable_addr (Dwarf_Attribute *attr, + const Dwarf_Op *op, + Dwarf_Relocatable *reloc) + __nonnull_attribute__ (2, 3); + /* Compute the byte-size of a type DIE according to DWARF rules. For most types, this is just DW_AT_byte_size. diff --cc libdw/libdw.map index d5444f6f6,1f71d03b5..af202f2af --- a/libdw/libdw.map +++ b/libdw/libdw.map @@@ -249,13 -249,8 +249,20 @@@ ELFUTILS_0.148 } ELFUTILS_0.146; ELFUTILS_0.149 { + global: + dwarf_getlocation_implicit_pointer; + + dwfl_dwarf_line; + } ELFUTILS_0.148; ++ ++ELFUTILS_0.151 { + global: + dwarf_form_relocatable; + dwarf_getsrc_relocatable; + dwarf_line_relocatable; + dwarf_getlocation_relocatable; + dwarf_getlocation_relocatable_addr; + dwarf_haspc_relocatable; + dwarf_ranges_relocatable; + dwarf_relocatable_info; - } ELFUTILS_0.148; ++} ELFUTILS_0.149; diff --cc libdw/libdwP.h index ce52ffdf7,da6efc537..b850dd314 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@@ -475,16 -451,15 +475,20 @@@ extern int __libdw_intern_expression (D unsigned int address_size, unsigned int ref_size, void **cache, const Dwarf_Block *block, - bool cfap, bool valuep, + bool reloc, bool cfap, bool valuep, Dwarf_Op **llbuf, size_t *listlen, int sec_index) - __nonnull_attribute__ (5, 6, 9, 10) internal_function; + __nonnull_attribute__ (5, 6, 10, 11) internal_function; + +extern int __libdw_getlocation (Dwarf_Attribute *attr, const Dwarf_Block *block, + bool reloc, + Dwarf_Op **llbuf, size_t *listlen, int sec_idx) + __nonnull_attribute__ (2, 4, 5) internal_function; + extern Dwarf_Die *__libdw_offdie (Dwarf *dbg, Dwarf_Off offset, + Dwarf_Die *result, bool debug_types) + internal_function; + /* Return error code of last failing function call. This value is kept separately for each thread. */ diff --cc libdwfl/ChangeLog index 0028979bb,9aebb786f..26e6caf07 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@@ -1,54 -1,72 +1,123 @@@ + 2011-01-04 Roland McGrath + + * dwfl_module_getdwarf.c (open_elf): Enhance address_sync calculation + logic to consider section addresses, the better to survive all the + possible prelink machinations. + * libdwflP.h (struct dwfl_file): Comment change. + + 2010-11-30 Roland McGrath + + * derelocate.c (dwfl_module_relocations): Remove over-eager assert. + + 2010-11-12 Roland McGrath + + * libdwflP.h (struct Dwfl_Module): New member main_bias. + (dwfl_adjusted_address, dwfl_deadjust_address): Use it. + * dwfl_module_getdwarf.c (__libdwfl_getelf): Initialize it. + + * libdwflP.h (dwfl_deadjust_address): New function. + (dwfl_deadjust_dwarf_addr, dwfl_deadjust_st_value): New functions. + * cu.c (addrarange): Use dwfl_deadjust_dwarf_addr. + * dwfl_module_addrsym.c: Use dwfl_deadjust_st_value. + + 2010-11-11 Roland McGrath + + * libdwflP.h (struct dwfl_file): Remove bias member. + Add vaddr and address_sync members instead. + (dwfl_adjusted_address): Calculate using vaddr. + (dwfl_adjusted_dwarf_addr): Calculate using address_sync and call that. + (dwfl_adjusted_st_value): Use one of those calls. + * dwfl_module_getdwarf.c (open_elf): Initialize vaddr and address_sync. + * dwfl_segment_report_module.c (dwfl_segment_report_module): Likewise. + * derelocate.c (dwfl_module_relocations): Update ET_EXEC assertions. + * link_map.c (consider_executable): Adjust only MOD->low_addr for + detected PIE bias change. + + * libdwflP.h (dwfl_adjusted_dwarf_addr): New function. + * dwfl_module_info.c: Use it. + * cu.c (addrarange): Likewise. + * dwfl_dwarf_line.c: Likewise. + * dwfl_module_dwarf_cfi.c: Likewise. + * dwfl_lineinfo.c: Likewise. + * dwfl_nextcu.c: Likewise. + * dwfl_module_getdwarf.c (dwfl_module_getdwarf): Likewise. + + * libdwflP.h (dwfl_adjusted_st_value): New function. + * relocate.c (resolve_symbol): Use it. + * dwfl_module_getsym.c: Likewise. + * dwfl_module_addrsym.c: Likewise. + * dwfl_module_info.c: Likewise. + + * libdwflP.h (dwfl_adjusted_address): New function. + * dwfl_module_build_id.c (__libdwfl_find_build_id): Use it. + * relocate.c (__libdwfl_relocate_value): Likewise. + * derelocate.c (cache_sections): Likewise. + (dwfl_module_address_section): Likewise. + * dwfl_module_getelf.c: Likewise. + * dwfl_module_eh_cfi.c: Likewise. + * link_map.c (consider_executable): Likewise. + + 2010-08-24 Roland McGrath + + * dwfl_dwarf_line.c: New file. + * Makefile.am (libdwfl_a_SOURCES): Add it. + + 2010-08-18 Roland McGrath + + * link_map.c (report_r_debug): Use found name if we have no name, + even if we already have an Elf handle. + +2010-06-30 Roland McGrath + + * relocate.c (relocate_section): Check for bad reloc type before + looking up symndx. + +2010-06-29 Roland McGrath + + * derelocate.c (check_module): Don't call dwfl_module_getdwarf. + + * dwfl_module_getdwarf.c (__libdwfl_relocate_setup): New function. + (load_dw): Set MOD->dw->relocate->dwflmod. + * dwfl_module.c (__libdwfl_module_free): Clear MOD->dw->relocate->ebl + if we set it. + * relocate.c (__libdw_relocate_shndx): New function. + (__libdwfl_relocate_symbol): New function. + + * libdwflP.h (struct dwfl_file): Add member shstrndx. + * dwfl_module_getdwarf.c (open_elf): Set it. + * dwfl_report_elf.c (__libdwfl_report_elf): Likewise. + * derelocate.c (cache_sections): Use it. + * dwfl_module_getsym.c: Likewise. + + * dwfl_lineinfo.c: Use dwarf_lineaddr. + + * relocate.c (relocate_section): Remove PARTIAL flag argument. + Reverse sense of DEBUGSCN flag: if set, skip if target section + is a debugging section. + (__libdwfl_relocate): Update caller. Remove flag argument. + (__libdwfl_relocate_section): Likewise. + * libdwflP.h: Update decls. + * dwfl_module_getelf.c: Update caller. + * dwfl_module_getdwarf.c: Likewise. + + * dwfl_module_getdwarf.c (load_dw): Don't relocate here. + Instead, hook into MOD->dw->relocate after dwarf_begin_elf. + +2010-06-21 Roland McGrath + + * open.c (__libdw_open_file): Close the fd when it's already mapped. + + * dwfl_module_getsrc_file.: Update for Dwarf_Line member change. + * dwfl_lineinfo.c: Likewise. Use dwarf_lineaddr. + +2010-06-20 Roland McGrath + + * relocate.c (struct reloc_symtab_cache): New members + rel8_types and rel4_types. + (relocate_section): Use ebl_reloc_simple_types instead of old + ebl_reloc_simple_type. Handle only 4 and 8 byte quantities, + and don't use gelf_xlatetom. + 2010-06-30 Roland McGrath * linux-kernel-modules.c (dwfl_linux_kernel_find_elf): Don't be diff --cc libdwfl/dwfl_lineinfo.c index 877648286,6049de84b..e517f5f90 --- a/libdwfl/dwfl_lineinfo.c +++ b/libdwfl/dwfl_lineinfo.c @@@ -1,5 -1,5 +1,5 @@@ /* Get information from a source line record returned by libdwfl. -- Copyright (C) 2005-2010 Red Hat, Inc. ++ Copyright (C) 2005-2011 Red Hat, Inc. This file is part of Red Hat elfutils. Red Hat elfutils is free software; you can redistribute it and/or modify @@@ -58,17 -58,10 +58,17 @@@ dwfl_lineinfo (Dwfl_Line *line, Dwarf_A return NULL; struct dwfl_cu *cu = dwfl_linecu (line); - const Dwarf_Line *info = &cu->die.cu->lines->info[line->idx]; + Dwarf_Line *info = &cu->die.cu->lines->info[line->idx]; if (addr != NULL) - *addr = dwfl_adjusted_dwarf_addr (cu->mod, info->addr); + { + if (INTUSE(dwarf_lineaddr) (info, addr)) + { + __libdwfl_seterrno (DWFL_E_LIBDW); + return NULL; + } - *addr += cu->mod->debug.bias; ++ *addr = dwfl_adjusted_dwarf_addr (cu->mod, *addr); + } if (linep != NULL) *linep = info->line; if (colp != NULL) diff --cc libdwfl/dwfl_module_getdwarf.c index 7f4dc062b,0bd231f9c..ffcc23283 --- a/libdwfl/dwfl_module_getdwarf.c +++ b/libdwfl/dwfl_module_getdwarf.c @@@ -93,16 -93,55 +93,58 @@@ open_elf (Dwfl_Module *mod, struct dwfl return DWFL_E (LIBELF, elf_errno ()); } + if (unlikely (elf_getshdrstrndx (file->elf, &file->shstrndx))) + file->shstrndx = SHN_UNDEF; + - /* The addresses in an ET_EXEC file are absolute. The lowest p_vaddr of - the main file can differ from that of the debug file due to prelink. - But that doesn't not change addresses that symbols, debuginfo, or - sh_addr of any program sections refer to. */ - file->bias = 0; - if (mod->e_type != ET_EXEC) + if (mod->e_type != ET_REL) { + /* In any non-ET_REL file, we compute the "synchronization address". + + We start with the address at the end of the first PT_LOAD + segment. When prelink converts REL to RELA in an ET_DYN + file, it expands the space between the beginning of the + segment and the actual code/data addresses. Since that + change wasn't made in the debug file, the distance from + p_vaddr to an address of interest (in an st_value or DWARF + data) now differs between the main and debug files. The + distance from address_sync to an address of interest remains + consistent. + + If there are no section headers at all (full stripping), then + the end of the first segment is a valid synchronization address. + This cannot happen in a prelinked file, since prelink itself + relies on section headers for prelinking and for undoing it. + (If you do full stripping on a prelinked file, then you get what + you deserve--you can neither undo the prelinking, nor expect to + line it up with a debug file separated before prelinking.) + + However, when prelink processes an ET_EXEC file, it can do + something different. There it juggles the "special" sections + (SHT_DYNSYM et al) to make space for the additional prelink + special sections. Sometimes it will do this by moving a special + section like .dynstr after the real program sections in the + first PT_LOAD segment--i.e. to the end. That changes the end + address of the segment, so it no longer lines up correctly and + is not a valid synchronization address to use. + + So, instead we use a method based on the section headers. We + look at the allocated SHT_PROGBITS (or SHT_NOBITS) sections. + (Most every file will have some SHT_PROGBITS sections, but it's + possible to have one with nothing but .bss, i.e. SHT_NOBITS.) + The special sections that can be moved around have different + sh_type values--except for .interp, the section that became the + PT_INTERP segment. So we exclude the SHT_PROGBITS section whose + address matches the PT_INTERP p_vaddr. + + Since the debug file will always have section headers, we must + choose a method of examining section headers that will also line + up with the end of the first PT_LOAD segment, in case the main + file was fully stripped so we are synchronizing between a + PT_LOAD-based and a section-based calculation. To that end, we + use the highest section end address that lies inside the first + segment. If none does, then we use the highest end address of + any non-special section. */ + size_t phnum; if (unlikely (elf_getphdrnum (file->elf, &phnum) != 0)) goto elf_error; @@@ -780,10 -857,10 +858,10 @@@ dwfl_module_getdwarf (Dwfl_Module *mod { mod->debug.relocated = true; if (mod->debug.elf != mod->main.elf) - (void) __libdwfl_relocate (mod, mod->debug.elf, false); + (void) __libdwfl_relocate (mod, mod->debug.elf); } - *bias = mod->debug.bias; + *bias = dwfl_adjusted_dwarf_addr (mod, 0); return mod->dw; } diff --cc libdwfl/dwfl_report_elf.c index 0a10ad1b7,4c4132b1f..a58272f9e --- a/libdwfl/dwfl_report_elf.c +++ b/libdwfl/dwfl_report_elf.c @@@ -248,10 -252,10 +252,12 @@@ __libdwfl_report_elf (Dwfl *dwfl, cons if (m->main.elf == NULL) { m->main.elf = elf; - m->main.bias = bias; + m->main.vaddr = vaddr; + m->main.address_sync = address_sync; + m->main_bias = bias; m->e_type = ehdr->e_type; + if (unlikely (elf_getshdrstrndx (elf, &m->main.shstrndx))) + m->main.shstrndx = SHN_UNDEF; } else { diff --cc libdwfl/libdwflP.h index 555c5bf04,93db52980..abab35616 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@@ -140,8 -140,14 +140,15 @@@ struct dwfl_fil bool relocated; /* Partial relocation of all sections done. */ Elf *elf; + size_t shstrndx; /* Cache of elf_getshdrstrndx on elf. */ - GElf_Addr bias; /* Actual load address - p_vaddr. */ + + /* This is the lowest p_vaddr in this ELF file, aligned to p_align. + For a file without phdrs, this is zero. */ + GElf_Addr vaddr; + + /* This is an address chosen for synchronization between the main file + and the debug file. See dwfl_module_getdwarf.c for how it's chosen. */ + GElf_Addr address_sync; }; struct Dwfl_Module diff --cc libebl/ChangeLog index c8afad76b,96f70ff8d..49da9aafd --- a/libebl/ChangeLog +++ b/libebl/ChangeLog @@@ -1,14 -1,7 +1,18 @@@ + 2010-07-07 Roland McGrath + + * eblopenbackend.c (default_debugscn_p): Match .gdb_index section. + +2010-06-20 Roland McGrath + + * ebl-hooks.h: Replace reloc_simple_type with reloc_simple_types. + * libebl.h: Likewise. + * eblrelocsimpletypes.c: New file. + * eblrelocsimpletype.c: File removed. + * Makefile.am (gen_SOURCES): Updated. + * eblopenbackend.c (default_reloc_simple_types): New function. + (default_reloc_simple_type): Removed. + (fill_defaults): Update initializer. + 2010-02-15 Roland McGrath * Makefile.am: Use config/eu.am for common stuff.