]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
get_synthetic_symtab fixes for commit 68bbe1183379
authorAlan Modra <amodra@gmail.com>
Fri, 4 Oct 2024 04:00:09 +0000 (13:30 +0930)
committerAlan Modra <amodra@gmail.com>
Fri, 4 Oct 2024 08:17:21 +0000 (17:47 +0930)
Given that relocation symbol name can now be NULL for ELF, adjust
various get_synthetic_symtab routines so they don't segfault.

* elf.c (_bfd_elf_get_synthetic_symtab): Cope with sym->name
possibly being NULL.
* elf32-arm.c (elf32_arm_get_synthetic_symtab): Likewise.
* elf32-ppc.c (ppc_elf_get_synthetic_symtab): Likewise.
* elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Likewise.
* elfxx-mips.c (_bfd_mips_elf_get_synthetic_symtab): Likewise.
* elfxx-x86.c (_bfd_x86_elf_get_synthetic_symtab): Likewise.

bfd/elf.c
bfd/elf32-arm.c
bfd/elf32-ppc.c
bfd/elf64-ppc.c
bfd/elfxx-mips.c
bfd/elfxx-x86.c

index 38bfb1c2064d06d6ae70a1c47dd9db4abea01da0..39ee641097b357be97392d925603154b6d02dd41 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -13537,17 +13537,19 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd,
   size = count * sizeof (asymbol);
   p = relplt->relocation;
   for (i = 0; i < count; i++, p += bed->s->int_rels_per_ext_rel)
-    {
-      size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
-      if (p->addend != 0)
-       {
+    if ((*p->sym_ptr_ptr)->name != NULL)
+      {
+       size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+       if (p->addend != 0)
+         {
 #ifdef BFD64
-         size += sizeof ("+0x") - 1 + 8 + 8 * (bed->s->elfclass == ELFCLASS64);
+           size += (sizeof ("+0x") - 1 + 8
+                    + 8 * (bed->s->elfclass == ELFCLASS64));
 #else
-         size += sizeof ("+0x") - 1 + 8;
+           size += sizeof ("+0x") - 1 + 8;
 #endif
-       }
-    }
+         }
+      }
 
   s = *ret = (asymbol *) bfd_malloc (size);
   if (s == NULL)
@@ -13565,6 +13567,9 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd,
       if (addr == (bfd_vma) -1)
        continue;
 
+      if ((*p->sym_ptr_ptr)->name == NULL)
+       continue;
+
       *s = **p->sym_ptr_ptr;
       /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
         we are defining a symbol, ensure one of them is set.  */
index 17df8b30eb63f821c1c0db047d7d3484cd07ca1d..f1d23342e66fd4af4993f457184c30335dca3244 100644 (file)
@@ -20100,6 +20100,7 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
   char *names;
   asection *plt;
   bfd_vma offset;
+  bfd_vma plt_size;
   bfd_byte *data;
 
   *ret = NULL;
@@ -20134,11 +20135,12 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
   size = count * sizeof (asymbol);
   p = relplt->relocation;
   for (i = 0; i < count; i++, p += elf32_arm_size_info.int_rels_per_ext_rel)
-    {
-      size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
-      if (p->addend != 0)
-       size += sizeof ("+0x") - 1 + 8;
-    }
+    if ((*p->sym_ptr_ptr)->name != NULL)
+      {
+       size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+       if (p->addend != 0)
+         size += sizeof ("+0x") - 1 + 8;
+      }
 
   offset = elf32_arm_plt0_size (abfd, data, plt->size);
   if (offset == (bfd_vma) -1
@@ -20149,16 +20151,19 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
     }
 
   names = (char *) (s + count);
-  p = relplt->relocation;
-  n = 0;
-  for (i = 0; i < count; i++, p += elf32_arm_size_info.int_rels_per_ext_rel)
+  for (i = 0, p = relplt->relocation, n = 0;
+       i < count;
+       i++, p += elf32_arm_size_info.int_rels_per_ext_rel, offset += plt_size)
     {
       size_t len;
 
-      bfd_vma plt_size = elf32_arm_plt_size (abfd, data, offset, plt->size);
+      plt_size = elf32_arm_plt_size (abfd, data, offset, plt->size);
       if (plt_size == (bfd_vma) -1)
        break;
 
+      if ((*p->sym_ptr_ptr)->name == NULL)
+       continue;
+
       *s = **p->sym_ptr_ptr;
       /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
         we are defining a symbol, ensure one of them is set.  */
@@ -20188,7 +20193,6 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
       memcpy (names, "@plt", sizeof ("@plt"));
       names += sizeof ("@plt");
       ++s, ++n;
-      offset += plt_size;
     }
 
   free (data);
index a5370a0624e8a7121e510d498e6e0f636a4e91b9..0d415d60936de63656b3ae6f932a855ec9ecc1fa 100644 (file)
@@ -1806,7 +1806,7 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
   bfd_vma stub_off;
   asymbol *s;
   arelent *p;
-  size_t count, i, stub_delta;
+  size_t count, n, i, stub_delta;
   size_t size;
   char *names;
   bfd_byte buf[4];
@@ -1935,11 +1935,12 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
   size = count * sizeof (asymbol);
   p = relplt->relocation;
   for (i = 0; i < count; i++, p++)
-    {
-      size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
-      if (p->addend != 0)
-       size += sizeof ("+0x") - 1 + 8;
-    }
+    if ((*p->sym_ptr_ptr)->name != NULL)
+      {
+       size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+       if (p->addend != 0)
+         size += sizeof ("+0x") - 1 + 8;
+      }
 
   size += sizeof (asymbol) + sizeof ("__glink");
 
@@ -1953,38 +1954,40 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
   stub_off = glink_vma - glink->vma;
   names = (char *) (s + count + 1 + (resolv_vma != 0));
   p = relplt->relocation + count - 1;
-  for (i = 0; i < count; i++)
-    {
-      size_t len;
-
-      stub_off -= stub_delta;
-      if (strcmp ((*p->sym_ptr_ptr)->name, "__tls_get_addr_opt") == 0)
-       stub_off -= 32;
-      *s = **p->sym_ptr_ptr;
-      /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
-        we are defining a symbol, ensure one of them is set.  */
-      if ((s->flags & BSF_LOCAL) == 0)
-       s->flags |= BSF_GLOBAL;
-      s->flags |= BSF_SYNTHETIC;
-      s->section = glink;
-      s->value = stub_off;
-      s->name = names;
-      s->udata.p = NULL;
-      len = strlen ((*p->sym_ptr_ptr)->name);
-      memcpy (names, (*p->sym_ptr_ptr)->name, len);
-      names += len;
-      if (p->addend != 0)
-       {
-         memcpy (names, "+0x", sizeof ("+0x") - 1);
-         names += sizeof ("+0x") - 1;
-         bfd_sprintf_vma (abfd, names, p->addend);
-         names += strlen (names);
-       }
-      memcpy (names, "@plt", sizeof ("@plt"));
-      names += sizeof ("@plt");
-      ++s;
-      --p;
-    }
+  for (n = 0, i = 0; i < count; i++)
+    if ((*p->sym_ptr_ptr)->name != NULL)
+      {
+       size_t len;
+
+       stub_off -= stub_delta;
+       if (strcmp ((*p->sym_ptr_ptr)->name, "__tls_get_addr_opt") == 0)
+         stub_off -= 32;
+       *s = **p->sym_ptr_ptr;
+       /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
+          we are defining a symbol, ensure one of them is set.  */
+       if ((s->flags & BSF_LOCAL) == 0)
+         s->flags |= BSF_GLOBAL;
+       s->flags |= BSF_SYNTHETIC;
+       s->section = glink;
+       s->value = stub_off;
+       s->name = names;
+       s->udata.p = NULL;
+       len = strlen ((*p->sym_ptr_ptr)->name);
+       memcpy (names, (*p->sym_ptr_ptr)->name, len);
+       names += len;
+       if (p->addend != 0)
+         {
+           memcpy (names, "+0x", sizeof ("+0x") - 1);
+           names += sizeof ("+0x") - 1;
+           bfd_sprintf_vma (abfd, names, p->addend);
+           names += strlen (names);
+         }
+       memcpy (names, "@plt", sizeof ("@plt"));
+       names += sizeof ("@plt");
+       ++s;
+       --p;
+       ++n;
+      }
 
   /* Add a symbol at the start of the glink branch table.  */
   memset (s, 0, sizeof *s);
@@ -1996,7 +1999,7 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
   memcpy (names, "__glink", sizeof ("__glink"));
   names += sizeof ("__glink");
   s++;
-  count++;
+  n++;
 
   if (resolv_vma)
     {
@@ -2010,10 +2013,10 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
       memcpy (names, "__glink_PLTresolve", sizeof ("__glink_PLTresolve"));
       names += sizeof ("__glink_PLTresolve");
       s++;
-      count++;
+      n++;
     }
 
-  return count;
+  return n;
 }
 \f
 /* The following functions are specific to the ELF linker, while
index cd3aaacaeb352d6bd74d563b1dbb2b370f852cd1..29221033cb0c47180de335245420f70ee80306db 100644 (file)
@@ -2402,7 +2402,8 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
 
          sym = *r->sym_ptr_ptr;
          if (!sym_exists_at (syms, opdsymend, symcount,
-                             sym->section->id, sym->value + r->addend))
+                             sym->section->id, sym->value + r->addend)
+             && syms[i]->name != NULL)
            {
              ++count;
              size += sizeof (asymbol);
@@ -2440,7 +2441,8 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
 
          sym = *r->sym_ptr_ptr;
          if (!sym_exists_at (syms, opdsymend, symcount,
-                             sym->section->id, sym->value + r->addend))
+                             sym->section->id, sym->value + r->addend)
+             && syms[i]->name != NULL)
            {
              size_t len;
 
@@ -2491,7 +2493,8 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
            continue;
 
          ent = bfd_get_64 (abfd, contents + syms[i]->value);
-         if (!sym_exists_at (syms, opdsymend, symcount, -1, ent))
+         if (!sym_exists_at (syms, opdsymend, symcount, -1, ent)
+             && syms[i]->name != NULL)
            {
              ++count;
              size += sizeof (asymbol);
@@ -2579,11 +2582,12 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
 
              p = relplt->relocation;
              for (i = 0; i < plt_count; i++, p++)
-               {
-                 size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
-                 if (p->addend != 0)
-                   size += sizeof ("+0x") - 1 + 16;
-               }
+               if ((*p->sym_ptr_ptr)->name != NULL)
+                 {
+                   size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+                   if (p->addend != 0)
+                     size += sizeof ("+0x") - 1 + 16;
+                 }
            }
        }
 
@@ -2603,7 +2607,8 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
            continue;
 
          ent = bfd_get_64 (abfd, contents + syms[i]->value);
-         if (!sym_exists_at (syms, opdsymend, symcount, -1, ent))
+         if (!sym_exists_at (syms, opdsymend, symcount, -1, ent)
+             && syms[i]->name != NULL)
            {
              size_t lo, hi;
              size_t len;
@@ -2691,42 +2696,43 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
             for pending shared library loads.  */
          p = relplt->relocation;
          for (i = 0; i < plt_count; i++, p++)
-           {
-             size_t len;
-
-             *s = **p->sym_ptr_ptr;
-             /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
-                we are defining a symbol, ensure one of them is set.  */
-             if ((s->flags & BSF_LOCAL) == 0)
-               s->flags |= BSF_GLOBAL;
-             s->flags |= BSF_SYNTHETIC;
-             s->section = glink;
-             s->value = glink_vma - glink->vma;
-             s->name = names;
-             s->udata.p = NULL;
-             len = strlen ((*p->sym_ptr_ptr)->name);
-             memcpy (names, (*p->sym_ptr_ptr)->name, len);
-             names += len;
-             if (p->addend != 0)
-               {
-                 memcpy (names, "+0x", sizeof ("+0x") - 1);
-                 names += sizeof ("+0x") - 1;
-                 bfd_sprintf_vma (abfd, names, p->addend);
-                 names += strlen (names);
-               }
-             memcpy (names, "@plt", sizeof ("@plt"));
-             names += sizeof ("@plt");
-             s++;
-             if (abi < 2)
-               {
-                 glink_vma += 8;
-                 if (i >= 0x8000)
-                   glink_vma += 4;
-               }
-             else
-               glink_vma += 4;
-           }
-         count += plt_count;
+           if ((*p->sym_ptr_ptr)->name != NULL)
+             {
+               size_t len;
+
+               *s = **p->sym_ptr_ptr;
+               /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
+                  we are defining a symbol, ensure one of them is set.  */
+               if ((s->flags & BSF_LOCAL) == 0)
+                 s->flags |= BSF_GLOBAL;
+               s->flags |= BSF_SYNTHETIC;
+               s->section = glink;
+               s->value = glink_vma - glink->vma;
+               s->name = names;
+               s->udata.p = NULL;
+               len = strlen ((*p->sym_ptr_ptr)->name);
+               memcpy (names, (*p->sym_ptr_ptr)->name, len);
+               names += len;
+               if (p->addend != 0)
+                 {
+                   memcpy (names, "+0x", sizeof ("+0x") - 1);
+                   names += sizeof ("+0x") - 1;
+                   bfd_sprintf_vma (abfd, names, p->addend);
+                   names += strlen (names);
+                 }
+               memcpy (names, "@plt", sizeof ("@plt"));
+               names += sizeof ("@plt");
+               s++;
+               if (abi < 2)
+                 {
+                   glink_vma += 8;
+                   if (i >= 0x8000)
+                     glink_vma += 4;
+                 }
+               else
+                 glink_vma += 4;
+               count++;
+             }
        }
     }
 
index 59444b063a440b457e67e35d9640d830cc276f9d..4c7cd7f77b0b88b50cf0bcd9413dd5c3b3a213e7 100644 (file)
@@ -16624,7 +16624,8 @@ _bfd_mips_elf_get_synthetic_symtab (bfd *abfd,
   size += count * (sizeof (mipssuffix) +
                   (micromips_p ? sizeof (microsuffix) : sizeof (m16suffix)));
   for (pi = 0; pi < counti; pi += bed->s->int_rels_per_ext_rel)
-    size += 2 * strlen ((*p[pi].sym_ptr_ptr)->name);
+    if ((*p[pi].sym_ptr_ptr)->name != NULL)
+      size += 2 * strlen ((*p[pi].sym_ptr_ptr)->name);
 
   /* Add the size of "_PROCEDURE_LINKAGE_TABLE_" too.  */
   size += sizeof (asymbol) + sizeof (pltname);
@@ -16754,31 +16755,34 @@ _bfd_mips_elf_get_synthetic_symtab (bfd *abfd,
 
       if (i < count)
        {
-         size_t namelen;
-         size_t len;
-
-         *s = **p[pi].sym_ptr_ptr;
-         /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
-            we are defining a symbol, ensure one of them is set.  */
-         if ((s->flags & BSF_LOCAL) == 0)
-           s->flags |= BSF_GLOBAL;
-         s->flags |= BSF_SYNTHETIC;
-         s->section = plt;
-         s->value = plt_offset;
-         s->name = names;
-         s->udata.i = other;
-
-         len = strlen ((*p[pi].sym_ptr_ptr)->name);
-         namelen = len + suffixlen;
-         if (names + namelen > nend)
-           break;
+         if ((*p[pi].sym_ptr_ptr)->name != NULL)
+           {
+             size_t namelen;
+             size_t len;
+
+             *s = **p[pi].sym_ptr_ptr;
+             /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL set.  Since
+                we are defining a symbol, ensure one of them is set.  */
+             if ((s->flags & BSF_LOCAL) == 0)
+               s->flags |= BSF_GLOBAL;
+             s->flags |= BSF_SYNTHETIC;
+             s->section = plt;
+             s->value = plt_offset;
+             s->name = names;
+             s->udata.i = other;
+
+             len = strlen ((*p[pi].sym_ptr_ptr)->name);
+             namelen = len + suffixlen;
+             if (names + namelen > nend)
+               break;
 
-         memcpy (names, (*p[pi].sym_ptr_ptr)->name, len);
-         names += len;
-         memcpy (names, suffix, suffixlen);
-         names += suffixlen;
+             memcpy (names, (*p[pi].sym_ptr_ptr)->name, len);
+             names += len;
+             memcpy (names, suffix, suffixlen);
+             names += suffixlen;
 
-         ++s, ++n;
+             ++s, ++n;
+           }
          pi = (pi + bed->s->int_rels_per_ext_rel) % counti;
        }
     }
index dd951b91f50281cd4db32a5bd554f42bfea055ef..dda3c7a9d7a78c9000f432a01ea11652037940b0 100644 (file)
@@ -3710,9 +3710,12 @@ _bfd_x86_elf_get_synthetic_symtab (bfd *abfd,
   for (i = 0; i < dynrelcount; i++)
     {
       p = dynrelbuf[i];
-      size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
-      if (p->addend != 0)
-       size += sizeof ("+0x") - 1 + 8 + 8 * ABI_64_P (abfd);
+      if ((*p->sym_ptr_ptr)->name != NULL)
+       {
+         size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+         if (p->addend != 0)
+           size += sizeof ("+0x") - 1 + 8 + 8 * ABI_64_P (abfd);
+       }
     }
 
   s = *ret = (asymbol *) bfd_zmalloc (size);
@@ -3817,7 +3820,8 @@ _bfd_x86_elf_get_synthetic_symtab (bfd *abfd,
            /* Skip unknown relocation.  PR 17512: file: bc9d6cf5.  */
            if (got_vma == p->address
                && p->howto != NULL
-               && valid_plt_reloc_p (p->howto->type))
+               && valid_plt_reloc_p (p->howto->type)
+               && (*p->sym_ptr_ptr)->name != NULL)
              {
                *s = **p->sym_ptr_ptr;
                /* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL