aboutsummaryrefslogtreecommitdiff
path: root/gold/output.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2010-08-02 11:59:11 +0000
committerIan Lance Taylor <ian@airs.com>2010-08-02 11:59:11 +0000
commit5f1ab67afc4b968ef1de25b13f644fd20ac029d9 (patch)
treefa058ec61f822375f9007fa84fe99943fe2c6e48 /gold/output.cc
parent85cfcbfb1a3bce62a3537eb7480ef1116f4c0d94 (diff)
downloadgdb-5f1ab67afc4b968ef1de25b13f644fd20ac029d9.zip
gdb-5f1ab67afc4b968ef1de25b13f644fd20ac029d9.tar.gz
gdb-5f1ab67afc4b968ef1de25b13f644fd20ac029d9.tar.bz2
PR 11866
* output.cc (Output_segment::set_offset): Search for the first and last sections rather than assuming that the list is in order. (Output_segment::find_first_and_last_list): New function. * output.h (class Output_segment): Update declarations. * testsuite/Makefile.am (check_PROGRAMS): Add relro_strip_test. (relro_strip_test_SOURCES): New variable. (relro_strip_test_DEPENDENCIES): New variable. (relro_strip_test_LDFLAGS): New variable. (relro_strip_test_LDADD): New variable. (relro_strip_test.so): New target.
Diffstat (limited to 'gold/output.cc')
-rw-r--r--gold/output.cc59
1 files changed, 43 insertions, 16 deletions
diff --git a/gold/output.cc b/gold/output.cc
index a487eb8..506edf7 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -4042,11 +4042,14 @@ Output_segment::set_offset(unsigned int increase)
return;
}
- const Output_data* first;
- if (this->output_data_.empty())
- first = this->output_bss_.front();
- else
- first = this->output_data_.front();
+ // Find the first and last section by address. The sections may
+ // have been sorted for the PT_LOAD segment.
+ const Output_data* first = NULL;
+ const Output_data* last_data = NULL;
+ const Output_data* last_bss = NULL;
+ this->find_first_and_last_list(&this->output_data_, &first, &last_data);
+ this->find_first_and_last_list(&this->output_bss_, &first, &last_bss);
+
this->vaddr_ = first->address();
this->paddr_ = (first->has_load_address()
? first->load_address()
@@ -4057,18 +4060,11 @@ Output_segment::set_offset(unsigned int increase)
if (this->output_data_.empty())
this->filesz_ = 0;
else
- {
- const Output_data* last_data = this->output_data_.back();
- this->filesz_ = (last_data->address()
- + last_data->data_size()
- - this->vaddr_);
- }
+ this->filesz_ = (last_data->address()
+ + last_data->data_size()
+ - this->vaddr_);
- const Output_data* last;
- if (this->output_bss_.empty())
- last = this->output_data_.back();
- else
- last = this->output_bss_.back();
+ const Output_data* last = last_bss != NULL ? last_bss : last_data;
this->memsz_ = (last->address()
+ last->data_size()
- this->vaddr_);
@@ -4087,6 +4083,37 @@ Output_segment::set_offset(unsigned int increase)
}
}
+// Look through a list of Output_data objects and find the first and
+// last by address.
+
+void
+Output_segment::find_first_and_last_list(const Output_data_list* pdl,
+ const Output_data** pfirst,
+ const Output_data** plast) const
+{
+ const Output_data* first = *pfirst;
+ const Output_data* last = *plast;
+ for (Output_data_list::const_iterator p = pdl->begin(); p != pdl->end(); ++p)
+ {
+ if (first == NULL
+ || (*p)->address() < first->address()
+ || ((*p)->address() == first->address()
+ && (*p)->data_size() < first->data_size()))
+ {
+ first = *p;
+ *pfirst = first;
+ }
+ if (last == NULL
+ || (*p)->address() > last->address()
+ || ((*p)->address() == last->address()
+ && (*p)->data_size() > last->data_size()))
+ {
+ last = *p;
+ *plast = last;
+ }
+ }
+}
+
// Set the TLS offsets of the sections in the PT_TLS segment.
void