Handle output sections with more than 0x7fffffff bytes.
authorIan Lance Taylor <ian@airs.com>
Thu, 10 Jul 2008 23:01:20 +0000 (23:01 +0000)
committerIan Lance Taylor <ian@airs.com>
Thu, 10 Jul 2008 23:01:20 +0000 (23:01 +0000)
* 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.

17 files changed:
gold/ChangeLog
gold/copy-relocs.cc
gold/copy-relocs.h
gold/i386.cc
gold/layout.cc
gold/mapfile.cc
gold/merge.h
gold/object.cc
gold/object.h
gold/output.cc
gold/output.h
gold/powerpc.cc
gold/reloc.cc
gold/sparc.cc
gold/symtab.cc
gold/target-reloc.h
gold/x86_64.cc

index f0f2c13f55745d3a566c3ea307735cec00f671ab..788a9410c8cb7cd9fb4a0c0e9499750a882adf30 100644 (file)
@@ -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
index c6cd994f8d937a7bc99d09884f848b4c471582ca..80b50df8838ca8a4bc3863f42a06a063bd9401a4 100644 (file)
@@ -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 =
index b7d0f5fb4f0be3a892f005ea28a1d8f167540290..2fe6a245e072f0295ee6b394f67260c33d55d5cb 100644 (file)
@@ -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_;
index 948b5d6598c6869dbdb3d7c98175c0c793be476f..2ccc3f9f7e20186a4ff25c843b3b6d707d9dc54e 100644 (file)
@@ -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)
   {
index 62ccaae2b1ea450b7c3f0cdeabc3e8948d85cd3f..13518d66299fa232a777199a872d7fecb0221c79 100644 (file)
@@ -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;
 
index e053419c092698e283b710d25c15fbf7ae30ef1c..3f1fe285cf48e40380d61f40948194aa0130534a 100644 (file)
@@ -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];
index 2aeff1e6fa18cfeec4db6395840cd16c4e93b3f2..fb6721d2925da70c63a5f5e2f1c785af8fec1cb6 100644 (file)
@@ -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
 {
index 8659cb24ba54e3e5cb07d2cb861f7460fc7983c0..2ecb8a9e915e93062fe01f944be5b34851df9ce4 100644 (file)
@@ -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;
index 4a01843bd9da98cf9dba94ca03a7d546003006da..df509b23de900d3cf28c127fc1d3bab880e37ac6 100644 (file)
@@ -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_;
 };
index a3dab399ad56c4ddca15dabe9f801074adfb4ac8..6ec4aef6601b02e02d32e6f38986b8daf8426a56 100644 (file)
@@ -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();
index 952f24f15034ba09de5445347d11ab30a1acbb2d..e2c41c7d7da74cecfda02676ff72a330b97ea4be 100644 (file)
@@ -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)); }
index 4e7406eb837d103c16570b6dc3bc8a04d6bf5f48..d69e94260875e154da999b24565040900fcdcd6b 100644 (file)
@@ -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)
   {
index b44dd721b1d1b4f3a3d2a15606e498b53121f842..daa0ea88ae3566b09a4776dbbbfe1c3deb1d7e63 100644 (file)
@@ -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,
index aa8bbbd912e2d765cdf8402a7c2ac7a22ca6b67e..ded63daf30d1d5ddc171b7678e25673ecc983bc2 100644 (file)
@@ -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)
   {
index 7b27350e5f423289da39b470707fdcfaa697d001..33a9151c3fd30daf21d65831dc009daebfa33de7 100644 (file)
@@ -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();
 
index 15d59bb9019dad431ba79ded5f8b915767ba16b3..6683ddd05fd9294cda2e6be50a00f5a9cb84804c 100644 (file)
@@ -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;
        }
 
index 356505c18355acd0b91bc34f989f88e9f18d890b..c4263706e6b2964e122b7fc837d1270afcfc794d 100644 (file)
@@ -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)
   {