Introduce dw2_linkage_name and dw2_linkage_name_attr.
[deliverable/binutils-gdb.git] / gold / layout.cc
index d14f27bddfcf48d1465e60cf0f6889c85ce5bb05..5f25faea5532b5291d097adbacfb52b0a24abafb 100644 (file)
@@ -1,6 +1,6 @@
 // layout.cc -- lay out output file sections for gold
 
-// Copyright (C) 2006-2016 Free Software Foundation, Inc.
+// Copyright (C) 2006-2017 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
 #include "libiberty.h"
 #include "md5.h"
 #include "sha1.h"
+#ifdef __MINGW32__
+#include <windows.h>
+#include <rpcdce.h>
+#endif
 
 #include "parameters.h"
 #include "options.h"
@@ -899,7 +903,7 @@ Layout::keep_input_section(const Relobj* relobj, const char* name)
   bool keep;
 
   name = ss->output_section_name(file_name, name, &output_section_slot,
-                                &script_section_type, &keep);
+                                &script_section_type, &keep, true);
   return name != NULL && keep;
 }
 
@@ -931,13 +935,16 @@ Layout::get_output_section_flags(elfcpp::Elf_Xword input_section_flags)
 // choosing an output section for an input section found in a input
 // file.  ORDER is where this section should appear in the output
 // sections.  IS_RELRO is true for a relro section.  This will return
-// NULL if the input section should be discarded.
+// NULL if the input section should be discarded.  MATCH_INPUT_SPEC
+// is true if the section name should be matched against input specs
+// in a linker script.
 
 Output_section*
 Layout::choose_output_section(const Relobj* relobj, const char* name,
                              elfcpp::Elf_Word type, elfcpp::Elf_Xword flags,
                              bool is_input_section, Output_section_order order,
-                             bool is_relro)
+                             bool is_relro, bool is_reloc,
+                             bool match_input_spec)
 {
   // We should not see any input sections after we have attached
   // sections to segments.
@@ -945,7 +952,7 @@ Layout::choose_output_section(const Relobj* relobj, const char* name,
 
   flags = this->get_output_section_flags(flags);
 
-  if (this->script_options_->saw_sections_clause())
+  if (this->script_options_->saw_sections_clause() && !is_reloc)
     {
       // We are using a SECTIONS clause, so the output section is
       // chosen based only on the name.
@@ -957,7 +964,8 @@ Layout::choose_output_section(const Relobj* relobj, const char* name,
       const char* orig_name = name;
       bool keep;
       name = ss->output_section_name(file_name, name, &output_section_slot,
-                                    &script_section_type, &keep);
+                                    &script_section_type, &keep,
+                                    match_input_spec);
 
       if (name == NULL)
        {
@@ -1180,7 +1188,8 @@ Layout::layout(Sized_relobj_file<size, big_endian>* object, unsigned int shndx,
        {
          os = this->choose_output_section(object, name, sh_type,
                                           shdr.get_sh_flags(), true,
-                                          ORDER_INVALID, false);
+                                          ORDER_INVALID, false, false,
+                                          true);
        }
       else
        {
@@ -1309,7 +1318,7 @@ Layout::layout_reloc(Sized_relobj_file<size, big_endian>* object,
       || (data_section->flags() & elfcpp::SHF_GROUP) == 0)
     os = this->choose_output_section(object, name.c_str(), sh_type,
                                     shdr.get_sh_flags(), false,
-                                    ORDER_INVALID, false);
+                                    ORDER_INVALID, false, true, false);
   else
     {
       const char* n = this->namepool_.add(name.c_str(), true, NULL);
@@ -1502,7 +1511,8 @@ Layout::make_eh_frame_section(const Relobj* object)
   Output_section* os = this->choose_output_section(object, ".eh_frame",
                                                   elfcpp::SHT_PROGBITS,
                                                   elfcpp::SHF_ALLOC, false,
-                                                  ORDER_EHFRAME, false);
+                                                  ORDER_EHFRAME, false, false,
+                                                  false);
   if (os == NULL)
     return NULL;
 
@@ -1519,7 +1529,8 @@ Layout::make_eh_frame_section(const Relobj* object)
            this->choose_output_section(NULL, ".eh_frame_hdr",
                                        elfcpp::SHT_PROGBITS,
                                        elfcpp::SHF_ALLOC, false,
-                                       ORDER_EHFRAME, false);
+                                       ORDER_EHFRAME, false, false,
+                                       false);
 
          if (hdr_os != NULL)
            {
@@ -1570,6 +1581,23 @@ Layout::add_eh_frame_for_plt(Output_data* plt, const unsigned char* cie_data,
     }
 }
 
+// Remove .eh_frame information for a PLT.  FDEs using the CIE must
+// be removed in reverse order to the order they were added.
+
+void
+Layout::remove_eh_frame_for_plt(Output_data* plt, const unsigned char* cie_data,
+                               size_t cie_length, const unsigned char* fde_data,
+                               size_t fde_length)
+{
+  if (parameters->incremental())
+    {
+      // FIXME: Maybe this could work some day....
+      return;
+    }
+  this->eh_frame_data_->remove_ehframe_for_plt(plt, cie_data, cie_length,
+                                              fde_data, fde_length);
+}
+
 // Scan a .debug_info or .debug_types section, and add summary
 // information to the .gdb_index section.
 
@@ -1588,7 +1616,7 @@ Layout::add_to_gdb_index(bool is_type_unit,
       Output_section* os = this->choose_output_section(NULL, ".gdb_index",
                                                       elfcpp::SHT_PROGBITS, 0,
                                                       false, ORDER_INVALID,
-                                                      false);
+                                                      false, false, false);
       if (os == NULL)
        return;
 
@@ -1612,7 +1640,8 @@ Layout::add_output_section_data(const char* name, elfcpp::Elf_Word type,
                                Output_section_order order, bool is_relro)
 {
   Output_section* os = this->choose_output_section(NULL, name, type, flags,
-                                                  false, order, is_relro);
+                                                  false, order, is_relro,
+                                                  false, false);
   if (os != NULL)
     os->add_output_section_data(posd);
   return os;
@@ -2153,7 +2182,7 @@ Layout::create_initial_dynamic_sections(Symbol_table* symtab)
                                                       (elfcpp::SHF_ALLOC
                                                        | elfcpp::SHF_WRITE),
                                                       false, ORDER_RELRO,
-                                                      true);
+                                                      true, false, false);
 
   // A linker script may discard .dynamic, so check for NULL.
   if (this->dynamic_section_ != NULL)
@@ -2581,7 +2610,7 @@ Layout::relaxation_loop_body(
   return off;
 }
 
-// Search the list of patterns and find the postion of the given section
+// Search the list of patterns and find the position of the given section
 // name in the output section.  If the section name matches a glob
 // pattern and a non-glob name, then the non-glob position takes
 // precedence.  Return 0 if no match is found.
@@ -2684,6 +2713,9 @@ off_t
 Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
                 Target* target, const Task* task)
 {
+  unsigned int local_dynamic_count = 0;
+  unsigned int forced_local_dynamic_count = 0;
+
   target->finalize_sections(this, input_objects, symtab);
 
   this->count_local_symbols(task, input_objects);
@@ -2704,11 +2736,12 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
       // Create the dynamic symbol table, including the hash table.
       Output_section* dynstr;
       std::vector<Symbol*> dynamic_symbols;
-      unsigned int local_dynamic_count;
       Versions versions(*this->script_options()->version_script_info(),
                        &this->dynpool_);
       this->create_dynamic_symtab(input_objects, symtab, &dynstr,
-                                 &local_dynamic_count, &dynamic_symbols,
+                                 &local_dynamic_count,
+                                 &forced_local_dynamic_count,
+                                 &dynamic_symbols,
                                  &versions);
 
       // Create the .interp section to hold the name of the
@@ -2729,7 +2762,9 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
 
       // Create the version sections.  We can't do this until the
       // dynamic string table is complete.
-      this->create_version_sections(&versions, symtab, local_dynamic_count,
+      this->create_version_sections(&versions, symtab,
+                                   (local_dynamic_count
+                                    + forced_local_dynamic_count),
                                    dynamic_symbols, dynstr);
 
       // Set the size of the _DYNAMIC symbol.  We can't do this until
@@ -2799,7 +2834,8 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
   shndx = this->set_section_indexes(shndx);
 
   // Create the symbol table sections.
-  this->create_symtab_sections(input_objects, symtab, shndx, &off);
+  this->create_symtab_sections(input_objects, symtab, shndx, &off,
+                              local_dynamic_count);
   if (!parameters->doing_static_link())
     this->assign_local_dynsym_offsets(input_objects);
 
@@ -2935,7 +2971,8 @@ Layout::create_note(const char* name, int note_type,
     }
   Output_section* os = this->choose_output_section(NULL, section_name,
                                                   elfcpp::SHT_NOTE,
-                                                  flags, false, order, false);
+                                                  flags, false, order, false,
+                                                  false, true);
   if (os == NULL)
     return NULL;
 
@@ -3067,6 +3104,7 @@ Layout::create_build_id()
     descsz = 160 / 8;
   else if (strcmp(style, "uuid") == 0)
     {
+#ifndef __MINGW32__
       const size_t uuidsz = 128 / 8;
 
       char buffer[uuidsz];
@@ -3089,6 +3127,26 @@ Layout::create_build_id()
 
       desc.assign(buffer, uuidsz);
       descsz = uuidsz;
+#else // __MINGW32__
+      UUID uuid;
+      typedef RPC_STATUS (RPC_ENTRY *UuidCreateFn)(UUID *Uuid);
+
+      HMODULE rpc_library = LoadLibrary("rpcrt4.dll");
+      if (!rpc_library)
+       gold_error(_("--build-id=uuid failed: could not load rpcrt4.dll"));
+      else
+       {
+         UuidCreateFn uuid_create = reinterpret_cast<UuidCreateFn>(
+             GetProcAddress(rpc_library, "UuidCreate"));
+         if (!uuid_create)
+           gold_error(_("--build-id=uuid failed: could not find UuidCreate"));
+         else if (uuid_create(&uuid) != RPC_S_OK)
+           gold_error(_("__build_id=uuid failed: call UuidCreate() failed"));
+         FreeLibrary(rpc_library);
+       }
+      desc.assign(reinterpret_cast<const char *>(&uuid), sizeof(UUID));
+      descsz = sizeof(UUID);
+#endif // __MINGW32__
     }
   else if (strncmp(style, "0x", 2) == 0)
     {
@@ -3259,6 +3317,11 @@ bool
 Layout::segment_precedes(const Output_segment* seg1,
                         const Output_segment* seg2)
 {
+  // In order to produce a stable ordering if we're called with the same pointer
+  // return false.
+  if (seg1 == seg2)
+    return false;
+
   elfcpp::Elf_Word type1 = seg1->type();
   elfcpp::Elf_Word type2 = seg2->type();
 
@@ -3418,7 +3481,7 @@ is_text_segment(const Target* target, const Output_segment* seg)
 }
 
 // Set the file offsets of all the segments, and all the sections they
-// contain.  They have all been created.  LOAD_SEG must be be laid out
+// contain.  They have all been created.  LOAD_SEG must be laid out
 // first.  Return the offset of the data to follow.
 
 off_t
@@ -3965,7 +4028,8 @@ void
 Layout::create_symtab_sections(const Input_objects* input_objects,
                               Symbol_table* symtab,
                               unsigned int shnum,
-                              off_t* poff)
+                              off_t* poff,
+                              unsigned int local_dynamic_count)
 {
   int symsize;
   unsigned int align;
@@ -4019,18 +4083,15 @@ Layout::create_symtab_sections(const Input_objects* input_objects,
   gold_assert(static_cast<off_t>(local_symcount * symsize) == off);
 
   off_t dynoff;
-  size_t dyn_global_index;
   size_t dyncount;
   if (this->dynsym_section_ == NULL)
     {
       dynoff = 0;
-      dyn_global_index = 0;
       dyncount = 0;
     }
   else
     {
-      dyn_global_index = this->dynsym_section_->info();
-      off_t locsize = dyn_global_index * this->dynsym_section_->entsize();
+      off_t locsize = local_dynamic_count * this->dynsym_section_->entsize();
       dynoff = this->dynsym_section_->offset() + locsize;
       dyncount = (this->dynsym_section_->data_size() - locsize) / symsize;
       gold_assert(static_cast<off_t>(dyncount * symsize)
@@ -4038,7 +4099,7 @@ Layout::create_symtab_sections(const Input_objects* input_objects,
     }
 
   off_t global_off = off;
-  off = symtab->finalize(off, dynoff, dyn_global_index, dyncount,
+  off = symtab->finalize(off, dynoff, local_dynamic_count, dyncount,
                         &this->sympool_, &local_symcount);
 
   if (!parameters->options().strip_all())
@@ -4204,12 +4265,18 @@ Layout::allocated_output_section_count() const
 }
 
 // Create the dynamic symbol table.
+// *PLOCAL_DYNAMIC_COUNT will be set to the number of local symbols
+// from input objects, and *PFORCED_LOCAL_DYNAMIC_COUNT will be set
+// to the number of global symbols that have been forced local.
+// We need to remember the former because the forced-local symbols are
+// written along with the global symbols in Symtab::write_globals().
 
 void
 Layout::create_dynamic_symtab(const Input_objects* input_objects,
                              Symbol_table* symtab,
                              Output_section** pdynstr,
                              unsigned int* plocal_dynamic_count,
+                             unsigned int* pforced_local_dynamic_count,
                              std::vector<Symbol*>* pdynamic_symbols,
                              Versions* pversions)
 {
@@ -4244,10 +4311,14 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
     }
 
   unsigned int local_symcount = index;
-  *plocal_dynamic_count = local_symcount;
+  unsigned int forced_local_count = 0;
 
-  index = symtab->set_dynsym_indexes(index, pdynamic_symbols,
-                                    &this->dynpool_, pversions);
+  index = symtab->set_dynsym_indexes(index, &forced_local_count,
+                                    pdynamic_symbols, &this->dynpool_,
+                                    pversions);
+
+  *plocal_dynamic_count = local_symcount;
+  *pforced_local_dynamic_count = forced_local_count;
 
   int symsize;
   unsigned int align;
@@ -4272,7 +4343,7 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
                                                       elfcpp::SHF_ALLOC,
                                                       false,
                                                       ORDER_DYNAMIC_LINKER,
-                                                      false);
+                                                      false, false, false);
 
   // Check for NULL as a linker script may discard .dynsym.
   if (dynsym != NULL)
@@ -4282,7 +4353,7 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
                                                               "** dynsym");
       dynsym->add_output_section_data(odata);
 
-      dynsym->set_info(local_symcount);
+      dynsym->set_info(local_symcount + forced_local_count);
       dynsym->set_entsize(symsize);
       dynsym->set_addralign(align);
 
@@ -4309,7 +4380,8 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
        this->choose_output_section(NULL, ".dynsym_shndx",
                                    elfcpp::SHT_SYMTAB_SHNDX,
                                    elfcpp::SHF_ALLOC,
-                                   false, ORDER_DYNAMIC_LINKER, false);
+                                   false, ORDER_DYNAMIC_LINKER, false, false,
+                                   false);
 
       if (dynsym_xindex != NULL)
        {
@@ -4337,7 +4409,7 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
                                                       elfcpp::SHF_ALLOC,
                                                       false,
                                                       ORDER_DYNAMIC_LINKER,
-                                                      false);
+                                                      false, false, false);
   *pdynstr = dynstr;
   if (dynstr != NULL)
     {
@@ -4365,13 +4437,15 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
     {
       unsigned char* phash;
       unsigned int hashlen;
-      Dynobj::create_gnu_hash_table(*pdynamic_symbols, local_symcount,
+      Dynobj::create_gnu_hash_table(*pdynamic_symbols,
+                                   local_symcount + forced_local_count,
                                    &phash, &hashlen);
 
       Output_section* hashsec =
        this->choose_output_section(NULL, ".gnu.hash", elfcpp::SHT_GNU_HASH,
                                    elfcpp::SHF_ALLOC, false,
-                                   ORDER_DYNAMIC_LINKER, false);
+                                   ORDER_DYNAMIC_LINKER, false, false,
+                                   false);
 
       Output_section_data* hashdata = new Output_data_const_buffer(phash,
                                                                   hashlen,
@@ -4401,13 +4475,15 @@ Layout::create_dynamic_symtab(const Input_objects* input_objects,
     {
       unsigned char* phash;
       unsigned int hashlen;
-      Dynobj::create_elf_hash_table(*pdynamic_symbols, local_symcount,
+      Dynobj::create_elf_hash_table(*pdynamic_symbols,
+                                   local_symcount + forced_local_count,
                                    &phash, &hashlen);
 
       Output_section* hashsec =
        this->choose_output_section(NULL, ".hash", elfcpp::SHT_HASH,
                                    elfcpp::SHF_ALLOC, false,
-                                   ORDER_DYNAMIC_LINKER, false);
+                                   ORDER_DYNAMIC_LINKER, false, false,
+                                   false);
 
       Output_section_data* hashdata = new Output_data_const_buffer(phash,
                                                                   hashlen,
@@ -4514,7 +4590,7 @@ Layout::sized_create_version_sections(
                                                     elfcpp::SHF_ALLOC,
                                                     false,
                                                     ORDER_DYNAMIC_LINKER,
-                                                    false);
+                                                    false, false, false);
 
   // Check for NULL since a linker script may discard this section.
   if (vsec != NULL)
@@ -4545,7 +4621,8 @@ Layout::sized_create_version_sections(
       vdsec = this->choose_output_section(NULL, ".gnu.version_d",
                                          elfcpp::SHT_GNU_verdef,
                                          elfcpp::SHF_ALLOC,
-                                         false, ORDER_DYNAMIC_LINKER, false);
+                                         false, ORDER_DYNAMIC_LINKER, false,
+                                         false, false);
 
       if (vdsec != NULL)
        {
@@ -4577,7 +4654,8 @@ Layout::sized_create_version_sections(
       vnsec = this->choose_output_section(NULL, ".gnu.version_r",
                                          elfcpp::SHT_GNU_verneed,
                                          elfcpp::SHF_ALLOC,
-                                         false, ORDER_DYNAMIC_LINKER, false);
+                                         false, ORDER_DYNAMIC_LINKER, false,
+                                         false, false);
 
       if (vnsec != NULL)
        {
@@ -4626,7 +4704,7 @@ Layout::create_interp(const Target* target)
                                                     elfcpp::SHT_PROGBITS,
                                                     elfcpp::SHF_ALLOC,
                                                     false, ORDER_INTERP,
-                                                    false);
+                                                    false, false, false);
   if (osec != NULL)
     osec->add_output_section_data(odata);
 }
This page took 0.031586 seconds and 4 git commands to generate.