diff options
author | Doug Kwan <dougkwan@google.com> | 2010-05-19 07:09:36 +0000 |
---|---|---|
committer | Doug Kwan <dougkwan@google.com> | 2010-05-19 07:09:36 +0000 |
commit | 6625d24e236a525781fda9482af925ade7f60c97 (patch) | |
tree | 486f3bcb594dee1205afa0342019f0733ebd31a0 /gold/arm.cc | |
parent | 51b5d4a8c5e50baae29270983b16cfdd49ed7646 (diff) | |
download | binutils-gdb-6625d24e236a525781fda9482af925ade7f60c97.tar.gz |
2010-05-14 Doug Kwan <dougkwan@google.com>
* arm.cc (Arm_input_section::original_size): New method.
(Arm_input_section::do_addralign): Add a cast.
(Arm_input_section::do_output_offset): Remove static cast.
(Arm_input_section::original_addralign,
Arm_input_section::original_size_): Change type to uint32_t.
(Arm_input_section::init): Add safe casts for section alignment
and size.
(Arm_input_section::set_final_data_size): Do not set address and
offset of stub table.
(Arm_output_section::fix_exidx_coverage): Change use of of
Output_section::Simple_input_section to that of
Output_section::Input_section.
(Target_arm::do_relax): Set addresses and file offsets of Stub_tables
except for the first pass.
* output.cc (Output_section::get_input_sections): Change type of
input_sections to std::list<Input_section>.
(Output_section::add_script_input_section): Rename from
Output_section::add_simple_input_section. Change type of SIS
parameter from Simple_input_section to Input_section.
* output.h (Output_section::Simple_input_section): Remove class.
(Output_section::Input_section): Change class visibility to public.
(Output_section::Input_section::addralign): Use stored alignments
for special input sections if set.
(Output_section::Input_section::set_addralign): New method.
(Output_section::get_input_sections): Change parameter type from
list of Simple_input_section to list of Input_section.
(Output_section::add_script_input_section): Rename from
Output_section::add_simple_input_section. Change first parameter's
type from Simple_input_section to Input_section and remove the
second and third parameters.
* script-sections.cc (Input_section::Input_section_list): Change
type to list of Output_section::Input_section/
(Input_section_info::Input_section_info): Change parameter type of
INPUT_SECTION to Output_section::Input_section.
(Input_section_info::input_section): Change return type.
(Input_section_info::input_section_): Change type to
Output_section::Input_section.
(Output_section_element_input::set_section_addresses): Adjust code
to use Output_section::Input_section instead of
Output_section::Simple_input_section. Adjust code for renaming
of Output_section::add_simple_input_section.
(Orphan_output_section::set_section_addresses): Ditto.
Diffstat (limited to 'gold/arm.cc')
-rw-r--r-- | gold/arm.cc | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/gold/arm.cc b/gold/arm.cc index c304d2acfc9..3dc2f22023e 100644 --- a/gold/arm.cc +++ b/gold/arm.cc @@ -1164,6 +1164,11 @@ class Arm_input_section : public Output_relaxed_input_section as_arm_input_section(Output_relaxed_input_section* poris) { return static_cast<Arm_input_section<big_endian>*>(poris); } + // Return the original size of the section. + uint32_t + original_size() const + { return this->original_size_; } + protected: // Write data to output file. void @@ -1175,7 +1180,7 @@ class Arm_input_section : public Output_relaxed_input_section { if (this->is_stub_table_owner()) return std::max(this->stub_table_->addralign(), - this->original_addralign_); + static_cast<uint64_t>(this->original_addralign_)); else return this->original_addralign_; } @@ -1197,8 +1202,7 @@ class Arm_input_section : public Output_relaxed_input_section if ((object == this->relobj()) && (shndx == this->shndx()) && (offset >= 0) - && (convert_types<uint64_t, section_offset_type>(offset) - <= this->original_size_)) + && (offset <= this->original_size_)) { *poutput = offset; return true; @@ -1213,9 +1217,9 @@ class Arm_input_section : public Output_relaxed_input_section Arm_input_section& operator=(const Arm_input_section&); // Address alignment of the original input section. - uint64_t original_addralign_; + uint32_t original_addralign_; // Section size of the original input section. - uint64_t original_size_; + uint32_t original_size_; // Stub table. Stub_table<big_endian>* stub_table_; }; @@ -4909,8 +4913,10 @@ Arm_input_section<big_endian>::init() // Cache these to speed up size and alignment queries. It is too slow // to call section_addraglin and section_size every time. - this->original_addralign_ = relobj->section_addralign(shndx); - this->original_size_ = relobj->section_size(shndx); + this->original_addralign_ = + convert_types<uint32_t, uint64_t>(relobj->section_addralign(shndx)); + this->original_size_ = + convert_types<uint32_t, uint64_t>(relobj->section_size(shndx)); // We want to make this look like the original input section after // output sections are finalized. @@ -4949,10 +4955,8 @@ Arm_input_section<big_endian>::set_final_data_size() if (this->is_stub_table_owner()) { - // The stub table comes after the original section contents. + this->stub_table_->finalize_data_size(); off = align_address(off, this->stub_table_->addralign()); - this->stub_table_->set_address_and_file_offset(this->address() + off, - this->offset() + off); off += this->stub_table_->data_size(); } this->set_data_size(off); @@ -5576,8 +5580,8 @@ Arm_output_section<big_endian>::fix_exidx_coverage( // Remove all input sections. uint64_t address = this->address(); - typedef std::list<Simple_input_section> Simple_input_section_list; - Simple_input_section_list input_sections; + typedef std::list<Output_section::Input_section> Input_section_list; + Input_section_list input_sections; this->reset_address_and_file_offset(); this->get_input_sections(address, std::string(""), &input_sections); @@ -5586,20 +5590,23 @@ Arm_output_section<big_endian>::fix_exidx_coverage( // Go through all the known input sections and record them. typedef Unordered_set<Section_id, Section_id_hash> Section_id_set; - Section_id_set known_input_sections; - for (Simple_input_section_list::const_iterator p = input_sections.begin(); + typedef Unordered_map<Section_id, const Output_section::Input_section*, + Section_id_hash> Text_to_exidx_map; + Text_to_exidx_map text_to_exidx_map; + for (Input_section_list::const_iterator p = input_sections.begin(); p != input_sections.end(); ++p) { // This should never happen. At this point, we should only see // plain EXIDX input sections. gold_assert(!p->is_relaxed_input_section()); - known_input_sections.insert(Section_id(p->relobj(), p->shndx())); + text_to_exidx_map[Section_id(p->relobj(), p->shndx())] = &(*p); } Arm_exidx_fixup exidx_fixup(this, merge_exidx_entries); // Go over the sorted text sections. + typedef Unordered_set<Section_id, Section_id_hash> Section_id_set; Section_id_set processed_input_sections; for (Text_section_list::const_iterator p = sorted_text_sections.begin(); p != sorted_text_sections.end(); @@ -5624,7 +5631,8 @@ Arm_output_section<big_endian>::fix_exidx_coverage( Relobj* exidx_relobj = exidx_input_section->relobj(); unsigned int exidx_shndx = exidx_input_section->shndx(); Section_id sid(exidx_relobj, exidx_shndx); - if (known_input_sections.find(sid) == known_input_sections.end()) + Text_to_exidx_map::const_iterator iter = text_to_exidx_map.find(sid); + if (iter == text_to_exidx_map.end()) { // This is odd. We have not seen this EXIDX input section before. // We cannot do fix-up. If we saw a SECTIONS clause in a script, @@ -5679,9 +5687,9 @@ Arm_output_section<big_endian>::fix_exidx_coverage( { // Just add back the EXIDX input section. gold_assert(section_offset_map == NULL); - Output_section::Simple_input_section sis(exidx_relobj, exidx_shndx); - this->add_simple_input_section(sis, exidx_input_section->size(), - exidx_input_section->addralign()); + const Output_section::Input_section* pis = iter->second; + gold_assert(pis->is_input_section()); + this->add_script_input_section(*pis); } processed_input_sections.insert(Section_id(exidx_relobj, exidx_shndx)); @@ -5691,7 +5699,7 @@ Arm_output_section<big_endian>::fix_exidx_coverage( exidx_fixup.add_exidx_cantunwind_as_needed(); // Remove any known EXIDX input sections that are not processed. - for (Simple_input_section_list::const_iterator p = input_sections.begin(); + for (Input_section_list::const_iterator p = input_sections.begin(); p != input_sections.end(); ++p) { @@ -10444,6 +10452,7 @@ Target_arm<big_endian>::do_relax( // If this is the first pass, we need to group input sections into // stub groups. bool done_exidx_fixup = false; + typedef typename Stub_table_list::iterator Stub_table_iterator; if (pass == 1) { // Determine the stub group size. The group size is the absolute @@ -10492,13 +10501,27 @@ Target_arm<big_endian>::do_relax( done_exidx_fixup = true; } } + else + { + // If this is not the first pass, addresses and file offsets have + // been reset at this point, set them here. + for (Stub_table_iterator sp = this->stub_tables_.begin(); + sp != this->stub_tables_.end(); + ++sp) + { + Arm_input_section<big_endian>* owner = (*sp)->owner(); + off_t off = align_address(owner->original_size(), + (*sp)->addralign()); + (*sp)->set_address_and_file_offset(owner->address() + off, + owner->offset() + off); + } + } // The Cortex-A8 stubs are sensitive to layout of code sections. At the // beginning of each relaxation pass, just blow away all the stubs. // Alternatively, we could selectively remove only the stubs and reloc // information for code sections that have moved since the last pass. // That would require more book-keeping. - typedef typename Stub_table_list::iterator Stub_table_iterator; if (this->fix_cortex_a8_) { // Clear all Cortex-A8 reloc information. |