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 : + \.\.\. + +000000000000000c : + c: 14000000 b 0 + c: R_MORELLO_JUMP26 x + 10: 14000000 b c + 10: R_MORELLO_JUMP26 f + 14: 17fffffe b c + 18: 17fffffd b c + 1c: 5400000d b\.le 0 + 1c: R_MORELLO_CONDBR19 x + 20: 5400000d b\.le c + 20: R_MORELLO_CONDBR19 f + 24: 54ffff4d b\.le c + 28: 54ffff2d b\.le c + 2c: 36080001 tbz w1, #1, 0 + 2c: R_MORELLO_TSTBR14 x + 30: 36080001 tbz w1, #1, c + 30: R_MORELLO_TSTBR14 f + 34: 360ffec1 tbz w1, #1, c + 38: 360ffea1 tbz w1, #1, c + 3c: 94000000 bl 0 + 3c: R_MORELLO_CALL26 x + 40: 94000000 bl c + 40: R_MORELLO_CALL26 f + 44: 97fffff2 bl c + 48: 97fffff1 bl c 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