PR29677, Field the_bfd
of asymbol
is uninitialised
Besides not initialising the_bfd of synthetic symbols, counting symbols when sizing didn't match symbols created if there were any dynsyms named "". We don't want synthetic symbols without names anyway, so get rid of them. Also, simplify and correct sanity checks. PR 29677 * mach-o.c (bfd_mach_o_get_synthetic_symtab): Rewrite.
This commit is contained in:
parent
b3a5b1fd71
commit
d12f8998d2
1 changed files with 32 additions and 42 deletions
74
bfd/mach-o.c
74
bfd/mach-o.c
|
@ -938,11 +938,9 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
|
|||
bfd_mach_o_symtab_command *symtab = mdata->symtab;
|
||||
asymbol *s;
|
||||
char * s_start;
|
||||
char * s_end;
|
||||
unsigned long count, i, j, n;
|
||||
size_t size;
|
||||
char *names;
|
||||
char *nul_name;
|
||||
const char stub [] = "$stub";
|
||||
|
||||
*ret = NULL;
|
||||
|
@ -955,27 +953,27 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
|
|||
/* We need to allocate a bfd symbol for every indirect symbol and to
|
||||
allocate the memory for its name. */
|
||||
count = dysymtab->nindirectsyms;
|
||||
size = count * sizeof (asymbol) + 1;
|
||||
|
||||
size = 0;
|
||||
for (j = 0; j < count; j++)
|
||||
{
|
||||
const char * strng;
|
||||
unsigned int isym = dysymtab->indirect_syms[j];
|
||||
const char *str;
|
||||
|
||||
/* Some indirect symbols are anonymous. */
|
||||
if (isym < symtab->nsyms && (strng = symtab->symbols[isym].symbol.name))
|
||||
/* PR 17512: file: f5b8eeba. */
|
||||
size += strnlen (strng, symtab->strsize - (strng - symtab->strtab)) + sizeof (stub);
|
||||
if (isym < symtab->nsyms
|
||||
&& (str = symtab->symbols[isym].symbol.name) != NULL)
|
||||
{
|
||||
/* PR 17512: file: f5b8eeba. */
|
||||
size += strnlen (str, symtab->strsize - (str - symtab->strtab));
|
||||
size += sizeof (stub);
|
||||
}
|
||||
}
|
||||
|
||||
s_start = bfd_malloc (size);
|
||||
s_start = bfd_malloc (size + count * sizeof (asymbol));
|
||||
s = *ret = (asymbol *) s_start;
|
||||
if (s == NULL)
|
||||
return -1;
|
||||
names = (char *) (s + count);
|
||||
nul_name = names;
|
||||
*names++ = 0;
|
||||
s_end = s_start + size;
|
||||
|
||||
n = 0;
|
||||
for (i = 0; i < mdata->nsects; i++)
|
||||
|
@ -997,47 +995,39 @@ bfd_mach_o_get_synthetic_symtab (bfd *abfd,
|
|||
entry_size = bfd_mach_o_section_get_entry_size (abfd, sec);
|
||||
|
||||
/* PR 17512: file: 08e15eec. */
|
||||
if (first >= count || last >= count || first > last)
|
||||
if (first >= count || last > count || first > last)
|
||||
goto fail;
|
||||
|
||||
for (j = first; j < last; j++)
|
||||
{
|
||||
unsigned int isym = dysymtab->indirect_syms[j];
|
||||
|
||||
/* PR 17512: file: 04d64d9b. */
|
||||
if (((char *) s) + sizeof (* s) > s_end)
|
||||
goto fail;
|
||||
|
||||
s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
|
||||
s->section = sec->bfdsection;
|
||||
s->value = addr - sec->addr;
|
||||
s->udata.p = NULL;
|
||||
const char *str;
|
||||
size_t len;
|
||||
|
||||
if (isym < symtab->nsyms
|
||||
&& symtab->symbols[isym].symbol.name)
|
||||
&& (str = symtab->symbols[isym].symbol.name) != NULL)
|
||||
{
|
||||
const char *sym = symtab->symbols[isym].symbol.name;
|
||||
size_t len;
|
||||
|
||||
/* PR 17512: file: 04d64d9b. */
|
||||
if (n >= count)
|
||||
goto fail;
|
||||
len = strnlen (str, symtab->strsize - (str - symtab->strtab));
|
||||
/* PR 17512: file: 47dfd4d2, 18f340a4. */
|
||||
if (size < len + sizeof (stub))
|
||||
goto fail;
|
||||
memcpy (names, str, len);
|
||||
memcpy (names + len, stub, sizeof (stub));
|
||||
s->name = names;
|
||||
len = strlen (sym);
|
||||
/* PR 17512: file: 47dfd4d2. */
|
||||
if (names + len >= s_end)
|
||||
goto fail;
|
||||
memcpy (names, sym, len);
|
||||
names += len;
|
||||
/* PR 17512: file: 18f340a4. */
|
||||
if (names + sizeof (stub) >= s_end)
|
||||
goto fail;
|
||||
memcpy (names, stub, sizeof (stub));
|
||||
names += sizeof (stub);
|
||||
names += len + sizeof (stub);
|
||||
size -= len + sizeof (stub);
|
||||
s->the_bfd = symtab->symbols[isym].symbol.the_bfd;
|
||||
s->flags = BSF_GLOBAL | BSF_SYNTHETIC;
|
||||
s->section = sec->bfdsection;
|
||||
s->value = addr - sec->addr;
|
||||
s->udata.p = NULL;
|
||||
s++;
|
||||
n++;
|
||||
}
|
||||
else
|
||||
s->name = nul_name;
|
||||
|
||||
addr += entry_size;
|
||||
s++;
|
||||
n++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Add table
Reference in a new issue