From be1ebb6710a8f707bd4b0eecbd00f4f4964050e5 Mon Sep 17 00:00:00 2001 From: mengqinggang Date: Sun, 25 Jun 2023 17:47:42 +0800 Subject: [PATCH] LoongArch: Add R_LARCH_64_PCREL relocation support Gas defaults to emit R_LARCH_ADD64/R_LARCH_SUB64 unless explcitly declared to emit R_LARCH_64_PCREL. The LoongArch ABI at here: https://github.com/loongson/la-abi-specs/blob/release/la-abi.adoc bfd/ChangeLog: * bfd-in2.h (not): Add R_LARCH_64_PCREL * elfnn-loongarch.c (perform_relocation): Likewise. * elfxx-loongarch.c: Likewise. * libbfd.h: Likewise. * reloc.c: Likewise. gas/ChangeLog: * config/tc-loongarch.c (loongarch_args_parser_can_match_arg_helper): (md_apply_fix): Add R_LARCH_64_PCREL. * testsuite/gas/loongarch/64_pcrel.d: New test. * testsuite/gas/loongarch/64_pcrel.s: New test. include/ChangeLog: * elf/loongarch.h (RELOC_NUMBER): Add R_LARCH_64_PCREL. ld/ChangeLog: * testsuite/ld-loongarch-elf/ld-loongarch-elf.exp: Add test. * testsuite/ld-loongarch-elf/64_pcrel.d: New test. * testsuite/ld-loongarch-elf/64_pcrel.s: New test. --- bfd/bfd-in2.h | 1 + bfd/elfnn-loongarch.c | 1 + bfd/elfxx-loongarch.c | 18 ++++++++++++++++++ bfd/libbfd.h | 1 + bfd/reloc.c | 3 +++ gas/config/tc-loongarch.c | 5 ++--- gas/testsuite/gas/loongarch/64_pcrel.d | 11 +++++++++++ gas/testsuite/gas/loongarch/64_pcrel.s | 2 ++ include/elf/loongarch.h | 2 ++ ld/testsuite/ld-loongarch-elf/64_pcrel.d | 4 ++++ ld/testsuite/ld-loongarch-elf/64_pcrel.s | 11 +++++++++++ .../ld-loongarch-elf/ld-loongarch-elf.exp | 16 ++++++++++++++++ 12 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 gas/testsuite/gas/loongarch/64_pcrel.d create mode 100644 gas/testsuite/gas/loongarch/64_pcrel.s create mode 100644 ld/testsuite/ld-loongarch-elf/64_pcrel.d create mode 100644 ld/testsuite/ld-loongarch-elf/64_pcrel.s diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 7399fb0fa60..c4fa0c1f9bf 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -7343,6 +7343,7 @@ assembler and not (currently) written to any object files. */ BFD_RELOC_LARCH_SUB6, BFD_RELOC_LARCH_ADD_ULEB128, BFD_RELOC_LARCH_SUB_ULEB128, + BFD_RELOC_LARCH_64_PCREL, BFD_RELOC_UNUSED }; typedef enum bfd_reloc_code_real bfd_reloc_code_real_type; diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index b16066c5d91..d3d8419d80b 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -2070,6 +2070,7 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section, /* For eh_frame and debug info. */ case R_LARCH_32_PCREL: + case R_LARCH_64_PCREL: { value -= sec_addr (input_section) + rel->r_offset; value += rel->r_addend; diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c index cb312c46bb2..da440d55c3c 100644 --- a/bfd/elfxx-loongarch.c +++ b/bfd/elfxx-loongarch.c @@ -1535,6 +1535,24 @@ static loongarch_reloc_howto_type loongarch_howto_table[] = NULL, /* adjust_reloc_bits. */ NULL), /* larch_reloc_type_name. */ + /* 64-bit PC relative. */ + LOONGARCH_HOWTO (R_LARCH_64_PCREL, /* type (109). */ + 0, /* rightshift. */ + 8, /* size. */ + 64, /* bitsize. */ + true, /* pc_relative. */ + 0, /* bitpos. */ + complain_overflow_signed, /* complain_on_overflow. */ + bfd_elf_generic_reloc, /* special_function. */ + "R_LARCH_64_PCREL", /* name. */ + false, /* partial_inplace. */ + 0, /* src_mask */ + 0xffffffffffffffff, /* dst_mask */ + false, /* pcrel_offset */ + BFD_RELOC_LARCH_64_PCREL, /* bfd_reloc_code_real_type */ + NULL, /* adjust_reloc_bits */ + NULL), /* larch_reloc_type_name */ + }; reloc_howto_type * diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 55aa8f91cbd..d4fb3107597 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -3524,6 +3524,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_LARCH_SUB6", "BFD_RELOC_LARCH_ADD_ULEB128", "BFD_RELOC_LARCH_SUB_ULEB128", + "BFD_RELOC_LARCH_64_PCREL", "@@overflow: BFD_RELOC_UNUSED@@", }; #endif diff --git a/bfd/reloc.c b/bfd/reloc.c index b38cb32a8c9..fbc67ac7280 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -8153,6 +8153,9 @@ ENUMX ENUMX BFD_RELOC_LARCH_SUB_ULEB128 +ENUMX + BFD_RELOC_LARCH_64_PCREL + ENUMDOC LARCH relocations. diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c index ba5b626e1ea..4ea7b87fb79 100644 --- a/gas/config/tc-loongarch.c +++ b/gas/config/tc-loongarch.c @@ -650,7 +650,7 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2, esc_ch1, esc_ch2, bit_field, arg); if (ip->reloc_info[0].type >= BFD_RELOC_LARCH_B16 - && ip->reloc_info[0].type < BFD_RELOC_LARCH_SUB_ULEB128) + && ip->reloc_info[0].type < BFD_RELOC_LARCH_64_PCREL) { /* As we compact stack-relocs, it is no need for pop operation. But break out until here in order to check the imm field. @@ -1230,8 +1230,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) function. If only fx_addsy not null, we generate BFD_RELOC_LARCH_ADD24/16/8 only, then generate R_LARCH_24/16/8. To avoid R_LARCH_ADDxx add extra value, we write 0 first - (use md_number_to_chars (buf, 0, fixP->fx_size)). - */ + (use md_number_to_chars (buf, 0, fixP->fx_size)). */ case BFD_RELOC_64: case BFD_RELOC_32: if (fixP->fx_r_type == BFD_RELOC_32 diff --git a/gas/testsuite/gas/loongarch/64_pcrel.d b/gas/testsuite/gas/loongarch/64_pcrel.d new file mode 100644 index 00000000000..6d4654b795e --- /dev/null +++ b/gas/testsuite/gas/loongarch/64_pcrel.d @@ -0,0 +1,11 @@ +#as: +#objdump: -dr + +.*:[ ]+file format .* + + +Disassembly of section .text: + +00000000.* <.text>: +[ ]+0:[ ]+03400000[ ]+andi[ ]+\$zero,[ ]+\$zero,[ ]+0x0 +[ ]+0:[ ]+R_LARCH_64_PCREL[ ]+\*ABS\* diff --git a/gas/testsuite/gas/loongarch/64_pcrel.s b/gas/testsuite/gas/loongarch/64_pcrel.s new file mode 100644 index 00000000000..932e1bf2016 --- /dev/null +++ b/gas/testsuite/gas/loongarch/64_pcrel.s @@ -0,0 +1,2 @@ +nop +.reloc 0, R_LARCH_64_PCREL, 0 diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h index 71ab34f2cef..e31395e13d5 100644 --- a/include/elf/loongarch.h +++ b/include/elf/loongarch.h @@ -249,6 +249,8 @@ RELOC_NUMBER (R_LARCH_SUB6, 106) RELOC_NUMBER (R_LARCH_ADD_ULEB128, 107) RELOC_NUMBER (R_LARCH_SUB_ULEB128, 108) +RELOC_NUMBER (R_LARCH_64_PCREL, 109) + END_RELOC_NUMBERS (R_LARCH_count) /* Processor specific flags for the ELF header e_flags field. */ diff --git a/ld/testsuite/ld-loongarch-elf/64_pcrel.d b/ld/testsuite/ld-loongarch-elf/64_pcrel.d new file mode 100644 index 00000000000..2ea063b7554 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/64_pcrel.d @@ -0,0 +1,4 @@ +#... +.*0xffffbffc.* +.*0xffffffff.* +#pass diff --git a/ld/testsuite/ld-loongarch-elf/64_pcrel.s b/ld/testsuite/ld-loongarch-elf/64_pcrel.s new file mode 100644 index 00000000000..68af590f492 --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/64_pcrel.s @@ -0,0 +1,11 @@ +.text + nop + nop +L1: + nop +.data + nop + nop + .8byte 0x1234567812345678 + .reloc 0,R_LARCH_64_PCREL,L1 + nop diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp index 50a12082b46..b95cc53e597 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -40,3 +40,19 @@ if [istarget "loongarch32-*-*"] { run_dump_test "syscall" run_dump_test "disas-jirl-32" } + +if [istarget "loongarch64-*-*"] { + run_ld_link_tests \ + [list \ + [list \ + "64_pcrel" \ + "-e 0x0 -z relro" "" \ + "" \ + {64_pcrel.s} \ + [list \ + [list objdump -D 64_pcrel.d] \ + ] \ + "64_pcrel" \ + ] \ + ] +} -- 2.30.2