diff options
author | Clément Chigot <clement.chigot@atos.net> | 2021-10-15 16:12:39 +0200 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-11-10 14:43:24 +1030 |
commit | e86fc4a5bc3747a6b811d93648a2afa4c1c74217 (patch) | |
tree | 00a19a31cfdddd830170cb363782279a0d39c212 /bfd/coffgen.c | |
parent | f493b71179ab70d5e278234cb763eede55d44e61 (diff) | |
download | gdb-e86fc4a5bc3747a6b811d93648a2afa4c1c74217.zip gdb-e86fc4a5bc3747a6b811d93648a2afa4c1c74217.tar.gz gdb-e86fc4a5bc3747a6b811d93648a2afa4c1c74217.tar.bz2 |
PR 28447: implement multiple parameters for .file on XCOFF
On XCOFF, ".file" pseudo-op allows 3 extras parameters to provide
additional information to AIX linker, or its debugger. These are
stored in auxiliary entries of the C_FILE symbol.
bfd/
PR 28447
* coffcode.h (combined_entry_type): Add extrap field.
(coff_bigobj_swap_aux_in): Adjust names of x_file fields.
(coff_bigobj_swap_aux_out): Likewise.
* coffgen.c (coff_write_auxent_fname): New function.
(coff_fix_symbol_name): Write x_file using
coff_write_auxent_fname.
(coff_write_symbol): Likewise.
(coff_write_symbols): Add C_FILE auxiliary entries to
string table if needed.
(coff_get_normalized_symtab): Adjust names of x_file fields.
Normalize C_FILE auxiliary entries.
(coff_print_symbol): Print C_FILE auxiliary entries.
* coff-rs6000.c (_bfd_xcoff_swap_aux_in): Adjust names of
x_file fields.
(_bfd_xcoff_swap_aux_out): Likewise.
* coff64-rs6000.c (_bfd_xcoff64_swap_aux_in): Likewise.
(_bfd_xcoff64_swap_aux_out): Likewise.
* cofflink.c (_bfd_coff_final_link): Likewise.
(_bfd_coff_link_input_bfd): Likewise.
* coffswap.h (coff_swap_aux_in): Likewise.
* peXXigen.c (_bfd_XXi_swap_aux_in): Likewise.
(_bfd_XXi_swap_aux_out): Likewise.
* xcofflink.c (xcoff_link_input_bfd): Likewise.
* libcoff.h: Regenerate.
gas/
* config/tc-ppc.c (ppc_file): New function.
* config/tc-ppc.h (OBJ_COFF_MAX_AUXENTRIES): Change to 4.
* testsuite/gas/ppc/aix.exp: Add tests.
* testsuite/gas/ppc/xcoff-file-32.d: New test.
* testsuite/gas/ppc/xcoff-file-64.d: New test.
* testsuite/gas/ppc/xcoff-file.s: New test.
include/
* coff/internal.h (union internal_auxent): Change x_file to be a
struct instead of a union. Add x_ftype field.
* coff/rs6000.h (union external_auxent): Add x_resv field.
* coff/xcoff.h (XFT_FN): New define.
(XFT_CT): Likewise.
(XFT_CV): Likewise.
(XFT_CD): Likewise.
Diffstat (limited to 'bfd/coffgen.c')
-rw-r--r-- | bfd/coffgen.c | 134 |
1 files changed, 105 insertions, 29 deletions
diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 6627a9a..40f1ac7 100644 --- a/bfd/coffgen.c +++ b/bfd/coffgen.c @@ -848,6 +848,34 @@ coff_mangle_symbols (bfd *bfd_ptr) } static void +coff_write_auxent_fname (bfd *abfd, + char *str, + union internal_auxent *auxent, + bfd_size_type *string_size_p) +{ + unsigned int str_length = strlen (str); + unsigned int filnmlen = bfd_coff_filnmlen (abfd); + + if (bfd_coff_long_filenames (abfd)) + { + if (str_length <= filnmlen) + strncpy (auxent->x_file.x_n.x_fname, str, filnmlen); + else + { + auxent->x_file.x_n.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE; + auxent->x_file.x_n.x_n.x_zeroes = 0; + *string_size_p += str_length + 1; + } + } + else + { + strncpy (auxent->x_file.x_n.x_fname, str, filnmlen); + if (str_length > filnmlen) + str[filnmlen] = '\0'; + } +} + +static void coff_fix_symbol_name (bfd *abfd, asymbol *symbol, combined_entry_type *native, @@ -856,7 +884,6 @@ coff_fix_symbol_name (bfd *abfd, bfd_size_type *debug_string_size_p) { unsigned int name_length; - union internal_auxent *auxent; char *name = (char *) (symbol->name); if (name == NULL) @@ -871,8 +898,6 @@ coff_fix_symbol_name (bfd *abfd, if (native->u.syment.n_sclass == C_FILE && native->u.syment.n_numaux > 0) { - unsigned int filnmlen; - if (bfd_coff_force_symnames_in_strings (abfd)) { native->u.syment._n._n_n._n_offset = @@ -884,27 +909,8 @@ coff_fix_symbol_name (bfd *abfd, strncpy (native->u.syment._n._n_name, ".file", SYMNMLEN); BFD_ASSERT (! (native + 1)->is_sym); - auxent = &(native + 1)->u.auxent; - - filnmlen = bfd_coff_filnmlen (abfd); - - if (bfd_coff_long_filenames (abfd)) - { - if (name_length <= filnmlen) - strncpy (auxent->x_file.x_fname, name, filnmlen); - else - { - auxent->x_file.x_n.x_offset = *string_size_p + STRING_SIZE_SIZE; - auxent->x_file.x_n.x_zeroes = 0; - *string_size_p += name_length + 1; - } - } - else - { - strncpy (auxent->x_file.x_fname, name, filnmlen); - if (name_length > filnmlen) - name[filnmlen] = '\0'; - } + coff_write_auxent_fname (abfd, name, &(native + 1)->u.auxent, + string_size_p); } else { @@ -1029,6 +1035,11 @@ coff_write_symbol (bfd *abfd, for (j = 0; j < native->u.syment.n_numaux; j++) { BFD_ASSERT (! (native + j + 1)->is_sym); + + if (native->u.syment.n_sclass == C_FILE && j > 0) + coff_write_auxent_fname (abfd, (char *) (native + j + 1)->extrap, + &(native + j + 1)->u.auxent, string_size_p); + bfd_coff_swap_aux_out (abfd, &((native + j + 1)->u.auxent), type, n_sclass, (int) j, @@ -1358,6 +1369,7 @@ coff_write_symbols (bfd *abfd) size_t name_length = strlen (q->name); coff_symbol_type *c_symbol = coff_symbol_from (q); size_t maxlen; + bool is_c_file = false; /* Figure out whether the symbol name should go in the string table. Symbol names that are short enough are stored @@ -1384,6 +1396,7 @@ coff_write_symbols (bfd *abfd) else if (c_symbol->native->u.syment.n_sclass == C_FILE && c_symbol->native->u.syment.n_numaux > 0) { + is_c_file=true; if (bfd_coff_force_symnames_in_strings (abfd)) { if (bfd_bwrite (".file", (bfd_size_type) 6, abfd) != 6) @@ -1400,6 +1413,30 @@ coff_write_symbols (bfd *abfd) abfd) != name_length + 1) return false; } + + /* Add strings for C_FILE aux entries. */ + if (is_c_file + && c_symbol->native->u.syment.n_numaux > 1) + { + for (int j = 1; j < c_symbol->native->u.syment.n_numaux; j++) + { + char *str; + size_t str_length; + + if (c_symbol->native[j + 1].u.auxent.x_file.x_n.x_fname[0] != 0) + continue; + + str = (char *) c_symbol->native[j + 1].extrap; + str_length = strlen (str); + if (str_length > maxlen) + { + if (bfd_bwrite ((void *) (str), (bfd_size_type) str_length + 1, + abfd) != str_length + 1) + return false; + } + + } + } } } else @@ -1872,7 +1909,7 @@ coff_get_normalized_symtab (bfd *abfd) the text ".file" is redundant. */ BFD_ASSERT (! aux->is_sym); - if (aux->u.auxent.x_file.x_n.x_zeroes == 0) + if (aux->u.auxent.x_file.x_n.x_n.x_zeroes == 0) { /* The filename is a long one, point into the string table. */ if (string_table == NULL) @@ -1882,12 +1919,12 @@ coff_get_normalized_symtab (bfd *abfd) return NULL; } - if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_offset) + if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_n.x_offset) >= obj_coff_strings_len (abfd)) internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) _("<corrupt>"); else internal_ptr->u.syment._n._n_n._n_offset = - (bfd_hostptr_t) (string_table + (aux->u.auxent.x_file.x_n.x_offset)); + (bfd_hostptr_t) (string_table + (aux->u.auxent.x_file.x_n.x_n.x_offset)); } else { @@ -1899,15 +1936,48 @@ coff_get_normalized_symtab (bfd *abfd) internal_ptr->u.syment._n._n_n._n_offset = (bfd_hostptr_t) copy_name (abfd, - aux->u.auxent.x_file.x_fname, + aux->u.auxent.x_file.x_n.x_fname, internal_ptr->u.syment.n_numaux * symesz); else internal_ptr->u.syment._n._n_n._n_offset = ((bfd_hostptr_t) copy_name (abfd, - aux->u.auxent.x_file.x_fname, + aux->u.auxent.x_file.x_n.x_fname, (size_t) bfd_coff_filnmlen (abfd))); } + + /* Normalize other strings available in C_FILE aux entries. */ + if (!coff_data (abfd)->pe) + for (int numaux = 1; numaux < internal_ptr->u.syment.n_numaux; numaux++) + { + aux = internal_ptr + numaux + 1; + BFD_ASSERT (! aux->is_sym); + + if (aux->u.auxent.x_file.x_n.x_n.x_zeroes == 0) + { + /* The string information is a long one, point into the string table. */ + if (string_table == NULL) + { + string_table = _bfd_coff_read_string_table (abfd); + if (string_table == NULL) + return NULL; + } + + if ((bfd_size_type)(aux->u.auxent.x_file.x_n.x_n.x_offset) + >= obj_coff_strings_len (abfd)) + aux->u.auxent.x_file.x_n.x_n.x_offset = (bfd_hostptr_t) _("<corrupt>"); + else + aux->u.auxent.x_file.x_n.x_n.x_offset = + (bfd_hostptr_t) (string_table + (aux->u.auxent.x_file.x_n.x_n.x_offset)); + } + else + aux->u.auxent.x_file.x_n.x_n.x_offset = + ((bfd_hostptr_t) + copy_name (abfd, + aux->u.auxent.x_file.x_n.x_fname, + (size_t) bfd_coff_filnmlen (abfd))); + } + } else { @@ -2135,6 +2205,12 @@ coff_print_symbol (bfd *abfd, { case C_FILE: fprintf (file, "File "); + /* Add additional information if this isn't the filename + auxiliary entry. */ + if (aux) + fprintf (file, "ftype %d fname \"%s\"", + auxp->u.auxent.x_file.x_ftype, + (char *) auxp->u.auxent.x_file.x_n.x_n.x_offset); break; case C_DWARF: |