[PATCH 5/5 v1] LoongArch: Delete R_LARCH_NONE from dynamic info.

liuzhensong liuzhensong@loongson.cn
Mon Jul 18 08:43:21 GMT 2022


  Some R_LARCH_64 in section .eh_frame will to generate
  R_LARCH_NONE, we change relocation to R_LARCH_32_PCREL
  from R_LARCH_64 in setction .eh_frame and not generate
  dynamic relocation for R_LARCH_32_PCREL.

  Add New relocate type R_LARCH_32_PCREL for .eh_frame.

  include/elf/
    loongarch.h

  bfd/
    bfd/bfd-in2.h
    libbfd.h
    reloc.c
    elfxx-loongarch.c
    elfnn-loongarch.c

  gas/config/
    tc-loongarch.c

  binutils/
    readelf.c

  ld/testsuite/ld-elf/
    eh5.d
---
 bfd/bfd-in2.h             |  1 +
 bfd/elfnn-loongarch.c     | 11 +++++++++++
 bfd/elfxx-loongarch.c     | 19 ++++++++++++++++++-
 bfd/libbfd.h              |  1 +
 bfd/reloc.c               |  3 +++
 binutils/readelf.c        |  2 ++
 include/elf/loongarch.h   |  5 ++++-
 ld/testsuite/ld-elf/eh5.d |  2 +-
 8 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index a71b3e82057..53abf36477f 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -6309,6 +6309,7 @@ assembler and not (currently) written to any object files.  */
   BFD_RELOC_LARCH_TLS_LD64_HI20,
   BFD_RELOC_LARCH_TLS_GD_PC_HI20,
   BFD_RELOC_LARCH_TLS_GD64_HI20,
+  BFD_RELOC_LARCH_32_PCREL,
   BFD_RELOC_LARCH_RELAX,
   BFD_RELOC_UNUSED };
 
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 5bb7596e5d0..44b8d6dca9b 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -2011,6 +2011,17 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
       bfd_put (bits, input_bfd, opr1 - value, contents + rel->r_offset);
       break;
 
+    /* For eh_frame and debug info.  */
+    case R_LARCH_32_PCREL:
+      value -= sec_addr (input_section) + rel->r_offset;
+      value += rel->r_addend;
+      bfd_vma word = bfd_get (howto->bitsize, input_bfd,
+			      contents + rel->r_offset);
+      word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
+      bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
+      r = bfd_reloc_ok;
+      break;
+
     /* New reloc type.
        R_LARCH_B16 ~ R_LARCH_TLS_GD64_HI20.  */
     case R_LARCH_B16:
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 1f6346ef5f3..1a4f99a8927 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -1327,7 +1327,24 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
 	 reloc_bits,				/* adjust_reloc_bits */
 	 "gd64_hi20"),				/* larch_reloc_type_name */
 
-  LOONGARCH_HOWTO (R_LARCH_RELAX,		/* type (99).  */
+  LOONGARCH_HOWTO (R_LARCH_32_PCREL,		/* type (99).  */
+	 0,					/* rightshift.  */
+	 4,					/* size.  */
+	 32,					/* bitsize.  */
+	 true,					/* pc_relative.  */
+	 0,					/* bitpos.  */
+	 complain_overflow_dont,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_32_PCREL",			/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask */
+	 0xffffffff,				/* dst_mask */
+	 false,					/* pcrel_offset */
+	 BFD_RELOC_LARCH_32_PCREL,		/* bfd_reloc_code_real_type */
+	 NULL,					/* adjust_reloc_bits */
+	 NULL),					/* larch_reloc_type_name */
+
+  LOONGARCH_HOWTO (R_LARCH_RELAX,		/* type (100).  */
 	 0,					/* rightshift */
 	 1,					/* size */
 	 0,					/* bitsize */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index b23ae4b755c..0b8610524e1 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3492,6 +3492,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_LARCH_TLS_LD64_HI20",
   "BFD_RELOC_LARCH_TLS_GD_PC_HI20",
   "BFD_RELOC_LARCH_TLS_GD64_HI20",
+  "BFD_RELOC_LARCH_32_PCREL",
   "BFD_RELOC_LARCH_RELAX",
  "@@overflow: BFD_RELOC_UNUSED@@",
 };
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 836fa162108..6f092235369 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -8304,6 +8304,9 @@ ENUMX
 ENUMX
   BFD_RELOC_LARCH_TLS_GD64_HI20
 
+ENUMX
+  BFD_RELOC_LARCH_32_PCREL
+
 ENUMX
   BFD_RELOC_LARCH_RELAX
 
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 0f5977bc072..74f59d49fdc 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -14388,6 +14388,8 @@ is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
     case EM_AVR_OLD:
     case EM_AVR:
       return reloc_type == 36; /* R_AVR_32_PCREL.  */
+    case EM_LOONGARCH:
+      return reloc_type == 99;  /* R_LARCH_32_PCREL.  */
     case EM_MICROBLAZE:
       return reloc_type == 2;  /* R_MICROBLAZE_32_PCREL.  */
     case EM_OR1K:
diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
index 863dad3a371..9e0a5217f60 100644
--- a/include/elf/loongarch.h
+++ b/include/elf/loongarch.h
@@ -223,8 +223,11 @@ RELOC_NUMBER (R_LARCH_TLS_GD_PC_HI20, 97)
    %gd64_hi20 (sym).  */
 RELOC_NUMBER (R_LARCH_TLS_GD64_HI20, 98)
 
+/* For eh_frame and debug info.  */
+RELOC_NUMBER (R_LARCH_32_PCREL, 99)
+
 /* RELAX.  */
-RELOC_NUMBER (R_LARCH_RELAX, 99)
+RELOC_NUMBER (R_LARCH_RELAX, 100)
 
 END_RELOC_NUMBERS (R_LARCH_count)
 
diff --git a/ld/testsuite/ld-elf/eh5.d b/ld/testsuite/ld-elf/eh5.d
index d614251587c..4a697482355 100644
--- a/ld/testsuite/ld-elf/eh5.d
+++ b/ld/testsuite/ld-elf/eh5.d
@@ -4,7 +4,7 @@
 #ld:
 #readelf: -wf
 #target: [check_as_cfi]
-#xfail: alpha-*-*ecoff hppa64-*-* tile*-*-* visium-*-* loongarch64-*-*
+#xfail: alpha-*-*ecoff hppa64-*-* tile*-*-* visium-*-*
 
 Contents of the .eh_frame section:
 
-- 
2.31.1



More information about the Binutils mailing list