AArch64: Add gdbserver MTE support
[deliverable/binutils-gdb.git] / bfd / linker.c
index edbd0a7df46901e016f43659ed6b6bdf588c560e..6f6e68429267da83cfef0b63913b0004380f75d4 100644 (file)
@@ -1,5 +1,5 @@
 /* linker.c -- BFD linker routines
-   Copyright (C) 1993-2019 Free Software Foundation, Inc.
+   Copyright (C) 1993-2021 Free Software Foundation, Inc.
    Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -536,7 +536,7 @@ bfd_wrapped_link_hash_lookup (bfd *abfd,
                              bfd_boolean copy,
                              bfd_boolean follow)
 {
-  bfd_size_type amt;
+  size_t amt;
 
   if (info->wrap_hash != NULL)
     {
@@ -579,7 +579,7 @@ bfd_wrapped_link_hash_lookup (bfd *abfd,
 #define REAL "__real_"
 
       if (*l == '_'
-         && CONST_STRNEQ (l, REAL)
+         && startswith (l, REAL)
          && bfd_hash_lookup (info->wrap_hash, l + sizeof REAL - 1,
                              FALSE, FALSE) != NULL)
        {
@@ -623,7 +623,7 @@ unwrap_hash_lookup (struct bfd_link_info *info,
       || *l == info->wrap_char)
     ++l;
 
-  if (CONST_STRNEQ (l, WRAP))
+  if (startswith (l, WRAP))
     {
       l += sizeof WRAP - 1;
 
@@ -764,7 +764,7 @@ struct bfd_link_hash_table *
 _bfd_generic_link_hash_table_create (bfd *abfd)
 {
   struct generic_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct generic_link_hash_table);
+  size_t amt = sizeof (struct generic_link_hash_table);
 
   ret = (struct generic_link_hash_table *) bfd_malloc (amt);
   if (ret == NULL)
@@ -810,14 +810,13 @@ bfd_generic_link_read_symbols (bfd *abfd)
       symsize = bfd_get_symtab_upper_bound (abfd);
       if (symsize < 0)
        return FALSE;
-      bfd_get_outsymbols (abfd) = (struct bfd_symbol **) bfd_alloc (abfd,
-                                                                   symsize);
+      abfd->outsymbols = bfd_alloc (abfd, symsize);
       if (bfd_get_outsymbols (abfd) == NULL && symsize != 0)
        return FALSE;
       symcount = bfd_canonicalize_symtab (abfd, bfd_get_outsymbols (abfd));
       if (symcount < 0)
        return FALSE;
-      bfd_get_symcount (abfd) = symcount;
+      abfd->symcount = symcount;
     }
 
   return TRUE;
@@ -965,7 +964,7 @@ _bfd_generic_link_add_archive_symbols
 
          if (h == NULL
              && info->pei386_auto_import
-             && CONST_STRNEQ (arsym->name, "__imp_"))
+             && startswith (arsym->name, "__imp_"))
            h = bfd_link_hash_lookup (info->hash, arsym->name + 6,
                                      FALSE, FALSE, TRUE);
          if (h == NULL)
@@ -1164,9 +1163,9 @@ generic_link_add_symbol_list (bfd *abfd,
                       | BSF_GLOBAL
                       | BSF_CONSTRUCTOR
                       | BSF_WEAK)) != 0
-         || bfd_is_und_section (bfd_get_section (p))
-         || bfd_is_com_section (bfd_get_section (p))
-         || bfd_is_ind_section (bfd_get_section (p)))
+         || bfd_is_und_section (bfd_asymbol_section (p))
+         || bfd_is_com_section (bfd_asymbol_section (p))
+         || bfd_is_ind_section (bfd_asymbol_section (p)))
        {
          const char *name;
          const char *string;
@@ -1192,7 +1191,7 @@ generic_link_add_symbol_list (bfd *abfd,
 
          bh = NULL;
          if (! (_bfd_generic_link_add_one_symbol
-                (info, abfd, name, p->flags, bfd_get_section (p),
+                (info, abfd, name, p->flags, bfd_asymbol_section (p),
                  p->value, string, FALSE, FALSE, &bh)))
            return FALSE;
          h = (struct generic_link_hash_entry *) bh;
@@ -1219,15 +1218,15 @@ generic_link_add_symbol_list (bfd *abfd,
          if (info->output_bfd->xvec == abfd->xvec)
            {
              if (h->sym == NULL
-                 || (! bfd_is_und_section (bfd_get_section (p))
-                     && (! bfd_is_com_section (bfd_get_section (p))
-                         || bfd_is_und_section (bfd_get_section (h->sym)))))
+                 || (! bfd_is_und_section (bfd_asymbol_section (p))
+                     && (! bfd_is_com_section (bfd_asymbol_section (p))
+                         || bfd_is_und_section (bfd_asymbol_section (h->sym)))))
                {
                  h->sym = p;
                  /* BSF_OLD_COMMON is a hack to support COFF reloc
                     reading, and it should go away when the COFF
                     linker is switched to the new version.  */
-                 if (bfd_is_com_section (bfd_get_section (p)))
+                 if (bfd_is_com_section (bfd_asymbol_section (p)))
                    p->flags |= BSF_OLD_COMMON;
                }
            }
@@ -1302,7 +1301,7 @@ static const enum link_action link_action[8][8] =
   /* current\prev    new    undef  undefw def    defw   com    indr   warn  */
   /* UNDEF_ROW */  {UND,   NOACT, UND,   REF,   REF,   NOACT, REFC,  WARNC },
   /* UNDEFW_ROW        */  {WEAK,  NOACT, NOACT, REF,   REF,   NOACT, REFC,  WARNC },
-  /* DEF_ROW   */  {DEF,   DEF,   DEF,   MDEF,  DEF,   CDEF,  MDEF,  CYCLE },
+  /* DEF_ROW   */  {DEF,   DEF,   DEF,   MDEF,  DEF,   CDEF,  MIND,  CYCLE },
   /* DEFW_ROW  */  {DEFW,  DEFW,  DEFW,  NOACT, NOACT, NOACT, NOACT, CYCLE },
   /* COMMON_ROW        */  {COM,   COM,   COM,   CREF,  COM,   BIG,   REFC,  WARNC },
   /* INDR_ROW  */  {IND,   IND,   IND,   MDEF,  IND,   CIND,  MIND,  CYCLE },
@@ -1421,24 +1420,12 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
   else if (bfd_is_com_section (section))
     {
       row = COMMON_ROW;
-      static bfd_boolean report_plugin_err = TRUE;
-      if (!bfd_link_relocatable (info) && report_plugin_err)
-       {
-         if (abfd->lto_slim_object)
-           {
-             report_plugin_err = FALSE;
-             _bfd_error_handler
-               (_("%pB: plugin needed to handle lto object"), abfd);
-           }
-         else if (name[0] == '_'
-                  && name[1] == '_'
-                  && strcmp (name + (name[2] == '_'), "__gnu_lto_slim") == 0)
-           {
-             report_plugin_err = FALSE;
-             _bfd_error_handler
-               (_("%pB: plugin needed to handle lto object"), abfd);
-           }
-       }
+      if (!bfd_link_relocatable (info)
+         && name[0] == '_'
+         && name[1] == '_'
+         && strcmp (name + (name[2] == '_'), "__gnu_lto_slim") == 0)
+       _bfd_error_handler
+         (_("%pB: plugin needed to handle lto object"), abfd);
     }
   else
     row = DEF_ROW;
@@ -1549,7 +1536,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
                s = name + 1;
                while (*s == '_')
                  ++s;
-               if (s[0] == 'G' && CONST_STRNEQ (s, CONS_PREFIX))
+               if (s[0] == 'G' && startswith (s, CONS_PREFIX))
                  {
                    char c;
 
@@ -1685,6 +1672,17 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
        case MIND:
          /* Multiple indirect symbols.  This is OK if they both point
             to the same symbol.  */
+         if (h->u.i.link->type == bfd_link_hash_defweak)
+           {
+             /* It is also OK to redefine a symbol that indirects to
+                a weak definition.  So for sym@ver -> sym@@ver where
+                sym@@ver is weak and we have a new strong sym@ver,
+                redefine sym@@ver.  Of course if there exists
+                sym -> sym@@ver then this also redefines sym.  */
+             h = h->u.i.link;
+             cycle = TRUE;
+             break;
+           }
          if (strcmp (h->u.i.link->root.string, string) == 0)
            break;
          /* Fall through.  */
@@ -1836,8 +1834,8 @@ _bfd_generic_final_link (bfd *abfd, struct bfd_link_info *info)
   size_t outsymalloc;
   struct generic_write_global_symbol_info wginfo;
 
-  bfd_get_outsymbols (abfd) = NULL;
-  bfd_get_symcount (abfd) = 0;
+  abfd->outsymbols = NULL;
+  abfd->symcount = 0;
   outsymalloc = 0;
 
   /* Mark all sections which will be included in the output file.  */
@@ -1970,12 +1968,12 @@ generic_add_output_symbol (bfd *output_bfd, size_t *psymalloc, asymbol *sym)
       newsyms = (asymbol **) bfd_realloc (bfd_get_outsymbols (output_bfd), amt);
       if (newsyms == NULL)
        return FALSE;
-      bfd_get_outsymbols (output_bfd) = newsyms;
+      output_bfd->outsymbols = newsyms;
     }
 
-  bfd_get_outsymbols (output_bfd) [bfd_get_symcount (output_bfd)] = sym;
+  output_bfd->outsymbols[output_bfd->symcount] = sym;
   if (sym != NULL)
-    ++ bfd_get_symcount (output_bfd);
+    ++output_bfd->symcount;
 
   return TRUE;
 }
@@ -2008,7 +2006,7 @@ _bfd_generic_link_output_symbols (bfd *output_bfd,
              newsym = bfd_make_empty_symbol (input_bfd);
              if (!newsym)
                return FALSE;
-             newsym->name = input_bfd->filename;
+             newsym->name = bfd_get_filename (input_bfd);
              newsym->value = 0;
              newsym->flags = BSF_LOCAL | BSF_FILE;
              newsym->section = sec;
@@ -2039,9 +2037,9 @@ _bfd_generic_link_output_symbols (bfd *output_bfd,
                         | BSF_GLOBAL
                         | BSF_CONSTRUCTOR
                         | BSF_WEAK)) != 0
-         || bfd_is_und_section (bfd_get_section (sym))
-         || bfd_is_com_section (bfd_get_section (sym))
-         || bfd_is_ind_section (bfd_get_section (sym)))
+         || bfd_is_und_section (bfd_asymbol_section (sym))
+         || bfd_is_com_section (bfd_asymbol_section (sym))
+         || bfd_is_ind_section (bfd_asymbol_section (sym)))
        {
          if (sym->udata.p != NULL)
            h = (struct generic_link_hash_entry *) sym->udata.p;
@@ -2057,7 +2055,7 @@ _bfd_generic_link_output_symbols (bfd *output_bfd,
                 the relocs in the output format being used.  */
              h = NULL;
            }
-         else if (bfd_is_und_section (bfd_get_section (sym)))
+         else if (bfd_is_und_section (bfd_asymbol_section (sym)))
            h = ((struct generic_link_hash_entry *)
                 bfd_wrapped_link_hash_lookup (output_bfd, info,
                                               bfd_asymbol_name (sym),
@@ -2409,13 +2407,13 @@ _bfd_generic_reloc_link_order (bfd *abfd,
          (*info->callbacks->reloc_overflow)
            (info, NULL,
             (link_order->type == bfd_section_reloc_link_order
-             ? bfd_section_name (abfd, link_order->u.reloc.p->u.section)
+             ? bfd_section_name (link_order->u.reloc.p->u.section)
              : link_order->u.reloc.p->u.name),
             r->howto->name, link_order->u.reloc.p->addend,
             NULL, NULL, 0);
          break;
        }
-      loc = link_order->offset * bfd_octets_per_byte (abfd);
+      loc = link_order->offset * bfd_octets_per_byte (abfd, sec);
       ok = bfd_set_section_contents (abfd, sec, buf, loc, size);
       free (buf);
       if (! ok)
@@ -2435,7 +2433,7 @@ _bfd_generic_reloc_link_order (bfd *abfd,
 struct bfd_link_order *
 bfd_new_link_order (bfd *abfd, asection *section)
 {
-  bfd_size_type amt = sizeof (struct bfd_link_order);
+  size_t amt = sizeof (struct bfd_link_order);
   struct bfd_link_order *new_lo;
 
   new_lo = (struct bfd_link_order *) bfd_zalloc (abfd, amt);
@@ -2482,7 +2480,7 @@ _bfd_default_link_order (bfd *abfd,
 
 static bfd_boolean
 default_data_link_order (bfd *abfd,
-                        struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                        struct bfd_link_info *info,
                         asection *sec,
                         struct bfd_link_order *link_order)
 {
@@ -2502,7 +2500,7 @@ default_data_link_order (bfd *abfd,
   fill_size = link_order->u.data.size;
   if (fill_size == 0)
     {
-      fill = abfd->arch_info->fill (size, bfd_big_endian (abfd),
+      fill = abfd->arch_info->fill (size, info->big_endian,
                                    (sec->flags & SEC_CODE) != 0);
       if (fill == NULL)
        return FALSE;
@@ -2531,7 +2529,7 @@ default_data_link_order (bfd *abfd,
        }
     }
 
-  loc = link_order->offset * bfd_octets_per_byte (abfd);
+  loc = link_order->offset * bfd_octets_per_byte (abfd, sec);
   result = bfd_set_section_contents (abfd, sec, fill, loc, size);
 
   if (fill != link_order->u.data.contents)
@@ -2614,15 +2612,15 @@ default_indirect_link_order (bfd *output_bfd,
                             | BSF_GLOBAL
                             | BSF_CONSTRUCTOR
                             | BSF_WEAK)) != 0
-             || bfd_is_und_section (bfd_get_section (sym))
-             || bfd_is_com_section (bfd_get_section (sym))
-             || bfd_is_ind_section (bfd_get_section (sym)))
+             || bfd_is_und_section (bfd_asymbol_section (sym))
+             || bfd_is_com_section (bfd_asymbol_section (sym))
+             || bfd_is_ind_section (bfd_asymbol_section (sym)))
            {
              /* sym->udata may have been set by
                 generic_link_add_symbol_list.  */
              if (sym->udata.p != NULL)
                h = (struct bfd_link_hash_entry *) sym->udata.p;
-             else if (bfd_is_und_section (bfd_get_section (sym)))
+             else if (bfd_is_und_section (bfd_asymbol_section (sym)))
                h = bfd_wrapped_link_hash_lookup (output_bfd, info,
                                                  bfd_asymbol_name (sym),
                                                  FALSE, FALSE, TRUE);
@@ -2668,18 +2666,17 @@ default_indirect_link_order (bfd *output_bfd,
     }
 
   /* Output the section contents.  */
-  loc = input_section->output_offset * bfd_octets_per_byte (output_bfd);
+  loc = (input_section->output_offset
+        * bfd_octets_per_byte (output_bfd, output_section));
   if (! bfd_set_section_contents (output_bfd, output_section,
                                  new_contents, loc, input_section->size))
     goto error_return;
 
-  if (contents != NULL)
-    free (contents);
+  free (contents);
   return TRUE;
 
  error_return:
-  if (contents != NULL)
-    free (contents);
+  free (contents);
   return FALSE;
 }
 
@@ -2906,10 +2903,8 @@ _bfd_handle_already_linked (asection *sec,
              (_("%pB: duplicate section `%pA' has different contents\n"),
               sec->owner, sec);
 
-         if (sec_contents)
-           free (sec_contents);
-         if (l_sec_contents)
-           free (l_sec_contents);
+         free (sec_contents);
+         free (l_sec_contents);
        }
       break;
     }
@@ -2955,7 +2950,7 @@ _bfd_generic_section_already_linked (bfd *abfd ATTRIBUTE_UNUSED,
      into a single large link once section, which defeats the purpose
      of having link once sections in the first place.  */
 
-  name = bfd_get_section_name (abfd, sec);
+  name = bfd_section_name (sec);
 
   already_linked_list = bfd_section_already_linked_table_lookup (name);
 
@@ -3111,8 +3106,13 @@ bfd_generic_define_common_symbol (bfd *output_bfd,
   section = h->u.c.p->section;
 
   /* Increase the size of the section to align the common symbol.
-     The alignment must be a power of two.  */
-  alignment = bfd_octets_per_byte (output_bfd) << power_of_two;
+     The alignment must be a power of two.  But if the section does
+     not have any alignment requirement then do not increase the
+     alignment unnecessarily.  */
+  if (power_of_two)
+    alignment = bfd_octets_per_byte (output_bfd, section) << power_of_two;
+  else
+    alignment = 1;
   BFD_ASSERT (alignment != 0 && (alignment & -alignment) == alignment);
   section->size += alignment - 1;
   section->size &= -alignment;
@@ -3188,6 +3188,7 @@ bfd_generic_define_start_stop (struct bfd_link_info *info,
 
   h = bfd_link_hash_lookup (info->hash, symbol, FALSE, FALSE, TRUE);
   if (h != NULL
+      && !h->ldscript_def
       && (h->type == bfd_link_hash_undefined
          || h->type == bfd_link_hash_undefweak))
     {
@@ -3473,6 +3474,13 @@ _bfd_nolink_bfd_is_group_section (bfd *abfd,
   return _bfd_bool_bfd_false_error (abfd);
 }
 
+const char *
+_bfd_nolink_bfd_group_name (bfd *abfd,
+                           const asection *sec ATTRIBUTE_UNUSED)
+{
+  return _bfd_ptr_bfd_null_error (abfd);
+}
+
 bfd_boolean
 _bfd_nolink_bfd_discard_group (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
 {
This page took 0.029387 seconds and 4 git commands to generate.