- return _bfd_elf_get_synthetic_symtab (abfd, symcount, syms,
- dynsymcount, dynsyms, ret);
-
- *ret = NULL;
-
- if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
- return 0;
-
- if (dynsymcount <= 0)
- return 0;
-
- relplt = bfd_get_section_by_name (abfd, ".rela.plt");
- if (relplt == NULL)
- return 0;
-
- hdr = &elf_section_data (relplt)->this_hdr;
- if (hdr->sh_link != elf_dynsymtab (abfd)
- || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA))
- return 0;
-
- slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
- if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
- return -1;
-
- count = relplt->size / hdr->sh_entsize;
- 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)
- size += sizeof ("+0x") - 1 + 8 + 8;
- }
-
- s = *ret = (asymbol *) bfd_malloc (size);
- if (s == NULL)
- return -1;
-
- names = (char *) (s + count);
- p = relplt->relocation;
- n = 0;
- for (i = 0; i < count; i++, p++)
- {
- bfd_vma offset;
- size_t len;
-
- if (p->howto->type != R_X86_64_JUMP_SLOT
- && p->howto->type != R_X86_64_IRELATIVE)
- continue;
-
- offset = elf_x86_64_plt_sym_val_offset_plt_bnd (i, plt_push);
-
- *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 = plt;
- s->value = offset;
- 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)
- {
- 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)
- ;
- len = strlen (a);
- memcpy (names, a, len);
- names += len;
- }
- memcpy (names, "@plt", sizeof ("@plt"));
- names += sizeof ("@plt");
- ++s, ++n;
- }
-
- return n;