mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
get_synthetic_symtab fixes for commit 68bbe11833
Given that relocation symbol name can now be NULL for ELF, adjust various get_synthetic_symtab routines so they don't segfault. * elf.c (_bfd_elf_get_synthetic_symtab): Cope with sym->name possibly being NULL. * elf32-arm.c (elf32_arm_get_synthetic_symtab): Likewise. * elf32-ppc.c (ppc_elf_get_synthetic_symtab): Likewise. * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Likewise. * elfxx-mips.c (_bfd_mips_elf_get_synthetic_symtab): Likewise. * elfxx-x86.c (_bfd_x86_elf_get_synthetic_symtab): Likewise.
This commit is contained in:
parent
265757dc6e
commit
0c13ac533e
21
bfd/elf.c
21
bfd/elf.c
@ -13537,17 +13537,19 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd,
|
||||
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)
|
||||
{
|
||||
if ((*p->sym_ptr_ptr)->name != NULL)
|
||||
{
|
||||
size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
|
||||
if (p->addend != 0)
|
||||
{
|
||||
#ifdef BFD64
|
||||
size += sizeof ("+0x") - 1 + 8 + 8 * (bed->s->elfclass == ELFCLASS64);
|
||||
size += (sizeof ("+0x") - 1 + 8
|
||||
+ 8 * (bed->s->elfclass == ELFCLASS64));
|
||||
#else
|
||||
size += sizeof ("+0x") - 1 + 8;
|
||||
size += sizeof ("+0x") - 1 + 8;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s = *ret = (asymbol *) bfd_malloc (size);
|
||||
if (s == NULL)
|
||||
@ -13565,6 +13567,9 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd,
|
||||
if (addr == (bfd_vma) -1)
|
||||
continue;
|
||||
|
||||
if ((*p->sym_ptr_ptr)->name == NULL)
|
||||
continue;
|
||||
|
||||
*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. */
|
||||
|
@ -20100,6 +20100,7 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
|
||||
char *names;
|
||||
asection *plt;
|
||||
bfd_vma offset;
|
||||
bfd_vma plt_size;
|
||||
bfd_byte *data;
|
||||
|
||||
*ret = NULL;
|
||||
@ -20134,11 +20135,12 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
|
||||
size = count * sizeof (asymbol);
|
||||
p = relplt->relocation;
|
||||
for (i = 0; i < count; i++, p += elf32_arm_size_info.int_rels_per_ext_rel)
|
||||
{
|
||||
size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
|
||||
if (p->addend != 0)
|
||||
size += sizeof ("+0x") - 1 + 8;
|
||||
}
|
||||
if ((*p->sym_ptr_ptr)->name != NULL)
|
||||
{
|
||||
size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
|
||||
if (p->addend != 0)
|
||||
size += sizeof ("+0x") - 1 + 8;
|
||||
}
|
||||
|
||||
offset = elf32_arm_plt0_size (abfd, data, plt->size);
|
||||
if (offset == (bfd_vma) -1
|
||||
@ -20149,16 +20151,19 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
|
||||
}
|
||||
|
||||
names = (char *) (s + count);
|
||||
p = relplt->relocation;
|
||||
n = 0;
|
||||
for (i = 0; i < count; i++, p += elf32_arm_size_info.int_rels_per_ext_rel)
|
||||
for (i = 0, p = relplt->relocation, n = 0;
|
||||
i < count;
|
||||
i++, p += elf32_arm_size_info.int_rels_per_ext_rel, offset += plt_size)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
bfd_vma plt_size = elf32_arm_plt_size (abfd, data, offset, plt->size);
|
||||
plt_size = elf32_arm_plt_size (abfd, data, offset, plt->size);
|
||||
if (plt_size == (bfd_vma) -1)
|
||||
break;
|
||||
|
||||
if ((*p->sym_ptr_ptr)->name == NULL)
|
||||
continue;
|
||||
|
||||
*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. */
|
||||
@ -20188,7 +20193,6 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
|
||||
memcpy (names, "@plt", sizeof ("@plt"));
|
||||
names += sizeof ("@plt");
|
||||
++s, ++n;
|
||||
offset += plt_size;
|
||||
}
|
||||
|
||||
free (data);
|
||||
|
@ -1806,7 +1806,7 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
|
||||
bfd_vma stub_off;
|
||||
asymbol *s;
|
||||
arelent *p;
|
||||
size_t count, i, stub_delta;
|
||||
size_t count, n, i, stub_delta;
|
||||
size_t size;
|
||||
char *names;
|
||||
bfd_byte buf[4];
|
||||
@ -1935,11 +1935,12 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
|
||||
size = count * sizeof (asymbol);
|
||||
p = relplt->relocation;
|
||||
for (i = 0; i < count; i++, p++)
|
||||
{
|
||||
size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
|
||||
if (p->addend != 0)
|
||||
size += sizeof ("+0x") - 1 + 8;
|
||||
}
|
||||
if ((*p->sym_ptr_ptr)->name != NULL)
|
||||
{
|
||||
size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
|
||||
if (p->addend != 0)
|
||||
size += sizeof ("+0x") - 1 + 8;
|
||||
}
|
||||
|
||||
size += sizeof (asymbol) + sizeof ("__glink");
|
||||
|
||||
@ -1953,38 +1954,40 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
|
||||
stub_off = glink_vma - glink->vma;
|
||||
names = (char *) (s + count + 1 + (resolv_vma != 0));
|
||||
p = relplt->relocation + count - 1;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
size_t len;
|
||||
for (n = 0, i = 0; i < count; i++)
|
||||
if ((*p->sym_ptr_ptr)->name != NULL)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
stub_off -= stub_delta;
|
||||
if (strcmp ((*p->sym_ptr_ptr)->name, "__tls_get_addr_opt") == 0)
|
||||
stub_off -= 32;
|
||||
*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 = glink;
|
||||
s->value = stub_off;
|
||||
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)
|
||||
{
|
||||
memcpy (names, "+0x", sizeof ("+0x") - 1);
|
||||
names += sizeof ("+0x") - 1;
|
||||
bfd_sprintf_vma (abfd, names, p->addend);
|
||||
names += strlen (names);
|
||||
}
|
||||
memcpy (names, "@plt", sizeof ("@plt"));
|
||||
names += sizeof ("@plt");
|
||||
++s;
|
||||
--p;
|
||||
}
|
||||
stub_off -= stub_delta;
|
||||
if (strcmp ((*p->sym_ptr_ptr)->name, "__tls_get_addr_opt") == 0)
|
||||
stub_off -= 32;
|
||||
*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 = glink;
|
||||
s->value = stub_off;
|
||||
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)
|
||||
{
|
||||
memcpy (names, "+0x", sizeof ("+0x") - 1);
|
||||
names += sizeof ("+0x") - 1;
|
||||
bfd_sprintf_vma (abfd, names, p->addend);
|
||||
names += strlen (names);
|
||||
}
|
||||
memcpy (names, "@plt", sizeof ("@plt"));
|
||||
names += sizeof ("@plt");
|
||||
++s;
|
||||
--p;
|
||||
++n;
|
||||
}
|
||||
|
||||
/* Add a symbol at the start of the glink branch table. */
|
||||
memset (s, 0, sizeof *s);
|
||||
@ -1996,7 +1999,7 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
|
||||
memcpy (names, "__glink", sizeof ("__glink"));
|
||||
names += sizeof ("__glink");
|
||||
s++;
|
||||
count++;
|
||||
n++;
|
||||
|
||||
if (resolv_vma)
|
||||
{
|
||||
@ -2010,10 +2013,10 @@ ppc_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms,
|
||||
memcpy (names, "__glink_PLTresolve", sizeof ("__glink_PLTresolve"));
|
||||
names += sizeof ("__glink_PLTresolve");
|
||||
s++;
|
||||
count++;
|
||||
n++;
|
||||
}
|
||||
|
||||
return count;
|
||||
return n;
|
||||
}
|
||||
|
||||
/* The following functions are specific to the ELF linker, while
|
||||
|
@ -2402,7 +2402,8 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
||||
|
||||
sym = *r->sym_ptr_ptr;
|
||||
if (!sym_exists_at (syms, opdsymend, symcount,
|
||||
sym->section->id, sym->value + r->addend))
|
||||
sym->section->id, sym->value + r->addend)
|
||||
&& syms[i]->name != NULL)
|
||||
{
|
||||
++count;
|
||||
size += sizeof (asymbol);
|
||||
@ -2440,7 +2441,8 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
||||
|
||||
sym = *r->sym_ptr_ptr;
|
||||
if (!sym_exists_at (syms, opdsymend, symcount,
|
||||
sym->section->id, sym->value + r->addend))
|
||||
sym->section->id, sym->value + r->addend)
|
||||
&& syms[i]->name != NULL)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
@ -2491,7 +2493,8 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
||||
continue;
|
||||
|
||||
ent = bfd_get_64 (abfd, contents + syms[i]->value);
|
||||
if (!sym_exists_at (syms, opdsymend, symcount, -1, ent))
|
||||
if (!sym_exists_at (syms, opdsymend, symcount, -1, ent)
|
||||
&& syms[i]->name != NULL)
|
||||
{
|
||||
++count;
|
||||
size += sizeof (asymbol);
|
||||
@ -2579,11 +2582,12 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
||||
|
||||
p = relplt->relocation;
|
||||
for (i = 0; i < plt_count; i++, p++)
|
||||
{
|
||||
size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
|
||||
if (p->addend != 0)
|
||||
size += sizeof ("+0x") - 1 + 16;
|
||||
}
|
||||
if ((*p->sym_ptr_ptr)->name != NULL)
|
||||
{
|
||||
size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
|
||||
if (p->addend != 0)
|
||||
size += sizeof ("+0x") - 1 + 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2603,7 +2607,8 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
||||
continue;
|
||||
|
||||
ent = bfd_get_64 (abfd, contents + syms[i]->value);
|
||||
if (!sym_exists_at (syms, opdsymend, symcount, -1, ent))
|
||||
if (!sym_exists_at (syms, opdsymend, symcount, -1, ent)
|
||||
&& syms[i]->name != NULL)
|
||||
{
|
||||
size_t lo, hi;
|
||||
size_t len;
|
||||
@ -2691,42 +2696,43 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd,
|
||||
for pending shared library loads. */
|
||||
p = relplt->relocation;
|
||||
for (i = 0; i < plt_count; i++, p++)
|
||||
{
|
||||
size_t len;
|
||||
if ((*p->sym_ptr_ptr)->name != NULL)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
*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 = glink;
|
||||
s->value = glink_vma - glink->vma;
|
||||
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)
|
||||
{
|
||||
memcpy (names, "+0x", sizeof ("+0x") - 1);
|
||||
names += sizeof ("+0x") - 1;
|
||||
bfd_sprintf_vma (abfd, names, p->addend);
|
||||
names += strlen (names);
|
||||
}
|
||||
memcpy (names, "@plt", sizeof ("@plt"));
|
||||
names += sizeof ("@plt");
|
||||
s++;
|
||||
if (abi < 2)
|
||||
{
|
||||
glink_vma += 8;
|
||||
if (i >= 0x8000)
|
||||
glink_vma += 4;
|
||||
}
|
||||
else
|
||||
glink_vma += 4;
|
||||
}
|
||||
count += plt_count;
|
||||
*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 = glink;
|
||||
s->value = glink_vma - glink->vma;
|
||||
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)
|
||||
{
|
||||
memcpy (names, "+0x", sizeof ("+0x") - 1);
|
||||
names += sizeof ("+0x") - 1;
|
||||
bfd_sprintf_vma (abfd, names, p->addend);
|
||||
names += strlen (names);
|
||||
}
|
||||
memcpy (names, "@plt", sizeof ("@plt"));
|
||||
names += sizeof ("@plt");
|
||||
s++;
|
||||
if (abi < 2)
|
||||
{
|
||||
glink_vma += 8;
|
||||
if (i >= 0x8000)
|
||||
glink_vma += 4;
|
||||
}
|
||||
else
|
||||
glink_vma += 4;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16624,7 +16624,8 @@ _bfd_mips_elf_get_synthetic_symtab (bfd *abfd,
|
||||
size += count * (sizeof (mipssuffix) +
|
||||
(micromips_p ? sizeof (microsuffix) : sizeof (m16suffix)));
|
||||
for (pi = 0; pi < counti; pi += bed->s->int_rels_per_ext_rel)
|
||||
size += 2 * strlen ((*p[pi].sym_ptr_ptr)->name);
|
||||
if ((*p[pi].sym_ptr_ptr)->name != NULL)
|
||||
size += 2 * strlen ((*p[pi].sym_ptr_ptr)->name);
|
||||
|
||||
/* Add the size of "_PROCEDURE_LINKAGE_TABLE_" too. */
|
||||
size += sizeof (asymbol) + sizeof (pltname);
|
||||
@ -16754,31 +16755,34 @@ _bfd_mips_elf_get_synthetic_symtab (bfd *abfd,
|
||||
|
||||
if (i < count)
|
||||
{
|
||||
size_t namelen;
|
||||
size_t len;
|
||||
if ((*p[pi].sym_ptr_ptr)->name != NULL)
|
||||
{
|
||||
size_t namelen;
|
||||
size_t len;
|
||||
|
||||
*s = **p[pi].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 = plt_offset;
|
||||
s->name = names;
|
||||
s->udata.i = other;
|
||||
*s = **p[pi].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 = plt_offset;
|
||||
s->name = names;
|
||||
s->udata.i = other;
|
||||
|
||||
len = strlen ((*p[pi].sym_ptr_ptr)->name);
|
||||
namelen = len + suffixlen;
|
||||
if (names + namelen > nend)
|
||||
break;
|
||||
len = strlen ((*p[pi].sym_ptr_ptr)->name);
|
||||
namelen = len + suffixlen;
|
||||
if (names + namelen > nend)
|
||||
break;
|
||||
|
||||
memcpy (names, (*p[pi].sym_ptr_ptr)->name, len);
|
||||
names += len;
|
||||
memcpy (names, suffix, suffixlen);
|
||||
names += suffixlen;
|
||||
memcpy (names, (*p[pi].sym_ptr_ptr)->name, len);
|
||||
names += len;
|
||||
memcpy (names, suffix, suffixlen);
|
||||
names += suffixlen;
|
||||
|
||||
++s, ++n;
|
||||
++s, ++n;
|
||||
}
|
||||
pi = (pi + bed->s->int_rels_per_ext_rel) % counti;
|
||||
}
|
||||
}
|
||||
|
@ -3710,9 +3710,12 @@ _bfd_x86_elf_get_synthetic_symtab (bfd *abfd,
|
||||
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);
|
||||
if ((*p->sym_ptr_ptr)->name != NULL)
|
||||
{
|
||||
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);
|
||||
@ -3817,7 +3820,8 @@ _bfd_x86_elf_get_synthetic_symtab (bfd *abfd,
|
||||
/* Skip unknown relocation. PR 17512: file: bc9d6cf5. */
|
||||
if (got_vma == p->address
|
||||
&& p->howto != NULL
|
||||
&& valid_plt_reloc_p (p->howto->type))
|
||||
&& valid_plt_reloc_p (p->howto->type)
|
||||
&& (*p->sym_ptr_ptr)->name != NULL)
|
||||
{
|
||||
*s = **p->sym_ptr_ptr;
|
||||
/* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL
|
||||
|
Loading…
Reference in New Issue
Block a user