x86: Add _bfd_x86_elf_get_synthetic_symtab
[deliverable/binutils-gdb.git] / bfd / elf32-i386.c
index 8e41c6eef27ff4bedcbdebafe9195fe0e5afced3..7b6d21f8fed79b74d8e28eedbdf609ca04dd5321 100644 (file)
@@ -5618,26 +5618,6 @@ elf_i386_output_arch_local_syms
   return TRUE;
 }
 
-enum elf_i386_plt_type
-{
-  plt_non_lazy = 0,
-  plt_lazy = 1 << 0,
-  plt_pic = 1 << 1,
-  plt_second = 1 << 2,
-  plt_unknown = -1
-};
-
-struct elf_i386_plt
-{
-  const char *name;
-  asection *sec;
-  bfd_byte *contents;
-  enum elf_i386_plt_type type;
-  unsigned int plt_got_offset;
-  unsigned int plt_entry_size;
-  long count;
-};
-
 /* Forward declaration.  */
 static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt;
 
@@ -5652,27 +5632,23 @@ elf_i386_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;
-  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_ibt_plt;
   const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt;
   asection *plt;
   bfd_vma got_addr;
-  char *names;
-  enum elf_i386_plt_type plt_type;
-  struct elf_i386_plt plts[] =
+  enum elf_x86_plt_type plt_type;
+  struct elf_x86_plt plts[] =
     {
-      { ".plt", NULL, NULL, plt_unknown, 0, 0, 0 },
-      { ".plt.got", NULL, NULL, plt_non_lazy, 0, 0, 0 },
-      { ".plt.sec", NULL, NULL, plt_second, 0, 0, 0 },
-      { NULL, NULL, NULL, plt_non_lazy, 0, 0, 0 }
+      { ".plt", NULL, NULL, plt_unknown, 0, 0, 0, 0 },
+      { ".plt.got", NULL, NULL, plt_non_lazy, 0, 0, 0, 0 },
+      { ".plt.sec", NULL, NULL, plt_second, 0, 0, 0, 0 },
+      { NULL, NULL, NULL, plt_non_lazy, 0, 0, 0, 0 }
     };
 
   *ret = NULL;
@@ -5838,176 +5814,9 @@ elf_i386_get_synthetic_symtab (bfd *abfd,
        got_addr = (bfd_vma) -1;
     }
 
-  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;
-    }
-
-  s = *ret = (asymbol *) bfd_zmalloc (size);
-  if (s == NULL)
-    goto bad_return;
-
-  if (got_addr)
-    {
-      /* Check .got.plt and then .got to get the _GLOBAL_OFFSET_TABLE_
-        address.  */
-      asection *sec = bfd_get_section_by_name (abfd, ".got.plt");
-      if (sec != NULL)
-       got_addr = sec->vma;
-      else
-       {
-         sec = bfd_get_section_by_name (abfd, ".got");
-         if (sec != NULL)
-           got_addr = sec->vma;
-       }
-
-      if (got_addr == (bfd_vma) -1)
-       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_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 GOT offset, a signed 32-bit integer.  */
-           off = H_GET_32 (abfd, (plt_contents + offset
-                                  + plt_got_offset));
-           got_vma = got_addr + off;
-
-           /* 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_386_JUMP_SLOT
-                   || p->howto->type == R_386_GLOB_DAT
-                   || p->howto->type == R_386_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_386_TLS_DESC 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,
+                                           got_addr, plts, dynsyms,
+                                           ret);
 }
 
 /* Set up i386 GNU properties.  Return the first relocatable ELF input
This page took 0.028345 seconds and 4 git commands to generate.