diff options
-rw-r--r-- | gold/ChangeLog | 71 | ||||
-rw-r--r-- | gold/copy-relocs.cc | 14 | ||||
-rw-r--r-- | gold/copy-relocs.h | 15 | ||||
-rw-r--r-- | gold/i386.cc | 3 | ||||
-rw-r--r-- | gold/layout.cc | 2 | ||||
-rw-r--r-- | gold/mapfile.cc | 10 | ||||
-rw-r--r-- | gold/merge.h | 2 | ||||
-rw-r--r-- | gold/object.cc | 96 | ||||
-rw-r--r-- | gold/object.h | 253 | ||||
-rw-r--r-- | gold/output.cc | 47 | ||||
-rw-r--r-- | gold/output.h | 38 | ||||
-rw-r--r-- | gold/powerpc.cc | 3 | ||||
-rw-r--r-- | gold/reloc.cc | 54 | ||||
-rw-r--r-- | gold/sparc.cc | 3 | ||||
-rw-r--r-- | gold/symtab.cc | 16 | ||||
-rw-r--r-- | gold/target-reloc.h | 32 | ||||
-rw-r--r-- | gold/x86_64.cc | 3 |
17 files changed, 377 insertions, 285 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index f0f2c13..788a941 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,74 @@ +2008-07-10 Ian Lance Taylor <iant@google.com> + + 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. + 2008-07-03 Ian Lance Taylor <iant@google.com> * layout.cc (Layout::include_section): Do not discard unrecognized diff --git a/gold/copy-relocs.cc b/gold/copy-relocs.cc index c6cd994..80b50df 100644 --- a/gold/copy-relocs.cc +++ b/gold/copy-relocs.cc @@ -58,7 +58,7 @@ Copy_relocs<sh_type, size, big_endian>::copy_reloc( Symbol_table* symtab, Layout* layout, Sized_symbol<size>* sym, - Relobj* object, + Sized_relobj<size, big_endian>* object, unsigned int shndx, Output_section *output_section, const Reloc& rel, @@ -81,7 +81,7 @@ template<int sh_type, int size, bool big_endian> bool Copy_relocs<sh_type, size, big_endian>::need_copy_reloc( Sized_symbol<size>* sym, - Relobj* object, + Sized_relobj<size, big_endian>* object, unsigned int shndx) const { // FIXME: Handle -z nocopyrelocs. @@ -172,10 +172,12 @@ Copy_relocs<sh_type, size, big_endian>::add_copy_reloc( template<int sh_type, int size, bool big_endian> void -Copy_relocs<sh_type, size, big_endian>::save(Symbol* sym, Relobj* object, - unsigned int shndx, - Output_section* output_section, - const Reloc& rel) +Copy_relocs<sh_type, size, big_endian>::save( + Symbol* sym, + Sized_relobj<size, big_endian>* object, + unsigned int shndx, + Output_section* output_section, + const Reloc& rel) { unsigned int reloc_type = elfcpp::elf_r_type<size>(rel.get_r_info()); typename elfcpp::Elf_types<size>::Elf_Addr addend = diff --git a/gold/copy-relocs.h b/gold/copy-relocs.h index b7d0f5f..2fe6a24 100644 --- a/gold/copy-relocs.h +++ b/gold/copy-relocs.h @@ -65,7 +65,8 @@ class Copy_relocs // will wind up. REL is the reloc itself. The Output_data_reloc // section is where the dynamic relocs are put. void - copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>* sym, Relobj* object, + copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>* sym, + Sized_relobj<size, big_endian>* object, unsigned int shndx, Output_section* output_section, const Reloc& rel, Output_data_reloc<sh_type, true, size, big_endian>*); @@ -91,7 +92,8 @@ class Copy_relocs { public: Copy_reloc_entry(Symbol* sym, unsigned int reloc_type, - Relobj* relobj, unsigned int shndx, + Sized_relobj<size, big_endian>* relobj, + unsigned int shndx, Output_section* output_section, Address address, Addend addend) : sym_(sym), reloc_type_(reloc_type), relobj_(relobj), @@ -108,7 +110,7 @@ class Copy_relocs private: Symbol* sym_; unsigned int reloc_type_; - Relobj* relobj_; + Sized_relobj<size, big_endian>* relobj_; unsigned int shndx_; Output_section* output_section_; Address address_; @@ -120,7 +122,8 @@ class Copy_relocs // Return whether we need a COPY reloc. bool - need_copy_reloc(Sized_symbol<size>* gsym, Relobj* object, + need_copy_reloc(Sized_symbol<size>* gsym, + Sized_relobj<size, big_endian>* object, unsigned int shndx) const; // Emit a COPY reloc. @@ -135,8 +138,8 @@ class Copy_relocs // Save a reloc against SYM for possible emission later. void - save(Symbol*, Relobj*, unsigned int shndx, Output_section*, - const Reloc& rel); + save(Symbol*, Sized_relobj<size, big_endian>*, unsigned int shndx, + Output_section*, const Reloc& rel); // The target specific relocation type of the COPY relocation. const unsigned int copy_reloc_type_; diff --git a/gold/i386.cc b/gold/i386.cc index 948b5d6..2ccc3f9 100644 --- a/gold/i386.cc +++ b/gold/i386.cc @@ -357,7 +357,8 @@ class Target_i386 : public Sized_target<32, false> // Add a potential copy relocation. void - copy_reloc(Symbol_table* symtab, Layout* layout, Relobj* object, + copy_reloc(Symbol_table* symtab, Layout* layout, + Sized_relobj<32, false>* object, unsigned int shndx, Output_section* output_section, Symbol* sym, const elfcpp::Rel<32, false>& reloc) { diff --git a/gold/layout.cc b/gold/layout.cc index 62ccaae..13518d6 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -448,6 +448,8 @@ Layout::layout(Sized_relobj<size, big_endian>* object, unsigned int shndx, const char* name, const elfcpp::Shdr<size, big_endian>& shdr, unsigned int reloc_shndx, unsigned int, off_t* off) { + *off = 0; + if (!this->include_section(object, name, shdr)) return NULL; diff --git a/gold/mapfile.cc b/gold/mapfile.cc index e053419..3f1fe28 100644 --- a/gold/mapfile.cc +++ b/gold/mapfile.cc @@ -256,12 +256,10 @@ Mapfile::print_input_section(Relobj* relobj, unsigned int shndx) } else { - section_offset_type offset; - os = relobj->output_section(shndx, &offset); - if (offset == -1) - addr = ~0ULL; - else - addr = os->address() + offset; + os = relobj->output_section(shndx); + addr = relobj->output_section_offset(shndx); + if (addr != -1U) + addr += os->address(); } char sizebuf[50]; diff --git a/gold/merge.h b/gold/merge.h index 2aeff1e..fb6721d 100644 --- a/gold/merge.h +++ b/gold/merge.h @@ -38,7 +38,7 @@ class Merge_map; // For each object with merge sections, we store an Object_merge_map. // This is used to map locations in input sections to a merged output // section. The output section itself is not recorded here--it can be -// found in the map_to_output_ field of the Object. +// found in the output_sections_ field of the Object. class Object_merge_map { 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; diff --git a/gold/object.h b/gold/object.h index 4a01843..df509b2 100644 --- a/gold/object.h +++ b/gold/object.h @@ -560,9 +560,7 @@ class Relobj : public Object public: Relobj(const std::string& name, Input_file* input_file, off_t offset = 0) : Object(name, input_file, false, offset), - map_to_output_(), - comdat_groups_(), - kept_comdat_sections_(), + output_sections_(), map_to_relocatable_relocs_(NULL), object_merge_map_(NULL), relocs_must_follow_section_writes_(false) @@ -619,39 +617,31 @@ class Relobj : public Object bool is_section_included(unsigned int shndx) const { - gold_assert(shndx < this->map_to_output_.size()); - return this->map_to_output_[shndx].output_section != NULL; + gold_assert(shndx < this->output_sections_.size()); + return this->output_sections_[shndx] != NULL; } - // Return whether an input section requires special - // handling--whether it is not simply mapped from the input file to - // the output file. - bool - is_section_specially_mapped(unsigned int shndx) const + // Given a section index, return the corresponding Output_section. + // The return value will be NULL if the section is not included in + // the link. + Output_section* + output_section(unsigned int shndx) const { - gold_assert(shndx < this->map_to_output_.size()); - return (this->map_to_output_[shndx].output_section != NULL - && this->map_to_output_[shndx].offset == -1); + gold_assert(shndx < this->output_sections_.size()); + return this->output_sections_[shndx]; } - // Given a section index, return the corresponding Output_section - // (which will be NULL if the section is not included in the link) - // and set *POFF to the offset within that section. *POFF will be - // set to -1 if the section requires special handling. - inline Output_section* - output_section(unsigned int shndx, section_offset_type* poff) const; + // Given a section index, return the offset in the Output_section. + // The return value will be -1U if the section is specially mapped, + // such as a merge section. + uint64_t + output_section_offset(unsigned int shndx) const + { return this->do_output_section_offset(shndx); } // Set the offset of an input section within its output section. - void - set_section_offset(unsigned int shndx, section_offset_type off) - { - gold_assert(shndx < this->map_to_output_.size()); - this->map_to_output_[shndx].offset = off; - } - - // Return the output address of the input section SHNDX. - uint64_t - output_section_address(unsigned int shndx) const; + virtual void + set_section_offset(unsigned int shndx, uint64_t off) + { this->do_set_section_offset(shndx, off); } // Return true if we need to wait for output sections to be written // before we can apply relocations. This is true if the object has @@ -690,54 +680,11 @@ class Relobj : public Object return (*this->map_to_relocatable_relocs_)[reloc_shndx]; } - // Information needed to keep track of kept comdat groups. This is - // simply a map from the section name to its section index. This may - // not be a one-to-one mapping, but we ignore that possibility since - // this is used only to attempt to handle stray relocations from - // non-comdat debug sections that refer to comdat loadable sections. - typedef Unordered_map<std::string, unsigned int> Comdat_group; - - // Find a comdat group table given its group section SHNDX. - Comdat_group* - find_comdat_group(unsigned int shndx) const - { - Comdat_group_table::const_iterator p = - this->comdat_groups_.find(shndx); - if (p != this->comdat_groups_.end()) - return p->second; - return NULL; - } - protected: - // What we need to know to map an input section to an output - // section. We keep an array of these, one for each input section, - // indexed by the input section number. - struct Map_to_output - { - // The output section. This is NULL if the input section is to be - // discarded. - Output_section* output_section; - // The offset within the output section. This is -1 if the - // section requires special handling. - section_offset_type offset; - }; - - // A map from group section index to the table of group members. - typedef std::map<unsigned int, Comdat_group*> Comdat_group_table; - - // To keep track of discarded comdat sections, we need to map a member - // section index to the object and section index of the corresponding - // kept section. - struct Kept_comdat_section - { - Kept_comdat_section(Relobj* object, unsigned int shndx) - : object_(object), shndx_(shndx) - { } - Relobj* object_; - unsigned int shndx_; - }; - typedef std::map<unsigned int, Kept_comdat_section*> - Kept_comdat_section_table; + // The output section to be used for each input section, indexed by + // the input section number. The output section is NULL if the + // input section is to be discarded. + typedef std::vector<Output_section*> Output_sections; // Read the relocs--implemented by child class. virtual void @@ -777,38 +724,22 @@ class Relobj : public Object do_relocate(const General_options& options, const Symbol_table* symtab, const Layout*, Output_file* of) = 0; - // Return the vector mapping input sections to output sections. - std::vector<Map_to_output>& - map_to_output() - { return this->map_to_output_; } - - const std::vector<Map_to_output>& - map_to_output() const - { return this->map_to_output_; } + // Get the offset of a section--implemented by child class. + virtual uint64_t + do_output_section_offset(unsigned int shndx) const = 0; - // Record a new comdat group whose group section index is SHNDX. - void - add_comdat_group(unsigned int shndx, Comdat_group* group) - { this->comdat_groups_[shndx] = group; } + // Set the offset of a section--implemented by child class. + virtual void + do_set_section_offset(unsigned int shndx, uint64_t off) = 0; - // Record a mapping from discarded section SHNDX to the corresponding - // kept section. - void - set_kept_comdat_section(unsigned int shndx, Kept_comdat_section* kept) - { - this->kept_comdat_sections_[shndx] = kept; - } + // Return the vector mapping input sections to output sections. + Output_sections& + output_sections() + { return this->output_sections_; } - // Find the kept section corresponding to the discarded section SHNDX. - Kept_comdat_section* - get_kept_comdat_section(unsigned int shndx) const - { - Kept_comdat_section_table::const_iterator p = - this->kept_comdat_sections_.find(shndx); - if (p == this->kept_comdat_sections_.end()) - return NULL; - return p->second; - } + const Output_sections& + output_sections() const + { return this->output_sections_; } // Set the size of the relocatable relocs array. void @@ -826,11 +757,7 @@ class Relobj : public Object private: // Mapping from input sections to output section. - std::vector<Map_to_output> map_to_output_; - // Table of kept comdat groups. - Comdat_group_table comdat_groups_; - // Table mapping discarded comdat sections to corresponding kept sections. - Kept_comdat_section_table kept_comdat_sections_; + Output_sections output_sections_; // Mapping from input section index to the information recorded for // the relocations. This is only used for a relocatable link. std::vector<Relocatable_relocs*>* map_to_relocatable_relocs_; @@ -842,16 +769,6 @@ class Relobj : public Object bool relocs_must_follow_section_writes_; }; -// Implement Object::output_section inline for efficiency. -inline Output_section* -Relobj::output_section(unsigned int shndx, section_offset_type* poff) const -{ - gold_assert(shndx < this->map_to_output_.size()); - const Map_to_output& mo(this->map_to_output_[shndx]); - *poff = mo.offset; - return mo.output_section; -} - // This class is used to handle relocations against a section symbol // in an SHF_MERGE section. For such a symbol, we need to know the // addend of the relocation before we can determine the final value. @@ -1356,6 +1273,17 @@ class Sized_relobj : public Relobj } } + // Get the offset of input section SHNDX within its output section. + // This is -1 if the input section requires a special mapping, such + // as a merge section. The output section can be found in the + // output_sections_ field of the parent class Relobj. + Address + get_output_section_offset(unsigned int shndx) const + { + gold_assert(shndx < this->section_offsets_.size()); + return this->section_offsets_[shndx]; + } + // Return the name of the symbol that spans the given offset in the // specified section in this object. This is used only for error // messages and is not particularly efficient. @@ -1467,6 +1395,19 @@ class Sized_relobj : public Relobj Xindex* do_initialize_xindex(); + // Get the offset of a section. + uint64_t + do_output_section_offset(unsigned int shndx) const + { return this->get_output_section_offset(shndx); } + + // Set the offset of a section. + void + do_set_section_offset(unsigned int shndx, uint64_t off) + { + gold_assert(shndx < this->section_offsets_.size()); + this->section_offsets_[shndx] = convert_types<Address, uint64_t>(off); + } + private: // For convenience. typedef Sized_relobj<size, big_endian> This; @@ -1475,6 +1416,47 @@ class Sized_relobj : public Relobj static const int sym_size = elfcpp::Elf_sizes<size>::sym_size; typedef elfcpp::Shdr<size, big_endian> Shdr; + // To keep track of discarded comdat sections, we need to map a member + // section index to the object and section index of the corresponding + // kept section. + struct Kept_comdat_section + { + Kept_comdat_section(Sized_relobj<size, big_endian>* object, + unsigned int shndx) + : object_(object), shndx_(shndx) + { } + Sized_relobj<size, big_endian>* object_; + unsigned int shndx_; + }; + typedef std::map<unsigned int, Kept_comdat_section*> + Kept_comdat_section_table; + + // Information needed to keep track of kept comdat groups. This is + // simply a map from the section name to its section index. This may + // not be a one-to-one mapping, but we ignore that possibility since + // this is used only to attempt to handle stray relocations from + // non-comdat debug sections that refer to comdat loadable sections. + typedef Unordered_map<std::string, unsigned int> Comdat_group; + + // A map from group section index to the table of group members. + typedef std::map<unsigned int, Comdat_group*> Comdat_group_table; + + // Find a comdat group table given its group section SHNDX. + Comdat_group* + find_comdat_group(unsigned int shndx) const + { + Comdat_group_table::const_iterator p = + this->comdat_groups_.find(shndx); + if (p != this->comdat_groups_.end()) + return p->second; + return NULL; + } + + // Record a new comdat group whose group section index is SHNDX. + void + add_comdat_group(unsigned int shndx, Comdat_group* group) + { this->comdat_groups_[shndx] = group; } + // Adjust a section index if necessary. unsigned int adjust_shndx(unsigned int shndx) @@ -1552,7 +1534,7 @@ class Sized_relobj : public Relobj void emit_relocs(const Relocate_info<size, big_endian>*, unsigned int, unsigned int sh_type, const unsigned char* prelocs, - size_t reloc_count, Output_section*, off_t output_offset, + size_t reloc_count, Output_section*, Address output_offset, unsigned char* view, Address address, section_size_type view_size, unsigned char* reloc_view, section_size_type reloc_view_size); @@ -1563,7 +1545,7 @@ class Sized_relobj : public Relobj void emit_relocs_reltype(const Relocate_info<size, big_endian>*, unsigned int, const unsigned char* prelocs, size_t reloc_count, - Output_section*, off_t output_offset, + Output_section*, Address output_offset, unsigned char* view, Address address, section_size_type view_size, unsigned char* reloc_view, @@ -1595,6 +1577,25 @@ class Sized_relobj : public Relobj this->local_got_offsets_.clear(); } + // Record a mapping from discarded section SHNDX to the corresponding + // kept section. + void + set_kept_comdat_section(unsigned int shndx, Kept_comdat_section* kept) + { + this->kept_comdat_sections_[shndx] = kept; + } + + // Find the kept section corresponding to the discarded section SHNDX. + Kept_comdat_section* + get_kept_comdat_section(unsigned int shndx) const + { + typename Kept_comdat_section_table::const_iterator p = + this->kept_comdat_sections_.find(shndx); + if (p == this->kept_comdat_sections_.end()) + return NULL; + return p->second; + } + // The GOT offsets of local symbols. This map also stores GOT offsets // for tp-relative offsets for TLS symbols. typedef Unordered_map<unsigned int, Got_offset_list*> Local_got_offsets; @@ -1636,6 +1637,14 @@ class Sized_relobj : public Relobj // GOT offsets for local non-TLS symbols, and tp-relative offsets // for TLS symbols, indexed by symbol number. Local_got_offsets local_got_offsets_; + // For each input section, the offset of the input section in its + // output section. This is -1U if the input section requires a + // special mapping. + std::vector<Address> section_offsets_; + // Table mapping discarded comdat sections to corresponding kept sections. + Kept_comdat_section_table kept_comdat_sections_; + // Table of kept comdat groups. + Comdat_group_table comdat_groups_; // Whether this object has a GNU style .eh_frame section. bool has_eh_frame_; }; diff --git a/gold/output.cc b/gold/output.cc index a3dab39..6ec4aef 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -617,7 +617,7 @@ template<bool dynamic, int size, bool big_endian> Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc( Symbol* gsym, unsigned int type, - Relobj* relobj, + Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address, bool is_relative) @@ -707,7 +707,7 @@ template<bool dynamic, int size, bool big_endian> Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc( Output_section* os, unsigned int type, - Relobj* relobj, + Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address) : address_(address), local_sym_index_(SECTION_CODE), type_(type), @@ -755,12 +755,7 @@ set_needs_dynsym_index() if (!this->is_section_symbol_) this->u1_.relobj->set_needs_output_dynsym_entry(lsi); else - { - section_offset_type dummy; - Output_section* os = this->u1_.relobj->output_section(lsi, &dummy); - gold_assert(os != NULL); - os->set_needs_dynsym_index(); - } + this->u1_.relobj->output_section(lsi)->set_needs_dynsym_index(); } break; } @@ -812,8 +807,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_symbol_index() } else { - section_offset_type dummy; - Output_section* os = this->u1_.relobj->output_section(lsi, &dummy); + Output_section* os = this->u1_.relobj->output_section(lsi); gold_assert(os != NULL); if (dynamic) index = os->dynsym_index(); @@ -831,7 +825,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_symbol_index() // within the input section. template<bool dynamic, int size, bool big_endian> -section_offset_type +typename elfcpp::Elf_types<size>::Elf_Addr Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>:: local_section_offset(Addend addend) const { @@ -840,14 +834,14 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>:: && this->local_sym_index_ != INVALID_CODE && this->is_section_symbol_); const unsigned int lsi = this->local_sym_index_; - section_offset_type offset; - Output_section* os = this->u1_.relobj->output_section(lsi, &offset); + Output_section* os = this->u1_.relobj->output_section(lsi); gold_assert(os != NULL); - if (offset != -1) + Address offset = this->u1_.relobj->get_output_section_offset(lsi); + if (offset != -1U) return offset + addend; // This is a merge section. offset = os->output_address(this->u1_.relobj, lsi, addend); - gold_assert(offset != -1); + gold_assert(offset != -1U); return offset; } @@ -860,11 +854,10 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_address() const Address address = this->address_; if (this->shndx_ != INVALID_CODE) { - section_offset_type off; - Output_section* os = this->u2_.relobj->output_section(this->shndx_, - &off); + Output_section* os = this->u2_.relobj->output_section(this->shndx_); gold_assert(os != NULL); - if (off != -1) + Address off = this->u2_.relobj->get_output_section_offset(this->shndx_); + if (off != -1U) address += os->address() + off; else { @@ -1094,8 +1087,7 @@ Output_data_group<size, big_endian>::do_write(Output_file* of) p != this->input_shndxes_.end(); ++p, ++contents) { - section_offset_type dummy; - Output_section* os = this->relobj_->output_section(*p, &dummy); + Output_section* os = this->relobj_->output_section(*p); unsigned int output_shndx; if (os != NULL) @@ -1358,8 +1350,7 @@ Output_data_got<size, big_endian>::add_local_pair_with_rel( this->entries_.push_back(Got_entry()); unsigned int got_offset = this->last_got_offset(); object->set_local_got_offset(symndx, got_type, got_offset); - section_offset_type off; - Output_section* os = object->output_section(shndx, &off); + Output_section* os = object->output_section(shndx); rel_dyn->add_output_section(os, r_type_1, this, got_offset); this->entries_.push_back(Got_entry(object, symndx)); @@ -1389,8 +1380,7 @@ Output_data_got<size, big_endian>::add_local_pair_with_rela( this->entries_.push_back(Got_entry()); unsigned int got_offset = this->last_got_offset(); object->set_local_got_offset(symndx, got_type, got_offset); - section_offset_type off; - Output_section* os = object->output_section(shndx, &off); + Output_section* os = object->output_section(shndx); rela_dyn->add_output_section(os, r_type_1, this, got_offset, 0); this->entries_.push_back(Got_entry(object, symndx)); @@ -1995,8 +1985,6 @@ Output_section::is_input_address_mapped(const Relobj* object, unsigned int shndx, off_t offset) const { - gold_assert(object->is_section_specially_mapped(shndx)); - for (Input_section_list::const_iterator p = this->input_sections_.begin(); p != this->input_sections_.end(); ++p) @@ -2021,7 +2009,6 @@ section_offset_type Output_section::output_offset(const Relobj* object, unsigned int shndx, section_offset_type offset) const { - gold_assert(object->is_section_specially_mapped(shndx)); // This can only be called meaningfully when layout is complete. gold_assert(Output_data::is_layout_complete()); @@ -2043,8 +2030,6 @@ uint64_t Output_section::output_address(const Relobj* object, unsigned int shndx, off_t offset) 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(); @@ -2076,8 +2061,6 @@ 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(); diff --git a/gold/output.h b/gold/output.h index 952f24f..e2c41c7 100644 --- a/gold/output.h +++ b/gold/output.h @@ -890,7 +890,8 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> Output_reloc(Symbol* gsym, unsigned int type, Output_data* od, Address address, bool is_relative); - Output_reloc(Symbol* gsym, unsigned int type, Relobj* relobj, + Output_reloc(Symbol* gsym, unsigned int type, + Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address, bool is_relative); // A reloc against a local symbol or local section symbol. @@ -910,7 +911,8 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> Output_reloc(Output_section* os, unsigned int type, Output_data* od, Address address); - Output_reloc(Output_section* os, unsigned int type, Relobj* relobj, + Output_reloc(Output_section* os, unsigned int type, + Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address); // Return TRUE if this is a RELATIVE relocation. @@ -931,7 +933,7 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> // For a local section symbol, return the offset of the input // section within the output section. ADDEND is the addend being // applied to the input section. - section_offset_type + Address local_section_offset(Addend addend) const; // Get the value of the symbol referred to by a Rel relocation when @@ -1004,7 +1006,7 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> { // If this->shndx_ is not INVALID CODE, the object which holds the // input section being used to specify the reloc address. - Relobj* relobj; + Sized_relobj<size, big_endian>* relobj; // If this->shndx_ is INVALID_CODE, the output data being used to // specify the reloc address. This may be NULL if the reloc // address is absolute. @@ -1053,7 +1055,8 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> : rel_(gsym, type, od, address, is_relative), addend_(addend) { } - Output_reloc(Symbol* gsym, unsigned int type, Relobj* relobj, + Output_reloc(Symbol* gsym, unsigned int type, + Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address, Addend addend, bool is_relative) : rel_(gsym, type, relobj, shndx, address, is_relative), addend_(addend) @@ -1086,7 +1089,8 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> : rel_(os, type, od, address), addend_(addend) { } - Output_reloc(Output_section* os, unsigned int type, Relobj* relobj, + Output_reloc(Output_section* os, unsigned int type, + Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address, Addend addend) : rel_(os, type, relobj, shndx, address), addend_(addend) { } @@ -1215,7 +1219,8 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> { this->add(od, Output_reloc_type(gsym, type, od, address, false)); } void - add_global(Symbol* gsym, unsigned int type, Output_data* od, Relobj* relobj, + add_global(Symbol* gsym, unsigned int type, Output_data* od, + Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address) { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, false)); } @@ -1231,7 +1236,8 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> } void - add_global(Symbol* gsym, unsigned int type, Output_data* od, Relobj* relobj, + add_global(Symbol* gsym, unsigned int type, Output_data* od, + Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address, Address addend) { gold_assert(addend == 0); @@ -1248,7 +1254,8 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> void add_global_relative(Symbol* gsym, unsigned int type, Output_data* od, - Relobj* relobj, unsigned int shndx, Address address) + Sized_relobj<size, big_endian>* relobj, + unsigned int shndx, Address address) { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, true)); @@ -1327,7 +1334,8 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> void add_output_section(Output_section* os, unsigned int type, Output_data* od, - Relobj* relobj, unsigned int shndx, Address address) + Sized_relobj<size, big_endian>* relobj, + unsigned int shndx, Address address) { this->add(od, Output_reloc_type(os, type, relobj, shndx, address)); } }; @@ -1359,7 +1367,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> false)); } void - add_global(Symbol* gsym, unsigned int type, Output_data* od, Relobj* relobj, + add_global(Symbol* gsym, unsigned int type, Output_data* od, + Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address, Addend addend) { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, @@ -1377,8 +1386,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> void add_global_relative(Symbol* gsym, unsigned int type, Output_data* od, - Relobj* relobj, unsigned int shndx, Address address, - Addend addend) + Sized_relobj<size, big_endian>* relobj, + unsigned int shndx, Address address, Addend addend) { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, addend, true)); } @@ -1455,7 +1464,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> { this->add(os, Output_reloc_type(os, type, od, address, addend)); } void - add_output_section(Output_section* os, unsigned int type, Relobj* relobj, + add_output_section(Output_section* os, unsigned int type, + Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address, Addend addend) { this->add(os, Output_reloc_type(os, type, relobj, shndx, address, addend)); } diff --git a/gold/powerpc.cc b/gold/powerpc.cc index 4e7406e..d69e942 100644 --- a/gold/powerpc.cc +++ b/gold/powerpc.cc @@ -280,7 +280,8 @@ class Target_powerpc : public Sized_target<size, big_endian> // Copy a relocation against a global symbol. void - copy_reloc(Symbol_table* symtab, Layout* layout, Relobj* object, + copy_reloc(Symbol_table* symtab, Layout* layout, + Sized_relobj<size, big_endian>* object, unsigned int shndx, Output_section* output_section, Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc) { diff --git a/gold/reloc.cc b/gold/reloc.cc index b44dd72..daa0ea8 100644 --- a/gold/reloc.cc +++ b/gold/reloc.cc @@ -193,7 +193,8 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd) rd->relocs.reserve(shnum / 2); - std::vector<Map_to_output>& map_sections(this->map_to_output()); + const Output_sections& out_sections(this->output_sections()); + const std::vector<Address>& out_offsets(this->section_offsets_); const unsigned char *pshdrs = this->get_view(this->elf_file_.shoff(), shnum * This::shdr_size, @@ -216,7 +217,7 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd) continue; } - Output_section* os = map_sections[shndx].output_section; + Output_section* os = out_sections[shndx]; if (os == NULL) continue; @@ -273,7 +274,7 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd) sr.sh_type = sh_type; sr.reloc_count = reloc_count; sr.output_section = os; - sr.needs_special_offset_handling = map_sections[shndx].offset == -1; + sr.needs_special_offset_handling = out_offsets[shndx] == -1U; sr.is_data_section_allocated = is_section_allocated; } @@ -534,7 +535,8 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs, Views* pviews) { unsigned int shnum = this->shnum(); - const std::vector<Map_to_output>& map_sections(this->map_to_output()); + const Output_sections& out_sections(this->output_sections()); + const std::vector<Address>& out_offsets(this->section_offsets_); File_read::Read_multiple rm; bool is_sorted = true; @@ -546,10 +548,10 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs, pvs->view = NULL; - const Output_section* os = map_sections[i].output_section; + const Output_section* os = out_sections[i]; if (os == NULL) continue; - off_t output_offset = map_sections[i].offset; + Address output_offset = out_offsets[i]; typename This::Shdr shdr(p); @@ -584,7 +586,7 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs, // In the normal case, this input section is simply mapped to // the output section at offset OUTPUT_OFFSET. - // However, if OUTPUT_OFFSET == -1, then input data is handled + // However, if OUTPUT_OFFSET == -1U, then input data is handled // specially--e.g., a .eh_frame section. The relocation // routines need to check for each reloc where it should be // applied. For this case, we need an input/output view for the @@ -602,21 +604,22 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs, // final data to the output file. off_t output_section_offset; - off_t output_section_size; + Address output_section_size; if (!os->requires_postprocessing()) { output_section_offset = os->offset(); - output_section_size = os->data_size(); + output_section_size = convert_types<Address, off_t>(os->data_size()); } else { output_section_offset = 0; - output_section_size = os->postprocessing_buffer_size(); + output_section_size = + convert_types<Address, off_t>(os->postprocessing_buffer_size()); } off_t view_start; section_size_type view_size; - if (output_offset != -1) + if (output_offset != -1U) { view_start = output_section_offset + output_offset; view_size = convert_to_section_size_type(shdr.get_sh_size()); @@ -630,17 +633,15 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs, if (view_size == 0) continue; - gold_assert(output_offset == -1 - || (output_offset >= 0 - && (output_offset + static_cast<off_t>(view_size) - <= output_section_size))); + gold_assert(output_offset == -1U + || output_offset + view_size <= output_section_size); unsigned char* view; if (os->requires_postprocessing()) { unsigned char* buffer = os->postprocessing_buffer(); view = buffer + view_start; - if (output_offset != -1) + if (output_offset != -1U) { off_t sh_offset = shdr.get_sh_offset(); if (!rm.empty() && rm.back().file_offset > sh_offset) @@ -651,7 +652,7 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs, } else { - if (output_offset == -1) + if (output_offset == -1U) view = of->get_input_output_view(view_start, view_size); else { @@ -666,11 +667,11 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs, pvs->view = view; pvs->address = os->address(); - if (output_offset != -1) + if (output_offset != -1U) pvs->address += output_offset; pvs->offset = view_start; pvs->view_size = view_size; - pvs->is_input_output_view = output_offset == -1; + pvs->is_input_output_view = output_offset == -1U; pvs->is_postprocessing_view = os->requires_postprocessing(); } @@ -698,7 +699,8 @@ Sized_relobj<size, big_endian>::relocate_sections( unsigned int shnum = this->shnum(); Sized_target<size, big_endian>* target = this->sized_target(); - const std::vector<Map_to_output>& map_sections(this->map_to_output()); + const Output_sections& out_sections(this->output_sections()); + const std::vector<Address>& out_offsets(this->section_offsets_); Relocate_info<size, big_endian> relinfo; relinfo.options = &options; @@ -723,14 +725,14 @@ Sized_relobj<size, big_endian>::relocate_sections( continue; } - Output_section* os = map_sections[index].output_section; + Output_section* os = out_sections[index]; if (os == NULL) { // This relocation section is against a section which we // discarded. continue; } - off_t output_offset = map_sections[index].offset; + Address output_offset = out_offsets[index]; gold_assert((*pviews)[index].view != NULL); if (parameters->options().relocatable()) @@ -770,7 +772,7 @@ Sized_relobj<size, big_endian>::relocate_sections( continue; } - gold_assert(output_offset != -1 + gold_assert(output_offset != -1U || this->relocs_must_follow_section_writes()); relinfo.reloc_shndx = i; @@ -782,7 +784,7 @@ Sized_relobj<size, big_endian>::relocate_sections( prelocs, reloc_count, os, - output_offset == -1, + output_offset == -1U, (*pviews)[index].view, (*pviews)[index].address, (*pviews)[index].view_size); @@ -825,7 +827,7 @@ Sized_relobj<size, big_endian>::emit_relocs( const unsigned char* prelocs, size_t reloc_count, Output_section* output_section, - off_t offset_in_output_section, + typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section, unsigned char* view, typename elfcpp::Elf_types<size>::Elf_Addr address, section_size_type view_size, @@ -861,7 +863,7 @@ Sized_relobj<size, big_endian>::emit_relocs_reltype( const unsigned char* prelocs, size_t reloc_count, Output_section* output_section, - off_t offset_in_output_section, + typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section, unsigned char* view, typename elfcpp::Elf_types<size>::Elf_Addr address, section_size_type view_size, diff --git a/gold/sparc.cc b/gold/sparc.cc index aa8bbbd..ded63da 100644 --- a/gold/sparc.cc +++ b/gold/sparc.cc @@ -296,7 +296,8 @@ class Target_sparc : public Sized_target<size, big_endian> // Copy a relocation against a global symbol. void - copy_reloc(Symbol_table* symtab, Layout* layout, Relobj* object, + copy_reloc(Symbol_table* symtab, Layout* layout, + Sized_relobj<size, big_endian>* object, unsigned int shndx, Output_section* output_section, Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc) { diff --git a/gold/symtab.cc b/gold/symtab.cc index 7b27350..33a9151 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -357,8 +357,7 @@ Symbol::output_section() const { gold_assert(!this->u_.from_object.object->is_dynamic()); Relobj* relobj = static_cast<Relobj*>(this->u_.from_object.object); - section_offset_type dummy; - return relobj->output_section(shndx, &dummy); + return relobj->output_section(shndx); } return NULL; } @@ -1943,6 +1942,8 @@ template<int size> bool Symbol_table::sized_finalize_symbol(Symbol* unsized_sym) { + typedef typename Sized_symbol<size>::Value_type Value_type; + Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(unsized_sym); // The default version of a symbol may appear twice in the symbol @@ -1958,7 +1959,7 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym) return false; } - typename Sized_symbol<size>::Value_type value; + Value_type value; switch (sym->source()) { @@ -1991,8 +1992,7 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym) else { Relobj* relobj = static_cast<Relobj*>(symobj); - section_offset_type secoff; - Output_section* os = relobj->output_section(shndx, &secoff); + Output_section* os = relobj->output_section(shndx); if (os == NULL) { @@ -2001,6 +2001,8 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym) return false; } + uint64_t secoff64 = relobj->output_section_offset(shndx); + Value_type secoff = convert_types<Value_type, uint64_t>(secoff64); if (sym->type() == elfcpp::STT_TLS) value = sym->value() + os->tls_offset() + secoff; else @@ -2208,9 +2210,7 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects, else { Relobj* relobj = static_cast<Relobj*>(symobj); - section_offset_type secoff; - Output_section* os = relobj->output_section(in_shndx, - &secoff); + Output_section* os = relobj->output_section(in_shndx); gold_assert(os != NULL); shndx = os->out_shndx(); diff --git a/gold/target-reloc.h b/gold/target-reloc.h index 15d59bb..6683ddd 100644 --- a/gold/target-reloc.h +++ b/gold/target-reloc.h @@ -417,12 +417,7 @@ scan_relocatable_relocs( { strategy = scan.local_section_strategy(r_type, object); if (strategy != Relocatable_relocs::RELOC_DISCARD) - { - section_offset_type dummy; - Output_section* os = object->output_section(shndx, - &dummy); - os->set_needs_symtab_index(); - } + object->output_section(shndx)->set_needs_symtab_index(); } } } @@ -441,7 +436,7 @@ relocate_for_relocatable( const unsigned char* prelocs, size_t reloc_count, Output_section* output_section, - off_t offset_in_output_section, + typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section, const Relocatable_relocs* rr, unsigned char* view, typename elfcpp::Elf_types<size>::Elf_Addr view_address, @@ -449,6 +444,7 @@ relocate_for_relocatable( unsigned char* reloc_view, section_size_type reloc_view_size) { + typedef typename elfcpp::Elf_types<size>::Elf_Addr Address; typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype; typedef typename Reloc_types<sh_type, size, big_endian>::Reloc_write Reltype_write; @@ -500,8 +496,7 @@ relocate_for_relocatable( unsigned int shndx = object->local_symbol_input_shndx(r_sym, &is_ordinary); gold_assert(is_ordinary); - section_offset_type dummy; - Output_section* os = object->output_section(shndx, &dummy); + Output_section* os = object->output_section(shndx); gold_assert(os != NULL); gold_assert(os->needs_symtab_index()); new_symndx = os->symtab_index(); @@ -526,16 +521,19 @@ relocate_for_relocatable( // Get the new offset--the location in the output section where // this relocation should be applied. - off_t offset = reloc.get_r_offset(); - off_t new_offset; - if (offset_in_output_section != -1) + Address offset = reloc.get_r_offset(); + Address new_offset; + if (offset_in_output_section != -1U) new_offset = offset + offset_in_output_section; else { - new_offset = output_section->output_offset(object, - relinfo->data_shndx, - offset); - gold_assert(new_offset != -1); + section_offset_type sot_offset = + convert_types<section_offset_type, Address>(offset); + section_offset_type new_sot_offset = + output_section->output_offset(object, relinfo->data_shndx, + sot_offset); + gold_assert(new_sot_offset != -1); + new_offset = new_sot_offset; } // In an object file, r_offset is an offset within the section. @@ -544,7 +542,7 @@ relocate_for_relocatable( if (!parameters->options().relocatable()) { new_offset += view_address; - if (offset_in_output_section != -1) + if (offset_in_output_section != -1U) new_offset -= offset_in_output_section; } diff --git a/gold/x86_64.cc b/gold/x86_64.cc index 356505c..c426370 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -368,7 +368,8 @@ class Target_x86_64 : public Sized_target<64, false> // Add a potential copy relocation. void - copy_reloc(Symbol_table* symtab, Layout* layout, Relobj* object, + copy_reloc(Symbol_table* symtab, Layout* layout, + Sized_relobj<64, false>* object, unsigned int shndx, Output_section* output_section, Symbol* sym, const elfcpp::Rela<64, false>& reloc) { |