[binutils-gdb] get_synthetic_symtab fixes for commit 68bbe1183379

Alan Modra amodra@sourceware.org
Fri Oct 4 08:25:19 GMT 2024


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0c13ac533e59589793ee6c8045cff98663f3ea85

commit 0c13ac533e59589793ee6c8045cff98663f3ea85
Author: Alan Modra <amodra@gmail.com>
Date:   Fri Oct 4 13:30:09 2024 +0930

    get_synthetic_symtab fixes for commit 68bbe1183379
    
    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.

Diff:
---
 bfd/elf.c        | 21 ++++++++-----
 bfd/elf32-arm.c  | 24 ++++++++------
 bfd/elf32-ppc.c  | 85 +++++++++++++++++++++++++------------------------
 bfd/elf64-ppc.c  | 96 ++++++++++++++++++++++++++++++--------------------------
 bfd/elfxx-mips.c | 52 ++++++++++++++++--------------
 bfd/elfxx-x86.c  | 12 ++++---
 6 files changed, 158 insertions(+), 132 deletions(-)

diff --git a/bfd/elf.c b/bfd/elf.c
index 38bfb1c2064..39ee641097b 100644
--- 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.  */
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 17df8b30eb6..f1d23342e66 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -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);
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index a5370a0624e..0d415d60936 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -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;
 }
 

 /* The following functions are specific to the ELF linker, while
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index cd3aaacaeb3..29221033cb0 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -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++;
+	      }
 	}
     }
 
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 59444b063a4..4c7cd7f77b0 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -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;
 	}
     }
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index dd951b91f50..dda3c7a9d7a 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -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


More information about the Binutils-cvs mailing list