PowerPC gold, fix 32-bit branch address arithmetic
[platform/upstream/binutils.git] / gold / layout.cc
index 147f740..7cbbe39 100644 (file)
@@ -563,7 +563,9 @@ static const char* gdb_fast_lookup_sections[] =
 {
   "aranges",
   "pubnames",
+  "gnu_pubnames",
   "pubtypes",
+  "gnu_pubtypes",
 };
 
 // Returns whether the given debug section is in the list of
@@ -4306,18 +4308,20 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
        }
     }
 
-  // Create the hash tables.
+  // Create the hash tables.  The Gnu-style hash table must be
+  // built first, because it changes the order of the symbols
+  // in the dynamic symbol table.
 
-  if (strcmp(parameters->options().hash_style(), "sysv") == 0
+  if (strcmp(parameters->options().hash_style(), "gnu") == 0
       || strcmp(parameters->options().hash_style(), "both") == 0)
     {
       unsigned char* phash;
       unsigned int hashlen;
-      Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
+      Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount,
                                    &phash, &hashlen);
 
       Output_section* hashsec =
-       this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH,
+       this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH,
                                    elfcpp::SHF_ALLOC, false,
                                    ORDER_DYNAMIC_LINKER, false);
 
@@ -4332,23 +4336,28 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
        {
          if (dynsym != NULL)
            hashsec->set_link_section(dynsym);
-         hashsec->set_entsize(4);
-       }
 
-      if (odyn != NULL)
-       odyn->add_section_address(elfcpp::DT_HASH, hashsec);
+         // For a 64-bit target, the entries in .gnu.hash do not have
+         // a uniform size, so we only set the entry size for a
+         // 32-bit target.
+         if (parameters->target().get_size() == 32)
+           hashsec->set_entsize(4);
+
+         if (odyn != NULL)
+           odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec);
+       }
     }
 
-  if (strcmp(parameters->options().hash_style(), "gnu") == 0
+  if (strcmp(parameters->options().hash_style(), "sysv") == 0
       || strcmp(parameters->options().hash_style(), "both") == 0)
     {
       unsigned char* phash;
       unsigned int hashlen;
-      Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount,
+      Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
                                    &phash, &hashlen);
 
       Output_section* hashsec =
-       this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH,
+       this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH,
                                    elfcpp::SHF_ALLOC, false,
                                    ORDER_DYNAMIC_LINKER, false);
 
@@ -4363,16 +4372,11 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
        {
          if (dynsym != NULL)
            hashsec->set_link_section(dynsym);
-
-         // For a 64-bit target, the entries in .gnu.hash do not have
-         // a uniform size, so we only set the entry size for a
-         // 32-bit target.
-         if (parameters->target().get_size() == 32)
-           hashsec->set_entsize(4);
-
-         if (odyn != NULL)
-           odyn->add_section_address(elfcpp::DT_GNU_HASH, hashsec);
+         hashsec->set_entsize(4);
        }
+
+      if (odyn != NULL)
+       odyn->add_section_address(elfcpp::DT_HASH, hashsec);
     }
 }
 
@@ -5492,6 +5496,10 @@ Layout::print_to_mapfile(Mapfile* mapfile) const
        p != this->segment_list_.end();
        ++p)
     (*p)->print_sections_to_mapfile(mapfile);
+  for (Section_list::const_iterator p = this->unattached_section_list_.begin();
+       p != this->unattached_section_list_.end();
+       ++p)
+    (*p)->print_to_mapfile(mapfile);
 }
 
 // Print statistical information to stderr.  This is used for --stats.
@@ -5526,6 +5534,8 @@ void
 Write_sections_task::locks(Task_locker* tl)
 {
   tl->add(this, this->output_sections_blocker_);
+  if (this->input_sections_blocker_ != NULL)
+    tl->add(this, this->input_sections_blocker_);
   tl->add(this, this->final_blocker_);
 }