LoongArch: Add R_LARCH_64_PCREL relocation support
authormengqinggang <mengqinggang@loongson.cn>
Sun, 25 Jun 2023 09:47:42 +0000 (17:47 +0800)
committerliuzhensong <liuzhensong@loongson.cn>
Wed, 28 Jun 2023 08:14:35 +0000 (16:14 +0800)
  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.

12 files changed:
bfd/bfd-in2.h
bfd/elfnn-loongarch.c
bfd/elfxx-loongarch.c
bfd/libbfd.h
bfd/reloc.c
gas/config/tc-loongarch.c
gas/testsuite/gas/loongarch/64_pcrel.d [new file with mode: 0644]
gas/testsuite/gas/loongarch/64_pcrel.s [new file with mode: 0644]
include/elf/loongarch.h
ld/testsuite/ld-loongarch-elf/64_pcrel.d [new file with mode: 0644]
ld/testsuite/ld-loongarch-elf/64_pcrel.s [new file with mode: 0644]
ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp

index 7399fb0fa6021a3f0a16b267c804af842a51eb0f..c4fa0c1f9bfa728047f669cf120bc6e10bfe88dd 100644 (file)
@@ -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;
 
index b16066c5d91c6d455277dbeff385351ce9c629dd..d3d8419d80b40b88c7f283795d2125a410c8ee56 100644 (file)
@@ -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;
index cb312c46bb210ab6b7cad9d376030ebf5190c6da..da440d55c3c58fe18d328b99a7e66e1e79de2db7 100644 (file)
@@ -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 *
index 55aa8f91cbdf53e2ac13973b6f60f42c92916fb8..d4fb31075976ace3b957cb554fb90665f19d506e 100644 (file)
@@ -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
index b38cb32a8c98dfae4909b23665d308137cd0908a..fbc67ac72805005ef7fa6da916d91e38456f480b 100644 (file)
@@ -8153,6 +8153,9 @@ ENUMX
 ENUMX
   BFD_RELOC_LARCH_SUB_ULEB128
 
+ENUMX
+  BFD_RELOC_LARCH_64_PCREL
+
 ENUMDOC
   LARCH relocations.
 
index ba5b626e1ea50bb804b53b8e4102bd8aa359ecde..4ea7b87fb79cb98ee6d8bfc1be9133f59753165a 100644 (file)
@@ -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 (file)
index 0000000..6d4654b
--- /dev/null
@@ -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 (file)
index 0000000..932e1bf
--- /dev/null
@@ -0,0 +1,2 @@
+nop
+.reloc 0, R_LARCH_64_PCREL, 0
index 71ab34f2cef9f953dda580906fb18cc00b86dcf6..e31395e13d57897194b89b1a8af5fc52ee5c1b1a 100644 (file)
@@ -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 (file)
index 0000000..2ea063b
--- /dev/null
@@ -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 (file)
index 0000000..68af590
--- /dev/null
@@ -0,0 +1,11 @@
+.text
+  nop
+  nop
+L1:
+  nop
+.data
+  nop
+  nop
+  .8byte 0x1234567812345678
+  .reloc 0,R_LARCH_64_PCREL,L1
+  nop
index 50a12082b4678f2c755dae2ae0df7a8a17b9c0b3..b95cc53e59711a212440341457eb0f6bb767f0a1 100644 (file)
@@ -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" \
+         ] \
+      ]
+}