aboutsummaryrefslogtreecommitdiff
path: root/gold/output.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-12-21 21:19:45 +0000
committerIan Lance Taylor <iant@google.com>2007-12-21 21:19:45 +0000
commita9a60db6891083f0afc4df6353a0c7ef80508874 (patch)
tree4a78b23b559b910d217cc25c71fbfea946f646cd /gold/output.cc
parentdf1764b8ab18419eab855810f86419777d12925a (diff)
downloadfsf-binutils-gdb-a9a60db6891083f0afc4df6353a0c7ef80508874.zip
fsf-binutils-gdb-a9a60db6891083f0afc4df6353a0c7ef80508874.tar.gz
fsf-binutils-gdb-a9a60db6891083f0afc4df6353a0c7ef80508874.tar.bz2
Speed up relocations against local symbols in merged sections.
Diffstat (limited to 'gold/output.cc')
-rw-r--r--gold/output.cc40
1 files changed, 40 insertions, 0 deletions
diff --git a/gold/output.cc b/gold/output.cc
index 793d6a3..3d1d27e 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -1369,6 +1369,18 @@ Output_section::Input_section::output_offset(
}
}
+// Return whether this is the merge section for the input section
+// SHNDX in OBJECT.
+
+inline bool
+Output_section::Input_section::is_merge_section_for(const Relobj* object,
+ unsigned int shndx) const
+{
+ if (this->is_input_section())
+ return false;
+ return this->u2_.posd->is_merge_section_for(object, shndx);
+}
+
// Write out the data. We don't have to do anything for an input
// section--they are handled via Object::relocate--but this is where
// we write out the data for an Output_section_data.
@@ -1710,6 +1722,34 @@ Output_section::output_address(const Relobj* object, unsigned int shndx,
gold_unreachable();
}
+// Return the output address of the start of the merged section for
+// input section SHNDX in object OBJECT.
+
+uint64_t
+Output_section::starting_output_address(const Relobj* object,
+ unsigned int shndx) const
+{
+ gold_assert(object->is_section_specially_mapped(shndx));
+
+ uint64_t addr = this->address() + this->first_input_offset_;
+ for (Input_section_list::const_iterator p = this->input_sections_.begin();
+ p != this->input_sections_.end();
+ ++p)
+ {
+ addr = align_address(addr, p->addralign());
+
+ // It would be nice if we could use the existing output_offset
+ // method to get the output offset of input offset 0.
+ // Unfortunately we don't know for sure that input offset 0 is
+ // mapped at all.
+ if (p->is_merge_section_for(object, shndx))
+ return addr;
+
+ addr += p->data_size();
+ }
+ gold_unreachable();
+}
+
// Set the data size of an Output_section. This is where we handle
// setting the addresses of any Output_section_data objects.