aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
Diffstat (limited to 'gold')
-rw-r--r--gold/ChangeLog13
-rw-r--r--gold/dwarf_reader.cc24
-rw-r--r--gold/dwarf_reader.h4
-rw-r--r--gold/reloc.cc14
-rw-r--r--gold/reloc.h7
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