Hi all,
This simple patch sets the ELF header flag EF_AARCH64_CHERI_PURECAP for
purecap Morello object files, as documented in aaelf64-morello (section 4.1):
https://github.com/ARM-software/abi-aa/blob/main/aaelf64-morello/aaelf64-mo…
Regression tested on aarch64-linux-gnu, OK for
users/ARM/morello-binutils-gdb-master?
Thanks,
Alex
gas/ChangeLog:
2021-09-24 Alex Coplan <alex.coplan(a)arm.com>
* config/tc-aarch64.c (md_begin): Set the ELF header flag
EF_AARCH64_CHERI_PURECAP if we have the C64 extension.
Hi all,
This patch fixes the encoding of the immediate in the A64C ldtr/sttr
instructions. Prior to this patch, GAS would accept immediates for these
instructions that were not multiples of 16, and would not scale the
immediate by 16.
Regression tested on aarch64-linux-gnu, OK for
users/ARM/morello-binutils-gdb-master?
Thanks,
Alex
---
gas/ChangeLog:
2021-09-24 Alex Coplan <alex.coplan(a)arm.com>
* testsuite/gas/aarch64/morello_ldst-c64.d: Update following
test + encoding change.
* testsuite/gas/aarch64/morello_ldst-invalid.d: New test.
* testsuite/gas/aarch64/morello_ldst-invalid.l: New test.
* testsuite/gas/aarch64/morello_ldst-invalid.s: New test.
* testsuite/gas/aarch64/morello_ldst.d: Update following
test + encoding change.
* testsuite/gas/aarch64/morello_ldst.s: Update to use valid
immediates for ldtr/sttr instructions.
opcodes/ChangeLog:
2021-09-24 Alex Coplan <alex.coplan(a)arm.com>
* aarch64-tbl.h (aarch64_opcode_table): Update A64C_INSNs
ldtr/sttr to take A64C_ADDR_SIMM9 instead of ADDR_SIMM9
operands.
This function had a buggy implementation of rounding a value up to a
given power of 2. Aligning to a multiple of 16 would align to a
multiple of 32 and so on.
This was observable when linking object files that had very large
objects in them. The compiler would ensure that these objects are large
enough that they are exactly representable, but the linker would
complain that they are not because the linker asserted extra alignment
than the compiler.
Here we fix the bug, add a few testcases, and adjust an existing
testcase in the area.
############### Attachment also inlined for ease of reply ###############
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 47001a5bdb91dc3e7341f1cf4068e74b12ff0df6..73ffdad33bc8d5bf9cf2e2d84a606e8d183695f7 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -4797,7 +4797,7 @@ exponent (uint64_t len)
#undef CAP_MAX_EXPONENT
}
-#define ONES(x) ((1ULL << ((x) + 1)) - 1)
+#define ONES(x) ((1ULL << (x)) - 1)
#define ALIGN_UP(x, a) (((x) + ONES (a)) & (~ONES (a)))
static bfd_boolean
diff --git a/ld/testsuite/ld-aarch64/aarch64-elf.exp b/ld/testsuite/ld-aarch64/aarch64-elf.exp
index e9cb95d5e17b43b5ed4fc25e782a9d668c9d785c..228cfe224c57efc1cac6c694d304d8186e8749d6 100644
--- a/ld/testsuite/ld-aarch64/aarch64-elf.exp
+++ b/ld/testsuite/ld-aarch64/aarch64-elf.exp
@@ -244,6 +244,8 @@ run_dump_test_lp64 "emit-relocs-morello-2"
run_dump_test_lp64 "emit-relocs-morello-2-a64c"
run_dump_test_lp64 "emit-relocs-morello-3"
run_dump_test_lp64 "emit-relocs-morello-3-a64c"
+run_dump_test_lp64 "emit-relocs-morello-4"
+run_dump_test_lp64 "emit-relocs-morello-5"
run_dump_test_lp64 "morello-capinit"
run_dump_test_lp64 "morello-stubs"
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-4.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-4.d
new file mode 100644
index 0000000000000000000000000000000000000000..04cfa79a042a40be2dc3e745437c0ae344b53cc3
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-4.d
@@ -0,0 +1,14 @@
+#source: emit-relocs-morello-4.s
+#as: -march=morello+c64
+#ld: -static
+#readelf: --relocs --syms
+
+
+#...
+Relocation section[^\n]*contains 1 entry:
+#...
+Symbol table[^\n]*contains[^\n]*:
+ Num: Value Size.*
+#...
+ [0-9]+: [0-9a-f]+0 64016 [^\n]* bigarray
+#pass
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-4.s b/ld/testsuite/ld-aarch64/emit-relocs-morello-4.s
new file mode 100644
index 0000000000000000000000000000000000000000..d91d85ab5eb9080b70e3e70ddc36f2b8e85a2157
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-4.s
@@ -0,0 +1,17 @@
+// Checking that having a relocation against very large arrays that are not
+// problematic w.r.t. capability bounds representation do not error.
+// The below is somthing that requires being padded
+.bss
+.globl bigarray
+.p2align 4
+bigarray:
+ .zero 64004
+ .zero 12 // Tail padding to ensure precise bounds.
+ .size bigarray, 64016
+
+.text
+.globl _start
+.type _start STT_FUNC
+_start:
+ adrp c0, :got:bigarray
+ ldr c0, [c0, #:got_lo12:bigarray]
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-5.d b/ld/testsuite/ld-aarch64/emit-relocs-morello-5.d
new file mode 100644
index 0000000000000000000000000000000000000000..05bbef145e03786dbb489b40441e78fbff69ddb5
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-5.d
@@ -0,0 +1,6 @@
+#source: emit-relocs-morello-5.s
+#as: -march=morello+c64
+#ld: -static
+#error: .*: capability range may exceed object bounds
+#error: .*: in function `_start':.*
+#error: .*: dangerous relocation: unsupported relocation
diff --git a/ld/testsuite/ld-aarch64/emit-relocs-morello-5.s b/ld/testsuite/ld-aarch64/emit-relocs-morello-5.s
new file mode 100644
index 0000000000000000000000000000000000000000..0493c26065ced0d117a7ab9ab3969a00ff2045b0
--- /dev/null
+++ b/ld/testsuite/ld-aarch64/emit-relocs-morello-5.s
@@ -0,0 +1,15 @@
+// Checking that having a relocation against very large arrays whose size can
+// not be represented gives the corresponding error.
+.bss
+.globl bigarray
+.p2align 4
+bigarray:
+ .zero 64004
+ .size bigarray, 64004
+
+.text
+.globl _start
+.type _start STT_FUNC
+_start:
+ adrp c0, :got:bigarray
+ ldr c0, [c0, #:got_lo12:bigarray]
diff --git a/ld/testsuite/ld-aarch64/morello-sec-round.d b/ld/testsuite/ld-aarch64/morello-sec-round.d
index 00eceb0386a3f8890c2876a4a6bac9569f146e33..b553a604acd92a2b0c5e151546e2c19a04101f70 100644
--- a/ld/testsuite/ld-aarch64/morello-sec-round.d
+++ b/ld/testsuite/ld-aarch64/morello-sec-round.d
@@ -7,5 +7,5 @@ Idx Name Size VMA LMA File off Algn
#...
1 .text_sec 00020004 ...........20000 [0-9a-f]+ [0-9a-f]+ 2\*\*17
CONTENTS, ALLOC, LOAD, READONLY, CODE
- 2 \..* [0-9a-f]+ ...........40080 [0-9a-f]+ [0-9a-f]+ .*
+ 2 \..* [0-9a-f]+ ...........40040 [0-9a-f]+ [0-9a-f]+ .*
#pass
Hi all,
As it stands, the architecture feature bits for Morello include FP16FML
(i.e. ARMv8.2-FHM) but not FP16: this is an invalid combination.
Looking at the Morello Arm ARM [1], it seems that Morello wants the
feature FP16 (ARMv8.2-FP16) but not FP16FML.
Regtested on aarch64-none-elf, OK for morello-binutils-gdb-master?
Thanks,
Alex
[1] : https://developer.arm.com/documentation/ddi0606/latest
include/ChangeLog:
* opcode/aarch64.h (AARCH64_ARCH_MORELLO): Change F16_FML
feature bit to F16.
After d30dd5c GAS now accounts for the LSB getting set on STT_FUNC by
maintaining the value of the relevant functions to include that LSB.
Previously GAS attempted to account for the LSB only when outputting the
file (i.e. in the obj_adjust_symtab hook and when a relocation is
getting made for the relevant symbol).
The obj_adjust_symtab hook is still needed, since this is about adding a
flag to an elf_sym rather than adjusting the value of the symbol.
We changed from this so that expressions given by the user would
naturally account for the LSB set on C64 STT_FUNC symbols. This means
that we no longer need to adjust local pc-relative relocations in
`parse_operands` since the relative relocation will naturally include
whether the LSB is set on the relevant symbol.
Here we remove the previous code to do this adjustment. With both
methods of accounting we ended up adding 2 to the relocation rather than
just setting the LSB.
Note that the combination of this change and d30dd5c has meant that a
`AARCH64_ADR_PREL_LO21` relocation to a locally defined function now points
directly to that function rather than to that function plus 1.
These relocations are left in the object file when the locally defined
function is declared global. This matches the behaviour of LLVM.
############### Attachment also inlined for ease of reply ###############
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index f550d9e042f4962e0d7c23eae40978610141e77b..5c0a8067168c2f9e0330f8b5c8c2f80c560c058c 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -6689,21 +6689,6 @@ bad_adrdp:
case pcreladdr:
gas_assert (operands[i] == AARCH64_OPND_ADDR_PCREL21);
inst.reloc.type = BFD_RELOC_AARCH64_ADR_LO21_PCREL;
- if (inst.reloc.exp.X_op == O_symbol
- && inst.reloc.exp.X_add_symbol != NULL)
- {
- symbolS *sym = inst.reloc.exp.X_add_symbol;
-
- /* We set LSB for C64 local functions. We do not do
- this for local labels even in code section because
- it could be embedded data. */
- if (S_IS_DEFINED (sym) && AARCH64_IS_C64 (sym)
- && (symbol_get_bfdsym (sym)->flags & BSF_FUNCTION))
- {
- inst.reloc.exp.X_add_number += 1;
- }
- }
-
break;
default:
gas_assert (0);
diff --git a/gas/testsuite/gas/aarch64/morello-lsb-relocs.d b/gas/testsuite/gas/aarch64/morello-lsb-relocs.d
index 226801b23a8a9061d466dbfcdc220b9eb279a25e..4fc9f8674175cd1c826053fcb20690e91914128f 100644
--- a/gas/testsuite/gas/aarch64/morello-lsb-relocs.d
+++ b/gas/testsuite/gas/aarch64/morello-lsb-relocs.d
@@ -20,27 +20,33 @@ Disassembly of section \.text:
\.\.\.
000000000000000c <f>:
- c: 14000000 b 0 <x>
- c: R_MORELLO_JUMP26 x
- 10: 14000000 b c <f>
- 10: R_MORELLO_JUMP26 f
- 14: 17fffffe b c <f>
- 18: 17fffffd b c <f>
- 1c: 5400000d b\.le 0 <x>
- 1c: R_MORELLO_CONDBR19 x
- 20: 5400000d b\.le c <f>
- 20: R_MORELLO_CONDBR19 f
- 24: 54ffff4d b\.le c <f>
- 28: 54ffff2d b\.le c <f>
- 2c: 36080001 tbz w1, #1, 0 <x>
- 2c: R_MORELLO_TSTBR14 x
- 30: 36080001 tbz w1, #1, c <f>
- 30: R_MORELLO_TSTBR14 f
- 34: 360ffec1 tbz w1, #1, c <f>
- 38: 360ffea1 tbz w1, #1, c <f>
- 3c: 94000000 bl 0 <x>
- 3c: R_MORELLO_CALL26 x
- 40: 94000000 bl c <f>
- 40: R_MORELLO_CALL26 f
- 44: 97fffff2 bl c <f>
- 48: 97fffff1 bl c <f>
+ c: 10000000 adr c0, 0 <x>
+ c: R_AARCH64_ADR_PREL_LO21 x
+ 10: 10000000 adr c0, c <f>
+ 10: R_AARCH64_ADR_PREL_LO21 f
+ 14: 30ffffc0 adr c0, d <f\+0x1>
+ 18: 10ffffa0 adr c0, c <f>
+ 1c: 14000000 b 0 <x>
+ 1c: R_MORELLO_JUMP26 x
+ 20: 14000000 b c <f>
+ 20: R_MORELLO_JUMP26 f
+ 24: 17fffffa b c <f>
+ 28: 17fffff9 b c <f>
+ 2c: 5400000d b\.le 0 <x>
+ 2c: R_MORELLO_CONDBR19 x
+ 30: 5400000d b\.le c <f>
+ 30: R_MORELLO_CONDBR19 f
+ 34: 54fffecd b\.le c <f>
+ 38: 54fffead b\.le c <f>
+ 3c: 36080001 tbz w1, #1, 0 <x>
+ 3c: R_MORELLO_TSTBR14 x
+ 40: 36080001 tbz w1, #1, c <f>
+ 40: R_MORELLO_TSTBR14 f
+ 44: 360ffe41 tbz w1, #1, c <f>
+ 48: 360ffe21 tbz w1, #1, c <f>
+ 4c: 94000000 bl 0 <x>
+ 4c: R_MORELLO_CALL26 x
+ 50: 94000000 bl c <f>
+ 50: R_MORELLO_CALL26 f
+ 54: 97ffffee bl c <f>
+ 58: 97ffffed bl c <f>
diff --git a/gas/testsuite/gas/aarch64/morello-lsb-relocs.s b/gas/testsuite/gas/aarch64/morello-lsb-relocs.s
index 227b023e220386e4630e869ca4f62e7b4e7ff410..26e498f59d07978a9d26384bfa92db3738837cd8 100644
--- a/gas/testsuite/gas/aarch64/morello-lsb-relocs.s
+++ b/gas/testsuite/gas/aarch64/morello-lsb-relocs.s
@@ -14,6 +14,11 @@ a: // This function is local, so the relocation on the ADR
// instruction will be relaxed to a value.
altlabel: // This label does not have function type, so will not have the
// LSB set.
+ adr c0, x
+ adr c0, f
+ adr c0, a // Local C64 function on instruction that does not
+ // ignore LSB so we the LSB included in the output.
+ adr c0, altlabel
b x
b f
b a
diff --git a/gas/testsuite/gas/aarch64/morello-lsb-relocs2.d b/gas/testsuite/gas/aarch64/morello-lsb-relocs2.d
index aa99c58a70c4e1a104525fef1d8eb997a346ad06..2b9386954fde61eb595e20fef42b1be94b989610 100644
--- a/gas/testsuite/gas/aarch64/morello-lsb-relocs2.d
+++ b/gas/testsuite/gas/aarch64/morello-lsb-relocs2.d
@@ -3,16 +3,18 @@
#source: morello-lsb-relocs.s
-Relocation section '\.rela\.text' at offset 0x198 contains 8 entries:
+Relocation section '\.rela\.text' at offset 0x1a8 contains 10 entries:
Offset Info Type Sym\. Value Sym\. Name \+ Addend
-00000000000c 00090000e002 R_MORELLO_JUMP26 0000000000000000 x \+ 0
-000000000010 00080000e002 R_MORELLO_JUMP26 000000000000000d f \+ 0
-00000000001c 00090000e001 R_MORELLO_CONDBR1 0000000000000000 x \+ 0
-000000000020 00080000e001 R_MORELLO_CONDBR1 000000000000000d f \+ 0
-00000000002c 00090000e000 R_MORELLO_TSTBR14 0000000000000000 x \+ 0
-000000000030 00080000e000 R_MORELLO_TSTBR14 000000000000000d f \+ 0
-00000000003c 00090000e003 R_MORELLO_CALL26 0000000000000000 x \+ 0
-000000000040 00080000e003 R_MORELLO_CALL26 000000000000000d f \+ 0
+00000000000c 000900000112 R_AARCH64_ADR_PRE 0000000000000000 x \+ 0
+000000000010 000800000112 R_AARCH64_ADR_PRE 000000000000000d f \+ 0
+00000000001c 00090000e002 R_MORELLO_JUMP26 0000000000000000 x \+ 0
+000000000020 00080000e002 R_MORELLO_JUMP26 000000000000000d f \+ 0
+00000000002c 00090000e001 R_MORELLO_CONDBR1 0000000000000000 x \+ 0
+000000000030 00080000e001 R_MORELLO_CONDBR1 000000000000000d f \+ 0
+00000000003c 00090000e000 R_MORELLO_TSTBR14 0000000000000000 x \+ 0
+000000000040 00080000e000 R_MORELLO_TSTBR14 000000000000000d f \+ 0
+00000000004c 00090000e003 R_MORELLO_CALL26 0000000000000000 x \+ 0
+000000000050 00080000e003 R_MORELLO_CALL26 000000000000000d f \+ 0
Symbol table '\.symtab' contains 10 entries:
Num: Value Size Type Bind Vis Ndx Name
Now that we internally handle a set LSB as part of a C64 STT_FUNC value
throughout the assembler rather than as something that is just
introduced by the linker, relocations to code labels now may or may not
include that LSB.
GAS checks that the target of an AARCH64 BRANCH19, TSTBR14, CALL26, or
JUMP26 relocation is aligned, since all uses should point to an
instruction and all instructions should be aligned.
Now that we are including the LSB in the value of STT_FUNC C64 symbols,
the relevant MORELLO_* relocations do not also satisfy this alignment
behaviour. When these relocations target a location generated from an
STT_FUNC C64 symbol, their value includes that LSB.
This behaviour is not relevant to the user since these relocations lose
the bottom 2 bits of the value they target. It does however match the
specification of the relocations in the ABI document, which includes the
`C` bit.
This fix avoids requiring that this LSB is unset when in `md_apply_fix`.
For extra robustness we also assert that when setting this LSB on the
symbol in the first place it was not set to begin with.
A downside is that if the LSB is set on non-function symbols the user
will not be warned about that. Any method to handle that would always
need to determine which expressions should include this LSB and which
shouldn't, which would be difficult to make perfect. On top of that,
the relevant code would either have to duplicate the code in
`fixup_segment` that resolves an expression into a single value, or
record another bit in the `TC_FIX_TYPE` structure just for this warning.
This seems like more complexity than the extra warning is worth.
We add two tests since `objdump` shows the resulting disassembly but
`readelf` shows the LSB getting set on the relevant functions.
############### Attachment also inlined for ease of reply ###############
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 4b66d542191263fbef4ff6f82957848c3fe2708f..765996c624f9b646317f33c7cc07d51ab359e6b4 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -7710,7 +7710,10 @@ aarch64_frob_label (symbolS * sym)
AARCH64_SET_C64 (sym, IS_C64);
if (AARCH64_IS_C64 (sym) && S_IS_FUNCTION (sym))
- *symbol_X_add_number (sym) += 1;
+ {
+ gas_assert ((*symbol_X_add_number (sym) & 1) == 0);
+ *symbol_X_add_number (sym) += 1;
+ }
dwarf2_emit_label (sym);
}
@@ -8500,6 +8503,15 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
int scale;
unsigned flags = fixP->fx_addnumber;
+ /* We check alignment for relocations of this kind. These relocations could
+ be applied on a C64 STT_FUNC symbol and hence may have the LSB set on
+ `*valP`, their AARCH64 counterparts can not be applied on such symbols and
+ hence should never have the LSB set on their value. */
+ valueT alignment_mask = (fixP->fx_r_type == BFD_RELOC_MORELLO_BRANCH19
+ || fixP->fx_r_type == BFD_RELOC_MORELLO_TSTBR14
+ || fixP->fx_r_type == BFD_RELOC_MORELLO_CALL26
+ || fixP->fx_r_type == BFD_RELOC_MORELLO_JUMP26)
+ ? 2 : 3;
DEBUG_TRACE ("\n\n");
DEBUG_TRACE ("~~~~~~~~~~~~~~~~~~~~~~~~~");
@@ -8609,7 +8621,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
case BFD_RELOC_MORELLO_BRANCH19:
if (fixP->fx_done || !seg->use_rela_p)
{
- if (value & 3)
+ if (value & alignment_mask)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("conditional branch target not word aligned"));
if (signed_overflow (value, 21))
@@ -8625,7 +8637,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
case BFD_RELOC_AARCH64_TSTBR14:
if (fixP->fx_done || !seg->use_rela_p)
{
- if (value & 3)
+ if (value & alignment_mask)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("conditional branch target not word aligned"));
if (signed_overflow (value, 16))
@@ -8643,7 +8655,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
case BFD_RELOC_AARCH64_JUMP26:
if (fixP->fx_done || !seg->use_rela_p)
{
- if (value & 3)
+ if (value & alignment_mask)
as_bad_where (fixP->fx_file, fixP->fx_line,
_("branch target not word aligned"));
if (signed_overflow (value, 28))
diff --git a/gas/testsuite/gas/aarch64/morello-lsb-relocs.d b/gas/testsuite/gas/aarch64/morello-lsb-relocs.d
new file mode 100644
index 0000000000000000000000000000000000000000..226801b23a8a9061d466dbfcdc220b9eb279a25e
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/morello-lsb-relocs.d
@@ -0,0 +1,46 @@
+#as: -march=armv8-a+c64
+#objdump: -drt
+
+.*\.o: file format .*
+
+SYMBOL TABLE:
+0000000000000000 l d \.text 0000000000000000 \.text
+0000000000000000 l d \.data 0000000000000000 \.data
+0000000000000000 l d \.bss 0000000000000000 \.bss
+000000000000000c l F \.text 0000000000000000 a
+000000000000000c l \.text 0000000000000000 altlabel
+000000000000000c g F \.text 0000000000000000 f
+0000000000000000 \*UND\* 0000000000000000 x
+
+
+
+Disassembly of section \.text:
+
+0000000000000000 <f-0xc>:
+ \.\.\.
+
+000000000000000c <f>:
+ c: 14000000 b 0 <x>
+ c: R_MORELLO_JUMP26 x
+ 10: 14000000 b c <f>
+ 10: R_MORELLO_JUMP26 f
+ 14: 17fffffe b c <f>
+ 18: 17fffffd b c <f>
+ 1c: 5400000d b\.le 0 <x>
+ 1c: R_MORELLO_CONDBR19 x
+ 20: 5400000d b\.le c <f>
+ 20: R_MORELLO_CONDBR19 f
+ 24: 54ffff4d b\.le c <f>
+ 28: 54ffff2d b\.le c <f>
+ 2c: 36080001 tbz w1, #1, 0 <x>
+ 2c: R_MORELLO_TSTBR14 x
+ 30: 36080001 tbz w1, #1, c <f>
+ 30: R_MORELLO_TSTBR14 f
+ 34: 360ffec1 tbz w1, #1, c <f>
+ 38: 360ffea1 tbz w1, #1, c <f>
+ 3c: 94000000 bl 0 <x>
+ 3c: R_MORELLO_CALL26 x
+ 40: 94000000 bl c <f>
+ 40: R_MORELLO_CALL26 f
+ 44: 97fffff2 bl c <f>
+ 48: 97fffff1 bl c <f>
diff --git a/gas/testsuite/gas/aarch64/morello-lsb-relocs.s b/gas/testsuite/gas/aarch64/morello-lsb-relocs.s
new file mode 100644
index 0000000000000000000000000000000000000000..227b023e220386e4630e869ca4f62e7b4e7ff410
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/morello-lsb-relocs.s
@@ -0,0 +1,32 @@
+ .text
+ // Just to make it a bit clearer to humans reading the tests that we
+ // use the address of `f` and `altlabel` in some places. Otherwise
+ // when reading the disassembly you just see `0` and it's not 100%
+ // clear that we're using the address vs using a dummy value for later.
+ .zero 12
+ .p2align 2
+ .globl f
+ .type f,@function
+ .type a,@function
+f: // This function is global, so relocations will remain in the
+ // object file.
+a: // This function is local, so the relocation on the ADR
+ // instruction will be relaxed to a value.
+altlabel: // This label does not have function type, so will not have the
+ // LSB set.
+ b x
+ b f
+ b a
+ b altlabel
+ b.le x
+ b.le f
+ b.le a
+ b.le altlabel
+ tbz x1, 1, x
+ tbz x1, 1, f
+ tbz x1, 1, a
+ tbz x1, 1, altlabel
+ bl x
+ bl f
+ bl a
+ bl altlabel
diff --git a/gas/testsuite/gas/aarch64/morello-lsb-relocs2.d b/gas/testsuite/gas/aarch64/morello-lsb-relocs2.d
new file mode 100644
index 0000000000000000000000000000000000000000..aa99c58a70c4e1a104525fef1d8eb997a346ad06
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/morello-lsb-relocs2.d
@@ -0,0 +1,28 @@
+#as: -march=morello+c64
+#readelf: --relocs --syms
+#source: morello-lsb-relocs.s
+
+
+Relocation section '\.rela\.text' at offset 0x198 contains 8 entries:
+ Offset Info Type Sym\. Value Sym\. Name \+ Addend
+00000000000c 00090000e002 R_MORELLO_JUMP26 0000000000000000 x \+ 0
+000000000010 00080000e002 R_MORELLO_JUMP26 000000000000000d f \+ 0
+00000000001c 00090000e001 R_MORELLO_CONDBR1 0000000000000000 x \+ 0
+000000000020 00080000e001 R_MORELLO_CONDBR1 000000000000000d f \+ 0
+00000000002c 00090000e000 R_MORELLO_TSTBR14 0000000000000000 x \+ 0
+000000000030 00080000e000 R_MORELLO_TSTBR14 000000000000000d f \+ 0
+00000000003c 00090000e003 R_MORELLO_CALL26 0000000000000000 x \+ 0
+000000000040 00080000e003 R_MORELLO_CALL26 000000000000000d f \+ 0
+
+Symbol table '\.symtab' contains 10 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0000000000000000 0 SECTION LOCAL DEFAULT 1
+ 2: 0000000000000000 0 SECTION LOCAL DEFAULT 3
+ 3: 0000000000000000 0 SECTION LOCAL DEFAULT 4
+ 4: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 \$d
+ 5: 000000000000000c 0 NOTYPE LOCAL DEFAULT 1 \$c
+ 6: 000000000000000d 0 FUNC LOCAL DEFAULT 1 a
+ 7: 000000000000000c 0 NOTYPE LOCAL DEFAULT 1 altlabel
+ 8: 000000000000000d 0 FUNC GLOBAL DEFAULT 1 f
+ 9: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND x
Before this change we had a check that any capinit directive had a plain
symbol (possibly plus an addend) as an argument.
Unfortunately, the check itself is actually that GAS can identify that
the expression we have is in that category *before* applying all
adjustments after alignment etc. Internally this not only required that
the expression was of a simple enough form, but also that if we had an
expression of the form `f+((.Ltmp+1)-f)` (which is a form that compilers
use for label addresses) this required that the `f` and `.Ltmp` labels
were in the same `frag`.
In order to be in the same `frag` there could be no alignment between
them, whether from alignment directives between the two labels, or
because we had a data directive in between them and the assembler
ensured we were aligned when re-entering code state.
This artificial requirement triggered an assembler error when running
the GCC testsuite, hence we have removed it. This matches LLVM
behaviour. More obvious errors like subtracting symbols from different
sections are still caught in the general expression handling code.
############### Attachment also inlined for ease of reply ###############
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 765996c624f9b646317f33c7cc07d51ab359e6b4..f550d9e042f4962e0d7c23eae40978610141e77b 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -2164,13 +2164,7 @@ static void
s_aarch64_capinit (int ignored ATTRIBUTE_UNUSED)
{
expressionS exp;
-
expression (&exp);
- if (exp.X_op != O_symbol)
- {
- as_bad (_(".capinit expects a target symbol as an argument"));
- return;
- }
/* align to 16 bytes. */
do_align (4, (char *) NULL, 0, 0);
@@ -2186,13 +2180,7 @@ static void
s_aarch64_chericap (int ignored ATTRIBUTE_UNUSED)
{
expressionS exp;
-
expression (&exp);
- if (exp.X_op != O_symbol)
- {
- as_bad (_(".chericap expects a target symbol as an argument"));
- return;
- }
#ifdef md_flush_pending_output
md_flush_pending_output ();
diff --git a/gas/testsuite/gas/aarch64/morello-capinit.d b/gas/testsuite/gas/aarch64/morello-capinit.d
index 788449ba7daec9e4131fe6cb0cdca0eff3c94687..6567a2964beafcd8fae1297579deaf7690384139 100644
--- a/gas/testsuite/gas/aarch64/morello-capinit.d
+++ b/gas/testsuite/gas/aarch64/morello-capinit.d
@@ -6,6 +6,10 @@
RELOCATION RECORDS FOR \[\.text\]:
OFFSET TYPE VALUE
0000000000000000 R_AARCH64_LDST128_ABS_LO12_NC \.data\+0x0000000000000010
+0000000000000008 R_AARCH64_LDST128_ABS_LO12_NC \.data\+0x0000000000000010
+0000000000000010 R_MORELLO_CAPINIT f\+0x0000000000000008
+0000000000000020 R_AARCH64_LDST128_ABS_LO12_NC \.data\+0x0000000000000010
+0000000000000030 R_MORELLO_CAPINIT f2\+0x000000000000000c
RELOCATION RECORDS FOR \[\.data\]:
@@ -21,8 +25,11 @@ OFFSET TYPE VALUE
0000000000000000 R_MORELLO_CAPINIT str2
-Contents of section \.text:
- 0000 420040c2 c053c2c2 .*
+Contents of section .text:
+ 0000 420040c2 c053c2c2 420040c2 1f2003d5 .*
+ 0010 00000000 00000000 00000000 00000000 .*
+ 0020 420040c2 00000000 00000000 1f2003d5 .*
+ 0030 00000000 00000000 00000000 00000000 .*
Contents of section \.data:
0000 48656c6c 6f20576f 726c6400 00000000 .*
0010 00000000 00000000 00000000 00000000 .*
diff --git a/gas/testsuite/gas/aarch64/morello-capinit.s b/gas/testsuite/gas/aarch64/morello-capinit.s
index 62b79b1b6a5e82f52384823da6069e062f606954..c3d44b9cbf31e115c5c6c0c8e8e781d81efb58f8 100644
--- a/gas/testsuite/gas/aarch64/morello-capinit.s
+++ b/gas/testsuite/gas/aarch64/morello-capinit.s
@@ -49,3 +49,20 @@ e:
_start:
ldr c2, [c2, :lo12:a]
ret
+
+ .type f, %function
+f:
+ ldr c2, [c2, :lo12:a]
+ .p2align 4
+.Llab:
+ .capinit f+((.Llab+1)-f)
+ .xword 0
+ .xword 0
+ .type f2, %function
+f2:
+ ldr c2, [c2, :lo12:a]
+ .8byte 0
+.Llab2:
+ .capinit f2+((.Llab2+1)-f2)
+ .xword 0
+ .xword 0
diff --git a/gas/testsuite/gas/aarch64/morello-chericap.d b/gas/testsuite/gas/aarch64/morello-chericap.d
index 2d855f283a37cd507954da6fdb2b6b7b74294a25..f8e1fe99f2edd3c7998a0367d1a4d2931297599e 100644
--- a/gas/testsuite/gas/aarch64/morello-chericap.d
+++ b/gas/testsuite/gas/aarch64/morello-chericap.d
@@ -17,6 +17,8 @@ SYMBOL TABLE:
0000000000000060 l \.data 0000000000000010 d
0000000000000000 l d \.data\.rel\.ro 0000000000000000 \.data\.rel\.ro
0000000000000000 l \.data\.rel\.ro 0000000000000010 e
+000000000000001c l F \.text 0000000000000000 g
+0000000000000030 l F \.text 0000000000000000 g2
0000000000000000 g F \.text 0000000000000013 f
0000000000000020 g \.data 000000000000000c str
0000000000000000 \*UND\* 0000000000000000 foo
@@ -26,6 +28,10 @@ SYMBOL TABLE:
RELOCATION RECORDS FOR \[\.text\]:
OFFSET TYPE VALUE
0000000000000014 R_AARCH64_LDST128_ABS_LO12_NC \.data\+0x0000000000000030
+000000000000001c R_AARCH64_LDST128_ABS_LO12_NC \.data\+0x0000000000000030
+0000000000000020 R_MORELLO_CAPINIT g\+0x0000000000000004
+0000000000000030 R_AARCH64_LDST128_ABS_LO12_NC \.data\+0x0000000000000030
+0000000000000040 R_MORELLO_CAPINIT g2\+0x000000000000000c
RELOCATION RECORDS FOR \[\.data\]:
@@ -45,7 +51,10 @@ OFFSET TYPE VALUE
Contents of section \.text:
0000 fd7bbf62 fdd3c1c2 01000014 fd7bc122 .*
- 0010 c053c2c2 420040c2 c053c2c2 .*
+ 0010 c053c2c2 420040c2 c053c2c2 420040c2 .*
+ 0020 00000000 00000000 00000000 00000000 .*
+ 0030 420040c2 00000000 00000000 1f2003d5 .*
+ 0040 00000000 00000000 00000000 00000000 .*
Contents of section \.data:
0000 00000000 00000000 00000000 00000000 .*
0010 00000000 00000000 00000000 00000000 .*
diff --git a/gas/testsuite/gas/aarch64/morello-chericap.s b/gas/testsuite/gas/aarch64/morello-chericap.s
index 1d44a4ffbb952f13d9abaf4288278d3d06786083..c733bb723e58bf88450a949ff04a9910d7522a1c 100644
--- a/gas/testsuite/gas/aarch64/morello-chericap.s
+++ b/gas/testsuite/gas/aarch64/morello-chericap.s
@@ -77,3 +77,16 @@ e:
_start:
ldr c2, [c2, :lo12:a]
ret
+
+ .type g, %function
+g:
+ ldr c2, [c2, :lo12:a]
+ .p2align 4
+.Llab:
+ .chericap g+((.Llab+1)-g)
+ .type g2, %function
+g2:
+ ldr c2, [c2, :lo12:a]
+ .8byte 0
+.Llab2:
+ .chericap g2+((.Llab2+1)-g2)
This whitespace is present in the output from objdump but is not in our test
patterns. Adding it makes the testcase pass.
############### Attachment also inlined for ease of reply ###############
diff --git a/gas/testsuite/gas/aarch64/morello-capinit.d b/gas/testsuite/gas/aarch64/morello-capinit.d
index 6567a2964beafcd8fae1297579deaf7690384139..ef71b4552a97900279051c7baa154ad60cbaf23f 100644
--- a/gas/testsuite/gas/aarch64/morello-capinit.d
+++ b/gas/testsuite/gas/aarch64/morello-capinit.d
@@ -4,7 +4,7 @@
.*: file format .*
RELOCATION RECORDS FOR \[\.text\]:
-OFFSET TYPE VALUE
+OFFSET TYPE VALUE
0000000000000000 R_AARCH64_LDST128_ABS_LO12_NC \.data\+0x0000000000000010
0000000000000008 R_AARCH64_LDST128_ABS_LO12_NC \.data\+0x0000000000000010
0000000000000010 R_MORELLO_CAPINIT f\+0x0000000000000008
@@ -13,7 +13,7 @@ OFFSET TYPE VALUE
RELOCATION RECORDS FOR \[\.data\]:
-OFFSET TYPE VALUE
+OFFSET TYPE VALUE
0000000000000010 R_MORELLO_CAPINIT str
0000000000000020 R_MORELLO_CAPINIT str\+0x0000000000000008
0000000000000030 R_MORELLO_CAPINIT foo\+0x0000000000000010
@@ -21,7 +21,7 @@ OFFSET TYPE VALUE
RELOCATION RECORDS FOR \[\.data\.rel\.ro\]:
-OFFSET TYPE VALUE
+OFFSET TYPE VALUE
0000000000000000 R_MORELLO_CAPINIT str2
This is just to help anyone trying to build Morello binutils with a very
old system compiler.
At the time we branched, binutils wanted to be able to be build using C89.
These changes are what is needed to compile using the `-ansi` flag (i.e.
using that C89 flag).
############### Attachment also inlined for ease of reply ###############
Inline version does not contain generated files
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index db04f8a0f8a0f05a108823541d38ae7d251f4ebf..94f5cbca3baf7415bc96365e592e98d905dac484 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -4892,6 +4892,7 @@ elfNN_c64_resize_sections (bfd *output_bfd, struct bfd_link_info *info,
asection *sec, *pcc_low_sec = NULL, *pcc_high_sec = NULL;
struct elf_aarch64_link_hash_table *htab = elf_aarch64_hash_table (info);
bfd_vma low = (bfd_vma) -1, high = 0;
+ bfd *input_bfd;
htab->layout_sections_again = layout_sections_again;
@@ -4903,7 +4904,7 @@ elfNN_c64_resize_sections (bfd *output_bfd, struct bfd_link_info *info,
/* First, walk through all the relocations to find those referring to linker
defined and ldscript defined symbols since we set their range to their
output sections. */
- for (bfd *input_bfd = info->input_bfds;
+ for (input_bfd = info->input_bfds;
htab->c64_rel && input_bfd != NULL; input_bfd = input_bfd->link.next)
{
Elf_Internal_Shdr *symtab_hdr;
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 5735d127848bdf22685b436b541424f4af0ae636..4b66d542191263fbef4ff6f82957848c3fe2708f 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -2206,7 +2206,8 @@ s_aarch64_chericap (int ignored ATTRIBUTE_UNUSED)
BFD_RELOC_MORELLO_CAPINIT);
mapping_state (MAP_DATA);
- for (int i = 0; i < 4; i++)
+ int i;
+ for (i = 0; i < 4; i++)
{
/* The documentation of our md_number_to_chars says the greatest value
size it can handle is 4 bytes. */
@@ -8031,7 +8032,7 @@ tc_aarch64_fde_entry_init_extra(struct fde_entry *fde)
bfd_boolean
tc_aarch64_cfi_startproc_exp (const char *arg)
{
- // Allow purecap only for C64 functions.
+ /* Allow purecap only for C64 functions. */
if (!strcmp ("purecap", arg) && IS_C64)
return TRUE;
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index c463d4ddaffa65d2c157a343ee3719c7b1b8628b..a13ff33ce4380479346ba1c10641583c69b334f9 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -470,7 +470,8 @@ get_form_from_value (aarch64_insn value)
const aarch64_form *
get_form_from_str (const char *form, size_t len)
{
- for (unsigned i = 1; i < sizeof (aarch64_forms) / sizeof (aarch64_form); i++)
+ unsigned i;
+ for (i = 1; i < sizeof (aarch64_forms) / sizeof (aarch64_form); i++)
if (!strncmp (form, aarch64_forms[i].name, len))
return &aarch64_forms[i];
@@ -2799,11 +2800,12 @@ operand_general_constraint_met_p (aarch64_feature_set features,
unsigned flags = 0;
int regno_idx = idx == 0 ? 1 : 0;
enum aarch64_opnd reg_type = opcode->operands[regno_idx];
+ size_t i;
if (reg_type == AARCH64_OPND_Cat)
flags = F_CAPREG;
- for (size_t i = 0; aarch64_sys_regs[i].name; ++i)
+ for (i = 0; aarch64_sys_regs[i].name; ++i)
if (aarch64_sys_regs[i].value == opnd->sysreg.value)
{
part_match = TRUE;
When GCC is given an ABI parameter with `-mabi=<whatever>` it passes
that argument down to GAS. GAS does not need to know the Morello ABI
that is being used, since all decisions are based on the processor state
(whether +c64 is enabled or not).
GAS doesn't currently accept `purecap` or `hybrid` as arguments to the
`-mabi` option. Even though it does not need this information, I think
it should accept the arguments. This would mean GCC does not need
implement special handling to avoid passing the `-mabi` argument to GAS
only in these specific cases.
gas/ChangeLog:
2021-07-30 Matthew Malcomson <matthew.malcomson(a)arm.com>
* config/tc-aarch64.c (aarch64_abi_type): Introduce PURECAP and
HYBRID enum entries.
(aarch64_abis): Add "purecap" and "hybrid" parameters.
* testsuite/gas/aarch64/morello-abis-ignored.s: New.
* testsuite/gas/aarch64/morello-abis-ignored.d: New.
############### Attachment also inlined for ease of reply ###############
Inline version does not contain generated files
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 3d0436d538c856a418f6949fb47998f69558b6fc..5735d127848bdf22685b436b541424f4af0ae636 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -75,7 +75,9 @@ enum aarch64_abi_type
{
AARCH64_ABI_NONE = 0,
AARCH64_ABI_LP64 = 1,
- AARCH64_ABI_ILP32 = 2
+ AARCH64_ABI_ILP32 = 2,
+ AARCH64_ABI_PURECAP = 3,
+ AARCH64_ABI_HYBRID = 4,
};
#ifndef DEFAULT_ARCH
@@ -10048,6 +10050,10 @@ struct aarch64_option_abi_value_table
static const struct aarch64_option_abi_value_table aarch64_abis[] = {
{"ilp32", AARCH64_ABI_ILP32},
{"lp64", AARCH64_ABI_LP64},
+ /* Note that these values are accepted since they are valid parameters to
+ the -mabi argument for GCC. However we base no decision on them. */
+ {"purecap", AARCH64_ABI_PURECAP},
+ {"hybrid", AARCH64_ABI_HYBRID},
};
static int
diff --git a/gas/testsuite/gas/aarch64/morello-abis-ignored.d b/gas/testsuite/gas/aarch64/morello-abis-ignored.d
new file mode 100644
index 0000000000000000000000000000000000000000..37d7735ac674389be82547c7896d5dd950630bff
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/morello-abis-ignored.d
@@ -0,0 +1,18 @@
+#name: Morello ABI arguments accepted but ignored.
+#as: -mabi=purecap
+#as: -mabi=lp64
+#as: -mabi=hybrid
+#readelf: --syms
+
+Symbol table '\.symtab' contains 10 entries:
+ Num: Value Size Type Bind Vis Ndx Name
+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
+ 1: 0000000000000000 0 SECTION LOCAL DEFAULT 1
+ 2: 0000000000000000 0 SECTION LOCAL DEFAULT 2
+ 3: 0000000000000000 0 SECTION LOCAL DEFAULT 3
+ 4: 0000000000000001 0 FUNC LOCAL DEFAULT 1 foo
+ 5: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 \$c
+ 6: 0000000000000008 0 FUNC LOCAL DEFAULT 1 bar
+ 7: 0000000000000008 0 NOTYPE LOCAL DEFAULT 1 \$x
+ 8: 0000000000000011 0 FUNC LOCAL DEFAULT 1 baz
+ 9: 0000000000000010 0 NOTYPE LOCAL DEFAULT 1 \$c
diff --git a/gas/testsuite/gas/aarch64/morello-abis-ignored.s b/gas/testsuite/gas/aarch64/morello-abis-ignored.s
new file mode 100644
index 0000000000000000000000000000000000000000..39590632b607d3a3f45da39c2d042b1d52ad1cf5
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/morello-abis-ignored.s
@@ -0,0 +1,15 @@
+ .arch morello+c64
+ .type foo, @function
+foo:
+ mov x0, #0
+ ret c30
+ .arch morello
+ .type bar,@function
+bar:
+ mov x0, #0
+ ret c30
+ .arch morello+c64
+ .type baz, @function
+baz:
+ mov x0, #0
+ ret c30