mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2025-01-26 11:34:43 +00:00
bfd: don't produce corrupt COFF symbol table due to long ELF file name symbols
The re-writing logic in _bfd_coff_final_link() overwrote the ".file" part of the symbol table entry, due to not coping with the auxiliary entry generated in all cases. Note that while I would have wanted to add a test case, (a) I didn't spot any one testing the base functionality here, and (b) I wasn't able to figure out proper conditionals to use in e.g. ld-elf/elf.exp to check for the necessary PE/PE+ support (which varies by target).
This commit is contained in:
parent
1d19cae752
commit
270f824531
@ -1,3 +1,17 @@
|
||||
2015-12-15 Jan Beulich <jbeulich@suse.com>
|
||||
|
||||
* coffgen.c (coff_write_alien_symbol): New parameter "iaux".
|
||||
(coff_write_symbols): Pass NULL for new argument.
|
||||
* cofflink.c (_bfd_coff_final_link): New local variables
|
||||
"iaux".
|
||||
Extend scope of local variables "indx" and "hash". Pass address
|
||||
of "iaux" to coff_write_alien_symbol(). Handle ".file" and the
|
||||
file name ending up in the string table separately. Avoid
|
||||
setting "rewrite" on more than one path.
|
||||
* libcoff-in.h (coff_write_alien_symbol): New parameter of type
|
||||
"union internal_auxent *".
|
||||
* libcoff.h: Re-generate.
|
||||
|
||||
2015-12-15 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
PR 19339
|
||||
|
@ -1066,6 +1066,7 @@ bfd_boolean
|
||||
coff_write_alien_symbol (bfd *abfd,
|
||||
asymbol *symbol,
|
||||
struct internal_syment *isym,
|
||||
union internal_auxent *iaux,
|
||||
bfd_vma *written,
|
||||
bfd_size_type *string_size_p,
|
||||
asection **debug_string_section_p,
|
||||
@ -1151,6 +1152,8 @@ coff_write_alien_symbol (bfd *abfd,
|
||||
debug_string_section_p, debug_string_size_p);
|
||||
if (isym != NULL)
|
||||
*isym = native->u.syment;
|
||||
if (iaux != NULL && native->u.syment.n_numaux)
|
||||
*iaux = native[1].u.auxent;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1268,7 +1271,7 @@ coff_write_symbols (bfd *abfd)
|
||||
if (c_symbol == (coff_symbol_type *) NULL
|
||||
|| c_symbol->native == (combined_entry_type *) NULL)
|
||||
{
|
||||
if (!coff_write_alien_symbol (abfd, symbol, NULL, &written,
|
||||
if (!coff_write_alien_symbol (abfd, symbol, NULL, NULL, &written,
|
||||
&string_size, &debug_string_section,
|
||||
&debug_string_size))
|
||||
return FALSE;
|
||||
|
@ -872,9 +872,10 @@ _bfd_coff_final_link (bfd *abfd,
|
||||
asymbol *sym = bfd_get_outsymbols (sub) [i];
|
||||
file_ptr pos;
|
||||
struct internal_syment isym;
|
||||
bfd_size_type string_size = 0;
|
||||
union internal_auxent iaux;
|
||||
bfd_size_type string_size = 0, indx;
|
||||
bfd_vma written = 0;
|
||||
bfd_boolean rewrite = FALSE;
|
||||
bfd_boolean rewrite = FALSE, hash;
|
||||
|
||||
if (! (sym->flags & BSF_LOCAL)
|
||||
|| (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
|
||||
@ -900,23 +901,52 @@ _bfd_coff_final_link (bfd *abfd,
|
||||
* symesz;
|
||||
if (bfd_seek (abfd, pos, SEEK_SET) != 0)
|
||||
goto error_return;
|
||||
if (! coff_write_alien_symbol(abfd, sym, &isym, &written,
|
||||
if (! coff_write_alien_symbol(abfd, sym, &isym, &iaux, &written,
|
||||
&string_size, NULL, NULL))
|
||||
goto error_return;
|
||||
|
||||
if (string_size)
|
||||
{
|
||||
bfd_boolean hash = !flaginfo.info->traditional_format;
|
||||
bfd_size_type indx;
|
||||
hash = !flaginfo.info->traditional_format;
|
||||
|
||||
indx = _bfd_stringtab_add (flaginfo.strtab,
|
||||
bfd_asymbol_name (sym), hash,
|
||||
if (string_size >= 6 && isym.n_sclass == C_FILE
|
||||
&& ! isym._n._n_n._n_zeroes && isym.n_numaux)
|
||||
{
|
||||
indx = _bfd_stringtab_add (flaginfo.strtab, ".file", hash,
|
||||
FALSE);
|
||||
if (indx == (bfd_size_type) -1)
|
||||
goto error_return;
|
||||
isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
|
||||
bfd_coff_swap_sym_out (abfd, &isym, flaginfo.outsyms);
|
||||
rewrite = TRUE;
|
||||
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|
||||
|| bfd_bwrite (flaginfo.outsyms, symesz,
|
||||
abfd) != symesz)
|
||||
goto error_return;
|
||||
string_size -= 6;
|
||||
}
|
||||
|
||||
if (string_size)
|
||||
{
|
||||
indx = _bfd_stringtab_add (flaginfo.strtab,
|
||||
bfd_asymbol_name (sym), hash,
|
||||
FALSE);
|
||||
if (indx == (bfd_size_type) -1)
|
||||
goto error_return;
|
||||
if (isym.n_sclass != C_FILE)
|
||||
{
|
||||
isym._n._n_n._n_offset = STRING_SIZE_SIZE + indx;
|
||||
bfd_coff_swap_sym_out (abfd, &isym, flaginfo.outsyms);
|
||||
rewrite = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
BFD_ASSERT (isym.n_numaux == 1);
|
||||
iaux.x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
|
||||
bfd_coff_swap_aux_out (abfd, &iaux, isym.n_type, C_FILE,
|
||||
0, 1, flaginfo.outsyms + symesz);
|
||||
if (bfd_seek (abfd, pos + symesz, SEEK_SET) != 0
|
||||
|| bfd_bwrite (flaginfo.outsyms + symesz, symesz,
|
||||
abfd) != symesz)
|
||||
goto error_return;
|
||||
}
|
||||
}
|
||||
|
||||
if (isym.n_sclass == C_FILE)
|
||||
|
@ -312,8 +312,8 @@ extern void coff_mangle_symbols
|
||||
extern bfd_boolean coff_write_symbols
|
||||
(bfd *);
|
||||
extern bfd_boolean coff_write_alien_symbol
|
||||
(bfd *, asymbol *, struct internal_syment *, bfd_vma *,
|
||||
bfd_size_type *, asection **, bfd_size_type *);
|
||||
(bfd *, asymbol *, struct internal_syment *, union internal_auxent *,
|
||||
bfd_vma *, bfd_size_type *, asection **, bfd_size_type *);
|
||||
extern bfd_boolean coff_write_linenumbers
|
||||
(bfd *);
|
||||
extern alent *coff_get_lineno
|
||||
|
@ -316,8 +316,8 @@ extern void coff_mangle_symbols
|
||||
extern bfd_boolean coff_write_symbols
|
||||
(bfd *);
|
||||
extern bfd_boolean coff_write_alien_symbol
|
||||
(bfd *, asymbol *, struct internal_syment *, bfd_vma *,
|
||||
bfd_size_type *, asection **, bfd_size_type *);
|
||||
(bfd *, asymbol *, struct internal_syment *, union internal_auxent *,
|
||||
bfd_vma *, bfd_size_type *, asection **, bfd_size_type *);
|
||||
extern bfd_boolean coff_write_linenumbers
|
||||
(bfd *);
|
||||
extern alent *coff_get_lineno
|
||||
|
Loading…
x
Reference in New Issue
Block a user