From b11b2969a9a507d9e42c8029cfeb06b9bc41fceb Mon Sep 17 00:00:00 2001 From: Cl?ment Chigot Date: Thu, 22 Apr 2021 12:28:50 +0100 Subject: Harmonize and improve auxiliary entries support for XCOFF bfd/ChangeLog: * coff-rs6000.c (_bfd_xcoff_swap_aux_in): Add errors for unsupported storage class or auxialiry entries. Improve and adapt to new aux structures. Add C_DWARF support. (_bfd_xcoff_swap_aux_out): Likewise. * coff64-rs6000.c (_bfd_xcoff64_swap_aux_in): Likewise. (_bfd_xcoff64_swap_aux_out): Likewise. binutils/ChangeLog: * od-xcoff.c (dump_xcoff32_symbols): Adapt to new aux structures. include/ChangeLog: * coff/internal.h (union internal_auxent): Add x_sect structure. * coff/rs6000.h (union external_auxent): Rework to match official documentation. * coff/rs6k64.h (union external_auxent): Likewise. (_AUX_SECT): New define. --- bfd/ChangeLog | 10 +++ bfd/coff-rs6000.c | 192 +++++++++++++++++++------------------------------ bfd/coff64-rs6000.c | 201 +++++++++++++++++++++++++++++++--------------------- 3 files changed, 203 insertions(+), 200 deletions(-) (limited to 'bfd') diff --git a/bfd/ChangeLog b/bfd/ChangeLog index db31bdb..abb9d5f 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2021-04-22 Clément Chigot + + * coff-rs6000.c (_bfd_xcoff_swap_aux_in): Add errors for + unsupported storage class or auxialiry entries. + Improve and adapt to new aux structures. + Add C_DWARF support. + (_bfd_xcoff_swap_aux_out): Likewise. + * coff64-rs6000.c (_bfd_xcoff64_swap_aux_in): Likewise. + (_bfd_xcoff64_swap_aux_out): Likewise. + 2021-04-21 Eli Zaretskii PR 27760 diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 7cfe404..491efba 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -470,14 +470,22 @@ _bfd_xcoff_swap_sym_out (bfd *abfd, void * inp, void * extp) } void -_bfd_xcoff_swap_aux_in (bfd *abfd, void * ext1, int type, int in_class, - int indx, int numaux, void * in1) +_bfd_xcoff_swap_aux_in (bfd *abfd, void * ext1, int type ATTRIBUTE_UNUSED, + int in_class, int indx, int numaux, void * in1) { AUXENT * ext = (AUXENT *)ext1; union internal_auxent *in = (union internal_auxent *)in1; switch (in_class) { + default: + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: unsupported swap_aux_in for storage class %#x"), + abfd, (unsigned int) in_class); + bfd_set_error (bfd_error_bad_value); + break; + case C_FILE: if (ext->x_file.x_n.x_fname[0] == 0) { @@ -486,21 +494,13 @@ _bfd_xcoff_swap_aux_in (bfd *abfd, void * ext1, int type, int in_class, H_GET_32 (abfd, ext->x_file.x_n.x_n.x_offset); } else - { - if (numaux > 1) - { - if (indx == 0) - memcpy (in->x_file.x_fname, ext->x_file.x_n.x_fname, - numaux * sizeof (AUXENT)); - } - else - { - memcpy (in->x_file.x_fname, ext->x_file.x_n.x_fname, FILNMLEN); - } - } - goto end; + memcpy (in->x_file.x_fname, ext->x_file.x_n.x_fname, FILNMLEN); + break; - /* RS/6000 "csect" auxents */ + /* RS/6000 "csect" auxents. + There is always a CSECT auxiliary entry. But functions can + have FCN ones too. In this case, CSECT is always the last + one. */ case C_EXT: case C_AIX_WEAKEXT: case C_HIDEXT: @@ -516,74 +516,47 @@ _bfd_xcoff_swap_aux_in (bfd *abfd, void * ext1, int type, int in_class, in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas); in->x_csect.x_stab = H_GET_32 (abfd, ext->x_csect.x_stab); in->x_csect.x_snstab = H_GET_16 (abfd, ext->x_csect.x_snstab); - goto end; + } + else + { + /* x_exptr isn't supported. */ + in->x_sym.x_misc.x_fsize + = H_GET_32 (abfd, ext->x_fcn.x_fsize); + in->x_sym.x_fcnary.x_fcn.x_lnnoptr + = H_GET_32 (abfd, ext->x_fcn.x_lnnoptr); + in->x_sym.x_fcnary.x_fcn.x_endndx.l + = H_GET_32 (abfd, ext->x_fcn.x_endndx); } break; case C_STAT: - case C_LEAFSTAT: - case C_HIDDEN: - if (type == T_NULL) - { - in->x_scn.x_scnlen = H_GET_32 (abfd, ext->x_scn.x_scnlen); - in->x_scn.x_nreloc = H_GET_16 (abfd, ext->x_scn.x_nreloc); - in->x_scn.x_nlinno = H_GET_16 (abfd, ext->x_scn.x_nlinno); - /* PE defines some extra fields; we zero them out for - safety. */ - in->x_scn.x_checksum = 0; - in->x_scn.x_associated = 0; - in->x_scn.x_comdat = 0; - - goto end; - } + in->x_scn.x_scnlen = H_GET_32 (abfd, ext->x_scn.x_scnlen); + in->x_scn.x_nreloc = H_GET_16 (abfd, ext->x_scn.x_nreloc); + in->x_scn.x_nlinno = H_GET_16 (abfd, ext->x_scn.x_nlinno); + /* PE defines some extra fields; we zero them out for + safety. */ + in->x_scn.x_checksum = 0; + in->x_scn.x_associated = 0; + in->x_scn.x_comdat = 0; break; - } - in->x_sym.x_tagndx.l = H_GET_32 (abfd, ext->x_sym.x_tagndx); - in->x_sym.x_tvndx = H_GET_16 (abfd, ext->x_sym.x_tvndx); + case C_BLOCK: + case C_FCN: + in->x_sym.x_misc.x_lnsz.x_lnno + = H_GET_32 (abfd, ext->x_sym.x_lnno); + break; - if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type) - || ISTAG (in_class)) - { - in->x_sym.x_fcnary.x_fcn.x_lnnoptr = - H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr); - in->x_sym.x_fcnary.x_fcn.x_endndx.l = - H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx); - } - else - { - in->x_sym.x_fcnary.x_ary.x_dimen[0] = - H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[0]); - in->x_sym.x_fcnary.x_ary.x_dimen[1] = - H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[1]); - in->x_sym.x_fcnary.x_ary.x_dimen[2] = - H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[2]); - in->x_sym.x_fcnary.x_ary.x_dimen[3] = - H_GET_16 (abfd, ext->x_sym.x_fcnary.x_ary.x_dimen[3]); - } + case C_DWARF: + in->x_sect.x_scnlen = H_GET_32 (abfd, ext->x_sect.x_scnlen); + in->x_sect.x_nreloc = H_GET_32 (abfd, ext->x_sect.x_nreloc); + break; - if (ISFCN (type)) - { - in->x_sym.x_misc.x_fsize = H_GET_32 (abfd, ext->x_sym.x_misc.x_fsize); } - else - { - in->x_sym.x_misc.x_lnsz.x_lnno = - H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_lnno); - in->x_sym.x_misc.x_lnsz.x_size = - H_GET_16 (abfd, ext->x_sym.x_misc.x_lnsz.x_size); - } - - end: ; - /* The semicolon is because MSVC doesn't like labels at - end of block. */ } unsigned int -_bfd_xcoff_swap_aux_out (bfd *abfd, void * inp, int type, int in_class, - int indx ATTRIBUTE_UNUSED, - int numaux ATTRIBUTE_UNUSED, - void * extp) +_bfd_xcoff_swap_aux_out (bfd *abfd, void * inp, int type ATTRIBUTE_UNUSED, + int in_class, int indx, int numaux, void * extp) { union internal_auxent *in = (union internal_auxent *)inp; AUXENT *ext = (AUXENT *)extp; @@ -591,6 +564,14 @@ _bfd_xcoff_swap_aux_out (bfd *abfd, void * inp, int type, int in_class, memset (ext, 0, bfd_coff_auxesz (abfd)); switch (in_class) { + default: + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: unsupported swap_aux_out for storage class %#x"), + abfd, (unsigned int) in_class); + bfd_set_error (bfd_error_bad_value); + break; + case C_FILE: if (in->x_file.x_fname[0] == 0) { @@ -599,10 +580,8 @@ _bfd_xcoff_swap_aux_out (bfd *abfd, void * inp, int type, int in_class, ext->x_file.x_n.x_n.x_offset); } else - { - memcpy (ext->x_file.x_n.x_fname, in->x_file.x_fname, FILNMLEN); - } - goto end; + memcpy (ext->x_file.x_n.x_fname, in->x_file.x_fname, FILNMLEN); + break; /* RS/6000 "csect" auxents */ case C_EXT: @@ -620,57 +599,34 @@ _bfd_xcoff_swap_aux_out (bfd *abfd, void * inp, int type, int in_class, H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas); H_PUT_32 (abfd, in->x_csect.x_stab, ext->x_csect.x_stab); H_PUT_16 (abfd, in->x_csect.x_snstab, ext->x_csect.x_snstab); - goto end; } - break; - - case C_STAT: - case C_LEAFSTAT: - case C_HIDDEN: - if (type == T_NULL) + else { - H_PUT_32 (abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen); - H_PUT_16 (abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc); - H_PUT_16 (abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno); - goto end; + H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_fcn.x_fsize); + H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, + ext->x_fcn.x_lnnoptr); + H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, + ext->x_fcn.x_endndx); } break; - } - H_PUT_32 (abfd, in->x_sym.x_tagndx.l, ext->x_sym.x_tagndx); - H_PUT_16 (abfd, in->x_sym.x_tvndx, ext->x_sym.x_tvndx); + case C_STAT: + H_PUT_32 (abfd, in->x_scn.x_scnlen, ext->x_scn.x_scnlen); + H_PUT_16 (abfd, in->x_scn.x_nreloc, ext->x_scn.x_nreloc); + H_PUT_16 (abfd, in->x_scn.x_nlinno, ext->x_scn.x_nlinno); + break; - if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type) - || ISTAG (in_class)) - { - H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, - ext->x_sym.x_fcnary.x_fcn.x_lnnoptr); - H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, - ext->x_sym.x_fcnary.x_fcn.x_endndx); - } - else - { - H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[0], - ext->x_sym.x_fcnary.x_ary.x_dimen[0]); - H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[1], - ext->x_sym.x_fcnary.x_ary.x_dimen[1]); - H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[2], - ext->x_sym.x_fcnary.x_ary.x_dimen[2]); - H_PUT_16 (abfd, in->x_sym.x_fcnary.x_ary.x_dimen[3], - ext->x_sym.x_fcnary.x_ary.x_dimen[3]); - } + case C_BLOCK: + case C_FCN: + H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext->x_sym.x_lnno); + break; - if (ISFCN (type)) - H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_sym.x_misc.x_fsize); - else - { - H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, - ext->x_sym.x_misc.x_lnsz.x_lnno); - H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size, - ext->x_sym.x_misc.x_lnsz.x_size); + case C_DWARF: + H_PUT_32 (abfd, in->x_sect.x_scnlen, ext->x_sect.x_scnlen); + H_PUT_32 (abfd, in->x_sect.x_nreloc, ext->x_sect.x_nreloc); + break; } - end: return bfd_coff_auxesz (abfd); } diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index 8895340..9e9f9c2 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -362,15 +362,28 @@ _bfd_xcoff64_swap_sym_out (bfd *abfd, void *inp, void *extp) } static void -_bfd_xcoff64_swap_aux_in (bfd *abfd, void *ext1, int type, int in_class, - int indx, int numaux, void *in1) +_bfd_xcoff64_swap_aux_in (bfd *abfd, void *ext1, int type ATTRIBUTE_UNUSED, + int in_class, int indx, int numaux, void *in1) { union external_auxent *ext = (union external_auxent *) ext1; union internal_auxent *in = (union internal_auxent *) in1; + unsigned char auxtype; switch (in_class) { + default: + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: unsupported swap_aux_in for storage class %#x"), + abfd, (unsigned int) in_class); + bfd_set_error (bfd_error_bad_value); + break; + case C_FILE: + auxtype = H_GET_8 (abfd, ext->x_file.x_auxtype); + if (auxtype != _AUX_FILE) + goto error; + if (ext->x_file.x_n.x_n.x_zeroes[0] == 0) { in->x_file.x_n.x_zeroes = 0; @@ -378,17 +391,25 @@ _bfd_xcoff64_swap_aux_in (bfd *abfd, void *ext1, int type, int in_class, H_GET_32 (abfd, ext->x_file.x_n.x_n.x_offset); } else - { - memcpy (in->x_file.x_fname, ext->x_file.x_n.x_fname, FILNMLEN); - } - goto end; + memcpy (in->x_file.x_fname, ext->x_file.x_n.x_fname, FILNMLEN); + break; - /* RS/6000 "csect" auxents */ + /* RS/6000 "csect" auxents. + There is always a CSECT auxiliary entry. But functions can + have FCN and EXCEPT ones too. In this case, CSECT is always the last + one. + For now, we only support FCN types. */ case C_EXT: case C_AIX_WEAKEXT: case C_HIDEXT: if (indx + 1 == numaux) { + /* C_EXT can have several aux enties. But the _AUX_CSECT is always + the last one. */ + auxtype = H_GET_8 (abfd, ext->x_csect.x_auxtype); + if (auxtype != _AUX_CSECT) + goto error; + bfd_signed_vma h = 0; bfd_vma l = 0; @@ -404,55 +425,67 @@ _bfd_xcoff64_swap_aux_in (bfd *abfd, void *ext1, int type, int in_class, byte orders. */ in->x_csect.x_smtyp = H_GET_8 (abfd, ext->x_csect.x_smtyp); in->x_csect.x_smclas = H_GET_8 (abfd, ext->x_csect.x_smclas); - goto end; + } + else + { + /* It can also be a _AUX_EXCEPT entry. But it's not supported + for now. */ + auxtype = H_GET_8 (abfd, ext->x_fcn.x_auxtype); + if (auxtype != _AUX_FCN) + goto error; + + in->x_sym.x_fcnary.x_fcn.x_lnnoptr + = H_GET_64 (abfd, ext->x_fcn.x_lnnoptr); + in->x_sym.x_misc.x_fsize + = H_GET_32 (abfd, ext->x_fcn.x_fsize); + in->x_sym.x_fcnary.x_fcn.x_endndx.l + = H_GET_32 (abfd, ext->x_fcn.x_endndx); } break; case C_STAT: - case C_LEAFSTAT: - case C_HIDDEN: - if (type == T_NULL) - { - /* PE defines some extra fields; we zero them out for - safety. */ - in->x_scn.x_checksum = 0; - in->x_scn.x_associated = 0; - in->x_scn.x_comdat = 0; - - goto end; - } + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: C_STAT isn't supported by XCOFF64"), + abfd); + bfd_set_error (bfd_error_bad_value); break; - } - if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type) - || ISTAG (in_class)) - { - in->x_sym.x_fcnary.x_fcn.x_lnnoptr - = H_GET_64 (abfd, ext->x_sym.x_fcnary.x_fcn.x_lnnoptr); - in->x_sym.x_fcnary.x_fcn.x_endndx.l - = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_endndx); - } - if (ISFCN (type)) - { - in->x_sym.x_misc.x_fsize - = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_fcn.x_fsize); - } - else - { + case C_BLOCK: + case C_FCN: + auxtype = H_GET_8 (abfd, ext->x_sym.x_auxtype); + if (auxtype != _AUX_SYM) + goto error; + in->x_sym.x_misc.x_lnsz.x_lnno - = H_GET_32 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_lnno); - in->x_sym.x_misc.x_lnsz.x_size - = H_GET_16 (abfd, ext->x_sym.x_fcnary.x_lnsz.x_size); + = H_GET_32 (abfd, ext->x_sym.x_lnno); + break; + + case C_DWARF: + auxtype = H_GET_8 (abfd, ext->x_sect.x_auxtype); + if (auxtype != _AUX_SECT) + goto error; + + in->x_sect.x_scnlen = H_GET_64 (abfd, ext->x_sect.x_scnlen); + in->x_sect.x_nreloc = H_GET_64 (abfd, ext->x_sect.x_nreloc); + break; } - end: ; + return; + + error: + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: wrong auxtype %#x for storage class %#x"), + abfd, auxtype, (unsigned int) in_class); + bfd_set_error (bfd_error_bad_value); + + } static unsigned int -_bfd_xcoff64_swap_aux_out (bfd *abfd, void *inp, int type, int in_class, - int indx ATTRIBUTE_UNUSED, - int numaux ATTRIBUTE_UNUSED, - void *extp) +_bfd_xcoff64_swap_aux_out (bfd *abfd, void *inp, int type ATTRIBUTE_UNUSED, + int in_class, int indx, int numaux, void *extp) { union internal_auxent *in = (union internal_auxent *) inp; union external_auxent *ext = (union external_auxent *) extp; @@ -460,6 +493,14 @@ _bfd_xcoff64_swap_aux_out (bfd *abfd, void *inp, int type, int in_class, memset (ext, 0, bfd_coff_auxesz (abfd)); switch (in_class) { + default: + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: unsupported swap_aux_out for storage class %#x"), + abfd, (unsigned int) in_class); + bfd_set_error (bfd_error_bad_value); + break; + case C_FILE: if (in->x_file.x_n.x_zeroes == 0) { @@ -468,13 +509,15 @@ _bfd_xcoff64_swap_aux_out (bfd *abfd, void *inp, int type, int in_class, ext->x_file.x_n.x_n.x_offset); } else - { - memcpy (ext->x_file.x_n.x_fname, in->x_file.x_fname, FILNMLEN); - } - H_PUT_8 (abfd, _AUX_FILE, ext->x_auxtype.x_auxtype); - goto end; + memcpy (ext->x_file.x_n.x_fname, in->x_file.x_fname, FILNMLEN); + H_PUT_8 (abfd, _AUX_FILE, ext->x_file.x_auxtype); + break; - /* RS/6000 "csect" auxents */ + /* RS/6000 "csect" auxents. + There is always a CSECT auxiliary entry. But functions can + have FCN and EXCEPT ones too. In this case, CSECT is always the last + one. + For now, we only support FCN types. */ case C_EXT: case C_AIX_WEAKEXT: case C_HIDEXT: @@ -493,45 +536,39 @@ _bfd_xcoff64_swap_aux_out (bfd *abfd, void *inp, int type, int in_class, byte orders. */ H_PUT_8 (abfd, in->x_csect.x_smtyp, ext->x_csect.x_smtyp); H_PUT_8 (abfd, in->x_csect.x_smclas, ext->x_csect.x_smclas); - H_PUT_8 (abfd, _AUX_CSECT, ext->x_auxtype.x_auxtype); - goto end; + H_PUT_8 (abfd, _AUX_CSECT, ext->x_csect.x_auxtype); + } + else + { + H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, + ext->x_fcn.x_lnnoptr); + H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, ext->x_fcn.x_fsize); + H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, + ext->x_fcn.x_endndx); + H_PUT_8 (abfd, _AUX_FCN, ext->x_csect.x_auxtype); } break; case C_STAT: - case C_LEAFSTAT: - case C_HIDDEN: - if (type == T_NULL) - { - goto end; - } + _bfd_error_handler + /* xgettext: c-format */ + (_("%pB: C_STAT isn't supported by XCOFF64"), + abfd); + bfd_set_error (bfd_error_bad_value); break; - } - if (in_class == C_BLOCK || in_class == C_FCN || ISFCN (type) - || ISTAG (in_class)) - { - H_PUT_64 (abfd, in->x_sym.x_fcnary.x_fcn.x_lnnoptr, - ext->x_sym.x_fcnary.x_fcn.x_lnnoptr); - H_PUT_8 (abfd, _AUX_FCN, - ext->x_auxtype.x_auxtype); - H_PUT_32 (abfd, in->x_sym.x_fcnary.x_fcn.x_endndx.l, - ext->x_sym.x_fcnary.x_fcn.x_endndx); - } - if (ISFCN (type)) - { - H_PUT_32 (abfd, in->x_sym.x_misc.x_fsize, - ext->x_sym.x_fcnary.x_fcn.x_fsize); - } - else - { - H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, - ext->x_sym.x_fcnary.x_lnsz.x_lnno); - H_PUT_16 (abfd, in->x_sym.x_misc.x_lnsz.x_size, - ext->x_sym.x_fcnary.x_lnsz.x_size); - } + case C_BLOCK: + case C_FCN: + H_PUT_32 (abfd, in->x_sym.x_misc.x_lnsz.x_lnno, ext->x_sym.x_lnno); + H_PUT_8 (abfd, _AUX_SYM, ext->x_sym.x_auxtype); + break; - end: + case C_DWARF: + H_PUT_64 (abfd, in->x_sect.x_scnlen, ext->x_sect.x_scnlen); + H_PUT_64 (abfd, in->x_sect.x_nreloc, ext->x_sect.x_nreloc); + H_PUT_8 (abfd, _AUX_SECT, ext->x_sect.x_auxtype); + break; + } return bfd_coff_auxesz (abfd); } -- cgit v1.1