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.
This commit is contained in:
Clément Chigot 2021-10-15 16:12:39 +02:00 committed by Alan Modra
parent f493b71179
commit e86fc4a5bc
18 changed files with 273 additions and 82 deletions

View file

@ -489,12 +489,13 @@ _bfd_xcoff_swap_aux_in (bfd *abfd, void * ext1, int type ATTRIBUTE_UNUSED,
case C_FILE:
if (ext->x_file.x_n.x_fname[0] == 0)
{
in->x_file.x_n.x_zeroes = 0;
in->x_file.x_n.x_offset =
in->x_file.x_n.x_n.x_zeroes = 0;
in->x_file.x_n.x_n.x_offset =
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);
memcpy (in->x_file.x_n.x_fname, ext->x_file.x_n.x_fname, FILNMLEN);
in->x_file.x_ftype = H_GET_8 (abfd, ext->x_file.x_ftype);
break;
/* RS/6000 "csect" auxents.
@ -573,14 +574,15 @@ _bfd_xcoff_swap_aux_out (bfd *abfd, void * inp, int type ATTRIBUTE_UNUSED,
break;
case C_FILE:
if (in->x_file.x_fname[0] == 0)
if (in->x_file.x_n.x_fname[0] == 0)
{
H_PUT_32 (abfd, 0, ext->x_file.x_n.x_n.x_zeroes);
H_PUT_32 (abfd, in->x_file.x_n.x_offset,
H_PUT_32 (abfd, in->x_file.x_n.x_n.x_offset,
ext->x_file.x_n.x_n.x_offset);
}
else
memcpy (ext->x_file.x_n.x_fname, in->x_file.x_fname, FILNMLEN);
memcpy (ext->x_file.x_n.x_fname, in->x_file.x_n.x_fname, FILNMLEN);
H_PUT_8 (abfd, in->x_file.x_ftype, ext->x_file.x_ftype);
break;
/* RS/6000 "csect" auxents */

View file

@ -386,12 +386,13 @@ _bfd_xcoff64_swap_aux_in (bfd *abfd, void *ext1, int type ATTRIBUTE_UNUSED,
if (ext->x_file.x_n.x_n.x_zeroes[0] == 0)
{
in->x_file.x_n.x_zeroes = 0;
in->x_file.x_n.x_offset =
in->x_file.x_n.x_n.x_zeroes = 0;
in->x_file.x_n.x_n.x_offset =
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);
memcpy (in->x_file.x_n.x_fname, ext->x_file.x_n.x_fname, FILNMLEN);
in->x_file.x_ftype = H_GET_8 (abfd, ext->x_file.x_ftype);
break;
/* RS/6000 "csect" auxents.
@ -499,14 +500,15 @@ _bfd_xcoff64_swap_aux_out (bfd *abfd, void *inp, int type ATTRIBUTE_UNUSED,
break;
case C_FILE:
if (in->x_file.x_n.x_zeroes == 0)
if (in->x_file.x_n.x_n.x_zeroes == 0)
{
H_PUT_32 (abfd, 0, ext->x_file.x_n.x_n.x_zeroes);
H_PUT_32 (abfd, in->x_file.x_n.x_offset,
H_PUT_32 (abfd, in->x_file.x_n.x_n.x_offset,
ext->x_file.x_n.x_n.x_offset);
}
else
memcpy (ext->x_file.x_n.x_fname, in->x_file.x_fname, FILNMLEN);
memcpy (ext->x_file.x_n.x_fname, in->x_file.x_n.x_fname, FILNMLEN);
H_PUT_8 (abfd, in->x_file.x_ftype, ext->x_file.x_ftype);
H_PUT_8 (abfd, _AUX_FILE, ext->x_file.x_auxtype);
break;

View file

@ -326,6 +326,10 @@ CODE_FRAGMENT
.
. {* Selector for the union above. *}
. bool is_sym;
.
. {* An extra pointer which can used by format based on COFF (like XCOFF)
. to provide extra information to their backend. *}
. void *extrap;
.} combined_entry_type;
.
.
@ -5663,11 +5667,11 @@ coff_bigobj_swap_aux_in (bfd *abfd,
if (numaux > 1)
{
if (indx == 0)
memcpy (in->x_file.x_fname, ext->File.Name,
memcpy (in->x_file.x_n.x_fname, ext->File.Name,
numaux * sizeof (AUXENT_BIGOBJ));
}
else
memcpy (in->x_file.x_fname, ext->File.Name, sizeof (ext->File.Name));
memcpy (in->x_file.x_n.x_fname, ext->File.Name, sizeof (ext->File.Name));
break;
case C_STAT:
@ -5712,7 +5716,7 @@ coff_bigobj_swap_aux_out (bfd * abfd,
switch (in_class)
{
case C_FILE:
memcpy (ext->File.Name, in->x_file.x_fname, sizeof (ext->File.Name));
memcpy (ext->File.Name, in->x_file.x_n.x_fname, sizeof (ext->File.Name));
return AUXESZ;

View file

@ -847,6 +847,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,
@ -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:

View file

@ -963,7 +963,7 @@ _bfd_coff_final_link (bfd *abfd,
else
{
BFD_ASSERT (isym.n_numaux == 1);
iaux.x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
iaux.x_file.x_n.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
@ -2006,13 +2006,13 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
{
/* If this is a long filename, we must put it in the
string table. */
if (auxp->x_file.x_n.x_zeroes == 0
&& auxp->x_file.x_n.x_offset != 0)
if (auxp->x_file.x_n.x_n.x_zeroes == 0
&& auxp->x_file.x_n.x_n.x_offset != 0)
{
const char *filename;
bfd_size_type indx;
BFD_ASSERT (auxp->x_file.x_n.x_offset
BFD_ASSERT (auxp->x_file.x_n.x_n.x_offset
>= STRING_SIZE_SIZE);
if (strings == NULL)
{
@ -2020,15 +2020,15 @@ _bfd_coff_link_input_bfd (struct coff_final_link_info *flaginfo, bfd *input_bfd)
if (strings == NULL)
return false;
}
if ((bfd_size_type) auxp->x_file.x_n.x_offset >= obj_coff_strings_len (input_bfd))
if ((bfd_size_type) auxp->x_file.x_n.x_n.x_offset >= obj_coff_strings_len (input_bfd))
filename = _("<corrupt>");
else
filename = strings + auxp->x_file.x_n.x_offset;
filename = strings + auxp->x_file.x_n.x_n.x_offset;
indx = _bfd_stringtab_add (flaginfo->strtab, filename,
hash, copy);
if (indx == (bfd_size_type) -1)
return false;
auxp->x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
auxp->x_file.x_n.x_n.x_offset = STRING_SIZE_SIZE + indx;
}
}
else if ((isymp->n_sclass != C_STAT || isymp->n_type != T_NULL)

View file

@ -418,8 +418,8 @@ coff_swap_aux_in (bfd *abfd,
case C_FILE:
if (ext->x_file.x_fname[0] == 0)
{
in->x_file.x_n.x_zeroes = 0;
in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
in->x_file.x_n.x_n.x_zeroes = 0;
in->x_file.x_n.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
}
else
{
@ -429,11 +429,11 @@ coff_swap_aux_in (bfd *abfd,
if (numaux > 1 && coff_data (abfd)->pe)
{
if (indx == 0)
memcpy (in->x_file.x_fname, ext->x_file.x_fname,
memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname,
numaux * sizeof (AUXENT));
}
else
memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN);
#endif
}
goto end;
@ -522,17 +522,17 @@ coff_swap_aux_out (bfd * abfd,
switch (in_class)
{
case C_FILE:
if (in->x_file.x_fname[0] == 0)
if (in->x_file.x_n.x_fname[0] == 0)
{
H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
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_fname, FILNMLEN);
memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, FILNMLEN);
#endif
}
goto end;

View file

@ -658,6 +658,10 @@ typedef struct coff_ptr_struct
/* Selector for the union above. */
bool is_sym;
/* An extra pointer which can used by format based on COFF (like XCOFF)
to provide extra information to their backend. */
void *extrap;
} combined_entry_type;

View file

@ -298,11 +298,11 @@ _bfd_XXi_swap_aux_in (bfd * abfd,
case C_FILE:
if (ext->x_file.x_fname[0] == 0)
{
in->x_file.x_n.x_zeroes = 0;
in->x_file.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
in->x_file.x_n.x_n.x_zeroes = 0;
in->x_file.x_n.x_n.x_offset = H_GET_32 (abfd, ext->x_file.x_n.x_offset);
}
else
memcpy (in->x_file.x_fname, ext->x_file.x_fname, FILNMLEN);
memcpy (in->x_file.x_n.x_fname, ext->x_file.x_fname, FILNMLEN);
return;
case C_STAT:
@ -370,13 +370,13 @@ _bfd_XXi_swap_aux_out (bfd * abfd,
switch (in_class)
{
case C_FILE:
if (in->x_file.x_fname[0] == 0)
if (in->x_file.x_n.x_fname[0] == 0)
{
H_PUT_32 (abfd, 0, ext->x_file.x_n.x_zeroes);
H_PUT_32 (abfd, in->x_file.x_n.x_offset, ext->x_file.x_n.x_offset);
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_fname, sizeof (ext->x_file.x_fname));
memcpy (ext->x_file.x_fname, in->x_file.x_n.x_fname, sizeof (ext->x_file.x_fname));
return AUXESZ;

View file

@ -4550,13 +4550,13 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo,
/* This is the file name (or some comment put in by
the compiler). If it is long, we must put it in
the string table. */
if (aux.x_file.x_n.x_zeroes == 0
&& aux.x_file.x_n.x_offset != 0)
if (aux.x_file.x_n.x_n.x_zeroes == 0
&& aux.x_file.x_n.x_n.x_offset != 0)
{
const char *filename;
bfd_size_type indx;
BFD_ASSERT (aux.x_file.x_n.x_offset
BFD_ASSERT (aux.x_file.x_n.x_n.x_offset
>= STRING_SIZE_SIZE);
if (strings == NULL)
{
@ -4564,15 +4564,15 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo,
if (strings == NULL)
return false;
}
if ((bfd_size_type) aux.x_file.x_n.x_offset >= obj_coff_strings_len (input_bfd))
if ((bfd_size_type) aux.x_file.x_n.x_n.x_offset >= obj_coff_strings_len (input_bfd))
filename = _("<corrupt>");
else
filename = strings + aux.x_file.x_n.x_offset;
filename = strings + aux.x_file.x_n.x_n.x_offset;
indx = _bfd_stringtab_add (flinfo->strtab, filename,
hash, copy);
if (indx == (bfd_size_type) -1)
return false;
aux.x_file.x_n.x_offset = STRING_SIZE_SIZE + indx;
aux.x_file.x_n.x_n.x_offset = STRING_SIZE_SIZE + indx;
}
}
else if (CSECT_SYM_P (isymp->n_sclass)

View file

@ -107,6 +107,7 @@ static void ppc_es (int);
static void ppc_csect (int);
static void ppc_dwsect (int);
static void ppc_change_csect (symbolS *, offsetT);
static void ppc_file (int);
static void ppc_function (int);
static void ppc_extern (int);
static void ppc_lglobl (int);
@ -227,6 +228,7 @@ const pseudo_typeS md_pseudo_table[] =
{ "ei", ppc_biei, 1 },
{ "es", ppc_es, 0 },
{ "extern", ppc_extern, 0 },
{ "file", ppc_file, 0 },
{ "function", ppc_function, 0 },
{ "lglobl", ppc_lglobl, 0 },
{ "ref", ppc_ref, 0 },
@ -5073,6 +5075,67 @@ ppc_stabx (int ignore ATTRIBUTE_UNUSED)
demand_empty_rest_of_line ();
}
/* The .file pseudo-op. On XCOFF, .file can have several parameters
which are being added to the symbol table to provide additional
information. */
static void
ppc_file (int ignore ATTRIBUTE_UNUSED)
{
char *sfname, *s1 = NULL, *s2 = NULL, *s3 = NULL;
int length, auxnb = 1;
/* Some assemblers tolerate immediately following '"'. */
if ((sfname = demand_copy_string (&length)) != 0)
{
coff_symbol_type *coffsym;
if (*input_line_pointer == ',')
{
++input_line_pointer;
s1 = demand_copy_string (&length);
auxnb++;
if (*input_line_pointer == ',')
{
++input_line_pointer;
s2 = demand_copy_string (&length);
auxnb++;
if (*input_line_pointer == ',')
{
++input_line_pointer;
s3 = demand_copy_string (&length);
auxnb++;
}
}
}
/* Use coff dot_file creation and adjust auxiliary entries. */
c_dot_file_symbol (sfname, 0);
S_SET_NUMBER_AUXILIARY (symbol_rootP, auxnb);
coffsym = coffsymbol (symbol_get_bfdsym (symbol_rootP));
coffsym->native[1].u.auxent.x_file.x_ftype = XFT_FN;
if (s1)
{
coffsym->native[2].u.auxent.x_file.x_ftype = XFT_CT;
coffsym->native[2].extrap = s1;
}
if (s2)
{
coffsym->native[3].u.auxent.x_file.x_ftype = XFT_CV;
coffsym->native[3].extrap = s2;
}
if (s3)
{
coffsym->native[4].u.auxent.x_file.x_ftype = XFT_CD;
coffsym->native[4].extrap = s3;
}
demand_empty_rest_of_line ();
}
}
/* The .function pseudo-op. This takes several arguments. The first
argument seems to be the external name of the symbol. The second
argument seems to be the label for the start of the function. gcc

View file

@ -146,7 +146,7 @@ struct ppc_tc_sy
#define TC_SYMFIELD_TYPE struct ppc_tc_sy
/* We need an additional auxent for function symbols. */
#define OBJ_COFF_MAX_AUXENTRIES 2
#define OBJ_COFF_MAX_AUXENTRIES 4
/* Square and curly brackets are permitted in symbol names. */
#define LEX_BR 3

View file

@ -84,4 +84,7 @@ if { [istarget "powerpc*-*-aix*"] || [istarget "rs6000-*-aix*"] } then {
run_dump_test "xcoff-stsym-32"
run_dump_test "xcoff-stsym-64"
run_dump_test "xcoff-file-32"
run_dump_test "xcoff-file-64"
}

View file

@ -0,0 +1,13 @@
#as: -a32
#source: xcoff-file.s
#objdump: -t
#name: XCOFF file test (32-bit)
.*
SYMBOL TABLE:
\[ 0\].*\(scl 103\) \(nx 4\) .* file.s
File
File ftype 1 fname "A long string"
File ftype 2 fname "short"
File ftype 128 fname "Another long string inside the strign table."

View file

@ -0,0 +1,13 @@
#as: -a64
#source: xcoff-file.s
#objdump: -t
#name: XCOFF file test (64-bit)
.*
SYMBOL TABLE:
\[ 0\].*\(scl 103\) \(nx 4\) .* file.s
File
File ftype 1 fname "A long string"
File ftype 2 fname "short"
File ftype 128 fname "Another long string inside the strign table."

View file

@ -0,0 +1 @@
.file "file.s", "A long string", "short", "Another long string inside the strign table."

View file

@ -578,18 +578,21 @@ union internal_auxent
unsigned short x_tvndx; /* tv index */
} x_sym;
union
struct
{
/* PR 17754: We use to FILNMLEN for the size of the x_fname
array, but that causes problems as PE targets use a larger
value. We cannot use their definition of E_FILNMLEN as this
header can be used without including any PE headers. */
char x_fname[20];
struct
{
long x_zeroes;
long x_offset;
} x_n;
union {
/* PR 17754: We use to FILNMLEN for the size of the x_fname
array, but that causes problems as PE targets use a larger
value. We cannot use their definition of E_FILNMLEN as this
header can be used without including any PE headers. */
char x_fname[20];
struct
{
long x_zeroes;
long x_offset;
} x_n;
} x_n;
unsigned char x_ftype;
} x_file;
struct

View file

@ -176,6 +176,7 @@ union external_auxent {
} x_n;
} x_n;
char x_ftype[1];
char x_resv[3];
} x_file;
struct {

View file

@ -190,6 +190,12 @@
#define XMC_UL 21 /* Read-write uninitialized TLS data */
#define XMC_TE 22 /* Same as XMC_TC but mapped after it */
/* x_ftype values: */
#define XFT_FN 0 /* Specifies the source-file name */
#define XFT_CT 1 /* Specifies the compiler time stamp */
#define XFT_CV 2 /* Specifies the compiler version number */
#define XFT_CD 128 /*Specifies compiler-defined information */
/* The ldhdr structure. This appears at the start of the .loader
section. */