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:
parent
f493b71179
commit
e86fc4a5bc
18 changed files with 273 additions and 82 deletions
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
134
bfd/coffgen.c
134
bfd/coffgen.c
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
13
gas/testsuite/gas/ppc/xcoff-file-32.d
Normal file
13
gas/testsuite/gas/ppc/xcoff-file-32.d
Normal 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."
|
13
gas/testsuite/gas/ppc/xcoff-file-64.d
Normal file
13
gas/testsuite/gas/ppc/xcoff-file-64.d
Normal 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."
|
1
gas/testsuite/gas/ppc/xcoff-file.s
Normal file
1
gas/testsuite/gas/ppc/xcoff-file.s
Normal file
|
@ -0,0 +1 @@
|
|||
.file "file.s", "A long string", "short", "Another long string inside the strign table."
|
|
@ -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
|
||||
|
|
|
@ -176,6 +176,7 @@ union external_auxent {
|
|||
} x_n;
|
||||
} x_n;
|
||||
char x_ftype[1];
|
||||
char x_resv[3];
|
||||
} x_file;
|
||||
|
||||
struct {
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue