This directive is the equivalent of the capinit directive except that it allocates space as well as creating a CAPINIT relocation. It is useful to be added to binutils since LLVM intend to transition away from using capinit to chericap and this helps enable that transition.
Here we just emit the required number of zeros into the output file with md_number_to_chars. Since we don't have to worry about endianness for a big zero this is not complicated.
############### 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 684058b1da7200de00ecd9ea73653ba59422633d..77caba2f13996e541b1e5c216a980aa1b91e038e 100644 --- a/gas/config/tc-aarch64.c +++ b/gas/config/tc-aarch64.c @@ -2176,6 +2176,37 @@ s_aarch64_capinit (int ignored ATTRIBUTE_UNUSED)
demand_empty_rest_of_line (); } + +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 (); +#endif + + frag_grow (16); + fix_new_aarch64 (frag_now, frag_more (0) - frag_now->fr_literal, 16, &exp, 0, + BFD_RELOC_MORELLO_CAPINIT); + + mapping_state (MAP_DATA); + for (int i = 0; i < 4; i++) + { + /* The documentation of our md_number_to_chars says the greatest value + size it can handle is 4 bytes. */ + char *p = frag_more (4); + md_number_to_chars (p, 0, 4); + } + demand_empty_rest_of_line (); +} #endif /* OBJ_ELF */
static void s_aarch64_arch (int); @@ -2211,6 +2242,7 @@ const pseudo_typeS md_pseudo_table[] = { {"dword", s_aarch64_elf_cons, 8}, {"variant_pcs", s_variant_pcs, 0}, {"capinit", s_aarch64_capinit, 0}, + {"chericap", s_aarch64_chericap, 0}, #endif {"float16", float_cons, 'h'}, {"bfloat16", float_cons, 'b'}, diff --git a/gas/testsuite/gas/aarch64/morello-chericap.d b/gas/testsuite/gas/aarch64/morello-chericap.d new file mode 100644 index 0000000000000000000000000000000000000000..2d855f283a37cd507954da6fdb2b6b7b74294a25 --- /dev/null +++ b/gas/testsuite/gas/aarch64/morello-chericap.d @@ -0,0 +1,61 @@ +#as: -march=armv8-a+c64 +#objdump: -srt + +.*: file format .* + +SYMBOL TABLE: +0000000000000000 l d .text 0000000000000000 .text +0000000000000000 l d .data 0000000000000000 .data +0000000000000000 l d .bss 0000000000000000 .bss +0000000000000000 l O .data 0000000000000010 bar +0000000000000010 l O .data 0000000000000010 f.p +0000000000000000 l d .rodata 0000000000000000 .rodata +0000000000000000 l .rodata 000000000000000c str2 +0000000000000030 l .data 0000000000000010 a +0000000000000040 l .data 0000000000000010 b +0000000000000050 l .data 0000000000000010 c +0000000000000060 l .data 0000000000000010 d +0000000000000000 l d .data.rel.ro 0000000000000000 .data.rel.ro +0000000000000000 l .data.rel.ro 0000000000000010 e +0000000000000000 g F .text 0000000000000013 f +0000000000000020 g .data 000000000000000c str +0000000000000000 *UND* 0000000000000000 foo +0000000000000014 g F .text 0000000000000000 _start + + +RELOCATION RECORDS FOR [.text]: +OFFSET TYPE VALUE +0000000000000014 R_AARCH64_LDST128_ABS_LO12_NC .data+0x0000000000000030 + + +RELOCATION RECORDS FOR [.data]: +OFFSET TYPE VALUE +0000000000000000 R_MORELLO_CAPINIT f+0x000000000000000c +0000000000000010 R_MORELLO_CAPINIT f+0x000000000000000c +0000000000000030 R_MORELLO_CAPINIT str +0000000000000040 R_MORELLO_CAPINIT str+0x0000000000000008 +0000000000000050 R_MORELLO_CAPINIT foo+0x0000000000000010 +0000000000000060 R_MORELLO_CAPINIT a + + +RELOCATION RECORDS FOR [.data.rel.ro]: +OFFSET TYPE VALUE +0000000000000000 R_MORELLO_CAPINIT str2 + + +Contents of section .text: + 0000 fd7bbf62 fdd3c1c2 01000014 fd7bc122 .* + 0010 c053c2c2 420040c2 c053c2c2 .* +Contents of section .data: + 0000 00000000 00000000 00000000 00000000 .* + 0010 00000000 00000000 00000000 00000000 .* + 0020 48656c6c 6f20576f 726c6400 00000000 .* + 0030 00000000 00000000 00000000 00000000 .* + 0040 00000000 00000000 00000000 00000000 .* + 0050 00000000 00000000 00000000 00000000 .* + 0060 00000000 00000000 00000000 00000000 .* +Contents of section .rodata: + 0000 48656c6c 6f20576f 726c6400 .* +Contents of section .data.rel.ro: + 0000 00000000 00000000 00000000 00000000 .* + diff --git a/gas/testsuite/gas/aarch64/morello-chericap.s b/gas/testsuite/gas/aarch64/morello-chericap.s new file mode 100644 index 0000000000000000000000000000000000000000..1d44a4ffbb952f13d9abaf4288278d3d06786083 --- /dev/null +++ b/gas/testsuite/gas/aarch64/morello-chericap.s @@ -0,0 +1,79 @@ +// Just using the same testcase as the capinit one, but with capinit switched +// to chericap. chericap does not allocate space so we remove the data +// directives. +// +// On top of that we add a testcase using a more complicated form that these +// directives see in the real world. Just to ensure that works too. + .text + .globl f + .p2align 2 + .type f,@function +f: + stp c29, c30, [csp, #-32]! + mov c29, csp + b .LBB0_1 +.Ltmp0: +.LBB0_1: + ldp c29, c30, [csp], #32 + ret c30 +.Lfunc_end0: + .size f, .Lfunc_end0-f + + .type bar,@object + .data + .p2align 4 +bar: + .chericap f+((.Ltmp0+1)-f) + .size bar, 16 + + .type f.p,@object + .data + .p2align 4 +f.p: + .capinit f+((.Ltmp0+1)-f) + .xword 0 + .xword 0 + .size f.p, 16 + + +.section .rodata +str2: + .string "Hello World" + .size str2, .-str2 + +.data +.globl str +str: + .string "Hello World" + .size str, .-str + +.align 4 +a: + .chericap str + .size a, .-a + +b: + .chericap str+8 + .size b, .-b + +c: + .chericap foo+16 + .size c, .-c + +d: + .chericap a + .size d, .-d + +.section .data.rel.ro +.align 4 +e: + .chericap str2 + .size e, .-e + +.align 4 +.text +.globl _start +.type _start STT_FUNC +_start: + ldr c2, [c2, :lo12:a] + ret