Index: dwarf_reader.cc =================================================================== RCS file: /cvs/src/src/gold/dwarf_reader.cc,v retrieving revision 1.28 diff -u -u -p -r1.28 dwarf_reader.cc --- dwarf_reader.cc 17 Nov 2010 01:53:22 -0000 1.28 +++ dwarf_reader.cc 1 Dec 2010 19:40:22 -0000 @@ -1,6 +1,6 @@ // dwarf_reader.cc -- parse dwarf2/3 debug information -// Copyright 2007, 2008, 2009 Free Software Foundation, Inc. +// Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -113,6 +113,7 @@ Sized_dwarf_line_info: { got_relocs = this->track_relocs_.initialize(object, reloc_shndx, reloc_sh_type); + this->track_relocs_type_ = reloc_sh_type; break; } } @@ -392,13 +393,21 @@ Sized_dwarf_line_info: case elfcpp::DW_LNE_set_address: { - lsm->address = elfcpp::Swap_unaligned::readval(start); + lsm->address = + elfcpp::Swap_unaligned::readval(start); typename Reloc_map::const_iterator it - = reloc_map_.find(start - this->buffer_); + = this->reloc_map_.find(start - this->buffer_); if (it != reloc_map_.end()) { - // value + addend. - lsm->address += it->second.second; + // If this is a SHT_RELA section, then ignore the + // section contents. This assumes that this is a + // straight reloc which just uses the reloc addend. + // The reloc addend has already been included in the + // symbol value. + if (this->track_relocs_type_ == elfcpp::SHT_RELA) + lsm->address = 0; + // Add in the symbol value. + lsm->address += it->second.second; lsm->shndx = it->second.first; } else @@ -536,7 +545,10 @@ Sized_dwarf_line_info: // There is no reason to record non-ordinary section indexes, or // SHN_UNDEF, because they will never match the real section. if (is_ordinary && shndx != elfcpp::SHN_UNDEF) - this->reloc_map_[reloc_offset] = std::make_pair(shndx, value); + { + value += this->track_relocs_.next_addend(); + this->reloc_map_[reloc_offset] = std::make_pair(shndx, value); + } this->track_relocs_.advance(reloc_offset + 1); } Index: dwarf_reader.h =================================================================== RCS file: /cvs/src/src/gold/dwarf_reader.h,v retrieving revision 1.17 diff -u -u -p -r1.17 dwarf_reader.h --- dwarf_reader.h 9 Dec 2009 03:02:28 -0000 1.17 +++ dwarf_reader.h 1 Dec 2010 19:40:22 -0000 @@ -1,6 +1,6 @@ // dwarf_reader.h -- parse dwarf2/3 debug information for gold -*- C++ -*- -// Copyright 2007, 2008, 2009 Free Software Foundation, Inc. +// Copyright 2007, 2008, 2009, 2010 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -178,6 +178,8 @@ class Sized_dwarf_line_info : public Dwa // This has relocations that point into buffer. Track_relocs track_relocs_; + // The type of the reloc section in track_relocs_--SHT_REL or SHT_RELA. + unsigned int track_relocs_type_; // This is used to figure out what section to apply a relocation to. const unsigned char* symtab_buffer_; Index: reloc.cc =================================================================== RCS file: /cvs/src/src/gold/reloc.cc,v retrieving revision 1.60 diff -u -u -p -r1.60 reloc.cc --- reloc.cc 14 Oct 2010 22:10:22 -0000 1.60 +++ reloc.cc 1 Dec 2010 19:40:22 -0000 @@ -1591,6 +1591,20 @@ Track_relocs::next_sym return elfcpp::elf_r_sym(rel.get_r_info()); } +// Return the addend of the next reloc, or 0 if there isn't one. + +template +uint64_t +Track_relocs::next_addend() const +{ + if (this->pos_ >= this->len_) + return 0; + if (this->reloc_size_ == elfcpp::Elf_sizes::rel_size) + return 0; + elfcpp::Rela rela(this->prelocs_ + this->pos_); + return rela.get_r_addend(); +} + // Advance to the next reloc whose r_offset is greater than or equal // to OFFSET. Return the number of relocs we skip. Index: reloc.h =================================================================== RCS file: /cvs/src/src/gold/reloc.h,v retrieving revision 1.29 diff -u -u -p -r1.29 reloc.h --- reloc.h 12 Feb 2010 04:33:53 -0000 1.29 +++ reloc.h 1 Dec 2010 19:40:22 -0000 @@ -678,7 +678,7 @@ class Track_relocs unsigned int reloc_type); // Return the offset in the data section to which the next reloc - // applies. THis returns -1 if there is no next reloc. + // applies. This returns -1 if there is no next reloc. off_t next_offset() const; @@ -687,6 +687,11 @@ class Track_relocs unsigned int next_symndx() const; + // Return the addend of the next reloc. This returns 0 if there is + // no next reloc. + uint64_t + next_addend() const; + // Advance to OFFSET within the data section, and return the number // of relocs which would be skipped. int