x86: Allocate space for symbol names with symbol table
authorH.J. Lu <hjl.tools@gmail.com>
Fri, 11 Aug 2017 16:32:44 +0000 (09:32 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 11 Aug 2017 16:40:39 +0000 (09:40 -0700)
When synthesizing symbols for PLT entries, allocate space for symbol
names with @plt suffixes together with symbol table so that all memory
is returned when symbol table is freed.

PR binutils/21943
* elf32-i386.c (elf_i386_get_synthetic_symtab): Allocate space
for @plt suffixes first.
* elf64-x86-64.c (elf_x86_64_get_synthetic_symtab): Likewise.

bfd/ChangeLog
bfd/elf32-i386.c
bfd/elf64-x86-64.c

index 3a09575..356d19b 100644 (file)
@@ -1,3 +1,10 @@
+2017-08-11  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR binutils/21943
+       * elf32-i386.c (elf_i386_get_synthetic_symtab): Allocate space
+       for @plt suffixes first.
+       * elf64-x86-64.c (elf_x86_64_get_synthetic_symtab): Likewise.
+
 2017-08-08  Nick Clifton  <nickc@redhat.com>
 
        PR 21916
index f1fcd21..d5477c4 100644 (file)
@@ -6272,13 +6272,13 @@ elf_i386_get_synthetic_symtab (bfd *abfd,
                               asymbol **dynsyms,
                               asymbol **ret)
 {
-  long size, count, i, n;
+  long size, count, i, n, len;
   int j;
   unsigned int plt_got_offset, plt_entry_size;
   asymbol *s;
   bfd_byte *plt_contents;
   long dynrelcount, relsize;
-  arelent **dynrelbuf;
+  arelent **dynrelbuf, *p;
   const struct elf_i386_lazy_plt_layout *lazy_plt;
   const struct elf_i386_non_lazy_plt_layout *non_lazy_plt;
   const struct elf_i386_lazy_plt_layout *lazy_ibt_plt;
@@ -6462,6 +6462,17 @@ elf_i386_get_synthetic_symtab (bfd *abfd,
     }
 
   size = count * sizeof (asymbol);
+
+  /* Allocate space for @plt suffixes.  */
+  n = 0;
+  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;
+    }
+
   s = *ret = (asymbol *) bfd_zmalloc (size);
   if (s == NULL)
     {
@@ -6492,6 +6503,7 @@ bad_return:
     }
 
   /* Check for each PLT section.  */
+  names = (char *) (s + count);
   size = 0;
   n = 0;
   for (j = 0; plts[j].name != NULL; j++)
@@ -6523,7 +6535,6 @@ bad_return:
            int off;
            bfd_vma got_vma;
            long min, max, mid;
-           arelent *p;
 
            /* Get the GOT offset, a signed 32-bit integer.  */
            off = H_GET_32 (abfd, (plt_contents + offset
@@ -6570,12 +6581,26 @@ bad_return:
                s->section = plt;
                s->the_bfd = plt->owner;
                s->value = offset;
-               /* Store relocation for later use.  */
-               s->udata.p = p;
-               /* Add @plt to function name later.  */
-               size += strlen (s->name) + sizeof ("@plt");
+               s->udata.p = NULL;
+               s->name = names;
+               len = strlen ((*p->sym_ptr_ptr)->name);
+               memcpy (names, (*p->sym_ptr_ptr)->name, len);
+               names += len;
                if (p->addend != 0)
-                 size += sizeof ("+0x") - 1 + 8;
+                 {
+                   char buf[30], *a;
+
+                   memcpy (names, "+0x", sizeof ("+0x") - 1);
+                   names += sizeof ("+0x") - 1;
+                   bfd_sprintf_vma (abfd, buf, p->addend);
+                   for (a = buf; *a == '0'; ++a)
+                     ;
+                   size = strlen (a);
+                   memcpy (names, a, size);
+                   names += size;
+                 }
+               memcpy (names, "@plt", sizeof ("@plt"));
+               names += sizeof ("@plt");
                n++;
                s++;
              }
@@ -6589,40 +6614,6 @@ bad_return:
 
   count = n;
 
-  /* Allocate space for @plt suffixes.  */
-  names = (char *) bfd_malloc (size);
-  if (s == NULL)
-    goto bad_return;
-
-  s = *ret;
-  for (i = 0; i < count; i++)
-    {
-      /* Add @plt to function name.  */
-      arelent *p = (arelent *) s->udata.p;
-      /* Clear it now.  */
-      s->udata.p = NULL;
-      size = strlen (s->name);
-      memcpy (names, s->name, size);
-      s->name = names;
-      names += size;
-      if (p->addend != 0)
-       {
-         char buf[30], *a;
-
-         memcpy (names, "+0x", sizeof ("+0x") - 1);
-         names += sizeof ("+0x") - 1;
-         bfd_sprintf_vma (abfd, buf, p->addend);
-         for (a = buf; *a == '0'; ++a)
-           ;
-         size = strlen (a);
-         memcpy (names, a, size);
-         names += size;
-       }
-      memcpy (names, "@plt", sizeof ("@plt"));
-      names += sizeof ("@plt");
-      s++;
-    }
-
   for (j = 0; plts[j].name != NULL; j++)
     if (plts[j].contents != NULL)
       free (plts[j].contents);
index 8364384..8a6bd62 100644 (file)
@@ -6634,13 +6634,13 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
                                 asymbol **dynsyms,
                                 asymbol **ret)
 {
-  long size, count, i, n;
+  long size, count, i, n, len;
   int j;
   unsigned int plt_got_offset, plt_entry_size, plt_got_insn_size;
   asymbol *s;
   bfd_byte *plt_contents;
   long dynrelcount, relsize;
-  arelent **dynrelbuf;
+  arelent **dynrelbuf, *p;
   const struct elf_x86_64_lazy_plt_layout *lazy_plt;
   const struct elf_x86_64_non_lazy_plt_layout *non_lazy_plt;
   const struct elf_x86_64_lazy_plt_layout *lazy_bnd_plt;
@@ -6821,6 +6821,17 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
     }
 
   size = count * sizeof (asymbol);
+
+  /* Allocate space for @plt suffixes.  */
+  n = 0;
+  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);
+    }
+
   s = *ret = (asymbol *) bfd_zmalloc (size);
   if (s == NULL)
     {
@@ -6833,6 +6844,7 @@ bad_return:
     }
 
   /* Check for each PLT section.  */
+  names = (char *) (s + count);
   size = 0;
   n = 0;
   for (j = 0; plts[j].name != NULL; j++)
@@ -6865,7 +6877,6 @@ bad_return:
            int off;
            bfd_vma got_vma;
            long min, max, mid;
-           arelent *p;
 
            /* Get the PC-relative offset, a signed 32-bit integer.  */
            off = H_GET_32 (abfd, (plt_contents + offset
@@ -6912,12 +6923,26 @@ bad_return:
                s->section = plt;
                s->the_bfd = plt->owner;
                s->value = offset;
-               /* Store relocation for later use.  */
-               s->udata.p = p;
-               /* Add @plt to function name later.  */
-               size += strlen (s->name) + sizeof ("@plt");
+               s->udata.p = NULL;
+               s->name = names;
+               len = strlen ((*p->sym_ptr_ptr)->name);
+               memcpy (names, (*p->sym_ptr_ptr)->name, len);
+               names += len;
                if (p->addend != 0)
-                 size += sizeof ("+0x") - 1 + 8 + 8 * ABI_64_P (abfd);
+                 {
+                   char buf[30], *a;
+
+                   memcpy (names, "+0x", sizeof ("+0x") - 1);
+                   names += sizeof ("+0x") - 1;
+                   bfd_sprintf_vma (abfd, buf, p->addend);
+                   for (a = buf; *a == '0'; ++a)
+                     ;
+                   size = strlen (a);
+                   memcpy (names, a, size);
+                   names += size;
+                 }
+               memcpy (names, "@plt", sizeof ("@plt"));
+               names += sizeof ("@plt");
                n++;
                s++;
              }
@@ -6931,40 +6956,6 @@ bad_return:
 
   count = n;
 
-  /* Allocate space for @plt suffixes.  */
-  names = (char *) bfd_malloc (size);
-  if (s == NULL)
-    goto bad_return;
-
-  s = *ret;
-  for (i = 0; i < count; i++)
-    {
-      /* Add @plt to function name.  */
-      arelent *p = (arelent *) s->udata.p;
-      /* Clear it now.  */
-      s->udata.p = NULL;
-      size = strlen (s->name);
-      memcpy (names, s->name, size);
-      s->name = names;
-      names += size;
-      if (p->addend != 0)
-       {
-         char buf[30], *a;
-
-         memcpy (names, "+0x", sizeof ("+0x") - 1);
-         names += sizeof ("+0x") - 1;
-         bfd_sprintf_vma (abfd, buf, p->addend);
-         for (a = buf; *a == '0'; ++a)
-           ;
-         size = strlen (a);
-         memcpy (names, a, size);
-         names += size;
-       }
-      memcpy (names, "@plt", sizeof ("@plt"));
-      names += sizeof ("@plt");
-      s++;
-    }
-
   for (j = 0; plts[j].name != NULL; j++)
     if (plts[j].contents != NULL)
       free (plts[j].contents);