From Craig Silverstein: rename some option functions in preparation
[external/binutils.git] / gold / layout.cc
index df10498..fd7f3af 100644 (file)
@@ -58,7 +58,7 @@ Layout_task_runner::run(Workqueue* workqueue, const Task* task)
   // Now we know the final size of the output file and we know where
   // each piece of information goes.
   Output_file* of = new Output_file(parameters->options().output_file_name());
-  if (this->options_.oformat() != General_options::OBJECT_FORMAT_ELF)
+  if (this->options_.oformat_enum() != General_options::OBJECT_FORMAT_ELF)
     of->set_is_temporary();
   of->open(file_size);
 
@@ -236,8 +236,21 @@ Layout::get_output_section(const char* name, Stringpool::Key name_key,
   else
     {
       // This is the first time we've seen this name/type/flags
-      // combination.
-      Output_section* os = this->make_output_section(name, type, flags);
+      // combination.  If the section has contents but no flags, then
+      // see whether we have an existing section with the same name.
+      // This is a workaround for cases where assembler code forgets
+      // to set section flags, and the GNU linker would simply pick an
+      // existing section with the same name.  FIXME: Perhaps there
+      // should be an option to control this.
+      Output_section* os = NULL;
+      if (type == elfcpp::SHT_PROGBITS && flags == 0)
+       {
+         os = this->find_output_section(name);
+         if (os != NULL && os->type() != elfcpp::SHT_PROGBITS)
+           os = NULL;
+       }
+      if (os == NULL)
+       os = this->make_output_section(name, type, flags);
       ins.first->second = os;
       return os;
     }
@@ -699,6 +712,18 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
   return os;
 }
 
+// Make an output section for a script.
+
+Output_section*
+Layout::make_output_section_for_script(const char* name)
+{
+  name = this->namepool_.add(name, false, NULL);
+  Output_section* os = this->make_output_section(name, elfcpp::SHT_PROGBITS,
+                                                elfcpp::SHF_ALLOC);
+  os->set_found_in_sections_clause();
+  return os;
+}
+
 // Return the number of segments we expect to see.
 
 size_t
@@ -962,7 +987,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
   else
     load_seg = this->find_first_load_seg();
 
-  if (this->options_.oformat() != General_options::OBJECT_FORMAT_ELF)
+  if (this->options_.oformat_enum() != General_options::OBJECT_FORMAT_ELF)
     load_seg = NULL;
 
   gold_assert(phdr_seg == NULL || load_seg != NULL);
@@ -1960,34 +1985,30 @@ Layout::create_version_sections(const Versions* versions,
     {
 #ifdef HAVE_TARGET_32_LITTLE
     case Parameters::TARGET_32_LITTLE:
-      this->sized_create_version_sections
-          SELECT_SIZE_ENDIAN_NAME(32, false)(
-              versions, symtab, local_symcount, dynamic_symbols, dynstr
-              SELECT_SIZE_ENDIAN(32, false));
+      this->sized_create_version_sections<32, false>(versions, symtab,
+                                                    local_symcount,
+                                                    dynamic_symbols, dynstr);
       break;
 #endif
 #ifdef HAVE_TARGET_32_BIG
     case Parameters::TARGET_32_BIG:
-      this->sized_create_version_sections
-          SELECT_SIZE_ENDIAN_NAME(32, true)(
-              versions, symtab, local_symcount, dynamic_symbols, dynstr
-              SELECT_SIZE_ENDIAN(32, true));
+      this->sized_create_version_sections<32, true>(versions, symtab,
+                                                   local_symcount,
+                                                   dynamic_symbols, dynstr);
       break;
 #endif
 #ifdef HAVE_TARGET_64_LITTLE
     case Parameters::TARGET_64_LITTLE:
-      this->sized_create_version_sections
-          SELECT_SIZE_ENDIAN_NAME(64, false)(
-              versions, symtab, local_symcount, dynamic_symbols, dynstr
-              SELECT_SIZE_ENDIAN(64, false));
+      this->sized_create_version_sections<64, false>(versions, symtab,
+                                                    local_symcount,
+                                                    dynamic_symbols, dynstr);
       break;
 #endif
 #ifdef HAVE_TARGET_64_BIG
     case Parameters::TARGET_64_BIG:
-      this->sized_create_version_sections
-          SELECT_SIZE_ENDIAN_NAME(64, true)(
-              versions, symtab, local_symcount, dynamic_symbols, dynstr
-              SELECT_SIZE_ENDIAN(64, true));
+      this->sized_create_version_sections<64, true>(versions, symtab,
+                                                   local_symcount,
+                                                   dynamic_symbols, dynstr);
       break;
 #endif
     default:
@@ -2004,8 +2025,7 @@ Layout::sized_create_version_sections(
     const Symbol_table* symtab,
     unsigned int local_symcount,
     const std::vector<Symbol*>& dynamic_symbols,
-    const Output_section* dynstr
-    ACCEPT_SIZE_ENDIAN)
+    const Output_section* dynstr)
 {
   Output_section* vsec = this->choose_output_section(NULL, ".gnu.version",
                                                     elfcpp::SHT_GNU_versym,
@@ -2014,9 +2034,10 @@ Layout::sized_create_version_sections(
 
   unsigned char* vbuf;
   unsigned int vsize;
-  versions->symbol_section_contents SELECT_SIZE_ENDIAN_NAME(size, big_endian)(
-      symtab, &this->dynpool_, local_symcount, dynamic_symbols, &vbuf, &vsize
-      SELECT_SIZE_ENDIAN(size, big_endian));
+  versions->symbol_section_contents<size, big_endian>(symtab, &this->dynpool_,
+                                                     local_symcount,
+                                                     dynamic_symbols,
+                                                     &vbuf, &vsize);
 
   Output_section_data* vdata = new Output_data_const_buffer(vbuf, vsize, 2);
 
@@ -2038,9 +2059,8 @@ Layout::sized_create_version_sections(
       unsigned char* vdbuf;
       unsigned int vdsize;
       unsigned int vdentries;
-      versions->def_section_contents SELECT_SIZE_ENDIAN_NAME(size, big_endian)(
-          &this->dynpool_, &vdbuf, &vdsize, &vdentries
-          SELECT_SIZE_ENDIAN(size, big_endian));
+      versions->def_section_contents<size, big_endian>(&this->dynpool_, &vdbuf,
+                                                      &vdsize, &vdentries);
 
       Output_section_data* vddata = new Output_data_const_buffer(vdbuf,
                                                                 vdsize,
@@ -2065,9 +2085,9 @@ Layout::sized_create_version_sections(
       unsigned char* vnbuf;
       unsigned int vnsize;
       unsigned int vnentries;
-      versions->need_section_contents SELECT_SIZE_ENDIAN_NAME(size, big_endian)
-        (&this->dynpool_, &vnbuf, &vnsize, &vnentries
-         SELECT_SIZE_ENDIAN(size, big_endian));
+      versions->need_section_contents<size, big_endian>(&this->dynpool_,
+                                                       &vnbuf, &vnsize,
+                                                       &vnentries);
 
       Output_section_data* vndata = new Output_data_const_buffer(vnbuf,
                                                                 vnsize,
@@ -2541,7 +2561,7 @@ Layout::write_sections_after_input_sections(Output_file* of)
 void
 Layout::write_binary(Output_file* in) const
 {
-  gold_assert(this->options_.oformat()
+  gold_assert(this->options_.oformat_enum()
              == General_options::OBJECT_FORMAT_BINARY);
 
   // Get the size of the binary file.
@@ -2712,7 +2732,7 @@ void
 Close_task_runner::run(Workqueue*, const Task*)
 {
   // If we've been asked to create a binary file, we do so here.
-  if (this->options_->oformat() != General_options::OBJECT_FORMAT_ELF)
+  if (this->options_->oformat_enum() != General_options::OBJECT_FORMAT_ELF)
     this->layout_->write_binary(this->of_);
 
   this->of_->close();