public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v1 0/6] Fix some bugs of relaxation
@ 2023-11-16  6:23 mengqinggang
  2023-11-16  6:23 ` [PATCH v1 1/6] LoongArch: Fix ld --no-relax bug mengqinggang
                   ` (5 more replies)
  0 siblings, 6 replies; 11+ messages in thread
From: mengqinggang @ 2023-11-16  6:23 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
	mengqinggang

These patches mainly fix the shared objects can't be relaxed bug.
The "elf_seg_map (info->output_bfd) == NULL" condition prevent the
shared object to be relaxed. Ld can perform up to 10 relaxation tries.
In first try, both execute file and shared object do not meet this condition.
But the execute file can trigger a second try because of the program header
size change due to the number of segement change (execute file add 
extra INTERP segemnt).

mengqinggang (6):
  LoongArch: Fix ld --no-relax bug
  LoongArch: Directly delete relaxed instuctions in first relaxation
    pass
  LoongArch: Multiple relax_trip in one relax_pass
  LoongArch: Remove "elf_seg_map (info->output_bfd) == NULL" relaxation
    condition
  LoongArch: Modify link_info.relax_pass from 3 to 2
  LoongArch: Add more relaxation testcases

 bfd/elfnn-loongarch.c                         | 53 +++++++-----
 ld/emultempl/loongarchelf.em                  | 20 ++++-
 .../ld-loongarch-elf/relax-segment-max.s      | 13 +++
 .../ld-loongarch-elf/relax-segment-min.s      | 13 +++
 ld/testsuite/ld-loongarch-elf/relax-so.s      |  4 +
 ld/testsuite/ld-loongarch-elf/relax.exp       | 80 +++++++++++++++++--
 6 files changed, 158 insertions(+), 25 deletions(-)
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-segment-max.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-segment-min.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-so.s

-- 
2.36.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v1 1/6] LoongArch: Fix ld --no-relax bug
  2023-11-16  6:23 [PATCH v1 0/6] Fix some bugs of relaxation mengqinggang
@ 2023-11-16  6:23 ` mengqinggang
  2023-11-16  7:34   ` WANG Xuerui
  2023-11-16  6:23 ` [PATCH v1 2/6] LoongArch: Directly delete relaxed instuctions in first relaxation pass mengqinggang
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 11+ messages in thread
From: mengqinggang @ 2023-11-16  6:23 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
	mengqinggang

When ld --no-relax, pcalau12i + ld.d still can be relaxed.
---
 bfd/elfnn-loongarch.c | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 18ad3cc91ca..1162cb35cd6 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3996,29 +3996,22 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
 	    loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
 	  break;
 	case R_LARCH_DELETE:
-	  if (info->relax_pass == 1)
+	  if (1 == info->relax_pass)
 	    {
 	      loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info);
 	      rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
 	    }
 	  break;
 	case R_LARCH_PCALA_HI20:
-	  if (info->relax_pass == 0)
-	    {
-	      if (i + 4 > sec->reloc_count)
-		break;
-	      loongarch_relax_pcala_addi (abfd, sec, rel, symval);
-	    }
+	  if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
+	    loongarch_relax_pcala_addi (abfd, sec, rel, symval);
 	  break;
 	case R_LARCH_GOT_PC_HI20:
-	  if (local_got)
+	  if (local_got && 0 == info->relax_pass
+	      && (i + 4) <= sec->reloc_count)
 	    {
-	      if (i + 4 > sec->reloc_count)
-		break;
 	      if (loongarch_relax_pcala_ld (abfd, sec, rel))
-		{
-		  loongarch_relax_pcala_addi (abfd, sec, rel, symval);
-		}
+		loongarch_relax_pcala_addi (abfd, sec, rel, symval);
 	    }
 	  break;
 	default:
-- 
2.36.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v1 2/6] LoongArch: Directly delete relaxed instuctions in first relaxation pass
  2023-11-16  6:23 [PATCH v1 0/6] Fix some bugs of relaxation mengqinggang
  2023-11-16  6:23 ` [PATCH v1 1/6] LoongArch: Fix ld --no-relax bug mengqinggang
@ 2023-11-16  6:23 ` mengqinggang
  2023-11-16  6:23 ` [PATCH v1 3/6] LoongArch: Multiple relax_trip in one relax_pass mengqinggang
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: mengqinggang @ 2023-11-16  6:23 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
	mengqinggang

Directly delete relaxed instuctions in first relaxation pass, not use
R_LARCH_DELETE relocation. If not, the PC-relative offset may increase.
---
 bfd/elfnn-loongarch.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 1162cb35cd6..9d4ea7e4ae7 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3739,7 +3739,8 @@ loongarch_relax_delete_bytes (bfd *abfd,
 /* Relax pcalau12i,addi.d => pcaddi.  */
 static bool
 loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
-		       Elf_Internal_Rela *rel_hi, bfd_vma symval)
+		       Elf_Internal_Rela *rel_hi, bfd_vma symval,
+		       struct bfd_link_info *info)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
   Elf_Internal_Rela *rel_lo = rel_hi + 2;
@@ -3771,8 +3772,9 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
   /* Adjust relocations.  */
   rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
 				 R_LARCH_PCREL20_S2);
-  rel_lo->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
-				 R_LARCH_DELETE);
+  rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
+
+  loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info);
 
   return true;
 }
@@ -4004,14 +4006,14 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
 	  break;
 	case R_LARCH_PCALA_HI20:
 	  if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
-	    loongarch_relax_pcala_addi (abfd, sec, rel, symval);
+	    loongarch_relax_pcala_addi (abfd, sec, rel, symval, info);
 	  break;
 	case R_LARCH_GOT_PC_HI20:
 	  if (local_got && 0 == info->relax_pass
 	      && (i + 4) <= sec->reloc_count)
 	    {
 	      if (loongarch_relax_pcala_ld (abfd, sec, rel))
-		loongarch_relax_pcala_addi (abfd, sec, rel, symval);
+		loongarch_relax_pcala_addi (abfd, sec, rel, symval, info);
 	    }
 	  break;
 	default:
-- 
2.36.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v1 3/6] LoongArch: Multiple relax_trip in one relax_pass
  2023-11-16  6:23 [PATCH v1 0/6] Fix some bugs of relaxation mengqinggang
  2023-11-16  6:23 ` [PATCH v1 1/6] LoongArch: Fix ld --no-relax bug mengqinggang
  2023-11-16  6:23 ` [PATCH v1 2/6] LoongArch: Directly delete relaxed instuctions in first relaxation pass mengqinggang
@ 2023-11-16  6:23 ` mengqinggang
  2023-11-16  6:23 ` [PATCH v1 4/6] LoongArch: Remove "elf_seg_map (info->output_bfd) == NULL" relaxation condition mengqinggang
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 11+ messages in thread
From: mengqinggang @ 2023-11-16  6:23 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
	mengqinggang

If deleting instructions in one relax_trip, set again to true to start the
next relax_trip.
---
 bfd/elfnn-loongarch.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 9d4ea7e4ae7..7436a14441f 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3740,7 +3740,7 @@ loongarch_relax_delete_bytes (bfd *abfd,
 static bool
 loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
 		       Elf_Internal_Rela *rel_hi, bfd_vma symval,
-		       struct bfd_link_info *info)
+		       struct bfd_link_info *info, bool *again)
 {
   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
   Elf_Internal_Rela *rel_lo = rel_hi + 2;
@@ -3766,6 +3766,9 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
       || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
     return false;
 
+  /* Continue next relax trip.  */
+  *again = true;
+
   pca = pcaddi | rd;
   bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
 
@@ -4006,14 +4009,15 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
 	  break;
 	case R_LARCH_PCALA_HI20:
 	  if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
-	    loongarch_relax_pcala_addi (abfd, sec, rel, symval, info);
+	    loongarch_relax_pcala_addi (abfd, sec, rel, symval, info, again);
 	  break;
 	case R_LARCH_GOT_PC_HI20:
 	  if (local_got && 0 == info->relax_pass
 	      && (i + 4) <= sec->reloc_count)
 	    {
 	      if (loongarch_relax_pcala_ld (abfd, sec, rel))
-		loongarch_relax_pcala_addi (abfd, sec, rel, symval, info);
+		loongarch_relax_pcala_addi (abfd, sec, rel, symval,
+					    info, again);
 	    }
 	  break;
 	default:
-- 
2.36.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v1 4/6] LoongArch: Remove "elf_seg_map (info->output_bfd) == NULL" relaxation condition
  2023-11-16  6:23 [PATCH v1 0/6] Fix some bugs of relaxation mengqinggang
                   ` (2 preceding siblings ...)
  2023-11-16  6:23 ` [PATCH v1 3/6] LoongArch: Multiple relax_trip in one relax_pass mengqinggang
@ 2023-11-16  6:23 ` mengqinggang
  2023-11-16  7:43   ` WANG Xuerui
  2023-11-16  6:23 ` [PATCH v1 5/6] LoongArch: Modify link_info.relax_pass from 3 to 2 mengqinggang
  2023-11-16  6:23 ` [PATCH v1 6/6] LoongArch: Add more relaxation testcases mengqinggang
  5 siblings, 1 reply; 11+ messages in thread
From: mengqinggang @ 2023-11-16  6:23 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
	mengqinggang

This condition cause .so(shared object) can't be relaxed.
Without this condition, we need to update program header size and .eh_frame_hdr
size before relaxation.
---
 bfd/elfnn-loongarch.c        | 24 ++++++++++++++++++++----
 ld/emultempl/loongarchelf.em | 18 ++++++++++++++++++
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 7436a14441f..d331eefb8ac 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3738,7 +3738,7 @@ loongarch_relax_delete_bytes (bfd *abfd,
 
 /* Relax pcalau12i,addi.d => pcaddi.  */
 static bool
-loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
+loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
 		       Elf_Internal_Rela *rel_hi, bfd_vma symval,
 		       struct bfd_link_info *info, bool *again)
 {
@@ -3747,7 +3747,23 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
   uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
   uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
   uint32_t rd = pca & 0x1f;
+
+  /* Because previous sections' relax, output_offset may increase and need to
+     be updated before relax. But it update after relax in
+     size_input_section defaultly, so we manually updating here.  */
+  sec->output_offset = sec->output_section->size;
   bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
+
+  /* If pc and symbol not in the same segment, add/sub segment alignment.
+     Fixme: if there are multiple readonly segments?  */
+  if (!(sym_sec->flags & SEC_READONLY))
+    {
+      if (symval > pc)
+	pc -= info->maxpagesize;
+      else if (symval < pc)
+	pc += info->maxpagesize;
+    }
+
   const uint32_t addi_d = 0x02c00000;
   const uint32_t pcaddi = 0x18000000;
 
@@ -3889,7 +3905,6 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
       || sec->sec_flg0
       || (sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
-      || elf_seg_map (info->output_bfd) == NULL
       || (info->disable_target_specific_optimizations
 	  && info->relax_pass == 0)
       /* The exp_seg_relro_adjust is enum phase_enum (0x4),
@@ -4009,14 +4024,15 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
 	  break;
 	case R_LARCH_PCALA_HI20:
 	  if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
-	    loongarch_relax_pcala_addi (abfd, sec, rel, symval, info, again);
+	    loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
+					info, again);
 	  break;
 	case R_LARCH_GOT_PC_HI20:
 	  if (local_got && 0 == info->relax_pass
 	      && (i + 4) <= sec->reloc_count)
 	    {
 	      if (loongarch_relax_pcala_ld (abfd, sec, rel))
-		loongarch_relax_pcala_addi (abfd, sec, rel, symval,
+		loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
 					    info, again);
 	    }
 	  break;
diff --git a/ld/emultempl/loongarchelf.em b/ld/emultempl/loongarchelf.em
index 4850feb8767..d81c99da48b 100644
--- a/ld/emultempl/loongarchelf.em
+++ b/ld/emultempl/loongarchelf.em
@@ -62,6 +62,24 @@ gld${EMULATION_NAME}_after_allocation (void)
 	}
     }
 
+  /* The program header size of executable file may increase.  */
+  if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
+      && !bfd_link_relocatable (&link_info))
+    {
+      if (lang_phdr_list == NULL)
+        elf_seg_map (link_info.output_bfd) = NULL;
+      if (!_bfd_elf_map_sections_to_segments (link_info.output_bfd,
+					      &link_info,
+					      NULL))
+        einfo (_("%F%P: map sections to segments failed: %E\n"));
+    }
+
+  /* Adjust program header size and .eh_frame_hdr size before
+     lang_relax_sections. Without it, the vma of data segment may increase.  */
+  lang_do_assignments (lang_allocating_phase_enum);
+  lang_reset_memory_regions ();
+  lang_size_sections (NULL, true);
+
   enum phase_enum *phase = &(expld.dataseg.phase);
   bfd_elf${ELFSIZE}_loongarch_set_data_segment_info (&link_info, (int *) phase);
   /* gld${EMULATION_NAME}_map_segments (need_layout); */
-- 
2.36.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v1 5/6] LoongArch: Modify link_info.relax_pass from 3 to 2
  2023-11-16  6:23 [PATCH v1 0/6] Fix some bugs of relaxation mengqinggang
                   ` (3 preceding siblings ...)
  2023-11-16  6:23 ` [PATCH v1 4/6] LoongArch: Remove "elf_seg_map (info->output_bfd) == NULL" relaxation condition mengqinggang
@ 2023-11-16  6:23 ` mengqinggang
  2023-11-16  6:23 ` [PATCH v1 6/6] LoongArch: Add more relaxation testcases mengqinggang
  5 siblings, 0 replies; 11+ messages in thread
From: mengqinggang @ 2023-11-16  6:23 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
	mengqinggang

The first pass handles R_LARCH_RELAX relocations, the second pass
handles R_LARCH_ALIGN relocations.
---
 bfd/elfnn-loongarch.c        | 2 +-
 ld/emultempl/loongarchelf.em | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index d331eefb8ac..9d0cfab5f36 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -4012,7 +4012,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
       switch (ELFNN_R_TYPE (rel->r_info))
 	{
 	case R_LARCH_ALIGN:
-	  if (2 == info->relax_pass)
+	  if (1 == info->relax_pass)
 	    loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
 	  break;
 	case R_LARCH_DELETE:
diff --git a/ld/emultempl/loongarchelf.em b/ld/emultempl/loongarchelf.em
index d81c99da48b..9974989489c 100644
--- a/ld/emultempl/loongarchelf.em
+++ b/ld/emultempl/loongarchelf.em
@@ -42,7 +42,7 @@ larch_elf_before_allocation (void)
 	ENABLE_RELAXATION;
     }
 
-  link_info.relax_pass = 3;
+  link_info.relax_pass = 2;
 }
 
 static void
-- 
2.36.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v1 6/6] LoongArch: Add more relaxation testcases
  2023-11-16  6:23 [PATCH v1 0/6] Fix some bugs of relaxation mengqinggang
                   ` (4 preceding siblings ...)
  2023-11-16  6:23 ` [PATCH v1 5/6] LoongArch: Modify link_info.relax_pass from 3 to 2 mengqinggang
@ 2023-11-16  6:23 ` mengqinggang
  2023-11-16  6:39   ` Fangrui Song
  5 siblings, 1 reply; 11+ messages in thread
From: mengqinggang @ 2023-11-16  6:23 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
	mengqinggang

1. .so relaxation testcase
2. ld --no-relax testcase
3. segment alignment testcase
---
 .../ld-loongarch-elf/relax-segment-max.s      | 13 +++
 .../ld-loongarch-elf/relax-segment-min.s      | 13 +++
 ld/testsuite/ld-loongarch-elf/relax-so.s      |  4 +
 ld/testsuite/ld-loongarch-elf/relax.exp       | 80 +++++++++++++++++--
 4 files changed, 105 insertions(+), 5 deletions(-)
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-segment-max.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-segment-min.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-so.s

diff --git a/ld/testsuite/ld-loongarch-elf/relax-segment-max.s b/ld/testsuite/ld-loongarch-elf/relax-segment-max.s
new file mode 100644
index 00000000000..417260fb880
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-segment-max.s
@@ -0,0 +1,13 @@
+# The .align may cause overflow because deleting nops.
+  .text		      # 0x120000000
+  .fill 0x4000
+  .align 3	      # 0x120004000
+  la.local $r12, .L1
+
+#  .fill 0x1f7ffc # max fill without overflow, .data address is 0x120200000
+#  .fill 0x1f8000 # min fill with overflow, .data address is 0x120204000
+  .fill 0x1fbff4 # max fill with overflow, .data address is 0x120204000
+
+  .data
+.L1:
+  .byte 2
diff --git a/ld/testsuite/ld-loongarch-elf/relax-segment-min.s b/ld/testsuite/ld-loongarch-elf/relax-segment-min.s
new file mode 100644
index 00000000000..14a541b97c8
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-segment-min.s
@@ -0,0 +1,13 @@
+# The .align may cause overflow because deleting nops.
+  .text		      # 0x120000000
+  .fill 0x4000
+  .align 3	      # 0x120004000
+  la.local $r12, .L1
+
+#  .fill 0x1f7ffc # max fill without overflow, .data address is 0x120200000
+  .fill 0x1f8000 # min fill with overflow, .data address is 0x120204000
+#  .fill 0x1fbff4 # max fill with overflow, .data address is 0x120204000
+
+  .data
+.L1:
+  .byte 2
diff --git a/ld/testsuite/ld-loongarch-elf/relax-so.s b/ld/testsuite/ld-loongarch-elf/relax-so.s
new file mode 100644
index 00000000000..01a404a8b47
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-so.s
@@ -0,0 +1,4 @@
+.text
+.align 2
+.L1:
+  la.local $r12, .L1
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index 7ff876d7914..426b72dac5d 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -22,7 +22,7 @@
 if [istarget loongarch64-*-*] {
 
   if [isbuild loongarch64-*-*] {
-    set testname "loongarch relax build"
+    set testname "loongarch relax .exe build"
     set pre_builds [list \
       [list \
 	"$testname" \
@@ -39,17 +39,87 @@ if [istarget loongarch64-*-*] {
     if [file exist "tmpdir/relax"] {
       set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax"]
       if { [ regexp ".*pcaddi.*pcaddi.*" $objdump_output] } {
-	pass "loongarch relax"
+	pass "loongarch relax .exe"
       } {
-	fail "loongarch relax"
+	fail "loongarch relax .exe"
       }
     }
+
+    set testname "loongarch ld --no-relax build"
+    set pre_builds [list \
+      [list \
+	"$testname" \
+	"-Wl,--no-relax" \
+	"" \
+	{relax.s} \
+	{} \
+	"norelax" \
+      ] \
+    ]
+
+    run_cc_link_tests $pre_builds
+
+    if [file exist "tmpdir/norelax"] {
+      set objdump_output [run_host_cmd "objdump" "-d tmpdir/norelax"]
+      if { [ regexp ".*pcaddi.*" $objdump_output] } {
+	fail "loongarch ld --no-relax"
+      } {
+	pass "loongarch ld --no-relax"
+      }
+    }
+
+    run_ld_link_tests \
+	[list \
+	    [list \
+		"loongarch relax .so build" \
+		"-shared -e 0x0" "" \
+		"" \
+		{relax-so.s} \
+		{} \
+		"relax-so" \
+	    ] \
+	]
+
+      if [file exist "tmpdir/relax-so"] {
+	set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-so"]
+	if { [ regexp ".*pcaddi.*" $objdump_output] } {
+	  pass "loongarch relax .so"
+	} {
+	  fail "loongarch relax .so"
+	}
+      }
+
+    # If symbol in data segment, offset need to sub segment align to prevent
+    # overflow.
+    run_ld_link_tests \
+	[list \
+	    [list \
+		"loongarch relax segment alignment min" \
+		"-e0 -Ttext 0x120000000 -pie" "" \
+		"" \
+		{relax-segment-min.s} \
+		{} \
+		"relax-segment-min" \
+	    ] \
+	]
+
+    run_ld_link_tests \
+	[list \
+	    [list \
+		"loongarch relax segment alignment max" \
+		"-e0 -Ttext 0x120000000 -pie" "" \
+		"" \
+		{relax-segment-max.s} \
+		{} \
+		"relax-segment-max" \
+	    ] \
+	]
   }
 
   run_ld_link_tests \
       [list \
 	  [list \
-	      "relax-align" \
+	      "loongarch relax-align" \
 	      "-e 0x0 -z relro" "" \
 	      "" \
 	      {relax-align.s} \
@@ -64,7 +134,7 @@ if [istarget loongarch64-*-*] {
   run_ld_link_tests \
       [list \
 	  [list \
-	      "uleb128" \
+	      "loongarch uleb128" \
 	      "-e 0x0" "" \
 	      "" \
 	      {uleb128.s} \
-- 
2.36.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v1 6/6] LoongArch: Add more relaxation testcases
  2023-11-16  6:23 ` [PATCH v1 6/6] LoongArch: Add more relaxation testcases mengqinggang
@ 2023-11-16  6:39   ` Fangrui Song
  0 siblings, 0 replies; 11+ messages in thread
From: Fangrui Song @ 2023-11-16  6:39 UTC (permalink / raw)
  To: mengqinggang
  Cc: binutils, xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray

On Wed, Nov 15, 2023 at 10:23 PM mengqinggang <mengqinggang@loongson.cn> wrote:
>
> 1. .so relaxation testcase
> 2. ld --no-relax testcase
> 3. segment alignment testcase
> ---
>  .../ld-loongarch-elf/relax-segment-max.s      | 13 +++
>  .../ld-loongarch-elf/relax-segment-min.s      | 13 +++
>  ld/testsuite/ld-loongarch-elf/relax-so.s      |  4 +
>  ld/testsuite/ld-loongarch-elf/relax.exp       | 80 +++++++++++++++++--
>  4 files changed, 105 insertions(+), 5 deletions(-)
>  create mode 100644 ld/testsuite/ld-loongarch-elf/relax-segment-max.s
>  create mode 100644 ld/testsuite/ld-loongarch-elf/relax-segment-min.s
>  create mode 100644 ld/testsuite/ld-loongarch-elf/relax-so.s
>
> diff --git a/ld/testsuite/ld-loongarch-elf/relax-segment-max.s b/ld/testsuite/ld-loongarch-elf/relax-segment-max.s
> new file mode 100644
> index 00000000000..417260fb880
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/relax-segment-max.s
> @@ -0,0 +1,13 @@
> +# The .align may cause overflow because deleting nops.
> +  .text                      # 0x120000000
> +  .fill 0x4000
> +  .align 3           # 0x120004000
> +  la.local $r12, .L1
> +
> +#  .fill 0x1f7ffc # max fill without overflow, .data address is 0x120200000
> +#  .fill 0x1f8000 # min fill with overflow, .data address is 0x120204000
> +  .fill 0x1fbff4 # max fill with overflow, .data address is 0x120204000
> +
> +  .data
> +.L1:
> +  .byte 2
> diff --git a/ld/testsuite/ld-loongarch-elf/relax-segment-min.s b/ld/testsuite/ld-loongarch-elf/relax-segment-min.s
> new file mode 100644
> index 00000000000..14a541b97c8
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/relax-segment-min.s
> @@ -0,0 +1,13 @@
> +# The .align may cause overflow because deleting nops.
> +  .text                      # 0x120000000
> +  .fill 0x4000
> +  .align 3           # 0x120004000
> +  la.local $r12, .L1
> +
> +#  .fill 0x1f7ffc # max fill without overflow, .data address is 0x120200000
> +  .fill 0x1f8000 # min fill with overflow, .data address is 0x120204000
> +#  .fill 0x1fbff4 # max fill with overflow, .data address is 0x120204000
> +
> +  .data
> +.L1:
> +  .byte 2

You may want something more complex.
When I implemented linker relaxation for lld, I put a lot of thoughts
into organizing the tests.
I have come up with

https://github.com/llvm/llvm-project/blob/main/lld/test/ELF/riscv-relax-call.s
https://github.com/llvm/llvm-project/blob/main/lld/test/ELF/riscv-relax-call2.s
https://github.com/llvm/llvm-project/blob/main/lld/test/ELF/riscv-relax-align.s

 .fill 0x4000 creates a lot of zeroes. I prefer output section addresses.

> diff --git a/ld/testsuite/ld-loongarch-elf/relax-so.s b/ld/testsuite/ld-loongarch-elf/relax-so.s
> new file mode 100644
> index 00000000000..01a404a8b47
> --- /dev/null
> +++ b/ld/testsuite/ld-loongarch-elf/relax-so.s
> @@ -0,0 +1,4 @@
> +.text
> +.align 2
> +.L1:
> +  la.local $r12, .L1
> diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
> index 7ff876d7914..426b72dac5d 100644
> --- a/ld/testsuite/ld-loongarch-elf/relax.exp
> +++ b/ld/testsuite/ld-loongarch-elf/relax.exp
> @@ -22,7 +22,7 @@
>  if [istarget loongarch64-*-*] {
>
>    if [isbuild loongarch64-*-*] {
> -    set testname "loongarch relax build"
> +    set testname "loongarch relax .exe build"
>      set pre_builds [list \
>        [list \
>         "$testname" \
> @@ -39,17 +39,87 @@ if [istarget loongarch64-*-*] {
>      if [file exist "tmpdir/relax"] {
>        set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax"]
>        if { [ regexp ".*pcaddi.*pcaddi.*" $objdump_output] } {
> -       pass "loongarch relax"
> +       pass "loongarch relax .exe"
>        } {
> -       fail "loongarch relax"
> +       fail "loongarch relax .exe"
>        }
>      }
> +
> +    set testname "loongarch ld --no-relax build"
> +    set pre_builds [list \
> +      [list \
> +       "$testname" \
> +       "-Wl,--no-relax" \
> +       "" \
> +       {relax.s} \
> +       {} \
> +       "norelax" \
> +      ] \
> +    ]
> +
> +    run_cc_link_tests $pre_builds
> +
> +    if [file exist "tmpdir/norelax"] {
> +      set objdump_output [run_host_cmd "objdump" "-d tmpdir/norelax"]
> +      if { [ regexp ".*pcaddi.*" $objdump_output] } {
> +       fail "loongarch ld --no-relax"
> +      } {
> +       pass "loongarch ld --no-relax"
> +      }
> +    }
> +
> +    run_ld_link_tests \
> +       [list \
> +           [list \
> +               "loongarch relax .so build" \
> +               "-shared -e 0x0" "" \
> +               "" \
> +               {relax-so.s} \
> +               {} \
> +               "relax-so" \
> +           ] \
> +       ]
> +
> +      if [file exist "tmpdir/relax-so"] {
> +       set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-so"]
> +       if { [ regexp ".*pcaddi.*" $objdump_output] } {
> +         pass "loongarch relax .so"
> +       } {
> +         fail "loongarch relax .so"
> +       }
> +      }
> +
> +    # If symbol in data segment, offset need to sub segment align to prevent
> +    # overflow.
> +    run_ld_link_tests \
> +       [list \
> +           [list \
> +               "loongarch relax segment alignment min" \
> +               "-e0 -Ttext 0x120000000 -pie" "" \
> +               "" \
> +               {relax-segment-min.s} \
> +               {} \
> +               "relax-segment-min" \
> +           ] \
> +       ]
> +
> +    run_ld_link_tests \
> +       [list \
> +           [list \
> +               "loongarch relax segment alignment max" \
> +               "-e0 -Ttext 0x120000000 -pie" "" \
> +               "" \
> +               {relax-segment-max.s} \
> +               {} \
> +               "relax-segment-max" \
> +           ] \
> +       ]
>    }
>
>    run_ld_link_tests \
>        [list \
>           [list \
> -             "relax-align" \
> +             "loongarch relax-align" \
>               "-e 0x0 -z relro" "" \
>               "" \
>               {relax-align.s} \
> @@ -64,7 +134,7 @@ if [istarget loongarch64-*-*] {
>    run_ld_link_tests \
>        [list \
>           [list \
> -             "uleb128" \
> +             "loongarch uleb128" \
>               "-e 0x0" "" \
>               "" \
>               {uleb128.s} \
> --
> 2.36.0
>

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v1 1/6] LoongArch: Fix ld --no-relax bug
  2023-11-16  6:23 ` [PATCH v1 1/6] LoongArch: Fix ld --no-relax bug mengqinggang
@ 2023-11-16  7:34   ` WANG Xuerui
  0 siblings, 0 replies; 11+ messages in thread
From: WANG Xuerui @ 2023-11-16  7:34 UTC (permalink / raw)
  To: mengqinggang, binutils
  Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray

On 11/16/23 14:23, mengqinggang wrote:
> When ld --no-relax, pcalau12i + ld.d still can be relaxed.

"When calling ld with --no-relax, ..."

Apart from the grammatical fix, is the "pcalau12i + ld.d pair still gets 
relaxed" behavior actually intended, or is it the broken behavior that's 
being fixed? Looking at the code it's not so evident so it's better to 
explain a bit.

> ---
>   bfd/elfnn-loongarch.c | 19 ++++++-------------
>   1 file changed, 6 insertions(+), 13 deletions(-)
>
> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
> index 18ad3cc91ca..1162cb35cd6 100644
> --- a/bfd/elfnn-loongarch.c
> +++ b/bfd/elfnn-loongarch.c
> @@ -3996,29 +3996,22 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
>   	    loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
>   	  break;
>   	case R_LARCH_DELETE:
> -	  if (info->relax_pass == 1)
> +	  if (1 == info->relax_pass)
>   	    {
>   	      loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info);
>   	      rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
>   	    }
>   	  break;
>   	case R_LARCH_PCALA_HI20:
> -	  if (info->relax_pass == 0)
> -	    {
> -	      if (i + 4 > sec->reloc_count)
> -		break;
> -	      loongarch_relax_pcala_addi (abfd, sec, rel, symval);
> -	    }
> +	  if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
> +	    loongarch_relax_pcala_addi (abfd, sec, rel, symval);
>   	  break;
>   	case R_LARCH_GOT_PC_HI20:
> -	  if (local_got)
> +	  if (local_got && 0 == info->relax_pass
> +	      && (i + 4) <= sec->reloc_count)
>   	    {
> -	      if (i + 4 > sec->reloc_count)
> -		break;
>   	      if (loongarch_relax_pcala_ld (abfd, sec, rel))
> -		{
> -		  loongarch_relax_pcala_addi (abfd, sec, rel, symval);
> -		}
> +		loongarch_relax_pcala_addi (abfd, sec, rel, symval);
>   	    }
>   	  break;
>   	default:

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v1 4/6] LoongArch: Remove "elf_seg_map (info->output_bfd) == NULL" relaxation condition
  2023-11-16  6:23 ` [PATCH v1 4/6] LoongArch: Remove "elf_seg_map (info->output_bfd) == NULL" relaxation condition mengqinggang
@ 2023-11-16  7:43   ` WANG Xuerui
  2023-11-16  9:38     ` mengqinggang
  0 siblings, 1 reply; 11+ messages in thread
From: WANG Xuerui @ 2023-11-16  7:43 UTC (permalink / raw)
  To: mengqinggang, binutils
  Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray

On 11/16/23 14:23, mengqinggang wrote:
> This condition cause .so(shared object) can't be relaxed.
"Previously the condition prevented shared objects from being relaxed."
> Without this condition, we need to update program header size and .eh_frame_hdr
> size before relaxation.
"To remove the limitation, we need to ..."
> ---
>   bfd/elfnn-loongarch.c        | 24 ++++++++++++++++++++----
>   ld/emultempl/loongarchelf.em | 18 ++++++++++++++++++
>   2 files changed, 38 insertions(+), 4 deletions(-)
>
> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
> index 7436a14441f..d331eefb8ac 100644
> --- a/bfd/elfnn-loongarch.c
> +++ b/bfd/elfnn-loongarch.c
> @@ -3738,7 +3738,7 @@ loongarch_relax_delete_bytes (bfd *abfd,
>   
>   /* Relax pcalau12i,addi.d => pcaddi.  */
>   static bool
> -loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
> +loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
>   		       Elf_Internal_Rela *rel_hi, bfd_vma symval,
>   		       struct bfd_link_info *info, bool *again)
>   {
> @@ -3747,7 +3747,23 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
>     uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
>     uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
>     uint32_t rd = pca & 0x1f;
> +
> +  /* Because previous sections' relax, output_offset may increase and need to
> +     be updated before relax. But it update after relax in
> +     size_input_section defaultly, so we manually updating here.  */

This is rather hard to understand...

"This section's output_offset may change after previous section(s) have 
been relaxed, so it needs to be updated beforehand. size_input_section 
already took care of updating it after relaxation, so we additionally 
update once here."

Does this sound okay?

> +  sec->output_offset = sec->output_section->size;
>     bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
> +
> +  /* If pc and symbol not in the same segment, add/sub segment alignment.
> +     Fixme: if there are multiple readonly segments?  */
Usually FIXME notes are spelled with all-caps to make it easier for the 
eyes and tools.
> +  if (!(sym_sec->flags & SEC_READONLY))
> +    {
> +      if (symval > pc)
> +	pc -= info->maxpagesize;
> +      else if (symval < pc)
> +	pc += info->maxpagesize;
> +    }
> +
>     const uint32_t addi_d = 0x02c00000;
>     const uint32_t pcaddi = 0x18000000;
>   
> @@ -3889,7 +3905,6 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
>         || sec->sec_flg0
>         || (sec->flags & SEC_RELOC) == 0
>         || sec->reloc_count == 0
> -      || elf_seg_map (info->output_bfd) == NULL
>         || (info->disable_target_specific_optimizations
>   	  && info->relax_pass == 0)
>         /* The exp_seg_relro_adjust is enum phase_enum (0x4),
> @@ -4009,14 +4024,15 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
>   	  break;
>   	case R_LARCH_PCALA_HI20:
>   	  if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
> -	    loongarch_relax_pcala_addi (abfd, sec, rel, symval, info, again);
> +	    loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
> +					info, again);
>   	  break;
>   	case R_LARCH_GOT_PC_HI20:
>   	  if (local_got && 0 == info->relax_pass
>   	      && (i + 4) <= sec->reloc_count)
>   	    {
>   	      if (loongarch_relax_pcala_ld (abfd, sec, rel))
> -		loongarch_relax_pcala_addi (abfd, sec, rel, symval,
> +		loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
>   					    info, again);
>   	    }
>   	  break;
> diff --git a/ld/emultempl/loongarchelf.em b/ld/emultempl/loongarchelf.em
> index 4850feb8767..d81c99da48b 100644
> --- a/ld/emultempl/loongarchelf.em
> +++ b/ld/emultempl/loongarchelf.em
> @@ -62,6 +62,24 @@ gld${EMULATION_NAME}_after_allocation (void)
>   	}
>       }
>   
> +  /* The program header size of executable file may increase.  */
> +  if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
> +      && !bfd_link_relocatable (&link_info))
> +    {
> +      if (lang_phdr_list == NULL)
> +        elf_seg_map (link_info.output_bfd) = NULL;
> +      if (!_bfd_elf_map_sections_to_segments (link_info.output_bfd,
> +					      &link_info,
> +					      NULL))
> +        einfo (_("%F%P: map sections to segments failed: %E\n"));
> +    }
> +
> +  /* Adjust program header size and .eh_frame_hdr size before
> +     lang_relax_sections. Without it, the vma of data segment may increase.  */
Out of curiosity (and unfamiliarity), is it only "increases" and no 
decreases?
> +  lang_do_assignments (lang_allocating_phase_enum);
> +  lang_reset_memory_regions ();
> +  lang_size_sections (NULL, true);
> +
>     enum phase_enum *phase = &(expld.dataseg.phase);
>     bfd_elf${ELFSIZE}_loongarch_set_data_segment_info (&link_info, (int *) phase);
>     /* gld${EMULATION_NAME}_map_segments (need_layout); */

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v1 4/6] LoongArch: Remove "elf_seg_map (info->output_bfd) == NULL" relaxation condition
  2023-11-16  7:43   ` WANG Xuerui
@ 2023-11-16  9:38     ` mengqinggang
  0 siblings, 0 replies; 11+ messages in thread
From: mengqinggang @ 2023-11-16  9:38 UTC (permalink / raw)
  To: WANG Xuerui, binutils; +Cc: xuchenghua, chenglulu, liuzhensong, xry111, maskray


在 2023/11/16 下午3:43, WANG Xuerui 写道:
> On 11/16/23 14:23, mengqinggang wrote:
>> This condition cause .so(shared object) can't be relaxed.
> "Previously the condition prevented shared objects from being relaxed."
>> Without this condition, we need to update program header size and 
>> .eh_frame_hdr
>> size before relaxation.
> "To remove the limitation, we need to ..."
>> ---
>>   bfd/elfnn-loongarch.c        | 24 ++++++++++++++++++++----
>>   ld/emultempl/loongarchelf.em | 18 ++++++++++++++++++
>>   2 files changed, 38 insertions(+), 4 deletions(-)
>>
>> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
>> index 7436a14441f..d331eefb8ac 100644
>> --- a/bfd/elfnn-loongarch.c
>> +++ b/bfd/elfnn-loongarch.c
>> @@ -3738,7 +3738,7 @@ loongarch_relax_delete_bytes (bfd *abfd,
>>     /* Relax pcalau12i,addi.d => pcaddi.  */
>>   static bool
>> -loongarch_relax_pcala_addi (bfd *abfd, asection *sec,
>> +loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection 
>> *sym_sec,
>>                  Elf_Internal_Rela *rel_hi, bfd_vma symval,
>>                  struct bfd_link_info *info, bool *again)
>>   {
>> @@ -3747,7 +3747,23 @@ loongarch_relax_pcala_addi (bfd *abfd, 
>> asection *sec,
>>     uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
>>     uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
>>     uint32_t rd = pca & 0x1f;
>> +
>> +  /* Because previous sections' relax, output_offset may increase 
>> and need to
>> +     be updated before relax. But it update after relax in
>> +     size_input_section defaultly, so we manually updating here.  */
>
> This is rather hard to understand...
>
> "This section's output_offset may change after previous section(s) 
> have been relaxed, so it needs to be updated beforehand. 
> size_input_section already took care of updating it after relaxation, 
> so we additionally update once here."
>
> Does this sound okay?
>
>> +  sec->output_offset = sec->output_section->size;
>>     bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
>> +
>> +  /* If pc and symbol not in the same segment, add/sub segment 
>> alignment.
>> +     Fixme: if there are multiple readonly segments?  */
> Usually FIXME notes are spelled with all-caps to make it easier for 
> the eyes and tools.
>> +  if (!(sym_sec->flags & SEC_READONLY))
>> +    {
>> +      if (symval > pc)
>> +    pc -= info->maxpagesize;
>> +      else if (symval < pc)
>> +    pc += info->maxpagesize;
>> +    }
>> +
>>     const uint32_t addi_d = 0x02c00000;
>>     const uint32_t pcaddi = 0x18000000;
>>   @@ -3889,7 +3905,6 @@ loongarch_elf_relax_section (bfd *abfd, 
>> asection *sec,
>>         || sec->sec_flg0
>>         || (sec->flags & SEC_RELOC) == 0
>>         || sec->reloc_count == 0
>> -      || elf_seg_map (info->output_bfd) == NULL
>>         || (info->disable_target_specific_optimizations
>>         && info->relax_pass == 0)
>>         /* The exp_seg_relro_adjust is enum phase_enum (0x4),
>> @@ -4009,14 +4024,15 @@ loongarch_elf_relax_section (bfd *abfd, 
>> asection *sec,
>>         break;
>>       case R_LARCH_PCALA_HI20:
>>         if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
>> -        loongarch_relax_pcala_addi (abfd, sec, rel, symval, info, 
>> again);
>> +        loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
>> +                    info, again);
>>         break;
>>       case R_LARCH_GOT_PC_HI20:
>>         if (local_got && 0 == info->relax_pass
>>             && (i + 4) <= sec->reloc_count)
>>           {
>>             if (loongarch_relax_pcala_ld (abfd, sec, rel))
>> -        loongarch_relax_pcala_addi (abfd, sec, rel, symval,
>> +        loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
>>                           info, again);
>>           }
>>         break;
>> diff --git a/ld/emultempl/loongarchelf.em b/ld/emultempl/loongarchelf.em
>> index 4850feb8767..d81c99da48b 100644
>> --- a/ld/emultempl/loongarchelf.em
>> +++ b/ld/emultempl/loongarchelf.em
>> @@ -62,6 +62,24 @@ gld${EMULATION_NAME}_after_allocation (void)
>>       }
>>       }
>>   +  /* The program header size of executable file may increase.  */
>> +  if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour
>> +      && !bfd_link_relocatable (&link_info))
>> +    {
>> +      if (lang_phdr_list == NULL)
>> +        elf_seg_map (link_info.output_bfd) = NULL;
>> +      if (!_bfd_elf_map_sections_to_segments (link_info.output_bfd,
>> +                          &link_info,
>> +                          NULL))
>> +        einfo (_("%F%P: map sections to segments failed: %E\n"));
>> +    }
>> +
>> +  /* Adjust program header size and .eh_frame_hdr size before
>> +     lang_relax_sections. Without it, the vma of data segment may 
>> increase.  */
> Out of curiosity (and unfamiliarity), is it only "increases" and no 
> decreases?


After relaxation, the vma of data segment may decreases. But before 
relaxation,
the vma of data segment should only increase due to the increase in the 
number of
segments and the determination of the .eh_frame_hdr section size.


>> +  lang_do_assignments (lang_allocating_phase_enum);
>> +  lang_reset_memory_regions ();
>> +  lang_size_sections (NULL, true);
>> +
>>     enum phase_enum *phase = &(expld.dataseg.phase);
>>     bfd_elf${ELFSIZE}_loongarch_set_data_segment_info (&link_info, 
>> (int *) phase);
>>     /* gld${EMULATION_NAME}_map_segments (need_layout); */


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2023-11-16  9:38 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-16  6:23 [PATCH v1 0/6] Fix some bugs of relaxation mengqinggang
2023-11-16  6:23 ` [PATCH v1 1/6] LoongArch: Fix ld --no-relax bug mengqinggang
2023-11-16  7:34   ` WANG Xuerui
2023-11-16  6:23 ` [PATCH v1 2/6] LoongArch: Directly delete relaxed instuctions in first relaxation pass mengqinggang
2023-11-16  6:23 ` [PATCH v1 3/6] LoongArch: Multiple relax_trip in one relax_pass mengqinggang
2023-11-16  6:23 ` [PATCH v1 4/6] LoongArch: Remove "elf_seg_map (info->output_bfd) == NULL" relaxation condition mengqinggang
2023-11-16  7:43   ` WANG Xuerui
2023-11-16  9:38     ` mengqinggang
2023-11-16  6:23 ` [PATCH v1 5/6] LoongArch: Modify link_info.relax_pass from 3 to 2 mengqinggang
2023-11-16  6:23 ` [PATCH v1 6/6] LoongArch: Add more relaxation testcases mengqinggang
2023-11-16  6:39   ` Fangrui Song

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).