diff options
author | Ian Lance Taylor <ian@airs.com> | 2010-08-02 11:59:11 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2010-08-02 11:59:11 +0000 |
commit | 5f1ab67afc4b968ef1de25b13f644fd20ac029d9 (patch) | |
tree | fa058ec61f822375f9007fa84fe99943fe2c6e48 /gold/output.cc | |
parent | 85cfcbfb1a3bce62a3537eb7480ef1116f4c0d94 (diff) | |
download | gdb-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.cc | 59 |
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 |