aarch64: override default elf .set handling in gas

Allow st_other values such as STO_AARCH64_VARIANT_PCS to be set for alias
symbols independently.  This is needed for ifunc symbols which are
aliased to the resolver using .set and don't expect resolver attributes
to override the ifunc symbol attributes.  This means .variant_pcs must be
added explicitly to aliases.

gas/ChangeLog:

	* config/tc-aarch64.c (aarch64_elf_copy_symbol_attributes): Define.
	* config/tc-aarch64.h (aarch64_elf_copy_symbol_attributes): Declare.
	(OBJ_COPY_SYMBOL_ATTRIBUTES): Define.
	* testsuite/gas/aarch64/symbol-variant_pcs-3.d: New test.
	* testsuite/gas/aarch64/symbol-variant_pcs-3.s: New test.
This commit is contained in:
Szabolcs Nagy 2019-04-25 15:07:10 +01:00
parent f166ae0188
commit 0b4eac57c4
5 changed files with 78 additions and 0 deletions

View File

@ -1,3 +1,11 @@
2019-05-24 Szabolcs Nagy <szabolcs.nagy@arm.com>
* config/tc-aarch64.c (aarch64_elf_copy_symbol_attributes): Define.
* config/tc-aarch64.h (aarch64_elf_copy_symbol_attributes): Declare.
(OBJ_COPY_SYMBOL_ATTRIBUTES): Define.
* testsuite/gas/aarch64/symbol-variant_pcs-3.d: New test.
* testsuite/gas/aarch64/symbol-variant_pcs-3.s: New test.
2019-05-24 Szabolcs Nagy <szabolcs.nagy@arm.com>
* config/tc-aarch64.c (s_variant_pcs): New function.

View File

@ -9420,3 +9420,35 @@ aarch64_copy_symbol_attributes (symbolS * dest, symbolS * src)
{
AARCH64_GET_FLAG (dest) = AARCH64_GET_FLAG (src);
}
#ifdef OBJ_ELF
/* Same as elf_copy_symbol_attributes, but without copying st_other.
This is needed so AArch64 specific st_other values can be independently
specified for an IFUNC resolver (that is called by the dynamic linker)
and the symbol it resolves (aliased to the resolver). In particular,
if a function symbol has special st_other value set via directives,
then attaching an IFUNC resolver to that symbol should not override
the st_other setting. Requiring the directive on the IFUNC resolver
symbol would be unexpected and problematic in C code, where the two
symbols appear as two independent function declarations. */
void
aarch64_elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
{
struct elf_obj_sy *srcelf = symbol_get_obj (src);
struct elf_obj_sy *destelf = symbol_get_obj (dest);
if (srcelf->size)
{
if (destelf->size == NULL)
destelf->size = XNEW (expressionS);
*destelf->size = *srcelf->size;
}
else
{
if (destelf->size != NULL)
free (destelf->size);
destelf->size = NULL;
}
S_SET_SIZE (dest, S_GET_SIZE (src));
}
#endif

View File

@ -130,6 +130,12 @@ void aarch64_copy_symbol_attributes (symbolS *, symbolS *);
(aarch64_copy_symbol_attributes (DEST, SRC))
#endif
#ifdef OBJ_ELF
void aarch64_elf_copy_symbol_attributes (symbolS *, symbolS *);
#define OBJ_COPY_SYMBOL_ATTRIBUTES(DEST, SRC) \
aarch64_elf_copy_symbol_attributes (DEST, SRC)
#endif
#define TC_START_LABEL(STR, NUL_CHAR, NEXT_CHAR) \
(NEXT_CHAR == ':' || (NEXT_CHAR == '/' && aarch64_data_in_code ()))
#define tc_canonicalize_symbol_name(str) aarch64_canonicalize_symbol_name (str);

View File

@ -0,0 +1,12 @@
#objdump: -t
.*: file format .*
SYMBOL TABLE:
0+ l d \.text 0+ \.text
0+ l d \.data 0+ \.data
0+ l d \.bss 0+ \.bss
0+ g \.text 0+ 0x80 foo_vpcs
0+ g \.text 0+ foo_base
0+ g \.text 0+ 0x80 alias_vpcs
0+ g \.text 0+ alias_base

View File

@ -0,0 +1,20 @@
.text
.global foo_vpcs
.global foo_base
.global alias_vpcs
.global alias_base
.variant_pcs foo_vpcs
.variant_pcs alias_vpcs
foo_vpcs:
foo_base:
bl foo_vpcs
bl foo_base
bl alias_vpcs
bl alias_base
/* Check that the STO_AARCH64_VARIANT_PCS is not affected by .set. */
.set alias_base, foo_vpcs
.set alias_vpcs, foo_base