From fac4bdbd57ce2c57d48323ac17f33b3606b22d3f Mon Sep 17 00:00:00 2001 From: Matthew Malcomson Date: Thu, 29 Jul 2021 15:08:35 +0100 Subject: [PATCH] gas: aarch64: Require 16 bytes for Morello capinit relocation The `capinit` directive does not allocate space for the relevant relocation, rather it creates a CAPINIT relocation on the 16 bytes immediately following it. Our implementation works by ensuring we can grow the existing `frag` (an internal structure that describes known contiguous bytes) by 8 bytes and then recording that we have an 8 byte sized CAPINIT relocation. It should be 16 bytes, since the relocation is on a 16 byte quantity. One symptom this problem can cause is where the section that a given CAPINIT relocation is recorded may not have enough space for the entire capability the CAPINIT relocation requests. The testcase we add demonstrated this problem before the current change. Now it errors out. Unfortunately the error is an internal one with a error message that references internal data structures, but I believe that is better than creating a faulty binary without complaint. --- gas/config/tc-aarch64.c | 4 ++-- .../gas/aarch64/morello-capinit-require-size.d | 3 +++ .../gas/aarch64/morello-capinit-require-size.l | 2 ++ .../gas/aarch64/morello-capinit-require-size.s | 17 +++++++++++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 gas/testsuite/gas/aarch64/morello-capinit-require-size.d create mode 100644 gas/testsuite/gas/aarch64/morello-capinit-require-size.l create mode 100644 gas/testsuite/gas/aarch64/morello-capinit-require-size.s diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c index db4431d929c..2afc7ec0f7e 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -2145,8 +2145,8 @@ s_aarch64_capinit (int ignored ATTRIBUTE_UNUSED) return; } - frag_grow (8); - fix_new_aarch64 (frag_now, frag_more (0) - frag_now->fr_literal, 8, &exp, 0, + frag_grow (16); + fix_new_aarch64 (frag_now, frag_more (0) - frag_now->fr_literal, 16, &exp, 0, BFD_RELOC_MORELLO_CAPINIT); demand_empty_rest_of_line (); diff --git a/gas/testsuite/gas/aarch64/morello-capinit-require-size.d b/gas/testsuite/gas/aarch64/morello-capinit-require-size.d new file mode 100644 index 00000000000..8a6370ecccc --- /dev/null +++ b/gas/testsuite/gas/aarch64/morello-capinit-require-size.d @@ -0,0 +1,3 @@ +#name: Capinit Requires 16 bytes +#as: -march=armv8-a+c64 +#error_output: morello-capinit-require-size.l diff --git a/gas/testsuite/gas/aarch64/morello-capinit-require-size.l b/gas/testsuite/gas/aarch64/morello-capinit-require-size.l new file mode 100644 index 00000000000..614213d95e9 --- /dev/null +++ b/gas/testsuite/gas/aarch64/morello-capinit-require-size.l @@ -0,0 +1,2 @@ +[^:]*: Assembler messages: +[^:]*:7: Error: internal error: fixup not contained within frag diff --git a/gas/testsuite/gas/aarch64/morello-capinit-require-size.s b/gas/testsuite/gas/aarch64/morello-capinit-require-size.s new file mode 100644 index 00000000000..6931c4997da --- /dev/null +++ b/gas/testsuite/gas/aarch64/morello-capinit-require-size.s @@ -0,0 +1,17 @@ +.data +.align 4 +a: + .8byte 0 + +d: + .capinit a + .8byte 0 + .size d, .-d + +// Need to switch section so that the capinit relocation does not have enough +// space in the relevant chunk. +.section .data.rel.ro +.align 4 +e: + .8byte 0 + .size e, .-e -- 2.47.2