public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: mengqinggang <mengqinggang@loongson.cn>
To: binutils@sourceware.org
Cc: xuchenghua@loongson.cn, liuzhensong@loongson.cn,
	chenglulu@loongson.cn, xry111@xry111.site, i.swmail@xen0n.name,
	maskray@google.com, mengqinggang <mengqinggang@loongson.cn>
Subject: [PATCH v1 4/6] LoongArch: binutils: Add support for linker relaxation.
Date: Mon,  5 Dec 2022 16:04:51 +0800	[thread overview]
Message-ID: <20221205080453.1352069-5-mengqinggang@loongson.cn> (raw)
In-Reply-To: <20221205080453.1352069-1-mengqinggang@loongson.cn>

Add support for relocs related to relax to readelf.

binutils/ChangeLog:

	* readelf.c (target_specific_reloc_handling): Handle ULEB128 reloc.
	  (is_32bit_inplace_add_reloc): Handle new reloc.
	  (is_32bit_inplace_sub_reloc): Likewise.
	  (is_64bit_inplace_add_reloc): Likewise.
	  (is_64bit_inplace_sub_reloc): Likewise.
	  (is_16bit_inplace_add_reloc): Likewise.
	  (is_16bit_inplace_sub_reloc): Likewise.
	  (is_8bit_inplace_add_reloc): Likewise.
	  (is_8bit_inplace_sub_reloc): Likewise.
	  (is_6bit_inplace_sub_reloc): Likewise.
	  (is_6bit_inplace_add_reloc): New function.
	  (apply_relocations): Handle new reloc.
	* testsuite/binutils-all/readelf.exp: Add -mno-relax option
	  for LoongArch.
---
 binutils/readelf.c                          | 84 ++++++++++++++++++++-
 binutils/testsuite/binutils-all/readelf.exp | 13 +++-
 2 files changed, 91 insertions(+), 6 deletions(-)

diff --git a/binutils/readelf.c b/binutils/readelf.c
index 6b2cbbcbb1b..dbca5552bdc 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -13961,6 +13961,51 @@ target_specific_reloc_handling (Filedata *           filedata,
 
   switch (filedata->file_header.e_machine)
     {
+    case EM_LOONGARCH:
+      {
+	switch (reloc_type)
+	  {
+	    /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
+	       at assembly time.  */
+	    case 107: /* R_LARCH_ADD_ULEB128.  */
+	    case 108: /* R_LARCH_SUB_ULEB128.  */
+	      {
+		uint64_t value;
+		unsigned int reloc_size = 0;
+		int leb_ret = 0;
+
+		value = read_leb128 (start + reloc->r_offset, end, false,
+			      &reloc_size, &leb_ret);
+		if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
+		  error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
+			   "ULEB128 value\n"),
+			 (long) reloc->r_offset);
+
+		if (107 == reloc_type)
+		  value += (reloc->r_addend + symtab[sym_index].st_value);
+		else if (108 == reloc_type)
+		  value -= (reloc->r_addend + symtab[sym_index].st_value);
+
+		/* Write uleb128 value to p.  */
+		bfd_byte c;
+		bfd_byte *p = start + reloc->r_offset;
+		do
+		  {
+		    c = value & 0x7f;
+		    if (reloc_size > 1)
+		      c |= 0x80;
+		    *(p++) = c;
+		    value >>= 7;
+		    reloc_size--;
+		  }
+		while (reloc_size);
+
+		return true;
+	      }
+	  }
+	break;
+      }
+
     case EM_MSP430:
     case EM_MSP430_OLD:
       {
@@ -14680,6 +14725,8 @@ is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
   switch (filedata->file_header.e_machine)
     {
+    case EM_LOONGARCH:
+      return reloc_type == 50; /* R_LARCH_ADD32.  */
     case EM_RISCV:
       return reloc_type == 35; /* R_RISCV_ADD32.  */
     default:
@@ -14696,6 +14743,8 @@ is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
   switch (filedata->file_header.e_machine)
     {
+    case EM_LOONGARCH:
+      return reloc_type == 55; /* R_LARCH_SUB32.  */
     case EM_RISCV:
       return reloc_type == 39; /* R_RISCV_SUB32.  */
     default:
@@ -14712,6 +14761,8 @@ is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
   switch (filedata->file_header.e_machine)
     {
+    case EM_LOONGARCH:
+      return reloc_type == 51; /* R_LARCH_ADD64.  */
     case EM_RISCV:
       return reloc_type == 36; /* R_RISCV_ADD64.  */
     default:
@@ -14728,6 +14779,8 @@ is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
   switch (filedata->file_header.e_machine)
     {
+    case EM_LOONGARCH:
+      return reloc_type == 56; /* R_LARCH_SUB64.  */
     case EM_RISCV:
       return reloc_type == 40; /* R_RISCV_SUB64.  */
     default:
@@ -14744,6 +14797,8 @@ is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
   switch (filedata->file_header.e_machine)
     {
+    case EM_LOONGARCH:
+      return reloc_type == 48; /* R_LARCH_ADD16.  */
     case EM_RISCV:
       return reloc_type == 34; /* R_RISCV_ADD16.  */
     default:
@@ -14760,6 +14815,8 @@ is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
   switch (filedata->file_header.e_machine)
     {
+    case EM_LOONGARCH:
+      return reloc_type == 53; /* R_LARCH_SUB16.  */
     case EM_RISCV:
       return reloc_type == 38; /* R_RISCV_SUB16.  */
     default:
@@ -14776,6 +14833,8 @@ is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
   switch (filedata->file_header.e_machine)
     {
+    case EM_LOONGARCH:
+      return reloc_type == 47; /* R_LARCH_ADD8.  */
     case EM_RISCV:
       return reloc_type == 33; /* R_RISCV_ADD8.  */
     default:
@@ -14792,6 +14851,8 @@ is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
   /* Please keep this table alpha-sorted for ease of visual lookup.  */
   switch (filedata->file_header.e_machine)
     {
+    case EM_LOONGARCH:
+      return reloc_type == 52; /* R_LARCH_SUB8.  */
     case EM_RISCV:
       return reloc_type == 37; /* R_RISCV_SUB8.  */
     default:
@@ -14799,6 +14860,21 @@ is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
     }
 }
 
+/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
+   a 6-bit inplace add RELA relocation used in DWARF debug sections.  */
+
+static bool
+is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
+{
+  switch (filedata->file_header.e_machine)
+    {
+    case EM_LOONGARCH:
+      return reloc_type == 105; /* R_LARCH_ADD6.  */
+    default:
+      return false;
+    }
+}
+
 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
    a 6-bit inplace sub RELA relocation used in DWARF debug sections.  */
 
@@ -14807,6 +14883,8 @@ is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
 {
   switch (filedata->file_header.e_machine)
     {
+    case EM_LOONGARCH:
+      return reloc_type == 106; /* R_LARCH_SUB6.  */
     case EM_RISCV:
       return reloc_type == 52; /* R_RISCV_SUB6.  */
     default:
@@ -15054,7 +15132,8 @@ apply_relocations (Filedata *filedata,
 	      reloc_inplace = true;
 	    }
 	  else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
-								reloc_type)))
+								reloc_type))
+		   || is_6bit_inplace_add_reloc (filedata, reloc_type))
 	    {
 	      reloc_size = 1;
 	      reloc_inplace = true;
@@ -15144,7 +15223,8 @@ apply_relocations (Filedata *filedata,
 		        reloc_size);
 	    }
 	  else if (is_6bit_abs_reloc (filedata, reloc_type)
-		   || is_6bit_inplace_sub_reloc (filedata, reloc_type))
+		   || is_6bit_inplace_sub_reloc (filedata, reloc_type)
+		   || is_6bit_inplace_add_reloc (filedata, reloc_type))
 	    {
 	      if (reloc_subtract)
 		addend -= sym->st_value;
diff --git a/binutils/testsuite/binutils-all/readelf.exp b/binutils/testsuite/binutils-all/readelf.exp
index d7f1524fc5c..07056aec6bb 100644
--- a/binutils/testsuite/binutils-all/readelf.exp
+++ b/binutils/testsuite/binutils-all/readelf.exp
@@ -489,18 +489,23 @@ if {![binutils_assemble $srcdir/$subdir/z.s tmpdir/z.o]} then {
     readelf_test {--decompress --hex-dump .debug_loc} $tempfile readelf.z
 }
 
-set hpux ""
+set flags ""
 
 # Skip the next test for the RISCV architectures because they
 # do not support .ULEB128 pseudo-ops with non-constant values.
 if ![istarget "riscv*-*-*"] then {
 
     if [istarget "hppa*64*-*-hpux*"] {
-	set hpux "--defsym HPUX=1"
+	set flags "--defsym HPUX=1"
     }
 
+    # LOONGARCH relax align add nops, so label subtractions will increase
+    if [istarget "loongarch*-*-*"] {
+	set flags "-mno-relax"
+     }
+
     # Assemble the DWARF-5 test file.
-    if {![binutils_assemble_flags $srcdir/$subdir/dw5.S tmpdir/dw5.o $hpux]} then {
+    if {![binutils_assemble_flags $srcdir/$subdir/dw5.S tmpdir/dw5.o $flags]} then {
 	unsupported "readelf -wiaoRlL dw5 (failed to assemble)"
     } else {
 
@@ -612,7 +617,7 @@ if ![is_remote host] {
 }
 
 # Check dwarf-5 support for DW_OP_addrx.
-if {![binutils_assemble_flags $srcdir/$subdir/dw5-op.S tmpdir/dw5-op.o $hpux]} then {
+if {![binutils_assemble_flags $srcdir/$subdir/dw5-op.S tmpdir/dw5-op.o $flags]} then {
     unsupported "readelf -wi dw5-op (failed to assemble)"
 } else {
 
-- 
2.36.0


  parent reply	other threads:[~2022-12-05  8:05 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-05  8:04 [PATCH v1 0/6] LoongArch linker relaxation support mengqinggang
2022-12-05  8:04 ` [PATCH v1 1/6] LoongArch: include: Add support for linker relaxation mengqinggang
2022-12-05  8:24   ` Xi Ruoyao
2022-12-06  2:59     ` mengqinggang
2022-12-05  8:04 ` [PATCH v1 2/6] LoongArch: bfd: " mengqinggang
2022-12-05  8:04 ` [PATCH v1 3/6] LoongArch: opcodes: " mengqinggang
2022-12-05  9:43   ` Andreas Schwab
2022-12-05  8:04 ` mengqinggang [this message]
2022-12-05  8:04 ` [PATCH v1 5/6] LoongArch: gas: " mengqinggang
2022-12-05  9:47   ` Andreas Schwab
2022-12-05  8:04 ` [PATCH v1 6/6] LoongArch: ld: " mengqinggang
2022-12-05  8:31   ` Xi Ruoyao
2022-12-05  8:43 ` [PATCH v1 0/6] LoongArch linker relaxation support Xi Ruoyao
2022-12-06  1:58   ` mengqinggang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221205080453.1352069-5-mengqinggang@loongson.cn \
    --to=mengqinggang@loongson.cn \
    --cc=binutils@sourceware.org \
    --cc=chenglulu@loongson.cn \
    --cc=i.swmail@xen0n.name \
    --cc=liuzhensong@loongson.cn \
    --cc=maskray@google.com \
    --cc=xry111@xry111.site \
    --cc=xuchenghua@loongson.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).