aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorSzabolcs Nagy <szabolcs.nagy@arm.com>2019-04-25 15:07:10 +0100
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2019-05-24 15:09:06 +0100
commit0b4eac57c44ec4c9e13f5201b40936c3b3e6c639 (patch)
treecbb5471417b7fdd03b84a21c4f856f5c0c2ab2d6 /gas/config
parentf166ae0188dcb89c5ae925034260a708a254ab2f (diff)
downloadgdb-0b4eac57c44ec4c9e13f5201b40936c3b3e6c639.zip
gdb-0b4eac57c44ec4c9e13f5201b40936c3b3e6c639.tar.gz
gdb-0b4eac57c44ec4c9e13f5201b40936c3b3e6c639.tar.bz2
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.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-aarch64.c32
-rw-r--r--gas/config/tc-aarch64.h6
2 files changed, 38 insertions, 0 deletions
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);