diff options
author | Ian Lance Taylor <ian@airs.com> | 2008-07-10 23:01:20 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2008-07-10 23:01:20 +0000 |
commit | ef9beddf72634055b25a631850464a701599585c (patch) | |
tree | fa8661a29f81c137fffc658c4104657e22732c2f /gold/object.cc | |
parent | 4c28f408dfc2ab71b7995f061cc725d3f217ec9c (diff) | |
download | gdb-ef9beddf72634055b25a631850464a701599585c.zip gdb-ef9beddf72634055b25a631850464a701599585c.tar.gz gdb-ef9beddf72634055b25a631850464a701599585c.tar.bz2 |
Handle output sections with more than 0x7fffffff bytes.
* object.h (class Relobj): Change map_to_output_ to
output_sections_, and just keep a section pointer. Change all
uses. Move comdat group support to Sized_relobj.
(Relobj::is_section_specially_mapped): Remove.
(Relobj::output_section): Remove poff parameter. Change all
callers.
(Relobj::output_section_offset): New function.
(Relobj::set_section_offset): Rewrite.
(Relobj::map_to_output): Remove.
(Relobj::output_sections): New function.
(Relobj::do_output_section_offset): New pure virtual function.
(Relobj::do_set_section_offset): Likewise.
(class Sized_relobj): Add section_offsets_ field. Add comdat
group support from Relobj. Update declarations.
(Sized_relobj::get_output_section_offset): New function.
(Sized_relobj::do_output_section_offset): New function.
(Sized_relobj::do_set_section_offset): New function.
* object.cc (Relobj::output_section_address): Remove.
(Sized_relobj::Sized_relobj): Initialize new fields.
(Sized_relobj::include_section_group): Cast find_kept_object to
Sized_relobj.
(Sized_relobj::include_linkonce_section): Likewise.
(Sized_relobj::do_layout): Use separate arrays for output section
and output offset.
(Sized_relobj::do_count_local_symbols): Change map_to_output to
output_sections.
(Sized_relobj::do_finalize_local_symbols): Change map_to_output to
output_sections and section_offsets.
(Sized_relobj::write_local_symbols): Likewise.
(map_to_kept_section): Compute output address directly.
* reloc.cc (Sized_relobj::do_read_relocs): Change map_to_output to
output_sections and section_offsets.
(Sized_relobj::write_sections): Likewise.
(Sized_relobj::relocate_sections): Likewise.
* symtab.cc (sized_finalize_symbol): Use output_section_offset.
* output.h (class Output_reloc): Update declarations. Change
u2_.relobj to Sized_relobj*.
(class Output_data_reloc): Change add functions to use
Sized_relobj*.
* output.cc (Output_reloc::Output_reloc): Change relobj to
Sized_relobj*.
(Output_reloc::local_section_offset): Change return type to
Elf_Addr. Use get_output_section_offset.
(Output_reloc::get_address): Likewise.
(Output_section::is_input_address_mapped): Don't call
is_section_specially_mapped.
(Output_section::output_offset): Likewise.
(Output_section::output_address): Likewise.
(Output_section::starting_output_address): Likewise.
* copy-relocs.cc (Copy_relocs::copy_reloc): Change object
parameter to Sized_relobj*.
(Copy_relocs::need_copy_reloc): Likewise.
(Copy_relocs::save): Likewise.
* copy-relocs.h (class Copy_relocs): Update declarations.
(class Copy_relocs::Copy_reloc_entry): Change constructor to use
Sized_relobj*. Change relobj_ field to Sized_relobj*.
* target-reloc.h (relocate_for_relocatable): Change
offset_in_output_section type to Elf_Addr. Change code that uses
it as well.
* layout.cc (Layout::layout): Always set *off.
* mapfile.cc (Mapfile::print_input_section): Use
output_section_offset.
* i386.cc (Target_i386::copy_reloc): Change object parameter to
Sized_relobj*.
* powerpc.cc (Target_powerpc::copy_reloc): Likewise.
* sparc.cc (Target_sparc::copy_reloc): Likewise.
* x86_64.cc (Target_x86_64::copy_reloc): Likewise.
Diffstat (limited to 'gold/object.cc')
-rw-r--r-- | gold/object.cc | 96 |
1 files changed, 53 insertions, 43 deletions
diff --git a/gold/object.cc b/gold/object.cc index 8659cb2..2ecb8a9 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -230,18 +230,6 @@ Object::handle_gnu_warning_section(const char* name, unsigned int shndx, return false; } -// Class Relobj. - -// Return the output address of the input section SHNDX. -uint64_t -Relobj::output_section_address(unsigned int shndx) const -{ - section_offset_type offset; - Output_section* os = this->output_section(shndx, &offset); - gold_assert(os != NULL && offset != -1); - return os->address() + offset; -} - // Class Sized_relobj. template<int size, bool big_endian> @@ -261,6 +249,8 @@ Sized_relobj<size, big_endian>::Sized_relobj( local_dynsym_offset_(0), local_values_(), local_got_offsets_(), + kept_comdat_sections_(), + comdat_groups_(), has_eh_frame_(false) { } @@ -610,7 +600,7 @@ Sized_relobj<size, big_endian>::include_section_group( bool include_group = ((flags & elfcpp::GRP_COMDAT) == 0 || layout->add_comdat(this, index, signature, true)); - Relobj* kept_object = NULL; + Sized_relobj<size, big_endian>* kept_object = NULL; Comdat_group* kept_group = NULL; if (!include_group) @@ -618,7 +608,9 @@ Sized_relobj<size, big_endian>::include_section_group( // This group is being discarded. Find the object and group // that was kept in its place. unsigned int kept_group_index = 0; - kept_object = layout->find_kept_object(signature, &kept_group_index); + Relobj* kept_relobj = layout->find_kept_object(signature, + &kept_group_index); + kept_object = static_cast<Sized_relobj<size, big_endian>*>(kept_relobj); if (kept_object != NULL) kept_group = kept_object->find_comdat_group(kept_group_index); } @@ -749,9 +741,11 @@ Sized_relobj<size, big_endian>::include_linkonce_section( // In this case, the section index stored with the layout object // is the linkonce section that was kept. unsigned int kept_group_index = 0; - Relobj* kept_object = layout->find_kept_object(sig2, &kept_group_index); - if (kept_object != NULL) + Relobj* kept_relobj = layout->find_kept_object(sig2, &kept_group_index); + if (kept_relobj != NULL) { + Sized_relobj<size, big_endian>* kept_object + = static_cast<Sized_relobj<size, big_endian>*>(kept_relobj); Kept_comdat_section* kept = new Kept_comdat_section(kept_object, kept_group_index); this->set_kept_comdat_section(index, kept); @@ -767,9 +761,11 @@ Sized_relobj<size, big_endian>::include_linkonce_section( // the group has only one member section. Otherwise, it's not // worth the effort. unsigned int kept_group_index = 0; - Relobj* kept_object = layout->find_kept_object(sig1, &kept_group_index); - if (kept_object != NULL) + Relobj* kept_relobj = layout->find_kept_object(sig1, &kept_group_index); + if (kept_relobj != NULL) { + Sized_relobj<size, big_endian>* kept_object = + static_cast<Sized_relobj<size, big_endian>*>(kept_relobj); Comdat_group* kept_group = kept_object->find_comdat_group(kept_group_index); if (kept_group != NULL && kept_group->size() == 1) @@ -841,8 +837,11 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, } } - std::vector<Map_to_output>& map_sections(this->map_to_output()); - map_sections.resize(shnum); + Output_sections& out_sections(this->output_sections()); + std::vector<Address>& out_section_offsets(this->section_offsets_); + + out_sections.resize(shnum); + out_section_offsets.resize(shnum); // If we are only linking for symbols, then there is nothing else to // do here. @@ -924,7 +923,8 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, if (discard) { // Do not include this section in the link. - map_sections[i].output_section = NULL; + out_sections[i] = NULL; + out_section_offsets[i] = -1U; continue; } @@ -963,8 +963,11 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, reloc_shndx[i], reloc_type[i], &offset); - map_sections[i].output_section = os; - map_sections[i].offset = offset; + out_sections[i] = os; + if (offset == -1) + out_section_offsets[i] = -1U; + else + out_section_offsets[i] = convert_types<Address, off_t>(offset); // If this section requires special handling, and if there are // relocs that apply to it, then we must do the special handling @@ -995,10 +998,11 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, continue; } - Output_section* data_section = map_sections[data_shndx].output_section; + Output_section* data_section = out_sections[data_shndx]; if (data_section == NULL) { - map_sections[i].output_section = NULL; + out_sections[i] = NULL; + out_section_offsets[i] = -1U; continue; } @@ -1007,8 +1011,8 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, Output_section* os = layout->layout_reloc(this, i, shdr, data_section, rr); - map_sections[i].output_section = os; - map_sections[i].offset = -1; + out_sections[i] = os; + out_section_offsets[i] = -1U; } // Handle the .eh_frame sections at the end. @@ -1034,8 +1038,11 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab, reloc_shndx[i], reloc_type[i], &offset); - map_sections[i].output_section = os; - map_sections[i].offset = offset; + out_sections[i] = os; + if (offset == -1) + out_section_offsets[i] = -1U; + else + out_section_offsets[i] = convert_types<Address, off_t>(offset); // If this section requires special handling, and if there are // relocs that apply to it, then we must do the special handling @@ -1131,7 +1138,7 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool, // Loop over the local symbols. - const std::vector<Map_to_output>& mo(this->map_to_output()); + const Output_sections& out_sections(this->output_sections()); unsigned int shnum = this->shnum(); unsigned int count = 0; unsigned int dyncount = 0; @@ -1158,7 +1165,7 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool, // Decide whether this symbol should go into the output file. - if (shndx < shnum && mo[shndx].output_section == NULL) + if (shndx < shnum && out_sections[shndx] == NULL) { lv.set_no_output_symtab_entry(); gold_assert(!lv.needs_output_dynsym_entry()); @@ -1213,7 +1220,8 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index, const unsigned int loccount = this->local_symbol_count_; this->local_symbol_offset_ = off; - const std::vector<Map_to_output>& mo(this->map_to_output()); + const Output_sections& out_sections(this->output_sections()); + const std::vector<Address>& out_offsets(this->section_offsets_); unsigned int shnum = this->shnum(); for (unsigned int i = 1; i < loccount; ++i) @@ -1224,7 +1232,7 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index, unsigned int shndx = lv.input_shndx(&is_ordinary); // Set the output symbol value. - + if (!is_ordinary) { if (shndx == elfcpp::SHN_ABS || shndx == elfcpp::SHN_COMMON) @@ -1245,7 +1253,7 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index, shndx = 0; } - Output_section* os = mo[shndx].output_section; + Output_section* os = out_sections[shndx]; if (os == NULL) { @@ -1255,7 +1263,7 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index, // so we leave the input value unchanged here. continue; } - else if (mo[shndx].offset == -1) + else if (out_offsets[shndx] == -1U) { // This is a SHF_MERGE section or one which otherwise // requires special handling. We get the output address @@ -1278,11 +1286,11 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index, } else if (lv.is_tls_symbol()) lv.set_output_value(os->tls_offset() - + mo[shndx].offset + + out_offsets[shndx] + lv.input_value()); else lv.set_output_value(os->address() - + mo[shndx].offset + + out_offsets[shndx] + lv.input_value()); } @@ -1385,7 +1393,7 @@ Sized_relobj<size, big_endian>::write_local_symbols( dyn_oview = of->get_output_view(this->local_dynsym_offset_, dyn_output_size); - const std::vector<Map_to_output>& mo(this->map_to_output()); + const Output_sections out_sections(this->output_sections()); gold_assert(this->local_values_.size() == loccount); @@ -1403,10 +1411,10 @@ Sized_relobj<size, big_endian>::write_local_symbols( &is_ordinary); if (is_ordinary) { - gold_assert(st_shndx < mo.size()); - if (mo[st_shndx].output_section == NULL) + gold_assert(st_shndx < out_sections.size()); + if (out_sections[st_shndx] == NULL) continue; - st_shndx = mo[st_shndx].output_section->out_shndx(); + st_shndx = out_sections[st_shndx]->out_shndx(); if (st_shndx >= elfcpp::SHN_LORESERVE) { if (lv.needs_output_symtab_entry()) @@ -1560,8 +1568,10 @@ Sized_relobj<size, big_endian>::map_to_kept_section( { gold_assert(kept->object_ != NULL); *found = true; - return (static_cast<Address> - (kept->object_->output_section_address(kept->shndx_))); + Output_section* os = kept->object_->output_section(kept->shndx_); + Address offset = kept->object_->get_output_section_offset(kept->shndx_); + gold_assert(os != NULL && offset != -1U); + return os->address() + offset; } *found = false; return 0; |