diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 8 | ||||
-rw-r--r-- | gas/config/tc-aarch64.c | 32 | ||||
-rw-r--r-- | gas/config/tc-aarch64.h | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/symbol-variant_pcs-3.d | 12 | ||||
-rw-r--r-- | gas/testsuite/gas/aarch64/symbol-variant_pcs-3.s | 20 |
5 files changed, 78 insertions, 0 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index ed69e9a..a6a539c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,13 @@ 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. * doc/c-aarch64.texi: Document .variant_pcs. * testsuite/gas/aarch64/symbol-variant_pcs-1.d: New test. diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 3bccfa2..000a81c 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -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 diff --git a/gas/config/tc-aarch64.h b/gas/config/tc-aarch64.h index b549072..f4eb1d5 100644 --- a/gas/config/tc-aarch64.h +++ b/gas/config/tc-aarch64.h @@ -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); diff --git a/gas/testsuite/gas/aarch64/symbol-variant_pcs-3.d b/gas/testsuite/gas/aarch64/symbol-variant_pcs-3.d new file mode 100644 index 0000000..204914e --- /dev/null +++ b/gas/testsuite/gas/aarch64/symbol-variant_pcs-3.d @@ -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 diff --git a/gas/testsuite/gas/aarch64/symbol-variant_pcs-3.s b/gas/testsuite/gas/aarch64/symbol-variant_pcs-3.s new file mode 100644 index 0000000..9960831 --- /dev/null +++ b/gas/testsuite/gas/aarch64/symbol-variant_pcs-3.s @@ -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 |