summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Malcomson <matthew.malcomson@arm.com>2022-08-05 17:19:32 +0100
committerMatthew Malcomson <matthew.malcomson@arm.com>2022-08-05 17:50:11 +0100
commit6b81133d16bb75b940cc8bed374981973d5a1dc7 (patch)
tree2ea06296ef7a7c337ebdb6df3841603b19811e59
parent8a4f850747b18a37417799831f9e477a1d367c7b (diff)
downloadbinutils-gdb-6b81133d16bb75b940cc8bed374981973d5a1dc7.tar.gz
Add new relocations to GAS
Also add the ability to disassemble these relocations correctly. Include checking that many different sizes work with different instructions, include error checking that the `size` relocation is not allowed in a64 mode. Ensure that the size relocation is not allowed on instructions other than mov[kz]. See the arm ABI aaelf64-morello document for the definition of these new relocations. Regenerate bfd/bfd-in2.h and bfd/libbfd.h from bfd/reloc.c.
-rw-r--r--bfd/bfd-in2.h38
-rw-r--r--bfd/libbfd.h10
-rw-r--r--bfd/reloc.c48
-rw-r--r--gas/config/tc-aarch64.c123
-rw-r--r--gas/testsuite/gas/aarch64/illegal-reloc-size.d18
-rw-r--r--gas/testsuite/gas/aarch64/illegal-reloc-size.s34
-rw-r--r--gas/testsuite/gas/aarch64/reloc-size-a64.d48
-rw-r--r--gas/testsuite/gas/aarch64/reloc-size.d97
-rw-r--r--gas/testsuite/gas/aarch64/reloc-size.s90
-rw-r--r--include/elf/aarch64.h12
10 files changed, 516 insertions, 2 deletions
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 4b180d83957..8ddc26289a3 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -5605,6 +5605,34 @@ of a signed value. */
of a signed value. */
BFD_RELOC_AARCH64_MOVW_PREL_G3,
+/* Morello MOV[KZ] instruction with most significant bits 0 to 15 of the size of
+a symbol. */
+ BFD_RELOC_MORELLO_MOVW_SIZE_G0,
+
+/* Morello MOV[KZ] instruction with less significant bits 0 to 15 of the size of
+a symbol. */
+ BFD_RELOC_MORELLO_MOVW_SIZE_G0_NC,
+
+/* Morello MOV[KZ] instruction with most significant bits 16 to 31 of the size
+of a symbol. */
+ BFD_RELOC_MORELLO_MOVW_SIZE_G1,
+
+/* Morello MOV[KZ] instruction with less significant bits 16 to 31 of the size
+of a symbol. */
+ BFD_RELOC_MORELLO_MOVW_SIZE_G1_NC,
+
+/* Morello MOV[KZ] instruction with most significant bits 32 to 47 of the size
+of a symbol. */
+ BFD_RELOC_MORELLO_MOVW_SIZE_G2,
+
+/* Morello MOV[KZ] instruction with less significant bits 32 to 47 of the size
+of a symbol. */
+ BFD_RELOC_MORELLO_MOVW_SIZE_G2_NC,
+
+/* Morello MOV[KZ] instruction with most significant bits 48 to 64 of the size
+of a symbol. */
+ BFD_RELOC_MORELLO_MOVW_SIZE_G3,
+
/* AArch64 A64C Load Literal instruction, holding a 17 bit pc-relative
word offset. The lowest four bits must be zero and are not stored in
the instruction, giving a 21 bit signed byte offset. */
@@ -5947,6 +5975,12 @@ instructions. */
TLS descriptor function. */
BFD_RELOC_MORELLO_TLSDESC_CALL,
+/* Morello TLS INITIAL EXEC relocation. */
+ BFD_RELOC_MORELLO_TLSIE_ADR_GOTTPREL_PAGE20,
+
+/* Morello TLS INITIAL EXEC relocation. */
+ BFD_RELOC_MORELLO_TLSIE_ADD_LO12,
+
/* AArch64 TLS relocation. */
BFD_RELOC_AARCH64_COPY,
@@ -5992,6 +6026,10 @@ TLS descriptor function. */
/* Morello TLS relocation, identifies the TLS descriptor to be filled. */
BFD_RELOC_MORELLO_TLSDESC,
+/* Morello TLS relocation, instructs the dynamic loader to initialize an offset
+and size for a given symbol. */
+ BFD_RELOC_MORELLO_TPREL128,
+
/* AArch64 pseudo relocation code to mark the end of the AArch64
relocation enumerators that have direct mapping to ELF reloc codes.
There are a few more enumerators after this one; those are mainly
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 9fd557d83a8..67e86952596 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3014,6 +3014,13 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_AARCH64_MOVW_PREL_G2",
"BFD_RELOC_AARCH64_MOVW_PREL_G2_NC",
"BFD_RELOC_AARCH64_MOVW_PREL_G3",
+ "BFD_RELOC_MORELLO_MOVW_SIZE_G0",
+ "BFD_RELOC_MORELLO_MOVW_SIZE_G0_NC",
+ "BFD_RELOC_MORELLO_MOVW_SIZE_G1",
+ "BFD_RELOC_MORELLO_MOVW_SIZE_G1_NC",
+ "BFD_RELOC_MORELLO_MOVW_SIZE_G2",
+ "BFD_RELOC_MORELLO_MOVW_SIZE_G2_NC",
+ "BFD_RELOC_MORELLO_MOVW_SIZE_G3",
"BFD_RELOC_MORELLO_LD_LO17_PCREL",
"BFD_RELOC_AARCH64_LD_LO19_PCREL",
"BFD_RELOC_MORELLO_ADR_HI20_PCREL",
@@ -3106,6 +3113,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_MORELLO_TLSDESC_ADR_PAGE20",
"BFD_RELOC_MORELLO_TLSDESC_LD128_LO12",
"BFD_RELOC_MORELLO_TLSDESC_CALL",
+ "BFD_RELOC_MORELLO_TLSIE_ADR_GOTTPREL_PAGE20",
+ "BFD_RELOC_MORELLO_TLSIE_ADD_LO12",
"BFD_RELOC_AARCH64_COPY",
"BFD_RELOC_AARCH64_GLOB_DAT",
"BFD_RELOC_AARCH64_JUMP_SLOT",
@@ -3121,6 +3130,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_MORELLO_RELATIVE",
"BFD_RELOC_MORELLO_IRELATIVE",
"BFD_RELOC_MORELLO_TLSDESC",
+ "BFD_RELOC_MORELLO_TPREL128",
"BFD_RELOC_AARCH64_RELOC_END",
"BFD_RELOC_AARCH64_GAS_INTERNAL_FIXUP",
"BFD_RELOC_AARCH64_LDST_LO12",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index de4e6a2a84b..d3b4211cd37 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -7103,6 +7103,41 @@ ENUMDOC
AArch64 MOVK instruction with most significant bits 47 to 63
of a signed value.
ENUM
+ BFD_RELOC_MORELLO_MOVW_SIZE_G0
+ENUMDOC
+ Morello MOV[KZ] instruction with most significant bits 0 to 15 of the size of
+ a symbol.
+ENUM
+ BFD_RELOC_MORELLO_MOVW_SIZE_G0_NC
+ENUMDOC
+ Morello MOV[KZ] instruction with less significant bits 0 to 15 of the size of
+ a symbol.
+ENUM
+ BFD_RELOC_MORELLO_MOVW_SIZE_G1
+ENUMDOC
+ Morello MOV[KZ] instruction with most significant bits 16 to 31 of the size
+ of a symbol.
+ENUM
+ BFD_RELOC_MORELLO_MOVW_SIZE_G1_NC
+ENUMDOC
+ Morello MOV[KZ] instruction with less significant bits 16 to 31 of the size
+ of a symbol.
+ENUM
+ BFD_RELOC_MORELLO_MOVW_SIZE_G2
+ENUMDOC
+ Morello MOV[KZ] instruction with most significant bits 32 to 47 of the size
+ of a symbol.
+ENUM
+ BFD_RELOC_MORELLO_MOVW_SIZE_G2_NC
+ENUMDOC
+ Morello MOV[KZ] instruction with less significant bits 32 to 47 of the size
+ of a symbol.
+ENUM
+ BFD_RELOC_MORELLO_MOVW_SIZE_G3
+ENUMDOC
+ Morello MOV[KZ] instruction with most significant bits 48 to 64 of the size
+ of a symbol.
+ENUM
BFD_RELOC_MORELLO_LD_LO17_PCREL
ENUMDOC
AArch64 A64C Load Literal instruction, holding a 17 bit pc-relative
@@ -7537,6 +7572,14 @@ ENUMDOC
Relocation to identify the BLR call which performs an indirect call to the
TLS descriptor function.
ENUM
+ BFD_RELOC_MORELLO_TLSIE_ADR_GOTTPREL_PAGE20
+ENUMDOC
+ Morello TLS INITIAL EXEC relocation.
+ENUM
+ BFD_RELOC_MORELLO_TLSIE_ADD_LO12
+ENUMDOC
+ Morello TLS INITIAL EXEC relocation.
+ENUM
BFD_RELOC_AARCH64_COPY
ENUMDOC
AArch64 TLS relocation.
@@ -7597,6 +7640,11 @@ ENUM
ENUMDOC
Morello TLS relocation, identifies the TLS descriptor to be filled.
ENUM
+ BFD_RELOC_MORELLO_TPREL128
+ENUMDOC
+ Morello TLS relocation, instructs the dynamic loader to initialize an offset
+ and size for a given symbol.
+ENUM
BFD_RELOC_AARCH64_RELOC_END
ENUMDOC
AArch64 pseudo relocation code to mark the end of the AArch64
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index ce17e497be5..a1bd6e1a769 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -3081,7 +3081,7 @@ static struct reloc_table_entry reloc_table[] = {
{"gottprel", 0,
0, /* adr_type */
BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21,
- 0,
+ BFD_RELOC_MORELLO_TLSIE_ADR_GOTTPREL_PAGE20,
0,
0,
0,
@@ -3093,7 +3093,7 @@ static struct reloc_table_entry reloc_table[] = {
0,
0,
0,
- 0,
+ BFD_RELOC_MORELLO_TLSIE_ADD_LO12,
BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC,
0},
@@ -3206,6 +3206,77 @@ static struct reloc_table_entry reloc_table[] = {
0,
BFD_RELOC_AARCH64_LD32_GOTPAGE_LO14,
0},
+
+ /* Most significant bits 0-15 of the size of a symbol: MOVZ */
+ {"size_g0", 0,
+ 0, /* adr_type */
+ 0,
+ 0,
+ BFD_RELOC_MORELLO_MOVW_SIZE_G0,
+ 0,
+ 0,
+ 0},
+
+ /* Less significant bits 0-15 of the size of a symbol: MOVK, no check */
+ {"size_g0_nc", 0,
+ 0, /* adr_type */
+ 0,
+ 0,
+ BFD_RELOC_MORELLO_MOVW_SIZE_G0_NC,
+ 0,
+ 0,
+ 0},
+
+ /* Most significant bits 16-31 of the size of a symbol: MOVZ */
+ {"size_g1", 0,
+ 0, /* adr_type */
+ 0,
+ 0,
+ BFD_RELOC_MORELLO_MOVW_SIZE_G1,
+ 0,
+ 0,
+ 0},
+
+ /* Less significant bits 16-31 of the size of a symbol: MOVK, no check */
+ {"size_g1_nc", 0,
+ 0, /* adr_type */
+ 0,
+ 0,
+ BFD_RELOC_MORELLO_MOVW_SIZE_G1_NC,
+ 0,
+ 0,
+ 0},
+
+ /* Most significant bits 32-47 of the size of a symbol: MOVZ */
+ {"size_g2", 0,
+ 0, /* adr_type */
+ 0,
+ 0,
+ BFD_RELOC_MORELLO_MOVW_SIZE_G2,
+ 0,
+ 0,
+ 0},
+
+ /* Less significant bits 32-47 of the size of a symbol: MOVK, no check */
+ {"size_g2_nc", 0,
+ 0, /* adr_type */
+ 0,
+ 0,
+ BFD_RELOC_MORELLO_MOVW_SIZE_G2_NC,
+ 0,
+ 0,
+ 0},
+
+ /* Most significant bits 48-63 of the size of a symbol: MOVZ */
+ {"size_g3", 0,
+ 0, /* adr_type */
+ 0,
+ 0,
+ BFD_RELOC_MORELLO_MOVW_SIZE_G3,
+ 0,
+ 0,
+ 0},
+
};
/* Given the address of a pointer pointing to the textual name of a
@@ -3565,6 +3636,12 @@ parse_shifter_operand_reloc (char **str, aarch64_opnd_info *operand,
(_("this relocation modifier is not allowed on this instruction"));
return FALSE;
}
+ if (entry->add_type == BFD_RELOC_MORELLO_TLSIE_ADD_LO12 && !IS_C64)
+ {
+ set_syntax_error
+ (_("this relocation modifier is not allowed in non-C64 mode"));
+ return FALSE;
+ }
/* Save str before we decompose it. */
p = *str;
@@ -4052,6 +4129,26 @@ parse_half (char **str, int *internal_fixup_p)
if (! my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX, 1))
return FALSE;
+ bfd_boolean is_morello_size_reloc
+ = (inst.reloc.type == BFD_RELOC_MORELLO_MOVW_SIZE_G0
+ || inst.reloc.type == BFD_RELOC_MORELLO_MOVW_SIZE_G0_NC
+ || inst.reloc.type == BFD_RELOC_MORELLO_MOVW_SIZE_G1
+ || inst.reloc.type == BFD_RELOC_MORELLO_MOVW_SIZE_G1_NC
+ || inst.reloc.type == BFD_RELOC_MORELLO_MOVW_SIZE_G2
+ || inst.reloc.type == BFD_RELOC_MORELLO_MOVW_SIZE_G2_NC
+ || inst.reloc.type == BFD_RELOC_MORELLO_MOVW_SIZE_G3);
+ if (inst.reloc.exp.X_add_symbol == 0 && is_morello_size_reloc)
+ {
+ set_syntax_error
+ (_("size relocation is not allowed on non-symbol expression"));
+ return FALSE;
+ }
+ if (is_morello_size_reloc && !IS_C64)
+ {
+ set_syntax_error (_("size relocation is not allowed in non-C64 mode"));
+ return FALSE;
+ }
+
*str = p;
return TRUE;
}
@@ -5599,6 +5696,8 @@ process_movw_reloc_info (void)
switch (inst.reloc.type)
{
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G0:
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G0_NC:
case BFD_RELOC_AARCH64_MOVW_G0:
case BFD_RELOC_AARCH64_MOVW_G0_NC:
case BFD_RELOC_AARCH64_MOVW_G0_S:
@@ -5614,6 +5713,8 @@ process_movw_reloc_info (void)
case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
shift = 0;
break;
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G1:
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G1_NC:
case BFD_RELOC_AARCH64_MOVW_G1:
case BFD_RELOC_AARCH64_MOVW_G1_NC:
case BFD_RELOC_AARCH64_MOVW_G1_S:
@@ -5629,6 +5730,8 @@ process_movw_reloc_info (void)
case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
shift = 16;
break;
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G2:
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G2_NC:
case BFD_RELOC_AARCH64_MOVW_G2:
case BFD_RELOC_AARCH64_MOVW_G2_NC:
case BFD_RELOC_AARCH64_MOVW_G2_S:
@@ -5645,6 +5748,7 @@ process_movw_reloc_info (void)
}
shift = 32;
break;
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G3:
case BFD_RELOC_AARCH64_MOVW_G3:
case BFD_RELOC_AARCH64_MOVW_PREL_G3:
if (is32)
@@ -8658,6 +8762,8 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
}
break;
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G0:
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G0_NC:
case BFD_RELOC_AARCH64_MOVW_G0:
case BFD_RELOC_AARCH64_MOVW_G0_NC:
case BFD_RELOC_AARCH64_MOVW_G0_S:
@@ -8666,6 +8772,8 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
case BFD_RELOC_AARCH64_MOVW_PREL_G0_NC:
scale = 0;
goto movw_common;
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G1:
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G1_NC:
case BFD_RELOC_AARCH64_MOVW_G1:
case BFD_RELOC_AARCH64_MOVW_G1_NC:
case BFD_RELOC_AARCH64_MOVW_G1_S:
@@ -8690,6 +8798,8 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
gas_assert (!fixP->fx_done);
gas_assert (seg->use_rela_p);
goto movw_common;
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G2:
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G2_NC:
case BFD_RELOC_AARCH64_MOVW_G2:
case BFD_RELOC_AARCH64_MOVW_G2_NC:
case BFD_RELOC_AARCH64_MOVW_G2_S:
@@ -8697,6 +8807,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
case BFD_RELOC_AARCH64_MOVW_PREL_G2_NC:
scale = 32;
goto movw_common;
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G3:
case BFD_RELOC_AARCH64_MOVW_G3:
case BFD_RELOC_AARCH64_MOVW_PREL_G3:
scale = 48;
@@ -8717,6 +8828,10 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
/* Check for overflow and scale. */
switch (fixP->fx_r_type)
{
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G0:
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G1:
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G2:
+ case BFD_RELOC_MORELLO_MOVW_SIZE_G3:
case BFD_RELOC_AARCH64_MOVW_G0:
case BFD_RELOC_AARCH64_MOVW_G1:
case BFD_RELOC_AARCH64_MOVW_G2:
@@ -8801,6 +8916,8 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
+ case BFD_RELOC_MORELLO_TLSIE_ADR_GOTTPREL_PAGE20:
+ case BFD_RELOC_MORELLO_TLSIE_ADD_LO12:
case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
@@ -9057,6 +9174,8 @@ aarch64_force_relocation (struct fix *fixp)
case BFD_RELOC_AARCH64_TLSGD_ADR_PREL21:
case BFD_RELOC_AARCH64_TLSGD_MOVW_G0_NC:
case BFD_RELOC_AARCH64_TLSGD_MOVW_G1:
+ case BFD_RELOC_MORELLO_TLSIE_ADR_GOTTPREL_PAGE20:
+ case BFD_RELOC_MORELLO_TLSIE_ADD_LO12:
case BFD_RELOC_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
case BFD_RELOC_AARCH64_TLSIE_LD32_GOTTPREL_LO12_NC:
case BFD_RELOC_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
diff --git a/gas/testsuite/gas/aarch64/illegal-reloc-size.d b/gas/testsuite/gas/aarch64/illegal-reloc-size.d
new file mode 100644
index 00000000000..87f3630297f
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/illegal-reloc-size.d
@@ -0,0 +1,18 @@
+#name: Illegal :size*: relocations.
+#as: -march=morello+c64
+#source: illegal-reloc-size.s
+#error: [^ :]+: Assembler messages:
+#error: [^ :]+:[0-9]+: Error: bad expression at operand 2 -- `mov x12,#:size_g0:sym1'
+#error: [^ :]+:[0-9]+: Error: bad expression at operand 2 -- `mov x12,#:size_g0_nc:sym1'
+#error: [^ :]+:[0-9]+: Error: this relocation modifier is not allowed on this instruction at operand 3 -- `add x12,x12,#:size_g0:sym1'
+#error: [^ :]+:[0-9]+: Error: this relocation modifier is not allowed on this instruction at operand 3 -- `add x12,x12,#:size_g0_nc:sym1'
+#error: [^ :]+:[0-9]+: Error: bad expression at operand 2 -- `mov x12,#:size_g1:sym1'
+#error: [^ :]+:[0-9]+: Error: bad expression at operand 2 -- `mov x12,#:size_g1_nc:sym1'
+#error: [^ :]+:[0-9]+: Error: this relocation modifier is not allowed on this instruction at operand 3 -- `add x12,x12,#:size_g1:sym1'
+#error: [^ :]+:[0-9]+: Error: this relocation modifier is not allowed on this instruction at operand 3 -- `add x12,x12,#:size_g1_nc:sym1'
+#error: [^ :]+:[0-9]+: Error: bad expression at operand 2 -- `mov x12,#:size_g2:sym1'
+#error: [^ :]+:[0-9]+: Error: bad expression at operand 2 -- `mov x12,#:size_g2_nc:sym1'
+#error: [^ :]+:[0-9]+: Error: this relocation modifier is not allowed on this instruction at operand 3 -- `add x12,x12,#:size_g2:sym1'
+#error: [^ :]+:[0-9]+: Error: this relocation modifier is not allowed on this instruction at operand 3 -- `add x12,x12,#:size_g2_nc:sym1'
+#error: [^ :]+:[0-9]+: Error: bad expression at operand 2 -- `mov x12,#:size_g3:sym1'
+#error: [^ :]+:[0-9]+: Error: this relocation modifier is not allowed on this instruction at operand 3 -- `add x12,x12,#:size_g3:sym1'
diff --git a/gas/testsuite/gas/aarch64/illegal-reloc-size.s b/gas/testsuite/gas/aarch64/illegal-reloc-size.s
new file mode 100644
index 00000000000..bd8044e1d56
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/illegal-reloc-size.s
@@ -0,0 +1,34 @@
+# Very simple check to see that we're disallowing the :size: relocationos on
+# non-mov[kz] instructions. We only check `add` and plain `mov` here.
+#
+# N.b. we follow the lead of the error messages that are emitted for the
+# `abs_*` relocations in that we emit "bad expression" complaints for the `mov`
+# instruction and "this relocation modifier is not allowed on this instruction"
+# for the `add` instruction.
+
+ .data
+ .globl sym1
+ .size sym1, 0xa0a0
+sym1:
+ .xword 0
+ .text
+ .globl _start
+ .type _start, STT_FUNC
+_start:
+ mov x12, #:size_g0:sym1
+ mov x12, #:size_g0_nc:sym1
+ add x12, x12, #:size_g0:sym1
+ add x12, x12, #:size_g0_nc:sym1
+
+ mov x12, #:size_g1:sym1
+ mov x12, #:size_g1_nc:sym1
+ add x12, x12, #:size_g1:sym1
+ add x12, x12, #:size_g1_nc:sym1
+
+ mov x12, #:size_g2:sym1
+ mov x12, #:size_g2_nc:sym1
+ add x12, x12, #:size_g2:sym1
+ add x12, x12, #:size_g2_nc:sym1
+
+ mov x12, #:size_g3:sym1
+ add x12, x12, #:size_g3:sym1
diff --git a/gas/testsuite/gas/aarch64/reloc-size-a64.d b/gas/testsuite/gas/aarch64/reloc-size-a64.d
new file mode 100644
index 00000000000..6563a7b0ca7
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-size-a64.d
@@ -0,0 +1,48 @@
+#source: reloc-size.s
+#as:
+#error: [^ :]+: Assembler messages:
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x12,#:size_g0:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x12,#:size_g0_nc:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x12,#:size_g1:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x12,#:size_g1_nc:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x12,#:size_g2:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x12,#:size_g2_nc:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x12,#:size_g3:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g0_nc:sym2'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g1:sym2'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g1_nc:sym2'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g2:sym2'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g2_nc:sym2'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g3:sym2'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g0_nc:sym3'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g1_nc:sym3'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g2:sym3'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g2_nc:sym3'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g3:sym3'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g0_nc:sym4'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g1_nc:sym4'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g2_nc:sym4'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movk x13,#:size_g3:sym4'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x12,#:size_g0:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x12,#:size_g0_nc:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x12,#:size_g1:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x12,#:size_g1_nc:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x12,#:size_g2:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x12,#:size_g2_nc:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x12,#:size_g3:sym1'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g0_nc:sym2'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g1:sym2'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g1_nc:sym2'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g2:sym2'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g2_nc:sym2'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g3:sym2'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g0_nc:sym3'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g1_nc:sym3'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g2:sym3'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g2_nc:sym3'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g3:sym3'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g0_nc:sym4'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g1_nc:sym4'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g2_nc:sym4'
+#error: [^ :]+:[0-9]+: Error: size relocation is not allowed in non-C64 mode at operand 2 -- `movz x13,#:size_g3:sym4'
+
diff --git a/gas/testsuite/gas/aarch64/reloc-size.d b/gas/testsuite/gas/aarch64/reloc-size.d
new file mode 100644
index 00000000000..a5e58c8c28e
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-size.d
@@ -0,0 +1,97 @@
+#as: -march=morello+c64
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+0000000000000000 <_start>:
+ 0: f280000c movk x12, #0x0
+ 0: R_MORELLO_MOVW_SIZE_G0 sym1
+ 4: f280000c movk x12, #0x0
+ 4: R_MORELLO_MOVW_SIZE_G0_NC sym1
+ 8: f2a0000c movk x12, #0x0, lsl #16
+ 8: R_MORELLO_MOVW_SIZE_G1 sym1
+ c: f2a0000c movk x12, #0x0, lsl #16
+ c: R_MORELLO_MOVW_SIZE_G1_NC sym1
+ 10: f2c0000c movk x12, #0x0, lsl #32
+ 10: R_MORELLO_MOVW_SIZE_G2 sym1
+ 14: f2c0000c movk x12, #0x0, lsl #32
+ 14: R_MORELLO_MOVW_SIZE_G2_NC sym1
+ 18: f2e0000c movk x12, #0x0, lsl #48
+ 18: R_MORELLO_MOVW_SIZE_G3 sym1
+ 1c: f280000d movk x13, #0x0
+ 1c: R_MORELLO_MOVW_SIZE_G0_NC sym2
+ 20: f2a0000d movk x13, #0x0, lsl #16
+ 20: R_MORELLO_MOVW_SIZE_G1 sym2
+ 24: f2a0000d movk x13, #0x0, lsl #16
+ 24: R_MORELLO_MOVW_SIZE_G1_NC sym2
+ 28: f2c0000d movk x13, #0x0, lsl #32
+ 28: R_MORELLO_MOVW_SIZE_G2 sym2
+ 2c: f2c0000d movk x13, #0x0, lsl #32
+ 2c: R_MORELLO_MOVW_SIZE_G2_NC sym2
+ 30: f2e0000d movk x13, #0x0, lsl #48
+ 30: R_MORELLO_MOVW_SIZE_G3 sym2
+ 34: f280000d movk x13, #0x0
+ 34: R_MORELLO_MOVW_SIZE_G0_NC sym3
+ 38: f2a0000d movk x13, #0x0, lsl #16
+ 38: R_MORELLO_MOVW_SIZE_G1_NC sym3
+ 3c: f2c0000d movk x13, #0x0, lsl #32
+ 3c: R_MORELLO_MOVW_SIZE_G2 sym3
+ 40: f2c0000d movk x13, #0x0, lsl #32
+ 40: R_MORELLO_MOVW_SIZE_G2_NC sym3
+ 44: f2e0000d movk x13, #0x0, lsl #48
+ 44: R_MORELLO_MOVW_SIZE_G3 sym3
+ 48: f280000d movk x13, #0x0
+ 48: R_MORELLO_MOVW_SIZE_G0_NC sym4
+ 4c: f2a0000d movk x13, #0x0, lsl #16
+ 4c: R_MORELLO_MOVW_SIZE_G1_NC sym4
+ 50: f2c0000d movk x13, #0x0, lsl #32
+ 50: R_MORELLO_MOVW_SIZE_G2_NC sym4
+ 54: f2e0000d movk x13, #0x0, lsl #48
+ 54: R_MORELLO_MOVW_SIZE_G3 sym4
+ 58: d280000c mov x12, #0x0 // #0
+ 58: R_MORELLO_MOVW_SIZE_G0 sym1
+ 5c: d280000c mov x12, #0x0 // #0
+ 5c: R_MORELLO_MOVW_SIZE_G0_NC sym1
+ 60: d2a0000c movz x12, #0x0, lsl #16
+ 60: R_MORELLO_MOVW_SIZE_G1 sym1
+ 64: d2a0000c movz x12, #0x0, lsl #16
+ 64: R_MORELLO_MOVW_SIZE_G1_NC sym1
+ 68: d2c0000c movz x12, #0x0, lsl #32
+ 68: R_MORELLO_MOVW_SIZE_G2 sym1
+ 6c: d2c0000c movz x12, #0x0, lsl #32
+ 6c: R_MORELLO_MOVW_SIZE_G2_NC sym1
+ 70: d2e0000c movz x12, #0x0, lsl #48
+ 70: R_MORELLO_MOVW_SIZE_G3 sym1
+ 74: d280000d mov x13, #0x0 // #0
+ 74: R_MORELLO_MOVW_SIZE_G0_NC sym2
+ 78: d2a0000d movz x13, #0x0, lsl #16
+ 78: R_MORELLO_MOVW_SIZE_G1 sym2
+ 7c: d2a0000d movz x13, #0x0, lsl #16
+ 7c: R_MORELLO_MOVW_SIZE_G1_NC sym2
+ 80: d2c0000d movz x13, #0x0, lsl #32
+ 80: R_MORELLO_MOVW_SIZE_G2 sym2
+ 84: d2c0000d movz x13, #0x0, lsl #32
+ 84: R_MORELLO_MOVW_SIZE_G2_NC sym2
+ 88: d2e0000d movz x13, #0x0, lsl #48
+ 88: R_MORELLO_MOVW_SIZE_G3 sym2
+ 8c: d280000d mov x13, #0x0 // #0
+ 8c: R_MORELLO_MOVW_SIZE_G0_NC sym3
+ 90: d2a0000d movz x13, #0x0, lsl #16
+ 90: R_MORELLO_MOVW_SIZE_G1_NC sym3
+ 94: d2c0000d movz x13, #0x0, lsl #32
+ 94: R_MORELLO_MOVW_SIZE_G2 sym3
+ 98: d2c0000d movz x13, #0x0, lsl #32
+ 98: R_MORELLO_MOVW_SIZE_G2_NC sym3
+ 9c: d2e0000d movz x13, #0x0, lsl #48
+ 9c: R_MORELLO_MOVW_SIZE_G3 sym3
+ a0: d280000d mov x13, #0x0 // #0
+ a0: R_MORELLO_MOVW_SIZE_G0_NC sym4
+ a4: d2a0000d movz x13, #0x0, lsl #16
+ a4: R_MORELLO_MOVW_SIZE_G1_NC sym4
+ a8: d2c0000d movz x13, #0x0, lsl #32
+ a8: R_MORELLO_MOVW_SIZE_G2_NC sym4
+ ac: d2e0000d movz x13, #0x0, lsl #48
+ ac: R_MORELLO_MOVW_SIZE_G3 sym4
diff --git a/gas/testsuite/gas/aarch64/reloc-size.s b/gas/testsuite/gas/aarch64/reloc-size.s
new file mode 100644
index 00000000000..04bff10a435
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-size.s
@@ -0,0 +1,90 @@
+# Description of the testcase:
+# Set of two chunks. Fist tests `movk`, second tests `movz`.
+#
+# Each chunk has 4 subparts. Those subparts check all viable relocations for
+# a size which fits into the bottom 16, 32, 48, and 64 bits respectively.
+ .data
+ .globl sym1
+ .size sym1, 0xa0a0
+sym1:
+ .xword 0
+ .globl sym2
+ .size sym2, 0xa0a0b0b0
+sym2:
+ .xword 0
+ .globl sym3
+ .size sym3, 0xa0a0b0b0c0c0
+sym3:
+ .xword 0
+ .globl sym4
+ .size sym4, 0xa0a0b0b0c0c0d0d0
+sym4:
+ .xword 0
+ .text
+ .globl _start
+ .type _start, STT_FUNC
+_start:
+ movk x12, #:size_g0:sym1
+ movk x12, #:size_g0_nc:sym1
+ movk x12, #:size_g1:sym1
+ movk x12, #:size_g1_nc:sym1
+ movk x12, #:size_g2:sym1
+ movk x12, #:size_g2_nc:sym1
+ movk x12, #:size_g3:sym1
+
+ # movk x13, #:size_g0:sym2
+ movk x13, #:size_g0_nc:sym2
+ movk x13, #:size_g1:sym2
+ movk x13, #:size_g1_nc:sym2
+ movk x13, #:size_g2:sym2
+ movk x13, #:size_g2_nc:sym2
+ movk x13, #:size_g3:sym2
+
+ # movk x13, #:size_g0:sym3
+ movk x13, #:size_g0_nc:sym3
+ # movk x13, #:size_g1:sym3
+ movk x13, #:size_g1_nc:sym3
+ movk x13, #:size_g2:sym3
+ movk x13, #:size_g2_nc:sym3
+ movk x13, #:size_g3:sym3
+
+ # movk x13, #:size_g0:sym4
+ movk x13, #:size_g0_nc:sym4
+ # movk x13, #:size_g1:sym4
+ movk x13, #:size_g1_nc:sym4
+ # movk x13, #:size_g2:sym4
+ movk x13, #:size_g2_nc:sym4
+ movk x13, #:size_g3:sym4
+
+
+ movz x12, #:size_g0:sym1
+ movz x12, #:size_g0_nc:sym1
+ movz x12, #:size_g1:sym1
+ movz x12, #:size_g1_nc:sym1
+ movz x12, #:size_g2:sym1
+ movz x12, #:size_g2_nc:sym1
+ movz x12, #:size_g3:sym1
+
+ # movz x13, #:size_g0:sym2
+ movz x13, #:size_g0_nc:sym2
+ movz x13, #:size_g1:sym2
+ movz x13, #:size_g1_nc:sym2
+ movz x13, #:size_g2:sym2
+ movz x13, #:size_g2_nc:sym2
+ movz x13, #:size_g3:sym2
+
+ # movz x13, #:size_g0:sym3
+ movz x13, #:size_g0_nc:sym3
+ # movz x13, #:size_g1:sym3
+ movz x13, #:size_g1_nc:sym3
+ movz x13, #:size_g2:sym3
+ movz x13, #:size_g2_nc:sym3
+ movz x13, #:size_g3:sym3
+
+ # movz x13, #:size_g0:sym4
+ movz x13, #:size_g0_nc:sym4
+ # movz x13, #:size_g1:sym4
+ movz x13, #:size_g1_nc:sym4
+ # movz x13, #:size_g2:sym4
+ movz x13, #:size_g2_nc:sym4
+ movz x13, #:size_g3:sym4
diff --git a/include/elf/aarch64.h b/include/elf/aarch64.h
index c8d9094b857..2b7e34b9c28 100644
--- a/include/elf/aarch64.h
+++ b/include/elf/aarch64.h
@@ -475,6 +475,17 @@ RELOC_NUMBER (R_MORELLO_LD128_GOT_LO12_NC, 57352)
RELOC_NUMBER (R_MORELLO_TLSDESC_ADR_PAGE20, 57600)
RELOC_NUMBER (R_MORELLO_TLSDESC_LD128_LO12, 57601)
RELOC_NUMBER (R_MORELLO_TLSDESC_CALL, 57602)
+RELOC_NUMBER (R_MORELLO_TLSIE_ADR_GOTTPREL_PAGE20, 57603)
+RELOC_NUMBER (R_MORELLO_TLSIE_ADD_LO12, 57604)
+
+/* Morello group relocation for size. */
+RELOC_NUMBER (R_MORELLO_MOVW_SIZE_G0 , 57353)
+RELOC_NUMBER (R_MORELLO_MOVW_SIZE_G0_NC , 57354)
+RELOC_NUMBER (R_MORELLO_MOVW_SIZE_G1 , 57355)
+RELOC_NUMBER (R_MORELLO_MOVW_SIZE_G1_NC , 57356)
+RELOC_NUMBER (R_MORELLO_MOVW_SIZE_G2 , 57357)
+RELOC_NUMBER (R_MORELLO_MOVW_SIZE_G2_NC , 57358)
+RELOC_NUMBER (R_MORELLO_MOVW_SIZE_G3 , 57359)
/* Morello dynamic relocations. */
@@ -484,6 +495,7 @@ RELOC_NUMBER (R_MORELLO_JUMP_SLOT, 59394)
RELOC_NUMBER (R_MORELLO_RELATIVE, 59395)
RELOC_NUMBER (R_MORELLO_IRELATIVE, 59396)
RELOC_NUMBER (R_MORELLO_TLSDESC, 59397)
+RELOC_NUMBER (R_MORELLO_TPREL128, 59398)
END_RELOC_NUMBERS (R_AARCH64_end)