diff options
-rw-r--r-- | gold/ChangeLog | 13 | ||||
-rw-r--r-- | gold/dwarf_reader.cc | 24 | ||||
-rw-r--r-- | gold/dwarf_reader.h | 4 | ||||
-rw-r--r-- | gold/reloc.cc | 14 | ||||
-rw-r--r-- | gold/reloc.h | 7 |
5 files changed, 54 insertions, 8 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 0d706f8..43eb9de 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,18 @@ 2010-12-01 Ian Lance Taylor <iant@google.com> + * dwarf_reader.h (class Sized_dwarf_line_info): Add + track_relocs_type_ field. + * dwarf_reader.cc (Sized_dwarf_line_info::Sized_dwarf_line_info): + Set track_relocs_type_. + (Sized_dwarf_line_info::process_one_opcode): Ignore the section + contents when using RELA relocs. + (Sized_dwarf_line_info::read_relocs): Add the reloc addend to + reloc_map_. + * reloc.cc (Track_relocs::next_addend): New function. + * reloc.h (class Track_relocs): Declare next_addend. + +2010-12-01 Ian Lance Taylor <iant@google.com> + * testsuite/icf_virtual_function_folding_test.cc (class Bar): Add virtual destructor. diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc index e83e7fb..c4c9bfc 100644 --- a/gold/dwarf_reader.cc +++ b/gold/dwarf_reader.cc @@ -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 <iant@google.com>. // This file is part of gold. @@ -113,6 +113,7 @@ Sized_dwarf_line_info<size, big_endian>::Sized_dwarf_line_info(Object* object, { 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<size, big_endian>::process_one_opcode( case elfcpp::DW_LNE_set_address: { - lsm->address = elfcpp::Swap_unaligned<size, big_endian>::readval(start); + lsm->address = + elfcpp::Swap_unaligned<size, big_endian>::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<size, big_endian>::read_relocs(Object* object) // 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); } diff --git a/gold/dwarf_reader.h b/gold/dwarf_reader.h index e2b8aa0..c197833 100644 --- a/gold/dwarf_reader.h +++ b/gold/dwarf_reader.h @@ -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 <iant@google.com>. // This file is part of gold. @@ -178,6 +178,8 @@ class Sized_dwarf_line_info : public Dwarf_line_info // This has relocations that point into buffer. Track_relocs<size, big_endian> 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_; diff --git a/gold/reloc.cc b/gold/reloc.cc index 9ffb693..51ced0f 100644 --- a/gold/reloc.cc +++ b/gold/reloc.cc @@ -1591,6 +1591,20 @@ Track_relocs<size, big_endian>::next_symndx() const return elfcpp::elf_r_sym<size>(rel.get_r_info()); } +// Return the addend of the next reloc, or 0 if there isn't one. + +template<int size, bool big_endian> +uint64_t +Track_relocs<size, big_endian>::next_addend() const +{ + if (this->pos_ >= this->len_) + return 0; + if (this->reloc_size_ == elfcpp::Elf_sizes<size>::rel_size) + return 0; + elfcpp::Rela<size, big_endian> 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. diff --git a/gold/reloc.h b/gold/reloc.h index f99da0c..87e70cc 100644 --- a/gold/reloc.h +++ b/gold/reloc.h @@ -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 |