From: Alan Modra Date: Sat, 23 Aug 2025 03:37:40 +0000 (+0930) Subject: PR 33302, Symbols truncated on i386pep target X-Git-Tag: gdb-17-branchpoint~189 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6274233ac8dddf923f567227dd887e1d79bf35d7;p=thirdparty%2Fbinutils-gdb.git PR 33302, Symbols truncated on i386pep target Commit 012d44268695 effectively made peXXigen.c _bfd_XXi_swap_aux_out always use the COFF E_FILNMLEN of 14. The problem was that the auxent x_fname field was defined in include/coff/external.h using a length of 14. Later, E_FILNMLEN is redefined to 18 in coff/pe.h. This no doubt falsely tripped memory checking tools. AUXESZ is 18, so no actual buffer overrun. This patch defines x_fname as an 18 char field, the full auxent, and uses E_FILNMLEN when accessing. PR 33302 include/ * coff/external.h (union external_auxent): Make x_fname AUXESZ chars. bfd/ * coffswap.h (coff_swap_aux_in): Correct #error message. (coff_swap_aux_out): Likewise. Use E_FILNMLEN when copying to ext field. * peXXigen.c (_bfd_XXi_swap_aux_in): Add #error. Style fix. (_bfd_XXi_swap_aux_out): Add #error. Don't use sizeof, use E_FILNMLEN when copying to ext field. gas * testsuite/gas/pe/long_file_symbol.d, * testsuite/gas/pe/long_file_symbol.s: New test. * testsuite/gas/pe/pe.exp: Run it. Reported-By: Frediano Ziglio --- diff --git a/bfd/coffswap.h b/bfd/coffswap.h index 4d63824f3d7..823d3fd9e65 100644 --- a/bfd/coffswap.h +++ b/bfd/coffswap.h @@ -422,13 +422,10 @@ coff_swap_aux_in (bfd *abfd, in->x_file.x_n.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset); } else - { #if FILNMLEN != E_FILNMLEN -#error we need to cope with truncating or extending FILNMLEN -#else - memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN); +#error we need to cope with truncating or extending x_fname #endif - } + memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN); goto end; case C_STAT: @@ -521,13 +518,10 @@ coff_swap_aux_out (bfd * abfd, H_PUT_32 (abfd, in->x_file.x_n.x_n.x_offset, ext->x_file.x_n.x_offset); } else - { #if FILNMLEN != E_FILNMLEN -#error we need to cope with truncating or extending FILNMLEN -#else - memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, FILNMLEN); +#error we need to cope with truncating or extending xfname #endif - } + memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, E_FILNMLEN); goto end; case C_STAT: diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index c337fc5b282..1a195d97c5c 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -289,7 +289,7 @@ _bfd_XXi_swap_aux_in (bfd * abfd, /* PR 17521: Make sure that all fields in the aux structure are initialised. */ - memset (in, 0, sizeof * in); + memset (in, 0, sizeof (*in)); switch (in_class) { case C_FILE: @@ -299,6 +299,9 @@ _bfd_XXi_swap_aux_in (bfd * abfd, in->x_file.x_n.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset); } else +#if FILNMLEN != E_FILNMLEN +#error we need to cope with truncating or extending x_fname +#endif memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN); return; @@ -373,7 +376,10 @@ _bfd_XXi_swap_aux_out (bfd * abfd, H_PUT_32 (abfd, in->x_file.x_n.x_n.x_offset, ext->x_file.x_n.x_offset); } else - memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, sizeof (ext->x_file.x_fname)); +#if FILNMLEN != E_FILNMLEN +#error we need to cope with truncating or extending x_fname +#endif + memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, E_FILNMLEN); return AUXESZ; diff --git a/gas/testsuite/gas/pe/long_file_symbol.d b/gas/testsuite/gas/pe/long_file_symbol.d new file mode 100644 index 00000000000..43510b98df7 --- /dev/null +++ b/gas/testsuite/gas/pe/long_file_symbol.d @@ -0,0 +1,5 @@ +#nm: -a + +#... +.* long_file_symbol.s +#pass diff --git a/gas/testsuite/gas/pe/long_file_symbol.s b/gas/testsuite/gas/pe/long_file_symbol.s new file mode 100644 index 00000000000..066499fefba --- /dev/null +++ b/gas/testsuite/gas/pe/long_file_symbol.s @@ -0,0 +1 @@ + .file "long_file_symbol.s" diff --git a/gas/testsuite/gas/pe/pe.exp b/gas/testsuite/gas/pe/pe.exp index 00a6d14fbfa..8682789d209 100644 --- a/gas/testsuite/gas/pe/pe.exp +++ b/gas/testsuite/gas/pe/pe.exp @@ -31,7 +31,7 @@ run_dump_test "aligncomm-a" run_dump_test "aligncomm-b" run_dump_test "aligncomm-c" run_dump_test "aligncomm-d" - +run_dump_test "long_file_symbol" run_dump_test "section-align-1" run_dump_test "section-align-3" run_dump_test "section-exclude" diff --git a/include/coff/external.h b/include/coff/external.h index 91c5dac5af1..1b3c06db2eb 100644 --- a/include/coff/external.h +++ b/include/coff/external.h @@ -223,7 +223,10 @@ typedef union external_auxent union { - char x_fname[E_FILNMLEN]; + /* Make x_fname the full auxent size, so that if coff/pe.h + redefines E_FILNMLEN from 14 to 18 we don't trigger sanitisers + accessing x_fname. Beware use of sizeof (x_file.x_fname). */ + char x_fname[AUXESZ]; struct {