From 98c5dfc99444094652c2f2259126f70e5cacf56f Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 11 Aug 2017 09:32:44 -0700 Subject: [PATCH] x86: Allocate space for symbol names with symbol table 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 | 7 +++++ bfd/elf32-i386.c | 75 ++++++++++++++++++++-------------------------- bfd/elf64-x86-64.c | 75 ++++++++++++++++++++-------------------------- 3 files changed, 73 insertions(+), 84 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 3a0957574ad..356d19b498d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2017-08-11 H.J. Lu + + 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 PR 21916 diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index f1fcd21072d..d5477c42153 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -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); diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 83643842ee1..8a6bd6285c8 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -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);