PR29677, Field `the_bfd` of `asymbol` is uninitialised
Checks
Commit Message
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.
@@ -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;
-
- s->name = names;
- len = strlen (sym);
- /* PR 17512: file: 47dfd4d2. */
- if (names + len >= s_end)
+ /* PR 17512: file: 04d64d9b. */
+ if (n >= count)
goto fail;
- memcpy (names, sym, len);
- names += len;
- /* PR 17512: file: 18f340a4. */
- if (names + sizeof (stub) >= s_end)
+ len = strnlen (str, symtab->strsize - (str - symtab->strtab));
+ /* PR 17512: file: 47dfd4d2, 18f340a4. */
+ if (size < len + sizeof (stub))
goto fail;
- memcpy (names, stub, sizeof (stub));
- names += sizeof (stub);
+ memcpy (names, str, len);
+ memcpy (names + len, stub, sizeof (stub));
+ s->name = names;
+ 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: