From 96cbfd9f0488e9536bfc27550ebf90cb1ecac93b Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 17 Jun 2021 16:19:20 +0100 Subject: [PATCH] Fix an assertion failure in the AArch64 assembler triggered by incorrect instruction syntax. PR 27904 * config/tc-aarch64.c (ldst_lo12_determine_real_reloc_type): Generate a syntax error message if the reloc qualifier does not match the instruction's size. --- gas/ChangeLog | 7 +++++++ gas/config/tc-aarch64.c | 15 ++++++++++++--- gas/testsuite/gas/aarch64/pr27904.d | 2 ++ gas/testsuite/gas/aarch64/pr27904.l | 2 ++ gas/testsuite/gas/aarch64/pr27904.s | 1 + 5 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 gas/testsuite/gas/aarch64/pr27904.d create mode 100644 gas/testsuite/gas/aarch64/pr27904.l create mode 100644 gas/testsuite/gas/aarch64/pr27904.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 821cc810e07..a1997d2c028 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,10 @@ +2021-06-17 Nick Clifton + + PR 27904 + * config/tc-aarch64.c (ldst_lo12_determine_real_reloc_type): + Generate a syntax error message if the reloc qualifier does not + match the instruction's size. + 2021-06-17 Clément Chigot * config/tc-ppc.c (md_begin): Create bss section with dummy diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index 69705521f00..9ff2d6803dd 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -5591,7 +5591,7 @@ get_logsz (unsigned int size) static inline bfd_reloc_code_real_type ldst_lo12_determine_real_reloc_type (void) { - unsigned logsz; + unsigned logsz, max_logsz; enum aarch64_opnd_qualifier opd0_qlf = inst.base.operands[0].qualifier; enum aarch64_opnd_qualifier opd1_qlf = inst.base.operands[1].qualifier; @@ -5650,13 +5650,22 @@ ldst_lo12_determine_real_reloc_type (void) gas_assert (opd1_qlf != AARCH64_OPND_QLF_NIL); logsz = get_logsz (aarch64_get_qualifier_esize (opd1_qlf)); + if (inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12 || inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC || inst.reloc.type == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12 || inst.reloc.type == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC) - gas_assert (logsz <= 3); + max_logsz = 3; else - gas_assert (logsz <= 4); + max_logsz = 4; + + if (logsz > max_logsz) + { + /* SEE PR 27904 for an example of this. */ + set_fatal_syntax_error + (_("relocation qualifier does not match instruction size")); + return BFD_RELOC_AARCH64_NONE; + } /* In reloc.c, these pseudo relocation types should be defined in similar order as above reloc_ldst_lo12 array. Because the array index calculation diff --git a/gas/testsuite/gas/aarch64/pr27904.d b/gas/testsuite/gas/aarch64/pr27904.d new file mode 100644 index 00000000000..927b72a19b7 --- /dev/null +++ b/gas/testsuite/gas/aarch64/pr27904.d @@ -0,0 +1,2 @@ +#name: PR 27904 +#error_output: pr27904.l diff --git a/gas/testsuite/gas/aarch64/pr27904.l b/gas/testsuite/gas/aarch64/pr27904.l new file mode 100644 index 00000000000..c8629c68b12 --- /dev/null +++ b/gas/testsuite/gas/aarch64/pr27904.l @@ -0,0 +1,2 @@ +[^:]*: Assembler messages: +[^:]*:1: Error: relocation qualifier does not match instruction size at operand 3 -- `ldr q24,\[x23,:dtprel_lo12_nc:sym\]' diff --git a/gas/testsuite/gas/aarch64/pr27904.s b/gas/testsuite/gas/aarch64/pr27904.s new file mode 100644 index 00000000000..904fe9dade1 --- /dev/null +++ b/gas/testsuite/gas/aarch64/pr27904.s @@ -0,0 +1 @@ +ldr q24, [x23, :dtprel_lo12_nc:sym] -- 2.30.2