This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH COMMITTED: Handle large output sections in gold


For speed on 32-bit hosts, gold holds some section offsets using the
types size_t and ptrdiff_t.  It does this when the output sections
must be in memory anyhow, as with a merged section.

Unfortunately, I made a mistake and also did this with the offset of
an input section in an output section.  This fails when the output
section is more than 0x7fffffff bytes.  This will generally not happen
for a 32-bit target, but it can reasonably happen for a 64-bit target
if the output file is very large.

This patch fixes the problem.  Previously a single structure,
Map_to_output, hold the output section and the offset within the
output section.  That structure was in Relobj.  I moved the offset
within the output section to Sized_relobj.  That permits it to remain
a 32-bit value for a 32-bit target.

The rest of the patch is fairly mechanical changes that result from
that.  The comdat group support moves to Sized_relobj.  A bunch of
pointers which converted from Relobj* to Sized_relobj* now remain as
Sized_relobj* through a series of function calls.

The biggest change is that Symbol_table::sized_finalize_symbol now
calls a virtual function to get the section offset.  If this turns out
to be a problem, we can templatize Symbol_table::sized_finalize on the
endianness and use a static cast in sized_finalize_symbol.

Ian


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.


Index: copy-relocs.cc
===================================================================
RCS file: /cvs/src/src/gold/copy-relocs.cc,v
retrieving revision 1.3
diff -u -u -p -r1.3 copy-relocs.cc
--- copy-relocs.cc	21 May 2008 21:37:44 -0000	1.3
+++ copy-relocs.cc	10 Jul 2008 23:00:43 -0000
@@ -58,7 +58,7 @@ Copy_relocs<sh_type, size, big_endian>::
     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
 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>::
 
 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: copy-relocs.h
===================================================================
RCS file: /cvs/src/src/gold/copy-relocs.h,v
retrieving revision 1.1
diff -u -u -p -r1.1 copy-relocs.h
--- copy-relocs.h	16 Apr 2008 22:54:29 -0000	1.1
+++ copy-relocs.h	10 Jul 2008 23:00:43 -0000
@@ -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: i386.cc
===================================================================
RCS file: /cvs/src/src/gold/i386.cc,v
retrieving revision 1.77
diff -u -u -p -r1.77 i386.cc
--- i386.cc	21 May 2008 21:37:44 -0000	1.77
+++ i386.cc	10 Jul 2008 23:00:43 -0000
@@ -357,7 +357,8 @@ class Target_i386 : public Sized_target<
 
   // 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: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.107
diff -u -u -p -r1.107 layout.cc
--- layout.cc	4 Jul 2008 03:34:01 -0000	1.107
+++ layout.cc	10 Jul 2008 23:00:43 -0000
@@ -448,6 +448,8 @@ Layout::layout(Sized_relobj<size, big_en
 	       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: mapfile.cc
===================================================================
RCS file: /cvs/src/src/gold/mapfile.cc,v
retrieving revision 1.1
diff -u -u -p -r1.1 mapfile.cc
--- mapfile.cc	21 May 2008 21:37:44 -0000	1.1
+++ mapfile.cc	10 Jul 2008 23:00:43 -0000
@@ -256,12 +256,10 @@ Mapfile::print_input_section(Relobj* rel
     }
   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: merge.h
===================================================================
RCS file: /cvs/src/src/gold/merge.h,v
retrieving revision 1.19
diff -u -u -p -r1.19 merge.h
--- merge.h	21 May 2008 21:37:44 -0000	1.19
+++ merge.h	10 Jul 2008 23:00:43 -0000
@@ -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: object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.75
diff -u -u -p -r1.75 object.cc
--- object.cc	25 Jun 2008 17:10:08 -0000	1.75
+++ object.cc	10 Jul 2008 23:00:43 -0000
@@ -230,18 +230,6 @@ Object::handle_gnu_warning_section(const
   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_re
     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_
   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_
       // 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_
       // 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_
       // 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_layou
 	}
     }
 
-  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_layou
       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_layou
 					  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_layou
 	  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_layou
 
       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_layou
 						   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
 
   // 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
 
       // 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_final
   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_final
       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_final
 	      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_final
               // 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_final
 	    }
           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_lo
     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_lo
 						     &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_k
     {
       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: object.h
===================================================================
RCS file: /cvs/src/src/gold/object.h,v
retrieving revision 1.60
diff -u -u -p -r1.60 object.h
--- object.h	21 May 2008 21:37:44 -0000	1.60
+++ object.h	10 Jul 2008 23:00:43 -0000
@@ -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_; }
-
-  // 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; }
+  // Get the offset of a section--implemented by child class.
+  virtual uint64_t
+  do_output_section_offset(unsigned int shndx) const = 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;
-  }
+  // Set the offset of a section--implemented by child class.
+  virtual void
+  do_set_section_offset(unsigned int shndx, uint64_t off) = 0;
 
-  // 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;
-  }
+  // Return the vector mapping input sections to output sections.
+  Output_sections&
+  output_sections()
+  { return this->output_sections_; }
+
+  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: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.79
diff -u -u -p -r1.79 output.cc
--- output.cc	21 May 2008 21:37:44 -0000	1.79
+++ output.cc	10 Jul 2008 23:00:43 -0000
@@ -617,7 +617,7 @@ template<bool dynamic, int size, bool bi
 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 bi
 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, s
           }
         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, s
 // 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, s
               && 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, s
   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_
        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_l
   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_l
   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(
 					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: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.73
diff -u -u -p -r1.73 output.h
--- output.h	18 Jun 2008 04:39:41 -0000	1.73
+++ output.h	10 Jul 2008 23:00:43 -0000
@@ -890,7 +890,8 @@ class Output_reloc<elfcpp::SHT_REL, dyna
   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, dyna
   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, dyna
   // 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, dyna
   {
     // 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, dyn
     : 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, dyn
     : 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,
   { 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,
   }
 
   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,
 
   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,
 
   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
                                     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
 
   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
   { 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: powerpc.cc
===================================================================
RCS file: /cvs/src/src/gold/powerpc.cc,v
retrieving revision 1.4
diff -u -u -p -r1.4 powerpc.cc
--- powerpc.cc	30 Jun 2008 16:36:40 -0000	1.4
+++ powerpc.cc	10 Jul 2008 23:00:43 -0000
@@ -280,7 +280,8 @@ class Target_powerpc : public Sized_targ
 
   // 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: reloc.cc
===================================================================
RCS file: /cvs/src/src/gold/reloc.cc,v
retrieving revision 1.36
diff -u -u -p -r1.36 reloc.cc
--- reloc.cc	19 Apr 2008 18:30:58 -0000	1.36
+++ reloc.cc	10 Jul 2008 23:00:43 -0000
@@ -193,7 +193,8 @@ Sized_relobj<size, big_endian>::do_read_
 
   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_
 	  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_
       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_se
 					       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_se
 
       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_se
       // 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_se
       // 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_se
       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_se
 	}
       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_se
 
       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
   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
 	  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
 	  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
 				   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_rel
     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_rel
     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: sparc.cc
===================================================================
RCS file: /cvs/src/src/gold/sparc.cc,v
retrieving revision 1.8
diff -u -u -p -r1.8 sparc.cc
--- sparc.cc	21 May 2008 21:37:44 -0000	1.8
+++ sparc.cc	10 Jul 2008 23:00:43 -0000
@@ -296,7 +296,8 @@ class Target_sparc : public Sized_target
 
   // 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: symtab.cc
===================================================================
RCS file: /cvs/src/src/gold/symtab.cc,v
retrieving revision 1.99
diff -u -u -p -r1.99 symtab.cc
--- symtab.cc	30 Jun 2008 18:16:31 -0000	1.99
+++ symtab.cc	10 Jul 2008 23:00:43 -0000
@@ -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(Symb
       return false;
     }
 
-  typename Sized_symbol<size>::Value_type value;
+  Value_type value;
 
   switch (sym->source())
     {
@@ -1991,8 +1992,7 @@ Symbol_table::sized_finalize_symbol(Symb
 	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(Symb
 		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 
 		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: target-reloc.h
===================================================================
RCS file: /cvs/src/src/gold/target-reloc.h,v
retrieving revision 1.26
diff -u -u -p -r1.26 target-reloc.h
--- target-reloc.h	29 May 2008 23:51:30 -0000	1.26
+++ target-reloc.h	10 Jul 2008 23:00:43 -0000
@@ -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: x86_64.cc
===================================================================
RCS file: /cvs/src/src/gold/x86_64.cc,v
retrieving revision 1.70
diff -u -u -p -r1.70 x86_64.cc
--- x86_64.cc	21 May 2008 21:37:44 -0000	1.70
+++ x86_64.cc	10 Jul 2008 23:00:43 -0000
@@ -368,7 +368,8 @@ class Target_x86_64 : public Sized_targe
 
   // 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)
   {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]