x86: Add _bfd_x86_elf_get_synthetic_symtab
[deliverable/binutils-gdb.git] / bfd / elf64-x86-64.c
index 3bf465b46fa83c2f228ecd24495133dbac85cf8f..0edb17470c4cff6493bd59d8aa7788ba63e3dc42 100644 (file)
@@ -5995,26 +5995,6 @@ elf_x86_64_output_arch_local_syms
   return TRUE;
 }
 
-enum elf_x86_64_plt_type
-{
-  plt_non_lazy = 0,
-  plt_lazy = 1 << 0,
-  plt_second = 1 << 1,
-  plt_unknown = -1
-};
-
-struct elf_x86_64_plt
-{
-  const char *name;
-  asection *sec;
-  bfd_byte *contents;
-  enum elf_x86_64_plt_type type;
-  unsigned int plt_got_offset;
-  unsigned int plt_got_insn_size;
-  unsigned int plt_entry_size;
-  long count;
-};
-
 /* Forward declaration.  */
 static const struct elf_x86_lazy_plt_layout elf_x86_64_nacl_plt;
 
@@ -6029,13 +6009,10 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
                                 asymbol **dynsyms,
                                 asymbol **ret)
 {
-  long size, count, i, n, len;
+  long count, i, n;
   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, *p;
+  long relsize;
   const struct elf_x86_lazy_plt_layout *lazy_plt;
   const struct elf_x86_non_lazy_plt_layout *non_lazy_plt;
   const struct elf_x86_lazy_plt_layout *lazy_bnd_plt;
@@ -6043,9 +6020,8 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
   const struct elf_x86_lazy_plt_layout *lazy_ibt_plt;
   const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt;
   asection *plt;
-  char *names;
-  enum elf_x86_64_plt_type plt_type;
-  struct elf_x86_64_plt plts[] =
+  enum elf_x86_plt_type plt_type;
+  struct elf_x86_plt plts[] =
     {
       { ".plt", NULL, NULL, plt_unknown, 0, 0, 0, 0 },
       { ".plt.got", NULL, NULL, plt_non_lazy, 0, 0, 0, 0 },
@@ -6213,159 +6189,9 @@ elf_x86_64_get_synthetic_symtab (bfd *abfd,
       plts[j].contents = plt_contents;
     }
 
-  if (count == 0)
-    return -1;
-
-  dynrelbuf = (arelent **) bfd_malloc (relsize);
-  if (dynrelbuf == NULL)
-    return -1;
-
-  dynrelcount = bfd_canonicalize_dynamic_reloc (abfd, dynrelbuf,
-                                               dynsyms);
-
-  /* Sort the relocs by address.  */
-  qsort (dynrelbuf, dynrelcount, sizeof (arelent *),
-        _bfd_x86_elf_compare_relocs);
-
-  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)
-    goto bad_return;
-
-  /* Check for each PLT section.  */
-  names = (char *) (s + count);
-  size = 0;
-  n = 0;
-  for (j = 0; plts[j].name != NULL; j++)
-    if ((plt_contents = plts[j].contents) != NULL)
-      {
-       long k;
-       bfd_vma offset;
-
-       plt_got_offset = plts[j].plt_got_offset;
-       plt_got_insn_size = plts[j].plt_got_insn_size;
-       plt_entry_size = plts[j].plt_entry_size;
-
-       plt = plts[j].sec;
-
-       if ((plts[j].type & plt_lazy))
-         {
-           /* Skip PLT0 in lazy PLT.  */
-           k = 1;
-           offset = plt_entry_size;
-         }
-       else
-         {
-           k = 0;
-           offset = 0;
-         }
-
-       /* Check each PLT entry against dynamic relocations.  */
-       for (; k < plts[j].count; k++)
-         {
-           int off;
-           bfd_vma got_vma;
-           long min, max, mid;
-
-           /* Get the PC-relative offset, a signed 32-bit integer.  */
-           off = H_GET_32 (abfd, (plt_contents + offset
-                                  + plt_got_offset));
-           got_vma = plt->vma + offset + off + plt_got_insn_size;
-
-           /* Binary search.  */
-           p = dynrelbuf[0];
-           min = 0;
-           max = dynrelcount;
-           while ((min + 1) < max)
-             {
-               arelent *r;
-
-               mid = (min + max) / 2;
-               r = dynrelbuf[mid];
-               if (got_vma > r->address)
-                 min = mid;
-               else if (got_vma < r->address)
-                 max = mid;
-               else
-                 {
-                   p = r;
-                   break;
-                 }
-             }
-
-           /* Skip unknown relocation.  PR 17512: file: bc9d6cf5.  */
-           if (got_vma == p->address
-               && p->howto != NULL
-               && (p->howto->type == R_X86_64_JUMP_SLOT
-                   || p->howto->type == R_X86_64_GLOB_DAT
-                   || p->howto->type == R_X86_64_IRELATIVE))
-             {
-               *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;
-               /* This is no longer a section symbol.  */
-               s->flags &= ~BSF_SECTION_SYM;
-               s->section = plt;
-               s->the_bfd = plt->owner;
-               s->value = offset;
-               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)
-                 {
-                   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++;
-             }
-           offset += plt_entry_size;
-         }
-      }
-
-  /* PLT entries with R_X86_64_TLSDESC relocations are skipped.  */
-  if (n == 0)
-    {
-bad_return:
-      count = -1;
-    }
-  else
-    count = n;
-
-  for (j = 0; plts[j].name != NULL; j++)
-    if (plts[j].contents != NULL)
-      free (plts[j].contents);
-
-  free (dynrelbuf);
-
-  return count;
+  return _bfd_x86_elf_get_synthetic_symtab (abfd, count, relsize,
+                                           (bfd_vma) 0, plts, dynsyms,
+                                           ret);
 }
 
 /* Handle an x86-64 specific section when reading an object file.  This
This page took 0.026273 seconds and 4 git commands to generate.