]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - bfd/elflink.c
ld: Change -z one-rosegment to --rosegment in comments
[thirdparty/binutils-gdb.git] / bfd / elflink.c
index 321e3d5e2ff614daeb20ff41b340b3a93aa0b789..9eb1122d5133259254c0d8899e1452558bd4e128 100644 (file)
@@ -64,7 +64,7 @@ _bfd_elf_link_keep_memory (struct bfd_link_info *info)
      this is opt-in by each backend.  */
   const struct elf_backend_data *bed
     = get_elf_backend_data (info->output_bfd);
      this is opt-in by each backend.  */
   const struct elf_backend_data *bed
     = get_elf_backend_data (info->output_bfd);
-  if (bed->use_mmap)
+  if (bed != NULL && bed->use_mmap)
     return false;
 #endif
   bfd *abfd;
     return false;
 #endif
   bfd *abfd;
@@ -2247,16 +2247,19 @@ _bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data)
 \f
 /* Return the glibc version reference if VERSION_DEP is added to the
    list of glibc version dependencies successfully.  VERSION_DEP will
 \f
 /* Return the glibc version reference if VERSION_DEP is added to the
    list of glibc version dependencies successfully.  VERSION_DEP will
-   be put into the .gnu.version_r section.  */
+   be put into the .gnu.version_r section.  GLIBC_MINOR_BASE is the
+   pointer to the glibc minor base version.  */
 
 static Elf_Internal_Verneed *
 elf_link_add_glibc_verneed (struct elf_find_verdep_info *rinfo,
                            Elf_Internal_Verneed *glibc_verref,
 
 static Elf_Internal_Verneed *
 elf_link_add_glibc_verneed (struct elf_find_verdep_info *rinfo,
                            Elf_Internal_Verneed *glibc_verref,
-                           const char *version_dep)
+                           const char *version_dep,
+                           int *glibc_minor_base)
 {
   Elf_Internal_Verneed *t;
   Elf_Internal_Vernaux *a;
   size_t amt;
 {
   Elf_Internal_Verneed *t;
   Elf_Internal_Vernaux *a;
   size_t amt;
+  int minor_version = -1;
 
   if (glibc_verref != NULL)
     {
 
   if (glibc_verref != NULL)
     {
@@ -2272,8 +2275,6 @@ elf_link_add_glibc_verneed (struct elf_find_verdep_info *rinfo,
     }
   else
     {
     }
   else
     {
-      bool is_glibc;
-
       for (t = elf_tdata (rinfo->info->output_bfd)->verref;
           t != NULL;
           t = t->vn_nextref)
       for (t = elf_tdata (rinfo->info->output_bfd)->verref;
           t != NULL;
           t = t->vn_nextref)
@@ -2287,7 +2288,6 @@ elf_link_add_glibc_verneed (struct elf_find_verdep_info *rinfo,
       if (t == NULL)
        return t;
 
       if (t == NULL)
        return t;
 
-      is_glibc = false;
       for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
        {
          /* Return if VERSION_DEP dependency has been added.  */
       for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
        {
          /* Return if VERSION_DEP dependency has been added.  */
@@ -2296,12 +2296,24 @@ elf_link_add_glibc_verneed (struct elf_find_verdep_info *rinfo,
            return t;
 
          /* Check if libc.so provides GLIBC_2.XX version.  */
            return t;
 
          /* Check if libc.so provides GLIBC_2.XX version.  */
-         if (!is_glibc && startswith (a->vna_nodename, "GLIBC_2."))
-           is_glibc = true;
+         if (startswith (a->vna_nodename, "GLIBC_2."))
+           {
+             minor_version = strtol (a->vna_nodename + 8, NULL, 10);
+             if (minor_version < *glibc_minor_base)
+               *glibc_minor_base = minor_version;
+           }
        }
 
       /* Skip if it isn't linked against glibc.  */
        }
 
       /* Skip if it isn't linked against glibc.  */
-      if (!is_glibc)
+      if (minor_version < 0)
+       return NULL;
+    }
+
+  /* Skip if 2.GLIBC_MINOR_BASE includes VERSION_DEP.  */
+  if (startswith (version_dep, "GLIBC_2."))
+    {
+      minor_version = strtol (version_dep + 8, NULL, 10);
+      if (minor_version <= *glibc_minor_base)
        return NULL;
     }
 
        return NULL;
     }
 
@@ -2333,10 +2345,12 @@ _bfd_elf_link_add_glibc_version_dependency
    const char *version_dep[])
 {
   Elf_Internal_Verneed *t = NULL;
    const char *version_dep[])
 {
   Elf_Internal_Verneed *t = NULL;
+  int glibc_minor_base = INT_MAX;
 
   do
     {
 
   do
     {
-      t = elf_link_add_glibc_verneed (rinfo, t, *version_dep);
+      t = elf_link_add_glibc_verneed (rinfo, t, *version_dep,
+                                     &glibc_minor_base);
       /* Return if there is no glibc version reference.  */
       if (t == NULL)
        return;
       /* Return if there is no glibc version reference.  */
       if (t == NULL)
        return;
@@ -2942,8 +2956,7 @@ _bfd_elf_link_output_relocs (bfd *output_bfd,
                             asection *input_section,
                             Elf_Internal_Shdr *input_rel_hdr,
                             Elf_Internal_Rela *internal_relocs,
                             asection *input_section,
                             Elf_Internal_Shdr *input_rel_hdr,
                             Elf_Internal_Rela *internal_relocs,
-                            struct elf_link_hash_entry **rel_hash
-                              ATTRIBUTE_UNUSED)
+                            struct elf_link_hash_entry **rel_hash)
 {
   Elf_Internal_Rela *irela;
   Elf_Internal_Rela *irelaend;
 {
   Elf_Internal_Rela *irela;
   Elf_Internal_Rela *irelaend;
@@ -2986,9 +2999,13 @@ _bfd_elf_link_output_relocs (bfd *output_bfd,
                      * bed->s->int_rels_per_ext_rel);
   while (irela < irelaend)
     {
                      * bed->s->int_rels_per_ext_rel);
   while (irela < irelaend)
     {
+      if (rel_hash && *rel_hash)
+       (*rel_hash)->has_reloc = 1;
       (*swap_out) (output_bfd, irela, erel);
       irela += bed->s->int_rels_per_ext_rel;
       erel += input_rel_hdr->sh_entsize;
       (*swap_out) (output_bfd, irela, erel);
       irela += bed->s->int_rels_per_ext_rel;
       erel += input_rel_hdr->sh_entsize;
+      if (rel_hash)
+       rel_hash++;
     }
 
   /* Bump the counter, so that we know where to add the next set of
     }
 
   /* Bump the counter, so that we know where to add the next set of
@@ -3636,6 +3653,7 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
      object file is an IR object, give linker LTO plugin a chance to
      get the correct symbol table.  */
   if (abfd->plugin_format == bfd_plugin_yes
      object file is an IR object, give linker LTO plugin a chance to
      get the correct symbol table.  */
   if (abfd->plugin_format == bfd_plugin_yes
+      || abfd->plugin_format == bfd_plugin_yes_unused
 #if BFD_SUPPORTS_PLUGINS
       || (abfd->plugin_format == bfd_plugin_unknown
          && bfd_link_plugin_object_p (abfd))
 #if BFD_SUPPORTS_PLUGINS
       || (abfd->plugin_format == bfd_plugin_unknown
          && bfd_link_plugin_object_p (abfd))
@@ -5677,7 +5695,8 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
       && !bfd_link_relocatable (info)
       && (abfd->flags & BFD_PLUGIN) == 0
       && !just_syms
       && !bfd_link_relocatable (info)
       && (abfd->flags & BFD_PLUGIN) == 0
       && !just_syms
-      && extsymcount)
+      && extsymcount != 0
+      && is_elf_hash_table (&htab->root))
     {
       int r_sym_shift;
 
     {
       int r_sym_shift;
 
@@ -5700,9 +5719,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
          if ((s->flags & SEC_RELOC) == 0
              || s->reloc_count == 0
              || (s->flags & SEC_EXCLUDE) != 0
          if ((s->flags & SEC_RELOC) == 0
              || s->reloc_count == 0
              || (s->flags & SEC_EXCLUDE) != 0
-             || ((info->strip == strip_all
-                  || info->strip == strip_debugger)
-                 && (s->flags & SEC_DEBUGGING) != 0))
+             || (s->flags & SEC_DEBUGGING) != 0)
            continue;
 
          internal_relocs = _bfd_elf_link_info_read_relocs
            continue;
 
          internal_relocs = _bfd_elf_link_info_read_relocs
@@ -6261,9 +6278,11 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
 
              if (!is_elf_hash_table (info->hash))
                continue;
 
              if (!is_elf_hash_table (info->hash))
                continue;
-             /* Ignore the archive if the symbol isn't defined in a
-                shared object.  */
-             if (!((struct elf_link_hash_entry *) h)->def_dynamic)
+             struct elf_link_hash_entry *eh
+               = (struct elf_link_hash_entry *) h;
+             /* Ignore the archive if the symbol isn't referenced by a
+                regular object or isn't defined in a shared object.  */
+             if (!eh->ref_regular || !eh->def_dynamic)
                continue;
              /* Ignore the dynamic definition if symbol is first
                 defined in this archive.  */
                continue;
              /* Ignore the dynamic definition if symbol is first
                 defined in this archive.  */
@@ -10767,6 +10786,13 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
           && (h->root.u.undef.abfd->flags & BFD_PLUGIN) != 0)
     strip = true;
 
           && (h->root.u.undef.abfd->flags & BFD_PLUGIN) != 0)
     strip = true;
 
+  /* Remember if this symbol should be stripped.  */
+  bool should_strip = strip;
+
+  /* Strip undefined weak symbols link if they don't have relocation.  */
+  if (!strip)
+    strip = !h->has_reloc && h->root.type == bfd_link_hash_undefweak;
+
   type = h->type;
 
   /* If we're stripping it, and it's not a dynamic symbol, there's
   type = h->type;
 
   /* If we're stripping it, and it's not a dynamic symbol, there's
@@ -10915,6 +10941,10 @@ elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
          eoinfo->failed = true;
          return false;
        }
          eoinfo->failed = true;
          return false;
        }
+      /* If a symbol is in the dynamic symbol table and isn't a
+        should-strip symbol, also keep it in the symbol table.  */
+      if (!should_strip)
+       strip = false;
     }
 
   /* If we are marking the symbol as undefined, and there are no
     }
 
   /* If we are marking the symbol as undefined, and there are no
@@ -11873,10 +11903,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
                    {
                      rel_hash = PTR_ADD (esdo->rela.hashes, esdo->rela.count);
                      rela_hash_list = rel_hash;
                    {
                      rel_hash = PTR_ADD (esdo->rela.hashes, esdo->rela.count);
                      rela_hash_list = rel_hash;
-                     if (bed->is_rela_normal != NULL)
-                       rela_normal = bed->is_rela_normal (irela);
-                     else
-                       rela_normal = bed->rela_normal;
+                     rela_normal = bed->rela_normal;
                    }
 
                  irela->r_offset = _bfd_elf_section_offset (output_bfd,
                    }
 
                  irela->r_offset = _bfd_elf_section_offset (output_bfd,