2009-12-16 Doug Kwan <dougkwan@google.com>
authorDoug Kwan <dougkwan@google.com>
Thu, 17 Dec 2009 00:00:26 +0000 (00:00 +0000)
committerDoug Kwan <dougkwan@google.com>
Thu, 17 Dec 2009 00:00:26 +0000 (00:00 +0000)
* arm.cc (Arm_relobj::scan_sections_for_stubs): Exclude ICF-eliminated
sections.
* object.cc (Sized_relobj::do_finalize_local_symbols): Handle
relaxed input sections.
* output.cc (Output_section::find_relaxed_input_section): Change
return type to Output_relaxed_input_section pointer.  Adjust code
for new type of relaxed_input_section_map_.
* output.h (Output_section::find_relaxed_input_section): Change
return type to Output_relaxed_input_section pointer.
(Output_section::Output_relaxed_input_section_by_input_section_map):
New type.
(Output_section::relaxed_input_section_map_): Change type to
Output_section::Output_relaxed_input_section_by_input_section_map.
* symtab.cc (Symbol_table::compute_final_value): Handle relaxed
input section.

gold/ChangeLog
gold/arm.cc
gold/object.cc
gold/output.cc
gold/output.h
gold/symtab.cc

index 86ed4e8f6f5d6434333498867a097d4ecc5c705f..b6cd629ab5171321b07bc2ca7e7ad50e8047be6a 100644 (file)
@@ -1,3 +1,21 @@
+2009-12-16  Doug Kwan  <dougkwan@google.com>
+
+       * arm.cc (Arm_relobj::scan_sections_for_stubs): Exclude ICF-eliminated
+       sections.
+       * object.cc (Sized_relobj::do_finalize_local_symbols): Handle
+       relaxed input sections.
+       * output.cc (Output_section::find_relaxed_input_section): Change
+       return type to Output_relaxed_input_section pointer.  Adjust code
+       for new type of relaxed_input_section_map_.
+       * output.h (Output_section::find_relaxed_input_section): Change
+       return type to Output_relaxed_input_section pointer.
+       (Output_section::Output_relaxed_input_section_by_input_section_map):
+       New type.
+       (Output_section::relaxed_input_section_map_): Change type to
+       Output_section::Output_relaxed_input_section_by_input_section_map.
+       * symtab.cc (Symbol_table::compute_final_value): Handle relaxed
+       input section.
+
 2009-12-15  Ian Lance Taylor  <iant@google.com>
 
        * layout.cc (Layout::create_shstrtab): Only write out after input
index 03cc69798f6f47cc531caea31676d4c6bc27889e..b02afbe23eac875afb88bf7c6a3c986e72cd7b0b 100644 (file)
@@ -3645,10 +3645,12 @@ Arm_relobj<big_endian>::scan_sections_for_stubs(
        }
 
       Output_section* os = out_sections[index];
-      if (os == NULL)
+      if (os == NULL
+         || symtab->is_section_folded(this, index))
        {
          // This relocation section is against a section which we
-         // discarded.
+         // discarded or if the section is folded into another
+         // section due to ICF.
          continue;
        }
       Arm_address output_offset = this->get_output_section_offset(index);
index 798e42d808d124398b40232a9e7a9e34b5767522..9baf22768d96a5d97dd273de043a6fcd679e2817 100644 (file)
@@ -1683,7 +1683,15 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
               os = folded_obj->output_section(folded.second);
               gold_assert(os != NULL);
               secoffset = folded_obj->get_output_section_offset(folded.second);
-              gold_assert(secoffset != invalid_address);
+
+             // This could be a relaxed input section.
+              if (secoffset == invalid_address)
+               {
+                 const Output_relaxed_input_section* relaxed_section =
+                   os->find_relaxed_input_section(folded_obj, folded.second);
+                 gold_assert(relaxed_section != NULL);
+                 secoffset = relaxed_section->address() - os->address();
+               }
             }
 
          if (os == NULL)
index 61c2ba6f4b1b4b6814a824386a696f48470fa6c7..440d4f2b579842e7f65e4c08dd586e953673c2af 100644 (file)
@@ -2224,7 +2224,7 @@ Output_section::find_merge_section(const Relobj* object,
 // Find an relaxed input section corresponding to an input section
 // in OBJECT with index SHNDX.
 
-const Output_section_data*
+const Output_relaxed_input_section*
 Output_section::find_relaxed_input_section(const Relobj* object,
                                           unsigned int shndx) const
 {
@@ -2247,7 +2247,7 @@ Output_section::find_relaxed_input_section(const Relobj* object,
     }
 
   Input_section_specifier iss(object, shndx);
-  Output_section_data_by_input_section_map::const_iterator p =
+  Output_relaxed_input_section_by_input_section_map::const_iterator p =
     this->relaxed_input_section_map_.find(iss);
   if (p != this->relaxed_input_section_map_.end())
     return p->second;
index 6631aa1e8495f856a73b4e48aa462385fa2402a7..3b060c8658457ccd228490fd9e588675128ed1ca 100644 (file)
@@ -2599,7 +2599,7 @@ class Output_section : public Output_data
 
   // Find a relaxed input section to an input section in OBJECT
   // with index SHNDX.  Return NULL if none is found.
-  const Output_section_data*
+  const Output_relaxed_input_section*
   find_relaxed_input_section(const Relobj* object, unsigned int shndx) const;
   
   // Print merge statistics to stderr.
@@ -3190,6 +3190,12 @@ class Output_section : public Output_data
                        Input_section_specifier::equal_to>
     Output_section_data_by_input_section_map;
 
+  // Map that link Input_section_specifier to Output_relaxed_input_section.
+  typedef Unordered_map<Input_section_specifier, Output_relaxed_input_section*,
+                       Input_section_specifier::hash,
+                       Input_section_specifier::equal_to>
+    Output_relaxed_input_section_by_input_section_map;
+
   // Map used during relaxation of existing sections.  This map
   // an input section specifier to an input section list index.
   // We assume that Input_section_list is a vector.
@@ -3358,7 +3364,8 @@ class Output_section : public Output_data
   // Map from input sections to relaxed input sections.  This is mutable
   // because it is updated lazily.  We may need to update it in a
   // const qualified method.
-  mutable Output_section_data_by_input_section_map relaxed_input_section_map_;
+  mutable Output_relaxed_input_section_by_input_section_map
+    relaxed_input_section_map_;
   // Whether relaxed_input_section_map_ is valid.
   mutable bool is_relaxed_input_section_map_valid_;
 };
index 7e8a89021d979148128ca1aa0083f84ae8f6fd25..8cd4a40f1cf4f4f368bd6bb0e33bf7732572d3c7 100644 (file)
@@ -2413,7 +2413,6 @@ Symbol_table::compute_final_value(
          {
            Relobj* relobj = static_cast<Relobj*>(symobj);
            Output_section* os = relobj->output_section(shndx);
-            uint64_t secoff64 = relobj->output_section_offset(shndx);
 
             if (this->is_section_folded(relobj, shndx))
               {
@@ -2423,11 +2422,17 @@ Symbol_table::compute_final_value(
                                                                    shndx);
                 gold_assert(folded.first != NULL);
                 Relobj* folded_obj = reinterpret_cast<Relobj*>(folded.first);
-                os = folded_obj->output_section(folded.second);  
+               unsigned folded_shndx = folded.second;
+
+                os = folded_obj->output_section(folded_shndx);  
                 gold_assert(os != NULL);
-                secoff64 = folded_obj->output_section_offset(folded.second);
+
+               // Replace (relobj, shndx) with canonical ICF input section.
+               shndx = folded_shndx;
+               relobj = folded_obj;
               }
 
+            uint64_t secoff64 = relobj->output_section_offset(shndx);
            if (os == NULL)
              {
                 bool static_or_reloc = (parameters->doing_static_link() ||