diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-08-30 12:27:17 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-08-30 12:27:30 -0700 |
commit | f493882dab762fb49ecb8685c18a85edfab5e6d3 (patch) | |
tree | d2bcf2441d2f01f84d4f5199e92b7db708cc8ceb /bfd/elf64-x86-64.c | |
parent | 5b86dbf4549af98c4428da4764182e03f22c58ab (diff) | |
download | gdb-f493882dab762fb49ecb8685c18a85edfab5e6d3.zip gdb-f493882dab762fb49ecb8685c18a85edfab5e6d3.tar.gz gdb-f493882dab762fb49ecb8685c18a85edfab5e6d3.tar.bz2 |
x86: Add _bfd_x86_elf_get_synthetic_symtab
Move the common codes in elf_i386_get_synthetic_symtab and
elf_x86_64_get_synthetic_symtab to _bfd_x86_elf_get_synthetic_symtab.
* elf32-i386.c (elf_i386_plt_type): Removed.
(elf_i386_plt): Likewise.
(elf_i386_get_synthetic_symtab): Updated. Call
_bfd_x86_elf_get_synthetic_symtab.
* elf64-x86-64.c (elf_x86_64_plt_type): Removed.
(elf_x86_64_plt): Likewise.
(elf_x86_64_get_synthetic_symtab): Updated. Call
_bfd_x86_elf_get_synthetic_symtab.
* elfxx-x86.c (elf_i386_get_plt_got_vma): New function.
(elf_x86_64_get_plt_got_vma): Likewise.
(elf_i386_valid_plt_reloc_p): Likewise.
(elf_x86_64_valid_plt_reloc_p): Likewise.
(_bfd_x86_elf_get_synthetic_symtab): Likewise.
* elfxx-x86.h (elf_x86_plt_type): New.
(elf_x86_plt): Likewise.
(_bfd_x86_elf_get_synthetic_symtab): Likewise.
Diffstat (limited to 'bfd/elf64-x86-64.c')
-rw-r--r-- | bfd/elf64-x86-64.c | 188 |
1 files changed, 7 insertions, 181 deletions
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 3bf465b..0edb174 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -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 |