!315 [sync] PR-312: LoongArch: backport master to 2.41

From: @openeuler-sync-bot 
Reviewed-by: @eastb233 
Signed-off-by: @eastb233
This commit is contained in:
openeuler-ci-bot 2024-11-07 02:37:59 +00:00 committed by Gitee
commit 3b7f67ac74
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
123 changed files with 32418 additions and 1 deletions

View File

@ -0,0 +1,599 @@
From 52fc0adff846e7fb01fd2995b5520e4194287489 Mon Sep 17 00:00:00 2001
From: Xin Wang <yw987194828@gmail.com>
Date: Fri, 6 Sep 2024 08:54:07 +0800
Subject: [PATCH 112/123] Add macros to get opcode of instructions approriately
LoongArch: Add macros to get opcode and register of instructions appropriately
Currently, we get opcode of an instruction by manipulate the binary with
it's mask, it's a bit of a pain. Now a macro is defined to do this and a
macro to get the RD and RJ registers which is applicable to most instructions
of LoongArch are added.
---
bfd/elfnn-loongarch.c | 62 +++---
gas/config/tc-loongarch.c | 36 +--
gas/testsuite/gas/loongarch/illegal-operand.l | 208 +++++++++---------
include/opcode/loongarch.h | 70 +++++-
4 files changed, 216 insertions(+), 160 deletions(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 30ac5555..770483cd 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -4064,7 +4064,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
/* For 2G jump, generate pcalau12i, jirl. */
/* If use jirl, turns to R_LARCH_B16. */
uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
- if ((insn & 0x4c000000) == 0x4c000000)
+ if (LARCH_INSN_JIRL(insn))
{
relocation &= 0xfff;
/* Signed extend. */
@@ -4704,7 +4704,7 @@ loongarch_tls_perform_trans (bfd *abfd, asection *sec,
pcalalau12i $a0,%desc_pc_hi20(var) =>
lu12i.w $a0,%le_hi20(var)
*/
- bfd_put (32, abfd, LARCH_LU12I_W | LARCH_RD_A0,
+ bfd_put (32, abfd, LARCH_OP_LU12I_W | LARCH_RD_A0,
contents + rel->r_offset);
rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_HI20);
}
@@ -4725,8 +4725,8 @@ loongarch_tls_perform_trans (bfd *abfd, asection *sec,
addi.d $a0,$a0,%desc_pc_lo12(var) =>
ori $a0,$a0,le_lo12(var)
*/
- insn = LARCH_ORI | LARCH_RD_RJ_A0;
- bfd_put (32, abfd, LARCH_ORI | LARCH_RD_RJ_A0,
+ insn = LARCH_OP_ORI | LARCH_RD_RJ_A0;
+ bfd_put (32, abfd, LARCH_OP_ORI | LARCH_RD_RJ_A0,
contents + rel->r_offset);
rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_LO12);
}
@@ -4736,7 +4736,7 @@ loongarch_tls_perform_trans (bfd *abfd, asection *sec,
addi.d $a0,$a0,%desc_pc_lo12(var) =>
ld.d $a0,$a0,%ie_pc_lo12(var)
*/
- bfd_put (32, abfd, LARCH_LD_D | LARCH_RD_RJ_A0,
+ bfd_put (32, abfd, LARCH_OP_LD_D | LARCH_RD_RJ_A0,
contents + rel->r_offset);
rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_IE_PC_LO12);
}
@@ -4763,7 +4763,7 @@ loongarch_tls_perform_trans (bfd *abfd, asection *sec,
lu12i.w $rd,%le_hi20(var)
*/
insn = bfd_getl32 (contents + rel->r_offset);
- bfd_put (32, abfd, LARCH_LU12I_W | (insn & 0x1f),
+ bfd_put (32, abfd, LARCH_OP_LU12I_W | LARCH_GET_RD(insn),
contents + rel->r_offset);
rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_HI20);
}
@@ -4777,7 +4777,7 @@ loongarch_tls_perform_trans (bfd *abfd, asection *sec,
ori $rd,$rj,le_lo12(var)
*/
insn = bfd_getl32 (contents + rel->r_offset);
- bfd_put (32, abfd, LARCH_ORI | (insn & 0x3ff),
+ bfd_put (32, abfd, LARCH_OP_ORI | (insn & 0x3ff),
contents + rel->r_offset);
rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_LO12);
}
@@ -4875,11 +4875,11 @@ loongarch_relax_tls_le (bfd *abfd, asection *sec,
/* Change rj to $tp. */
insn_rj = 0x2 << 5;
/* Get rd register. */
- insn_rd = insn & 0x1f;
+ insn_rd = LARCH_GET_RD(insn);
/* Write symbol offset. */
symval <<= 10;
/* Writes the modified instruction. */
- insn = insn & 0xffc00000;
+ insn = insn & LARCH_MK_ADDI_D;
insn = insn | symval | insn_rj | insn_rd;
bfd_put (32, abfd, insn, contents + rel->r_offset);
}
@@ -4894,7 +4894,7 @@ loongarch_relax_tls_le (bfd *abfd, asection *sec,
break;
case R_LARCH_TLS_LE_LO12:
- bfd_put (32, abfd, LARCH_ORI | (insn & 0x1f),
+ bfd_put (32, abfd, LARCH_OP_ORI | LARCH_GET_RD(insn),
contents + rel->r_offset);
break;
@@ -4940,7 +4940,7 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
Elf_Internal_Rela *rel_lo = rel_hi + 2;
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;
+ uint32_t rd = LARCH_GET_RD(pca);
/* This section's output_offset need to subtract the bytes of instructions
relaxed by the previous sections, so it needs to be updated beforehand.
@@ -4961,18 +4961,17 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
else if (symval < pc)
pc += (max_alignment > 4 ? max_alignment : 0);
- const uint32_t addi_d = 0x02c00000;
- const uint32_t pcaddi = 0x18000000;
+ const uint32_t pcaddi = LARCH_OP_PCADDI;
/* Is pcalau12i + addi.d insns? */
if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_PCALA_LO12)
|| (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
|| (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
|| (rel_hi->r_offset + 4 != rel_lo->r_offset)
- || ((add & addi_d) != addi_d)
+ || !LARCH_INSN_ADDI_D(add)
/* Is pcalau12i $rd + addi.d $rd,$rd? */
- || ((add & 0x1f) != rd)
- || (((add >> 5) & 0x1f) != rd)
+ || (LARCH_GET_RD(add) != rd)
+ || (LARCH_GET_RJ(add) != rd)
/* Can be relaxed to pcaddi? */
|| (symval & 0x3) /* 4 bytes align. */
|| ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
@@ -5005,7 +5004,7 @@ loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec,
{
bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
uint32_t jirl = bfd_get (32, abfd, contents + rel->r_offset + 4);
- uint32_t rd = jirl & 0x1f;
+ uint32_t rd = LARCH_GET_RD(jirl);
/* This section's output_offset need to subtract the bytes of instructions
relaxed by the previous sections, so it needs to be updated beforehand.
@@ -5026,11 +5025,10 @@ loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec,
else if (symval < pc)
pc += (max_alignment > 4 ? max_alignment : 0);
- const uint32_t jirl_opcode = 0x4c000000;
/* Is pcalau12i + addi.d insns? */
if ((ELFNN_R_TYPE ((rel + 1)->r_info) != R_LARCH_RELAX)
- || ((jirl & jirl_opcode) != jirl_opcode)
+ || !LARCH_INSN_JIRL(jirl)
|| ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xf8000000)
|| ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x7fffffc))
return false;
@@ -5038,8 +5036,8 @@ loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec,
/* Continue next relax trip. */
*again = true;
- const uint32_t bl = 0x54000000;
- const uint32_t b = 0x50000000;
+ const uint32_t bl = LARCH_OP_BL;
+ const uint32_t b = LARCH_OP_B;
if (rd)
bfd_put (32, abfd, bl, contents + rel->r_offset);
@@ -5062,17 +5060,16 @@ loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
Elf_Internal_Rela *rel_lo = rel_hi + 2;
uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
uint32_t ld = bfd_get (32, abfd, contents + rel_lo->r_offset);
- uint32_t rd = pca & 0x1f;
- const uint32_t ld_d = 0x28c00000;
- uint32_t addi_d = 0x02c00000;
+ uint32_t rd = LARCH_GET_RD(pca);
+ uint32_t addi_d = LARCH_OP_ADDI_D;
if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
|| (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
|| (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
|| (rel_hi->r_offset + 4 != rel_lo->r_offset)
- || ((ld & 0x1f) != rd)
- || (((ld >> 5) & 0x1f) != rd)
- || ((ld & ld_d) != ld_d))
+ || (LARCH_GET_RD(ld) != rd)
+ || (LARCH_GET_RJ(ld) != rd)
+ || !LARCH_INSN_LD_D(ld))
return false;
addi_d = addi_d | (rd << 5) | rd;
@@ -5165,7 +5162,7 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
Elf_Internal_Rela *rel_lo = rel_hi + 2;
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;
+ uint32_t rd = LARCH_GET_RD(pca);
/* This section's output_offset need to subtract the bytes of instructions
relaxed by the previous sections, so it needs to be updated beforehand.
@@ -5186,8 +5183,7 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
else if (symval < pc)
pc += (max_alignment > 4 ? max_alignment : 0);
- const uint32_t addi_d = 0x02c00000;
- const uint32_t pcaddi = 0x18000000;
+ const uint32_t pcaddi = LARCH_OP_PCADDI;
/* Is pcalau12i + addi.d insns? */
if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12
@@ -5195,10 +5191,10 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
|| (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
|| (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
|| (rel_hi->r_offset + 4 != rel_lo->r_offset)
- || ((add & addi_d) != addi_d)
+ || !LARCH_INSN_ADDI_D(add)
/* Is pcalau12i $rd + addi.d $rd,$rd? */
- || ((add & 0x1f) != rd)
- || (((add >> 5) & 0x1f) != rd)
+ || (LARCH_GET_RD(add) != rd)
+ || (LARCH_GET_RJ(add) != rd)
/* Can be relaxed to pcaddi? */
|| (symval & 0x3) /* 4 bytes align. */
|| ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 16355cac..046e198f 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -1078,34 +1078,34 @@ check_this_insn_before_appending (struct loongarch_cl_insn *ip)
ip->reloc_info[ip->reloc_num].value = const_0;
ip->reloc_num++;
}
- else if (ip->insn->mask == 0xffff8000
- /* amcas.b rd, rk, rj */
- && ((ip->insn_bin & 0xfff80000) == 0x38580000
- /* amswap.w rd, rk, rj */
- || (ip->insn_bin & 0xfff00000) == 0x38600000
- /* ammax_db.wu rd, rk, rj */
- || (ip->insn_bin & 0xffff0000) == 0x38700000
- /* ammin_db.wu rd, rk, rj */
- || (ip->insn_bin & 0xffff0000) == 0x38710000))
+ /* check all atomic memory insns */
+ else if (ip->insn->mask == LARCH_MK_ATOMIC_MEM
+ && LARCH_INSN_ATOMIC_MEM(ip->insn_bin))
{
/* For AMO insn amswap.[wd], amadd.[wd], etc. */
if (ip->args[0] != 0
&& (ip->args[0] == ip->args[1] || ip->args[0] == ip->args[2]))
- as_bad (_("automic memory operations insns require rd != rj"
+ as_bad (_("atomic memory operations insns require rd != rj"
" && rd != rk when rd isn't r0"));
}
- else if ((ip->insn->mask == 0xffe08000
- /* bstrins.w rd, rj, msbw, lsbw */
- && (ip->insn_bin & 0xffe00000) == 0x00600000)
- || (ip->insn->mask == 0xffc00000
- /* bstrins.d rd, rj, msbd, lsbd */
- && (ip->insn_bin & 0xff800000) == 0x00800000))
+ else if ((ip->insn->mask == LARCH_MK_BSTRINS_W
+ /* bstr(ins|pick).w rd, rj, msbw, lsbw */
+ && (LARCH_INSN_BSTRINS_W(ip->insn_bin)
+ || LARCH_INSN_BSTRPICK_W(ip->insn_bin)))
+ || (ip->insn->mask == LARCH_MK_BSTRINS_D
+ /* bstr(ins|pick).d rd, rj, msbd, lsbd */
+ && (LARCH_INSN_BSTRINS_D(ip->insn_bin)
+ || LARCH_INSN_BSTRPICK_D(ip->insn_bin))))
{
/* For bstr(ins|pick).[wd]. */
if (ip->args[2] < ip->args[3])
as_bad (_("bstr(ins|pick).[wd] require msbd >= lsbd"));
}
- else if (ip->insn->mask != 0 && (ip->insn_bin & 0xfe0003c0) == 0x04000000
+ else if (ip->insn->mask != 0
+ && (LARCH_INSN_CSRXCHG(ip->insn_bin)
+ || LARCH_INSN_GCSRXCHG(ip->insn_bin))
+ && (LARCH_GET_RJ(ip->insn_bin) == 0
+ || LARCH_GET_RJ(ip->insn_bin) == 1)
/* csrxchg rd, rj, csr_num */
&& (strcmp ("csrxchg", ip->name) == 0
|| strcmp ("gcsrxchg", ip->name) == 0))
@@ -2207,7 +2207,7 @@ loongarch_convert_frag_branch (fragS *fragp)
case RELAX_BRANCH_26:
insn = bfd_getl32 (buf);
/* Invert the branch condition. */
- if (LARCH_FLOAT_BRANCH == (insn & LARCH_BRANCH_OPCODE_MASK))
+ if (LARCH_INSN_FLOAT_BRANCH(insn))
insn ^= LARCH_FLOAT_BRANCH_INVERT_BIT;
else
insn ^= LARCH_BRANCH_INVERT_BIT;
diff --git a/gas/testsuite/gas/loongarch/illegal-operand.l b/gas/testsuite/gas/loongarch/illegal-operand.l
index dddc6d6f..33e859c7 100644
--- a/gas/testsuite/gas/loongarch/illegal-operand.l
+++ b/gas/testsuite/gas/loongarch/illegal-operand.l
@@ -1,108 +1,108 @@
.*: Assembler messages:
-.*:2: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:3: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:4: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:5: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:6: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:7: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:8: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:9: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:10: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:11: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:12: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:13: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:14: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:15: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:16: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:17: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:18: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:19: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:20: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:21: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:22: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:23: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:24: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:25: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:26: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:27: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:28: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:29: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:30: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:31: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:32: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:33: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:34: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:35: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:36: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:37: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:38: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:39: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:40: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:41: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:42: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:43: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:44: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:45: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:46: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:47: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:48: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:49: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:50: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:51: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:52: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:53: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:54: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:55: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:56: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:57: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:58: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:59: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:60: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:61: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:62: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:63: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:64: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:65: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:66: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:67: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:68: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:69: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:70: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:71: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:72: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:73: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:74: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:75: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:76: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:77: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:78: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:79: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:80: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:81: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:82: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:83: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:84: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:85: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:86: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:87: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:88: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:89: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:90: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:91: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:92: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:93: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:94: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:95: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:96: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:97: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:98: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:99: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:100: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:101: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:102: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:103: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:104: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
-.*:105: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:2: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:3: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:4: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:5: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:6: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:7: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:8: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:9: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:10: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:11: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:12: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:13: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:14: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:15: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:16: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:17: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:18: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:19: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:20: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:21: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:22: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:23: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:24: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:25: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:26: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:27: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:28: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:29: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:30: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:31: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:32: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:33: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:34: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:35: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:36: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:37: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:38: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:39: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:40: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:41: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:42: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:43: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:44: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:45: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:46: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:47: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:48: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:49: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:50: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:51: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:52: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:53: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:54: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:55: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:56: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:57: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:58: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:59: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:60: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:61: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:62: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:63: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:64: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:65: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:66: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:67: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:68: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:69: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:70: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:71: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:72: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:73: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:74: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:75: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:76: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:77: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:78: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:79: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:80: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:81: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:82: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:83: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:84: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:85: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:86: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:87: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:88: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:89: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:90: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:91: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:92: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:93: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:94: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:95: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:96: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:97: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:98: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:99: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:100: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:101: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:102: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:103: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:104: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:105: Error: atomic memory operations insns require rd != rj && rd != rk when rd isn't r0
.*:108: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
.*:109: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
.*:110: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
index 024ba99c..1dbc16fc 100644
--- a/include/opcode/loongarch.h
+++ b/include/opcode/loongarch.h
@@ -31,22 +31,82 @@ extern "C"
#define LARCH_NOP 0x03400000
#define LARCH_B 0x50000000
/* BCEQZ/BCNEZ. */
- #define LARCH_FLOAT_BRANCH 0x48000000
- #define LARCH_BRANCH_OPCODE_MASK 0xfc000000
#define LARCH_BRANCH_INVERT_BIT 0x04000000
#define LARCH_FLOAT_BRANCH_INVERT_BIT 0x00000100
+ #define LARCH_MK_ADDI_D 0xffc00000
+ #define LARCH_OP_ADDI_D 0x02c00000
+ #define LARCH_MK_PCADDI 0xfe000000
+ #define LARCH_OP_PCADDI 0x18000000
+ #define LARCH_MK_B 0xfc000000
+ #define LARCH_OP_B 0x50000000
+ #define LARCH_MK_BL 0xfc000000
+ #define LARCH_OP_BL 0x54000000
+ #define LARCH_MK_ORI 0xffc00000
+ #define LARCH_OP_ORI 0x03800000
+ #define LARCH_MK_LU12I_W 0xfe000000
+ #define LARCH_OP_LU12I_W 0x14000000
+ #define LARCH_MK_LD_D 0xffc00000
+ #define LARCH_OP_LD_D 0x28c00000
+ #define LARCH_MK_JIRL 0xfc000000
+ #define LARCH_OP_JIRL 0x4c000000
+ #define LARCH_MK_BCEQZ 0xfc000300
+ #define LARCH_OP_BCEQZ 0x48000000
+ #define LARCH_MK_BCNEZ 0xfc000300
+ #define LARCH_OP_BCNEZ 0x48000100
+ #define LARCH_MK_ATOMIC_MEM 0xffff8000
+ #define LARCH_MK_BSTRINS_W 0xffe08000
+ #define LARCH_OP_BSTRINS_W 0x00600000
+ #define LARCH_MK_BSTRPICK_W 0xffe08000
+ #define LARCH_OP_BSTRPICK_W 0x00608000
+ #define LARCH_MK_BSTRINS_D 0xffc00000
+ #define LARCH_OP_BSTRINS_D 0x00800000
+ #define LARCH_MK_BSTRPICK_D 0xffc00000
+ #define LARCH_OP_BSTRPICK_D 0x00c00000
+ #define LARCH_MK_CSRRD 0xff0003e0
+ #define LARCH_OP_CSRRD 0x04000000
+ #define LARCH_MK_CSRWR 0xff0003e0
+ #define LARCH_OP_CSRWR 0x04000020
+ #define LARCH_MK_CSRXCHG 0xff000000
+ #define LARCH_OP_CSRXCHG 0x04000000
+ #define LARCH_MK_GCSRXCHG 0xff000000
+ #define LARCH_OP_GCSRXCHG 0x05000000
+
+ #define LARCH_INSN_OPS(insn, op) ((insn & LARCH_MK_##op) == LARCH_OP_##op)
+ #define LARCH_INSN_ADDI_D(insn) LARCH_INSN_OPS((insn), ADDI_D)
+ #define LARCH_INSN_PCADDI(insn) LARCH_INSN_OPS((insn), PCADDI)
+ #define LARCH_INSN_B(insn) LARCH_INSN_OPS((insn), B)
+ #define LARCH_INSN_BL(insn) LARCH_INSN_OPS((insn), BL)
+ #define LARCH_INSN_ORI(insn) LARCH_INSN_OPS((insn), ORI)
+ #define LARCH_INSN_LU12I_W(insn) LARCH_INSN_OPS((insn), LU12I_W)
+ #define LARCH_INSN_LD_D(insn) LARCH_INSN_OPS((insn), LD_D)
+ #define LARCH_INSN_JIRL(insn) LARCH_INSN_OPS((insn), JIRL)
+ #define LARCH_INSN_BCEQZ(insn) LARCH_INSN_OPS((insn), BCEQZ)
+ #define LARCH_INSN_BCNEZ(insn) LARCH_INSN_OPS((insn), BCNEZ)
+ #define LARCH_INSN_FLOAT_BRANCH(insn) (LARCH_INSN_BCEQZ(insn) || LARCH_INSN_BCNEZ(insn))
+ #define LARCH_INSN_BSTRINS_W(insn) LARCH_INSN_OPS((insn), BSTRINS_W)
+ #define LARCH_INSN_BSTRPICK_W(insn) LARCH_INSN_OPS((insn), BSTRPICK_W)
+ #define LARCH_INSN_BSTRINS_D(insn) LARCH_INSN_OPS((insn), BSTRINS_D)
+ #define LARCH_INSN_BSTRPICK_D(insn) LARCH_INSN_OPS((insn), BSTRPICK_D)
+ #define LARCH_INSN_CSRXCHG(insn) LARCH_INSN_OPS((insn), CSRXCHG)
+ #define LARCH_INSN_GCSRXCHG(insn) LARCH_INSN_OPS((insn), GCSRXCHG)
+
+ #define LARCH_INSN_ATOMIC_MEM(insn) \
+ ((insn & 0xfff80000) == 0x38580000 \
+ || (insn & 0xfff00000) == 0x38600000 \
+ || (insn & 0xffff0000) == 0x38700000 \
+ || (insn & 0xffff0000) == 0x38710000)
+
#define ENCODE_BRANCH16_IMM(x) (((x) >> 2) << 10)
#define OUT_OF_RANGE(value, bits, align) \
((value) < (-(1 << ((bits) - 1) << align)) \
|| (value) > ((((1 << ((bits) - 1)) - 1) << align)))
- #define LARCH_LU12I_W 0x14000000
- #define LARCH_ORI 0x03800000
- #define LARCH_LD_D 0x28c00000
#define LARCH_RD_A0 0x04
#define LARCH_RD_RJ_A0 0x084
+ #define LARCH_GET_RD(insn) (insn & 0x1f)
+ #define LARCH_GET_RJ(insn) ((insn >> 5) & 0x1f)
typedef uint32_t insn_t;
--
2.33.0

View File

@ -0,0 +1,156 @@
From 6a9c6951245b9b344ebb7ababd1e9f8192d8eccd Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Mon, 30 Oct 2023 17:07:08 +0800
Subject: [PATCH 017/123] Add support for ilp32 register alias.
---
gas/config/tc-loongarch.c | 41 +++++++++++++++++---------------------
include/opcode/loongarch.h | 8 ++++----
opcodes/loongarch-dis.c | 4 ++--
opcodes/loongarch-opc.c | 8 ++++----
4 files changed, 28 insertions(+), 33 deletions(-)
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 49c70bf1..59232832 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -303,6 +303,15 @@ loongarch_after_parse_args ()
for (i = 0; i < ARRAY_SIZE (loongarch_r_normal_name); i++)
str_hash_insert (r_htab, loongarch_r_normal_name[i], (void *) (i + 1), 0);
+ /* Init ilp32/lp64 registers alias. */
+ r_abi_names = loongarch_r_alias;
+ for (i = 0; i < ARRAY_SIZE (loongarch_r_alias); i++)
+ str_hash_insert (r_htab, loongarch_r_alias[i], (void *) (i + 1),
+ 0);
+ for (i = 0; i < ARRAY_SIZE (loongarch_r_alias_deprecated); i++)
+ str_hash_insert (r_deprecated_htab, loongarch_r_alias_deprecated[i],
+ (void *) (i + 1), 0);
+
if (!cr_htab)
cr_htab = str_htab_create (), str_hash_insert (cr_htab, "", 0, 0);
@@ -323,6 +332,15 @@ loongarch_after_parse_args ()
str_hash_insert (f_htab, loongarch_f_normal_name[i], (void *) (i + 1),
0);
+ /* Init float-ilp32/lp64 registers alias. */
+ f_abi_names = loongarch_f_alias;
+ for (i = 0; i < ARRAY_SIZE (loongarch_f_alias); i++)
+ str_hash_insert (f_htab, loongarch_f_alias[i],
+ (void *) (i + 1), 0);
+ for (i = 0; i < ARRAY_SIZE (loongarch_f_alias_deprecated); i++)
+ str_hash_insert (f_deprecated_htab, loongarch_f_alias_deprecated[i],
+ (void *) (i + 1), 0);
+
if (!fc_htab)
fc_htab = str_htab_create (), str_hash_insert (fc_htab, "", 0, 0);
@@ -366,29 +384,6 @@ loongarch_after_parse_args ()
0);
}
- /* Init lp64 registers alias. */
- if (LARCH_opts.ase_lp64)
- {
- r_abi_names = loongarch_r_lp64_name;
- for (i = 0; i < ARRAY_SIZE (loongarch_r_lp64_name); i++)
- str_hash_insert (r_htab, loongarch_r_lp64_name[i], (void *) (i + 1),
- 0);
- for (i = 0; i < ARRAY_SIZE (loongarch_r_lp64_name_deprecated); i++)
- str_hash_insert (r_deprecated_htab, loongarch_r_lp64_name_deprecated[i],
- (void *) (i + 1), 0);
- }
-
- /* Init float-lp64 registers alias */
- if ((LARCH_opts.ase_sf || LARCH_opts.ase_df) && LARCH_opts.ase_lp64)
- {
- f_abi_names = loongarch_f_lp64_name;
- for (i = 0; i < ARRAY_SIZE (loongarch_f_lp64_name); i++)
- str_hash_insert (f_htab, loongarch_f_lp64_name[i],
- (void *) (i + 1), 0);
- for (i = 0; i < ARRAY_SIZE (loongarch_f_lp64_name_deprecated); i++)
- str_hash_insert (f_deprecated_htab, loongarch_f_lp64_name_deprecated[i],
- (void *) (i + 1), 0);
- }
}
const char *
diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
index f358ff42..da936f79 100644
--- a/include/opcode/loongarch.h
+++ b/include/opcode/loongarch.h
@@ -189,11 +189,11 @@ dec2 : [1-9][0-9]?
extern void loongarch_eliminate_adjacent_repeat_char (char *dest, char c);
extern const char *const loongarch_r_normal_name[32];
- extern const char *const loongarch_r_lp64_name[32];
- extern const char *const loongarch_r_lp64_name_deprecated[32];
+ extern const char *const loongarch_r_alias[32];
+ extern const char *const loongarch_r_alias_deprecated[32];
extern const char *const loongarch_f_normal_name[32];
- extern const char *const loongarch_f_lp64_name[32];
- extern const char *const loongarch_f_lp64_name_deprecated[32];
+ extern const char *const loongarch_f_alias[32];
+ extern const char *const loongarch_f_alias_deprecated[32];
extern const char *const loongarch_fc_normal_name[4];
extern const char *const loongarch_fc_numeric_name[4];
extern const char *const loongarch_c_normal_name[8];
diff --git a/opcodes/loongarch-dis.c b/opcodes/loongarch-dis.c
index 1e711f27..969ea28f 100644
--- a/opcodes/loongarch-dis.c
+++ b/opcodes/loongarch-dis.c
@@ -82,8 +82,8 @@ set_default_loongarch_dis_options (void)
LARCH_opts.ase_lvz = 1;
LARCH_opts.ase_lbt = 1;
- loongarch_r_disname = loongarch_r_lp64_name;
- loongarch_f_disname = loongarch_f_lp64_name;
+ loongarch_r_disname = loongarch_r_alias;
+ loongarch_f_disname = loongarch_f_alias;
loongarch_fc_disname = loongarch_fc_normal_name;
loongarch_c_disname = loongarch_c_normal_name;
loongarch_cr_disname = loongarch_cr_normal_name;
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index 5cd1411a..15c7da63 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -41,7 +41,7 @@ const char *const loongarch_r_normal_name[32] =
"$r24", "$r25", "$r26", "$r27", "$r28", "$r29", "$r30", "$r31",
};
-const char *const loongarch_r_lp64_name[32] =
+const char *const loongarch_r_alias[32] =
{
"$zero", "$ra", "$tp", "$sp", "$a0", "$a1", "$a2", "$a3",
"$a4", "$a5", "$a6", "$a7", "$t0", "$t1", "$t2", "$t3",
@@ -49,7 +49,7 @@ const char *const loongarch_r_lp64_name[32] =
"$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7", "$s8",
};
-const char *const loongarch_r_lp64_name_deprecated[32] =
+const char *const loongarch_r_alias_deprecated[32] =
{
"", "", "", "", "$v0", "$v1", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "$x", "", "", "", "", "", "", "", "", "", "",
@@ -63,7 +63,7 @@ const char *const loongarch_f_normal_name[32] =
"$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
};
-const char *const loongarch_f_lp64_name[32] =
+const char *const loongarch_f_alias[32] =
{
"$fa0", "$fa1", "$fa2", "$fa3", "$fa4", "$fa5", "$fa6", "$fa7",
"$ft0", "$ft1", "$ft2", "$ft3", "$ft4", "$ft5", "$ft6", "$ft7",
@@ -71,7 +71,7 @@ const char *const loongarch_f_lp64_name[32] =
"$fs0", "$fs1", "$fs2", "$fs3", "$fs4", "$fs5", "$fs6", "$fs7",
};
-const char *const loongarch_f_lp64_name_deprecated[32] =
+const char *const loongarch_f_alias_deprecated[32] =
{
"$fv0", "$fv1", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
--
2.33.0

View File

@ -0,0 +1,446 @@
From 91fcca79e66c426791c9055156644e96024e6599 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Mon, 18 Sep 2023 18:00:21 +0800
Subject: [PATCH 010/123] Add support for "pcaddi rd, symbol"
Add a macro pcaddi instruction to support "pcaddi rd, symbol".
pcaddi has a 20-bit signed immediate, it can address a +/- 2MB pc relative
address, and the address should be 4-byte aligned.
---
bfd/elfxx-loongarch.c | 4 +-
gas/testsuite/gas/loongarch/imm_ins.d | 137 ++++++++++++-----------
gas/testsuite/gas/loongarch/imm_ins_32.d | 91 +++++++--------
gas/testsuite/gas/loongarch/imm_op.d | 82 +++++++-------
gas/testsuite/gas/loongarch/imm_op.s | 2 +-
gas/testsuite/gas/loongarch/pcaddi.d | 13 +++
gas/testsuite/gas/loongarch/pcaddi.s | 4 +
opcodes/loongarch-opc.c | 2 +-
8 files changed, 177 insertions(+), 158 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/pcaddi.d
create mode 100644 gas/testsuite/gas/loongarch/pcaddi.s
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 16a2b2fc..fd9507ce 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -1415,7 +1415,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
NULL, /* adjust_reloc_bits. */
NULL), /* larch_reloc_type_name. */
- /* pcala_hi20 + pcala_lo12 relaxed to pcrel20_s2. */
+ /* For pcaddi and pcala_hi20 + pcala_lo12 can relax to pcrel_20. */
LOONGARCH_HOWTO (R_LARCH_PCREL20_S2, /* type (103). */
2, /* rightshift. */
4, /* size. */
@@ -1431,7 +1431,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
false, /* pcrel_offset. */
BFD_RELOC_LARCH_PCREL20_S2, /* bfd_reloc_code_real_type. */
reloc_sign_bits, /* adjust_reloc_bits. */
- NULL), /* larch_reloc_type_name. */
+ "pcrel_20"), /* larch_reloc_type_name. */
/* Canonical Frame Address. */
LOONGARCH_HOWTO (R_LARCH_CFA, /* type (104). */
diff --git a/gas/testsuite/gas/loongarch/imm_ins.d b/gas/testsuite/gas/loongarch/imm_ins.d
index f00110cd..b54df873 100644
--- a/gas/testsuite/gas/loongarch/imm_ins.d
+++ b/gas/testsuite/gas/loongarch/imm_ins.d
@@ -7,74 +7,75 @@
Disassembly of section .text:
-00000000.* <.text>:
-[ ]+0:[ ]+03848c0c[ ]+li.w[ ]+\$t0,[ ]+0x123
-[ ]+4:[ ]+15ffe00d[ ]+lu12i.w[ ]+\$t1,[ ]+-256
-[ ]+8:[ ]+16001fed[ ]+lu32i.d[ ]+\$t1,[ ]+255
-[ ]+c:[ ]+02bffc0e[ ]+li.w[ ]+\$t2,[ ]+-1
-[ ]+10:[ ]+1601ffee[ ]+lu32i.d[ ]+\$t2,[ ]+4095
-[ ]+14:[ ]+0004b58b[ ]+alsl.w[ ]+\$a7,[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+18:[ ]+0006b58b[ ]+alsl.wu[ ]+\$a7,[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+1c:[ ]+0009358b[ ]+bytepick.w[ ]+\$a7,[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+20:[ ]+000d358b[ ]+bytepick.d[ ]+\$a7,[ ]+\$t0,[ ]+\$t1,[ ]+0x2
+[ ]*0000000000000000 <.text>:
+[ ]+0:[ ]+03848c0c[ ]+li.w[ ]+\$t0, 0x123
+[ ]+4:[ ]+15ffe00d[ ]+lu12i.w[ ]+\$t1, -256
+[ ]+8:[ ]+16001fed[ ]+lu32i.d[ ]+\$t1, 255
+[ ]+c:[ ]+02bffc0e[ ]+li.w[ ]+\$t2, -1
+[ ]+10:[ ]+1601ffee[ ]+lu32i.d[ ]+\$t2, 4095
+[ ]+14:[ ]+0004b58b[ ]+alsl.w[ ]+\$a7, \$t0, \$t1, 0x2
+[ ]+18:[ ]+0006b58b[ ]+alsl.wu[ ]+\$a7, \$t0, \$t1, 0x2
+[ ]+1c:[ ]+0009358b[ ]+bytepick.w[ ]+\$a7, \$t0, \$t1, 0x2
+[ ]+20:[ ]+000d358b[ ]+bytepick.d[ ]+\$a7, \$t0, \$t1, 0x2
[ ]+24:[ ]+002a0002[ ]+break[ ]+0x2
[ ]+28:[ ]+002a8002[ ]+dbcl[ ]+0x2
[ ]+2c:[ ]+002b0002[ ]+syscall[ ]+0x2
-[ ]+30:[ ]+002cb58b[ ]+alsl.d[ ]+\$a7,[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+34:[ ]+0040898b[ ]+slli.w[ ]+\$a7,[ ]+\$t0,[ ]+0x2
-[ ]+38:[ ]+0041098b[ ]+slli.d[ ]+\$a7,[ ]+\$t0,[ ]+0x2
-[ ]+3c:[ ]+0044898b[ ]+srli.w[ ]+\$a7,[ ]+\$t0,[ ]+0x2
-[ ]+40:[ ]+004509ac[ ]+srli.d[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+44:[ ]+004889ac[ ]+srai.w[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+48:[ ]+004909ac[ ]+srai.d[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+4c:[ ]+006209ac[ ]+bstrins.w[ ]+\$t0,[ ]+\$t1,[ ]+0x2,[ ]+0x2
-[ ]+50:[ ]+008209ac[ ]+bstrins.d[ ]+\$t0,[ ]+\$t1,[ ]+0x2,[ ]+0x2
-[ ]+54:[ ]+00c209ac[ ]+bstrpick.d[ ]+\$t0,[ ]+\$t1,[ ]+0x2,[ ]+0x2
-[ ]+58:[ ]+00c209ac[ ]+bstrpick.d[ ]+\$t0,[ ]+\$t1,[ ]+0x2,[ ]+0x2
-[ ]+5c:[ ]+02048dac[ ]+slti[ ]+\$t0,[ ]+\$t1,[ ]+291
-[ ]+60:[ ]+02448dac[ ]+sltui[ ]+\$t0,[ ]+\$t1,[ ]+291
-[ ]+64:[ ]+02848dac[ ]+addi.w[ ]+\$t0,[ ]+\$t1,[ ]+291
-[ ]+68:[ ]+02c48dac[ ]+addi.d[ ]+\$t0,[ ]+\$t1,[ ]+291
-[ ]+6c:[ ]+03048dac[ ]+lu52i.d[ ]+\$t0,[ ]+\$t1,[ ]+291
-[ ]+70:[ ]+034009ac[ ]+andi[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+74:[ ]+038009ac[ ]+ori[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+78:[ ]+03c009ac[ ]+xori[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+7c:[ ]+100009ac[ ]+addu16i.d[ ]+\$t0,[ ]+\$t1,[ ]+2
-[ ]+80:[ ]+1400246c[ ]+lu12i.w[ ]+\$t0,[ ]+291
-[ ]+84:[ ]+1600246c[ ]+lu32i.d[ ]+\$t0,[ ]+291
-[ ]+88:[ ]+1800246c[ ]+pcaddi[ ]+\$t0,[ ]+291
-[ ]+8c:[ ]+1a00246c[ ]+pcalau12i[ ]+\$t0,[ ]+291
-[ ]+90:[ ]+1c00246c[ ]+pcaddu12i[ ]+\$t0,[ ]+291
-[ ]+94:[ ]+1e00246c[ ]+pcaddu18i[ ]+\$t0,[ ]+291
-[ ]+98:[ ]+04048c0c[ ]+csrrd[ ]+\$t0,[ ]+0x123
-[ ]+9c:[ ]+04048c2c[ ]+csrwr[ ]+\$t0,[ ]+0x123
-[ ]+a0:[ ]+040009ac[ ]+csrxchg[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+a4:[ ]+060009a2[ ]+cacop[ ]+0x2,[ ]+\$t1,[ ]+2
-[ ]+a8:[ ]+064009ac[ ]+lddir[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+ac:[ ]+06440980[ ]+ldpte[ ]+\$t0,[ ]+0x2
-[ ]+b0:[ ]+0649b9a2[ ]+invtlb[ ]+0x2,[ ]+\$t1,[ ]+\$t2
-[ ]+b4:[ ]+200101ac[ ]+ll.w[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+b8:[ ]+210101ac[ ]+sc.w[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+bc:[ ]+220101ac[ ]+ll.d[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+c0:[ ]+230101ac[ ]+sc.d[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+c4:[ ]+240101ac[ ]+ldptr.w[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+c8:[ ]+250101ac[ ]+stptr.w[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+cc:[ ]+260101ac[ ]+ldptr.d[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+d0:[ ]+270101ac[ ]+stptr.d[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+d4:[ ]+280401ac[ ]+ld.b[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+d8:[ ]+284401ac[ ]+ld.h[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+dc:[ ]+288401ac[ ]+ld.w[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+e0:[ ]+28c401ac[ ]+ld.d[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+e4:[ ]+290401ac[ ]+st.b[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+e8:[ ]+294401ac[ ]+st.h[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+ec:[ ]+298401ac[ ]+st.w[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+f0:[ ]+29c401ac[ ]+st.d[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+f4:[ ]+2a0401ac[ ]+ld.bu[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+f8:[ ]+2a4401ac[ ]+ld.hu[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+fc:[ ]+2a8401ac[ ]+ld.wu[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+100:[ ]+2ac401a2[ ]+preld[ ]+0x2,[ ]+\$t1,[ ]+256
-[ ]+104:[ ]+382c39a2[ ]+preldx[ ]+0x2,[ ]+\$t1,[ ]+\$t2
-[ ]+108:[ ]+2b048d8a[ ]+fld.s[ ]+\$ft2,[ ]+\$t0,[ ]+291
-[ ]+10c:[ ]+2b448d8a[ ]+fst.s[ ]+\$ft2,[ ]+\$t0,[ ]+291
-[ ]+110:[ ]+2b848d8a[ ]+fld.d[ ]+\$ft2,[ ]+\$t0,[ ]+291
-[ ]+114:[ ]+2bc48d8a[ ]+fst.d[ ]+\$ft2,[ ]+\$t0,[ ]+291
+[ ]+30:[ ]+002cb58b[ ]+alsl.d[ ]+\$a7, \$t0, \$t1, 0x2
+[ ]+34:[ ]+0040898b[ ]+slli.w[ ]+\$a7, \$t0, 0x2
+[ ]+38:[ ]+0041098b[ ]+slli.d[ ]+\$a7, \$t0, 0x2
+[ ]+3c:[ ]+0044898b[ ]+srli.w[ ]+\$a7, \$t0, 0x2
+[ ]+40:[ ]+004509ac[ ]+srli.d[ ]+\$t0, \$t1, 0x2
+[ ]+44:[ ]+004889ac[ ]+srai.w[ ]+\$t0, \$t1, 0x2
+[ ]+48:[ ]+004909ac[ ]+srai.d[ ]+\$t0, \$t1, 0x2
+[ ]+4c:[ ]+006209ac[ ]+bstrins.w[ ]+\$t0, \$t1, 0x2, 0x2
+[ ]+50:[ ]+008209ac[ ]+bstrins.d[ ]+\$t0, \$t1, 0x2, 0x2
+[ ]+54:[ ]+00c209ac[ ]+bstrpick.d[ ]+\$t0, \$t1, 0x2, 0x2
+[ ]+58:[ ]+00c209ac[ ]+bstrpick.d[ ]+\$t0, \$t1, 0x2, 0x2
+[ ]+5c:[ ]+02048dac[ ]+slti[ ]+\$t0, \$t1, 291
+[ ]+60:[ ]+02448dac[ ]+sltui[ ]+\$t0, \$t1, 291
+[ ]+64:[ ]+02848dac[ ]+addi.w[ ]+\$t0, \$t1, 291
+[ ]+68:[ ]+02c48dac[ ]+addi.d[ ]+\$t0, \$t1, 291
+[ ]+6c:[ ]+03048dac[ ]+lu52i.d[ ]+\$t0, \$t1, 291
+[ ]+70:[ ]+034009ac[ ]+andi[ ]+\$t0, \$t1, 0x2
+[ ]+74:[ ]+038009ac[ ]+ori[ ]+\$t0, \$t1, 0x2
+[ ]+78:[ ]+03c009ac[ ]+xori[ ]+\$t0, \$t1, 0x2
+[ ]+7c:[ ]+100009ac[ ]+addu16i.d[ ]+\$t0, \$t1, 2
+[ ]+80:[ ]+1400246c[ ]+lu12i.w[ ]+\$t0, 291
+[ ]+84:[ ]+1600246c[ ]+lu32i.d[ ]+\$t0, 291
+[ ]+88:[ ]+1800000c[ ]+pcaddi[ ]+\$t0, 0
+[ ]+88: R_LARCH_PCREL20_S2[ ]+\*ABS\*\+0x123
+[ ]+8c:[ ]+1a00246c[ ]+pcalau12i[ ]+\$t0, 291
+[ ]+90:[ ]+1c00246c[ ]+pcaddu12i[ ]+\$t0, 291
+[ ]+94:[ ]+1e00246c[ ]+pcaddu18i[ ]+\$t0, 291
+[ ]+98:[ ]+04048c0c[ ]+csrrd[ ]+\$t0, 0x123
+[ ]+9c:[ ]+04048c2c[ ]+csrwr[ ]+\$t0, 0x123
+[ ]+a0:[ ]+040009ac[ ]+csrxchg[ ]+\$t0, \$t1, 0x2
+[ ]+a4:[ ]+060009a2[ ]+cacop[ ]+0x2, \$t1, 2
+[ ]+a8:[ ]+064009ac[ ]+lddir[ ]+\$t0, \$t1, 0x2
+[ ]+ac:[ ]+06440980[ ]+ldpte[ ]+\$t0, 0x2
+[ ]+b0:[ ]+0649b9a2[ ]+invtlb[ ]+0x2, \$t1, \$t2
+[ ]+b4:[ ]+200101ac[ ]+ll.w[ ]+\$t0, \$t1, 256
+[ ]+b8:[ ]+210101ac[ ]+sc.w[ ]+\$t0, \$t1, 256
+[ ]+bc:[ ]+220101ac[ ]+ll.d[ ]+\$t0, \$t1, 256
+[ ]+c0:[ ]+230101ac[ ]+sc.d[ ]+\$t0, \$t1, 256
+[ ]+c4:[ ]+240101ac[ ]+ldptr.w[ ]+\$t0, \$t1, 256
+[ ]+c8:[ ]+250101ac[ ]+stptr.w[ ]+\$t0, \$t1, 256
+[ ]+cc:[ ]+260101ac[ ]+ldptr.d[ ]+\$t0, \$t1, 256
+[ ]+d0:[ ]+270101ac[ ]+stptr.d[ ]+\$t0, \$t1, 256
+[ ]+d4:[ ]+280401ac[ ]+ld.b[ ]+\$t0, \$t1, 256
+[ ]+d8:[ ]+284401ac[ ]+ld.h[ ]+\$t0, \$t1, 256
+[ ]+dc:[ ]+288401ac[ ]+ld.w[ ]+\$t0, \$t1, 256
+[ ]+e0:[ ]+28c401ac[ ]+ld.d[ ]+\$t0, \$t1, 256
+[ ]+e4:[ ]+290401ac[ ]+st.b[ ]+\$t0, \$t1, 256
+[ ]+e8:[ ]+294401ac[ ]+st.h[ ]+\$t0, \$t1, 256
+[ ]+ec:[ ]+298401ac[ ]+st.w[ ]+\$t0, \$t1, 256
+[ ]+f0:[ ]+29c401ac[ ]+st.d[ ]+\$t0, \$t1, 256
+[ ]+f4:[ ]+2a0401ac[ ]+ld.bu[ ]+\$t0, \$t1, 256
+[ ]+f8:[ ]+2a4401ac[ ]+ld.hu[ ]+\$t0, \$t1, 256
+[ ]+fc:[ ]+2a8401ac[ ]+ld.wu[ ]+\$t0, \$t1, 256
+[ ]+100:[ ]+2ac401a2[ ]+preld[ ]+0x2, \$t1, 256
+[ ]+104:[ ]+382c39a2[ ]+preldx[ ]+0x2, \$t1, \$t2
+[ ]+108:[ ]+2b048d8a[ ]+fld.s[ ]+\$ft2, \$t0, 291
+[ ]+10c:[ ]+2b448d8a[ ]+fst.s[ ]+\$ft2, \$t0, 291
+[ ]+110:[ ]+2b848d8a[ ]+fld.d[ ]+\$ft2, \$t0, 291
+[ ]+114:[ ]+2bc48d8a[ ]+fst.d[ ]+\$ft2, \$t0, 291
diff --git a/gas/testsuite/gas/loongarch/imm_ins_32.d b/gas/testsuite/gas/loongarch/imm_ins_32.d
index dc2eeb9e..3662fdda 100644
--- a/gas/testsuite/gas/loongarch/imm_ins_32.d
+++ b/gas/testsuite/gas/loongarch/imm_ins_32.d
@@ -7,51 +7,52 @@
Disassembly of section .text:
-00000000.* <.text>:
-[ ]+0:[ ]+03848c0c[ ]+li.w[ ]+\$t0,[ ]+0x123
-[ ]+4:[ ]+0004b58b[ ]+alsl.w[ ]+\$a7,[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+8:[ ]+0006b58b[ ]+alsl.wu[ ]+\$a7,[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+c:[ ]+0009358b[ ]+bytepick.w[ ]+\$a7,[ ]+\$t0,[ ]+\$t1,[ ]+0x2
+.* <.text>:
+[ ]+0:[ ]+03848c0c[ ]+li.w[ ]+\$t0, 0x123
+[ ]+4:[ ]+0004b58b[ ]+alsl.w[ ]+\$a7, \$t0, \$t1, 0x2
+[ ]+8:[ ]+0006b58b[ ]+alsl.wu[ ]+\$a7, \$t0, \$t1, 0x2
+[ ]+c:[ ]+0009358b[ ]+bytepick.w[ ]+\$a7, \$t0, \$t1, 0x2
[ ]+10:[ ]+002a0002[ ]+break[ ]+0x2
[ ]+14:[ ]+002a8002[ ]+dbcl[ ]+0x2
[ ]+18:[ ]+002b0002[ ]+syscall[ ]+0x2
-[ ]+1c:[ ]+0040898b[ ]+slli.w[ ]+\$a7,[ ]+\$t0,[ ]+0x2
-[ ]+20:[ ]+0044898b[ ]+srli.w[ ]+\$a7,[ ]+\$t0,[ ]+0x2
-[ ]+24:[ ]+004889ac[ ]+srai.w[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+28:[ ]+006209ac[ ]+bstrins.w[ ]+\$t0,[ ]+\$t1,[ ]+0x2,[ ]+0x2
-[ ]+2c:[ ]+02048dac[ ]+slti[ ]+\$t0,[ ]+\$t1,[ ]+291
-[ ]+30:[ ]+02448dac[ ]+sltui[ ]+\$t0,[ ]+\$t1,[ ]+291
-[ ]+34:[ ]+02848dac[ ]+addi.w[ ]+\$t0,[ ]+\$t1,[ ]+291
-[ ]+38:[ ]+034009ac[ ]+andi[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+3c:[ ]+038009ac[ ]+ori[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+40:[ ]+03c009ac[ ]+xori[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+44:[ ]+1400246c[ ]+lu12i.w[ ]+\$t0,[ ]+291
-[ ]+48:[ ]+1800246c[ ]+pcaddi[ ]+\$t0,[ ]+291
-[ ]+4c:[ ]+1a00246c[ ]+pcalau12i[ ]+\$t0,[ ]+291
-[ ]+50:[ ]+1c00246c[ ]+pcaddu12i[ ]+\$t0,[ ]+291
-[ ]+54:[ ]+1e00246c[ ]+pcaddu18i[ ]+\$t0,[ ]+291
-[ ]+58:[ ]+04048c0c[ ]+csrrd[ ]+\$t0,[ ]+0x123
-[ ]+5c:[ ]+04048c2c[ ]+csrwr[ ]+\$t0,[ ]+0x123
-[ ]+60:[ ]+040009ac[ ]+csrxchg[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+64:[ ]+060009a2[ ]+cacop[ ]+0x2,[ ]+\$t1,[ ]+2
-[ ]+68:[ ]+064009ac[ ]+lddir[ ]+\$t0,[ ]+\$t1,[ ]+0x2
-[ ]+6c:[ ]+06440980[ ]+ldpte[ ]+\$t0,[ ]+0x2
-[ ]+70:[ ]+0649b9a2[ ]+invtlb[ ]+0x2,[ ]+\$t1,[ ]+\$t2
-[ ]+74:[ ]+200101ac[ ]+ll.w[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+78:[ ]+210101ac[ ]+sc.w[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+7c:[ ]+220101ac[ ]+ll.d[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+80:[ ]+230101ac[ ]+sc.d[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+84:[ ]+240101ac[ ]+ldptr.w[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+88:[ ]+250101ac[ ]+stptr.w[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+8c:[ ]+284401ac[ ]+ld.h[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+90:[ ]+288401ac[ ]+ld.w[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+94:[ ]+290401ac[ ]+st.b[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+98:[ ]+294401ac[ ]+st.h[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+9c:[ ]+298401ac[ ]+st.w[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+a0:[ ]+2a0401ac[ ]+ld.bu[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+a4:[ ]+2a4401ac[ ]+ld.hu[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+a8:[ ]+2a8401ac[ ]+ld.wu[ ]+\$t0,[ ]+\$t1,[ ]+256
-[ ]+ac:[ ]+2ac401a2[ ]+preld[ ]+0x2,[ ]+\$t1,[ ]+256
-[ ]+b0:[ ]+382c39a2[ ]+preldx[ ]+0x2,[ ]+\$t1,[ ]+\$t2
-[ ]+b4:[ ]+2b048d8a[ ]+fld.s[ ]+\$ft2,[ ]+\$t0,[ ]+291
-[ ]+b8:[ ]+2b448d8a[ ]+fst.s[ ]+\$ft2,[ ]+\$t0,[ ]+291
+[ ]+1c:[ ]+0040898b[ ]+slli.w[ ]+\$a7, \$t0, 0x2
+[ ]+20:[ ]+0044898b[ ]+srli.w[ ]+\$a7, \$t0, 0x2
+[ ]+24:[ ]+004889ac[ ]+srai.w[ ]+\$t0, \$t1, 0x2
+[ ]+28:[ ]+006209ac[ ]+bstrins.w[ ]+\$t0, \$t1, 0x2, 0x2
+[ ]+2c:[ ]+02048dac[ ]+slti[ ]+\$t0, \$t1, 291
+[ ]+30:[ ]+02448dac[ ]+sltui[ ]+\$t0, \$t1, 291
+[ ]+34:[ ]+02848dac[ ]+addi.w[ ]+\$t0, \$t1, 291
+[ ]+38:[ ]+034009ac[ ]+andi[ ]+\$t0, \$t1, 0x2
+[ ]+3c:[ ]+038009ac[ ]+ori[ ]+\$t0, \$t1, 0x2
+[ ]+40:[ ]+03c009ac[ ]+xori[ ]+\$t0, \$t1, 0x2
+[ ]+44:[ ]+1400246c[ ]+lu12i.w[ ]+\$t0, 291
+[ ]+48:[ ]+1800000c[ ]+pcaddi[ ]+\$t0, 0
+[ ]+48: R_LARCH_PCREL20_S2[ ]+\*ABS\*\+0x123
+[ ]+4c:[ ]+1a00246c[ ]+pcalau12i[ ]+\$t0, 291
+[ ]+50:[ ]+1c00246c[ ]+pcaddu12i[ ]+\$t0, 291
+[ ]+54:[ ]+1e00246c[ ]+pcaddu18i[ ]+\$t0, 291
+[ ]+58:[ ]+04048c0c[ ]+csrrd[ ]+\$t0, 0x123
+[ ]+5c:[ ]+04048c2c[ ]+csrwr[ ]+\$t0, 0x123
+[ ]+60:[ ]+040009ac[ ]+csrxchg[ ]+\$t0, \$t1, 0x2
+[ ]+64:[ ]+060009a2[ ]+cacop[ ]+0x2, \$t1, 2
+[ ]+68:[ ]+064009ac[ ]+lddir[ ]+\$t0, \$t1, 0x2
+[ ]+6c:[ ]+06440980[ ]+ldpte[ ]+\$t0, 0x2
+[ ]+70:[ ]+0649b9a2[ ]+invtlb[ ]+0x2, \$t1, \$t2
+[ ]+74:[ ]+200101ac[ ]+ll.w[ ]+\$t0, \$t1, 256
+[ ]+78:[ ]+210101ac[ ]+sc.w[ ]+\$t0, \$t1, 256
+[ ]+7c:[ ]+220101ac[ ]+ll.d[ ]+\$t0, \$t1, 256
+[ ]+80:[ ]+230101ac[ ]+sc.d[ ]+\$t0, \$t1, 256
+[ ]+84:[ ]+240101ac[ ]+ldptr.w[ ]+\$t0, \$t1, 256
+[ ]+88:[ ]+250101ac[ ]+stptr.w[ ]+\$t0, \$t1, 256
+[ ]+8c:[ ]+284401ac[ ]+ld.h[ ]+\$t0, \$t1, 256
+[ ]+90:[ ]+288401ac[ ]+ld.w[ ]+\$t0, \$t1, 256
+[ ]+94:[ ]+290401ac[ ]+st.b[ ]+\$t0, \$t1, 256
+[ ]+98:[ ]+294401ac[ ]+st.h[ ]+\$t0, \$t1, 256
+[ ]+9c:[ ]+298401ac[ ]+st.w[ ]+\$t0, \$t1, 256
+[ ]+a0:[ ]+2a0401ac[ ]+ld.bu[ ]+\$t0, \$t1, 256
+[ ]+a4:[ ]+2a4401ac[ ]+ld.hu[ ]+\$t0, \$t1, 256
+[ ]+a8:[ ]+2a8401ac[ ]+ld.wu[ ]+\$t0, \$t1, 256
+[ ]+ac:[ ]+2ac401a2[ ]+preld[ ]+0x2, \$t1, 256
+[ ]+b0:[ ]+382c39a2[ ]+preldx[ ]+0x2, \$t1, \$t2
+[ ]+b4:[ ]+2b048d8a[ ]+fld.s[ ]+\$ft2, \$t0, 291
+[ ]+b8:[ ]+2b448d8a[ ]+fst.s[ ]+\$ft2, \$t0, 291
diff --git a/gas/testsuite/gas/loongarch/imm_op.d b/gas/testsuite/gas/loongarch/imm_op.d
index 3d4cba45..2885fc96 100644
--- a/gas/testsuite/gas/loongarch/imm_op.d
+++ b/gas/testsuite/gas/loongarch/imm_op.d
@@ -1,48 +1,48 @@
#as:
#objdump: -dr
-.*:[ ]+file format .*
+.*:[ ]+file format .*
Disassembly of section .text:
-00000000.* <.text>:
-[ ]+0:[ ]+020000a4 [ ]+slti[ ]+[ ]+\$a0, \$a1, 0
-[ ]+4:[ ]+021ffca4 [ ]+slti[ ]+[ ]+\$a0, \$a1, 2047
-[ ]+8:[ ]+022004a4 [ ]+slti[ ]+[ ]+\$a0, \$a1, -2047
-[ ]+c:[ ]+024000a4 [ ]+sltui[ ]+[ ]+\$a0, \$a1, 0
-[ ]+10:[ ]+025ffca4 [ ]+sltui[ ]+[ ]+\$a0, \$a1, 2047
-[ ]+14:[ ]+026004a4 [ ]+sltui[ ]+[ ]+\$a0, \$a1, -2047
-[ ]+18:[ ]+028000a4 [ ]+addi.w[ ]+[ ]+\$a0, \$a1, 0
-[ ]+1c:[ ]+029ffca4 [ ]+addi.w[ ]+[ ]+\$a0, \$a1, 2047
-[ ]+20:[ ]+02a004a4 [ ]+addi.w[ ]+[ ]+\$a0, \$a1, -2047
-[ ]+24:[ ]+02c000a4 [ ]+addi.d[ ]+[ ]+\$a0, \$a1, 0
-[ ]+28:[ ]+02dffca4 [ ]+addi.d[ ]+[ ]+\$a0, \$a1, 2047
-[ ]+2c:[ ]+02e004a4 [ ]+addi.d[ ]+[ ]+\$a0, \$a1, -2047
-[ ]+30:[ ]+030000a4 [ ]+lu52i.d[ ]+[ ]+\$a0, \$a1, 0
-[ ]+34:[ ]+031ffca4 [ ]+lu52i.d[ ]+[ ]+\$a0, \$a1, 2047
-[ ]+38:[ ]+032004a4 [ ]+lu52i.d[ ]+[ ]+\$a0, \$a1, -2047
-[ ]+3c:[ ]+034000a4 [ ]+andi[ ]+[ ]+\$a0, \$a1, 0x0
-[ ]+40:[ ]+035ffca4 [ ]+andi[ ]+[ ]+\$a0, \$a1, 0x7ff
-[ ]+44:[ ]+038000a4 [ ]+ori[ ]+[ ]+\$a0, \$a1, 0x0
-[ ]+48:[ ]+039ffca4 [ ]+ori[ ]+[ ]+\$a0, \$a1, 0x7ff
-[ ]+4c:[ ]+03c000a4 [ ]+xori[ ]+[ ]+\$a0, \$a1, 0x0
-[ ]+50:[ ]+03dffca4 [ ]+xori[ ]+[ ]+\$a0, \$a1, 0x7ff
-[ ]+54:[ ]+100000a4 [ ]+addu16i.d[ ]+[ ]+\$a0, \$a1, 0
-[ ]+58:[ ]+11fffca4 [ ]+addu16i.d[ ]+[ ]+\$a0, \$a1, 32767
-[ ]+5c:[ ]+120004a4 [ ]+addu16i.d[ ]+[ ]+\$a0, \$a1, -32767
-[ ]+60:[ ]+14000004 [ ]+lu12i.w[ ]+[ ]+\$a0, 0
-[ ]+64:[ ]+14ffffe4 [ ]+lu12i.w[ ]+[ ]+\$a0, 524287
-[ ]+68:[ ]+17000024 [ ]+lu32i.d[ ]+[ ]+\$a0, -524287
-[ ]+6c:[ ]+18000004 [ ]+pcaddi[ ]+[ ]+\$a0, 0
-[ ]+70:[ ]+18ffffe4 [ ]+pcaddi[ ]+[ ]+\$a0, 524287
-[ ]+74:[ ]+19000024 [ ]+pcaddi[ ]+[ ]+\$a0, -524287
-[ ]+78:[ ]+1a000004 [ ]+pcalau12i[ ]+[ ]+\$a0, 0
-[ ]+7c:[ ]+1affffe4 [ ]+pcalau12i[ ]+[ ]+\$a0, 524287
-[ ]+80:[ ]+1b000024 [ ]+pcalau12i[ ]+[ ]+\$a0, -524287
-[ ]+84:[ ]+1c000004 [ ]+pcaddu12i[ ]+[ ]+\$a0, 0
-[ ]+88:[ ]+1cffffe4 [ ]+pcaddu12i[ ]+[ ]+\$a0, 524287
-[ ]+8c:[ ]+1d000024 [ ]+pcaddu12i[ ]+[ ]+\$a0, -524287
-[ ]+90:[ ]+1e000004 [ ]+pcaddu18i[ ]+[ ]+\$a0, 0
-[ ]+94:[ ]+1effffe4 [ ]+pcaddu18i[ ]+[ ]+\$a0, 524287
-[ ]+98:[ ]+1f000024 [ ]+pcaddu18i[ ]+[ ]+\$a0, -524287
+.* <.text>:
+[ ]+0:[ ]+020000a4[ ]+slti[ ]+\$a0, \$a1, 0
+[ ]+4:[ ]+021ffca4[ ]+slti[ ]+\$a0, \$a1, 2047
+[ ]+8:[ ]+022004a4[ ]+slti[ ]+\$a0, \$a1, -2047
+[ ]+c:[ ]+024000a4[ ]+sltui[ ]+\$a0, \$a1, 0
+[ ]+10:[ ]+025ffca4[ ]+sltui[ ]+\$a0, \$a1, 2047
+[ ]+14:[ ]+026004a4[ ]+sltui[ ]+\$a0, \$a1, -2047
+[ ]+18:[ ]+028000a4[ ]+addi.w[ ]+\$a0, \$a1, 0
+[ ]+1c:[ ]+029ffca4[ ]+addi.w[ ]+\$a0, \$a1, 2047
+[ ]+20:[ ]+02a004a4[ ]+addi.w[ ]+\$a0, \$a1, -2047
+[ ]+24:[ ]+02c000a4[ ]+addi.d[ ]+\$a0, \$a1, 0
+[ ]+28:[ ]+02dffca4[ ]+addi.d[ ]+\$a0, \$a1, 2047
+[ ]+2c:[ ]+02e004a4[ ]+addi.d[ ]+\$a0, \$a1, -2047
+[ ]+30:[ ]+030000a4[ ]+lu52i.d[ ]+\$a0, \$a1, 0
+[ ]+34:[ ]+031ffca4[ ]+lu52i.d[ ]+\$a0, \$a1, 2047
+[ ]+38:[ ]+032004a4[ ]+lu52i.d[ ]+\$a0, \$a1, -2047
+[ ]+3c:[ ]+034000a4[ ]+andi[ ]+\$a0, \$a1, 0x0
+[ ]+40:[ ]+035ffca4[ ]+andi[ ]+\$a0, \$a1, 0x7ff
+[ ]+44:[ ]+038000a4[ ]+ori[ ]+\$a0, \$a1, 0x0
+[ ]+48:[ ]+039ffca4[ ]+ori[ ]+\$a0, \$a1, 0x7ff
+[ ]+4c:[ ]+03c000a4[ ]+xori[ ]+\$a0, \$a1, 0x0
+[ ]+50:[ ]+03dffca4[ ]+xori[ ]+\$a0, \$a1, 0x7ff
+[ ]+54:[ ]+100000a4[ ]+addu16i.d[ ]+\$a0, \$a1, 0
+[ ]+58:[ ]+11fffca4[ ]+addu16i.d[ ]+\$a0, \$a1, 32767
+[ ]+5c:[ ]+120004a4[ ]+addu16i.d[ ]+\$a0, \$a1, -32767
+[ ]+60:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+64:[ ]+14ffffe4[ ]+lu12i.w[ ]+\$a0, 524287
+[ ]+68:[ ]+17000024[ ]+lu32i.d[ ]+\$a0, -524287
+[ ]+6c:[ ]+18000004[ ]+pcaddi[ ]+\$a0, 0
+[ ]+70:[ ]+18ffffe4[ ]+pcaddi[ ]+\$a0, 524287
+[ ]+74:[ ]+19000004[ ]+pcaddi[ ]+\$a0, -524288
+[ ]+78:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+7c:[ ]+1affffe4[ ]+pcalau12i[ ]+\$a0, 524287
+[ ]+80:[ ]+1b000024[ ]+pcalau12i[ ]+\$a0, -524287
+[ ]+84:[ ]+1c000004[ ]+pcaddu12i[ ]+\$a0, 0
+[ ]+88:[ ]+1cffffe4[ ]+pcaddu12i[ ]+\$a0, 524287
+[ ]+8c:[ ]+1d000024[ ]+pcaddu12i[ ]+\$a0, -524287
+[ ]+90:[ ]+1e000004[ ]+pcaddu18i[ ]+\$a0, 0
+[ ]+94:[ ]+1effffe4[ ]+pcaddu18i[ ]+\$a0, 524287
+[ ]+98:[ ]+1f000024[ ]+pcaddu18i[ ]+\$a0, -524287
diff --git a/gas/testsuite/gas/loongarch/imm_op.s b/gas/testsuite/gas/loongarch/imm_op.s
index 7e1c5518..eae18260 100644
--- a/gas/testsuite/gas/loongarch/imm_op.s
+++ b/gas/testsuite/gas/loongarch/imm_op.s
@@ -27,7 +27,7 @@ lu12i.w $r4,0x7ffff
lu32i.d $r4,-0x7ffff
pcaddi $r4,0
pcaddi $r4,0x7ffff
-pcaddi $r4,-0x7ffff
+pcaddi $r4,-0x80000
pcalau12i $r4,0
pcalau12i $r4,0x7ffff
pcalau12i $r4,-0x7ffff
diff --git a/gas/testsuite/gas/loongarch/pcaddi.d b/gas/testsuite/gas/loongarch/pcaddi.d
new file mode 100644
index 00000000..3ddbbba5
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/pcaddi.d
@@ -0,0 +1,13 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+.* <.L1>:
+[ ]+0:[ ]+1800000c[ ]+pcaddi[ ]+\$t0, 0
+[ ]+0: R_LARCH_PCREL20_S2[ ]+.L1
+[ ]+4:[ ]+1800000c[ ]+pcaddi[ ]+\$t0, 0
+[ ]+4: R_LARCH_PCREL20_S2[ ]+.L2
diff --git a/gas/testsuite/gas/loongarch/pcaddi.s b/gas/testsuite/gas/loongarch/pcaddi.s
new file mode 100644
index 00000000..10d23e84
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/pcaddi.s
@@ -0,0 +1,4 @@
+.L1:
+ pcaddi $r12, .L1
+ pcaddi $r12, .L2
+.L2:
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index 4a88c4d7..5cd1411a 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -340,7 +340,7 @@ static struct loongarch_opcode loongarch_macro_opcodes[] =
{ 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD64, 0 },
{ 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD64_LARGE_ABS, 0 },
{ 0, 0, "la.tls.gd", "r,r,l", INSN_LA_TLS_GD64_LARGE_PCREL, 0 },
-
+ { 0, 0, "pcaddi", "r,la", "pcaddi %1, %%pcrel_20(%2)", &LARCH_opts.ase_ilp32, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminate the list. */
};
--
2.33.0

View File

@ -0,0 +1,247 @@
From aa0064d1240e10856f352516f6097f3e75c5e463 Mon Sep 17 00:00:00 2001
From: cailulu <cailulu@loongson.cn>
Date: Fri, 1 Sep 2023 11:09:01 +0800
Subject: [PATCH 007/123] Add testcase for generation of 32/64_PCREL.
---
gas/testsuite/gas/loongarch/pcrel_norelax.d | 56 +++++++++++++++++++
gas/testsuite/gas/loongarch/pcrel_norelax.s | 42 +++++++++++++++
gas/testsuite/gas/loongarch/pcrel_relax.d | 60 +++++++++++++++++++++
gas/testsuite/gas/loongarch/pcrel_relax.s | 46 ++++++++++++++++
4 files changed, 204 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/pcrel_norelax.d
create mode 100644 gas/testsuite/gas/loongarch/pcrel_norelax.s
create mode 100644 gas/testsuite/gas/loongarch/pcrel_relax.d
create mode 100644 gas/testsuite/gas/loongarch/pcrel_relax.s
diff --git a/gas/testsuite/gas/loongarch/pcrel_norelax.d b/gas/testsuite/gas/loongarch/pcrel_norelax.d
new file mode 100644
index 00000000..842c8d48
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/pcrel_norelax.d
@@ -0,0 +1,56 @@
+#as: -mno-relax
+#objdump: -Dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.L1>:
+[ ]+...
+[ ]+0:[ ]+R_LARCH_32_PCREL[ ]+.L3
+[ ]+4:[ ]+R_LARCH_32_PCREL[ ]+.L3\+0x4
+
+0*00000008[ ]+<.L2>:
+[ ]+...
+[ ]+8:[ ]+R_LARCH_64_PCREL[ ]+.L3
+[ ]+10:[ ]+R_LARCH_64_PCREL[ ]+.L3\+0x8
+
+Disassembly[ ]+of[ ]+section[ ]+sx:
+
+0*00000000[ ]+<.L3>:
+[ ]+0:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
+[ ]+4:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
+[ ]+8:[ ]+ffffffff[ ]+.word[ ]+0xffffffff
+
+0*0000000c[ ]+<.L4>:
+[ ]+...
+[ ]+c:[ ]+R_LARCH_ADD32[ ]+.L4
+[ ]+c:[ ]+R_LARCH_SUB32[ ]+.L5
+[ ]+10:[ ]+R_LARCH_ADD64[ ]+.L4
+[ ]+10:[ ]+R_LARCH_SUB64[ ]+.L5
+
+Disassembly[ ]+of[ ]+section[ ]+sy:
+
+0*00000000[ ]+<.L5>:
+[ ]+...
+[ ]+0:[ ]+R_LARCH_32_PCREL[ ]+.L1
+[ ]+4:[ ]+R_LARCH_32_PCREL[ ]+.L2\+0x4
+[ ]+8:[ ]+R_LARCH_64_PCREL[ ]+.L1\+0x8
+[ ]+10:[ ]+R_LARCH_64_PCREL[ ]+.L2\+0x10
+
+Disassembly[ ]+of[ ]+section[ ]+sz:
+
+0*00000000[ ]+<sz>:
+[ ]+0:[ ]+fffffff8[ ]+.word[ ]+0xfffffff8
+[ ]+4:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
+[ ]+8:[ ]+00000000[ ]+.word[ ]+0x00000000
+[ ]+8:[ ]+R_LARCH_ADD32[ ]+.L2
+[ ]+8:[ ]+R_LARCH_SUB32[ ]+.L3
+[ ]+c:[ ]+fffffff8[ ]+.word[ ]+0xfffffff8
+[ ]+10:[ ]+ffffffff[ ]+.word[ ]+0xffffffff
+[ ]+14:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
+[ ]+18:[ ]+ffffffff[ ]+.word[ ]+0xffffffff
+[ ]+...
+[ ]+1c:[ ]+R_LARCH_ADD64[ ]+.L2
+[ ]+1c:[ ]+R_LARCH_SUB64[ ]+.L3
diff --git a/gas/testsuite/gas/loongarch/pcrel_norelax.s b/gas/testsuite/gas/loongarch/pcrel_norelax.s
new file mode 100644
index 00000000..09527f14
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/pcrel_norelax.s
@@ -0,0 +1,42 @@
+ .section .text
+.L1:
+ # 32_pcrel
+ .4byte .L3-.L1
+ .4byte .L3-.L1
+.L2:
+ # 64_pcrel
+ .8byte .L3-.L2
+ .8byte .L3-.L2
+
+ .section sx
+.L3:
+ # no relocation
+ .4byte .L3-.L4
+ .8byte .L3-.L4
+.L4:
+ # add32+sub32
+ .4byte .L4-.L5
+ # add64+sub64
+ .8byte .L4-.L5
+
+ .section sy
+.L5:
+ # 32_pcrel
+ .4byte .L1-.L5
+ .4byte .L2-.L5
+ # 64_pcrel
+ .8byte .L1-.L5
+ .8byte .L2-.L5
+
+ .section sz
+ # no relocation
+ .4byte .L1-.L2
+ .4byte .L3-.L4
+ # add32+sub32
+ .4byte .L2-.L3
+
+ # no relocation
+ .8byte .L1-.L2
+ .8byte .L3-.L4
+ # add64+sub64
+ .8byte .L2-.L3
diff --git a/gas/testsuite/gas/loongarch/pcrel_relax.d b/gas/testsuite/gas/loongarch/pcrel_relax.d
new file mode 100644
index 00000000..d6f87525
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/pcrel_relax.d
@@ -0,0 +1,60 @@
+#as:
+#objdump: -Dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.L1>:
+[ ]+...
+[ ]+0:[ ]+R_LARCH_32_PCREL[ ]+.L3
+[ ]+4:[ ]+R_LARCH_ADD32[ ]+.L3
+[ ]+4:[ ]+R_LARCH_SUB32[ ]+.L1
+
+0*00000008[ ]+<.L2>:
+[ ]+...
+[ ]+8:[ ]+R_LARCH_64_PCREL[ ]+.L3
+[ ]+10:[ ]+R_LARCH_ADD64[ ]+.L3
+[ ]+10:[ ]+R_LARCH_SUB64[ ]+.L2
+
+Disassembly[ ]+of[ ]+section[ ]+sx:
+
+0*00000000[ ]+<.L3>:
+[ ]+0:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
+[ ]+4:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
+[ ]+8:[ ]+ffffffff[ ]+.word[ ]+0xffffffff
+
+0*0000000c[ ]+<.L4>:
+[ ]+...
+[ ]+c:[ ]+R_LARCH_ADD32[ ]+.L4
+[ ]+c:[ ]+R_LARCH_SUB32[ ]+.L5
+[ ]+10:[ ]+R_LARCH_ADD64[ ]+.L4
+[ ]+10:[ ]+R_LARCH_SUB64[ ]+.L5
+
+Disassembly[ ]+of[ ]+section[ ]+sy:
+
+0*00000000[ ]+<.L5>:
+[ ]+...
+[ ]+0:[ ]+R_LARCH_32_PCREL[ ]+.L1
+[ ]+4:[ ]+R_LARCH_32_PCREL[ ]+.L3\+0x4
+[ ]+8:[ ]+R_LARCH_64_PCREL[ ]+.L1\+0x8
+[ ]+10:[ ]+R_LARCH_64_PCREL[ ]+.L3\+0x10
+
+Disassembly[ ]+of[ ]+section[ ]+sz:
+
+0*00000000[ ]+<sz>:
+[ ]+0:[ ]+00000000[ ]+.word[ ]+0x00000000
+[ ]+0:[ ]+R_LARCH_ADD32[ ]+.L1
+[ ]+0:[ ]+R_LARCH_SUB32[ ]+.L2
+[ ]+4:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
+[ ]+...
+[ ]+8:[ ]+R_LARCH_ADD32[ ]+.L3
+[ ]+8:[ ]+R_LARCH_SUB32[ ]+.L5
+[ ]+c:[ ]+R_LARCH_ADD64[ ]+.L1
+[ ]+c:[ ]+R_LARCH_SUB64[ ]+.L2
+[ ]+14:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
+[ ]+18:[ ]+ffffffff[ ]+.word[ ]+0xffffffff
+[ ]+...
+[ ]+1c:[ ]+R_LARCH_ADD64[ ]+.L3
+[ ]+1c:[ ]+R_LARCH_SUB64[ ]+.L5
diff --git a/gas/testsuite/gas/loongarch/pcrel_relax.s b/gas/testsuite/gas/loongarch/pcrel_relax.s
new file mode 100644
index 00000000..ded275fa
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/pcrel_relax.s
@@ -0,0 +1,46 @@
+ .section .text
+.L1:
+ # 32_pcrel
+ .4byte .L3-.L1
+ # add32+sub32
+ .4byte .L3-.L1
+.L2:
+ # 64_pcrel
+ .8byte .L3-.L2
+ # add64+sub64
+ .8byte .L3-.L2
+
+ .section sx
+.L3:
+ # no relocation
+ .4byte .L3-.L4
+ .8byte .L3-.L4
+.L4:
+ # add32+sub32
+ .4byte .L4-.L5
+ # add64+sub64
+ .8byte .L4-.L5
+
+ .section sy
+.L5:
+ # 32_pcrel
+ .4byte .L1-.L5
+ .4byte .L3-.L5
+ # 64_pcrel
+ .8byte .L1-.L5
+ .8byte .L3-.L5
+
+ .section sz
+ # add32+sub32
+ .4byte .L1-.L2
+ # no relocation
+ .4byte .L3-.L4
+ # add32+sub32
+ .4byte .L3-.L5
+
+ #add64+sub64
+ .8byte .L1-.L2
+ # no relocation
+ .8byte .L3-.L4
+ #add64+sub64
+ .8byte .L3-.L5
--
2.33.0

View File

@ -0,0 +1,307 @@
From 7904eb84e70187141d105971ff38de06215102cb Mon Sep 17 00:00:00 2001
From: cailulu <cailulu@loongson.cn>
Date: Thu, 28 Sep 2023 16:01:53 +0800
Subject: [PATCH 012/123] Add testsuits for new assembler option of
mthin-add-sub.
---
gas/testsuite/gas/loongarch/no_thin_add_sub.d | 66 +++++++++++++++++++
gas/testsuite/gas/loongarch/no_thin_add_sub.s | 44 +++++++++++++
...pcrel_norelax.d => thin_add_sub_norelax.d} | 25 ++++---
...pcrel_norelax.s => thin_add_sub_norelax.s} | 8 +--
.../{pcrel_relax.d => thin_add_sub_relax.d} | 12 ++--
.../{pcrel_relax.s => thin_add_sub_relax.s} | 0
6 files changed, 131 insertions(+), 24 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/no_thin_add_sub.d
create mode 100644 gas/testsuite/gas/loongarch/no_thin_add_sub.s
rename gas/testsuite/gas/loongarch/{pcrel_norelax.d => thin_add_sub_norelax.d} (75%)
rename gas/testsuite/gas/loongarch/{pcrel_norelax.s => thin_add_sub_norelax.s} (87%)
rename gas/testsuite/gas/loongarch/{pcrel_relax.d => thin_add_sub_relax.d} (91%)
rename gas/testsuite/gas/loongarch/{pcrel_relax.s => thin_add_sub_relax.s} (100%)
diff --git a/gas/testsuite/gas/loongarch/no_thin_add_sub.d b/gas/testsuite/gas/loongarch/no_thin_add_sub.d
new file mode 100644
index 00000000..614aca71
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/no_thin_add_sub.d
@@ -0,0 +1,66 @@
+#as:
+#objdump: -Dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+00000000.* <.L1>:
+[ ]+...
+[ ]+0:[ ]+R_LARCH_ADD32[ ]+.L3
+[ ]+0:[ ]+R_LARCH_SUB32[ ]+.L1
+[ ]+4:[ ]+R_LARCH_ADD32[ ]+.L3
+[ ]+4:[ ]+R_LARCH_SUB32[ ]+.L1
+
+0*00000008[ ]+<.L2>:
+[ ]+...
+[ ]+8:[ ]+R_LARCH_ADD64[ ]+.L3
+[ ]+8:[ ]+R_LARCH_SUB64[ ]+.L2
+[ ]+10:[ ]+R_LARCH_ADD64[ ]+.L3
+[ ]+10:[ ]+R_LARCH_SUB64[ ]+.L2
+
+Disassembly[ ]+of[ ]+section[ ]+sx:
+
+0*00000000[ ]+<.L3>:
+[ ]+0:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
+[ ]+4:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
+[ ]+8:[ ]+ffffffff[ ]+.word[ ]+0xffffffff
+
+0*0000000c[ ]+<.L4>:
+[ ]+...
+[ ]+c:[ ]+R_LARCH_ADD32[ ]+.L4
+[ ]+c:[ ]+R_LARCH_SUB32[ ]+.L5
+[ ]+10:[ ]+R_LARCH_ADD64[ ]+.L4
+[ ]+10:[ ]+R_LARCH_SUB64[ ]+.L5
+
+Disassembly[ ]+of[ ]+section[ ]+sy:
+
+0*00000000[ ]+<.L5>:
+[ ]+...
+[ ]+0:[ ]+R_LARCH_ADD32[ ]+.L1
+[ ]+0:[ ]+R_LARCH_SUB32[ ]+.L5
+[ ]+4:[ ]+R_LARCH_ADD32[ ]+.L3
+[ ]+4:[ ]+R_LARCH_SUB32[ ]+.L5
+[ ]+8:[ ]+R_LARCH_ADD64[ ]+.L1
+[ ]+8:[ ]+R_LARCH_SUB64[ ]+.L5
+[ ]+10:[ ]+R_LARCH_ADD64[ ]+.L3
+[ ]+10:[ ]+R_LARCH_SUB64[ ]+.L5
+
+Disassembly[ ]+of[ ]+section[ ]+sz:
+
+0*00000000[ ]+<sz>:
+[ ]+0:[ ]+00000000[ ]+.word[ ]+0x00000000
+[ ]+0:[ ]+R_LARCH_ADD32[ ]+.L1
+[ ]+0:[ ]+R_LARCH_SUB32[ ]+.L2
+[ ]+4:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
+[ ]+...
+[ ]+8:[ ]+R_LARCH_ADD32[ ]+.L3
+[ ]+8:[ ]+R_LARCH_SUB32[ ]+.L5
+[ ]+c:[ ]+R_LARCH_ADD64[ ]+.L1
+[ ]+c:[ ]+R_LARCH_SUB64[ ]+.L2
+[ ]+14:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
+[ ]+18:[ ]+ffffffff[ ]+.word[ ]+0xffffffff
+[ ]+...
+[ ]+1c:[ ]+R_LARCH_ADD64[ ]+.L3
+[ ]+1c:[ ]+R_LARCH_SUB64[ ]+.L5
diff --git a/gas/testsuite/gas/loongarch/no_thin_add_sub.s b/gas/testsuite/gas/loongarch/no_thin_add_sub.s
new file mode 100644
index 00000000..c6801689
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/no_thin_add_sub.s
@@ -0,0 +1,44 @@
+ .section .text
+.L1:
+ # add32+sub32
+ .4byte .L3-.L1
+ .4byte .L3-.L1
+.L2:
+ # add64+sub64
+ .8byte .L3-.L2
+ .8byte .L3-.L2
+
+ .section sx
+.L3:
+ # no relocation
+ .4byte .L3-.L4
+ .8byte .L3-.L4
+.L4:
+ # add32+sub32
+ .4byte .L4-.L5
+ # add64+sub64
+ .8byte .L4-.L5
+
+ .section sy
+.L5:
+ # add32+sub32
+ .4byte .L1-.L5
+ .4byte .L3-.L5
+ # add64+sub64
+ .8byte .L1-.L5
+ .8byte .L3-.L5
+
+ .section sz
+ # add32+sub32
+ .4byte .L1-.L2
+ # no relocation
+ .4byte .L3-.L4
+ # add32+sub32
+ .4byte .L3-.L5
+
+ # add64+sub64
+ .8byte .L1-.L2
+ # no relocation
+ .8byte .L3-.L4
+ # add64+sub64
+ .8byte .L3-.L5
diff --git a/gas/testsuite/gas/loongarch/pcrel_norelax.d b/gas/testsuite/gas/loongarch/thin_add_sub_norelax.d
similarity index 75%
rename from gas/testsuite/gas/loongarch/pcrel_norelax.d
rename to gas/testsuite/gas/loongarch/thin_add_sub_norelax.d
index 842c8d48..702093b6 100644
--- a/gas/testsuite/gas/loongarch/pcrel_norelax.d
+++ b/gas/testsuite/gas/loongarch/thin_add_sub_norelax.d
@@ -1,4 +1,4 @@
-#as: -mno-relax
+#as: -mthin-add-sub -mno-relax
#objdump: -Dr
.*:[ ]+file format .*
@@ -10,20 +10,17 @@ Disassembly of section .text:
[ ]+...
[ ]+0:[ ]+R_LARCH_32_PCREL[ ]+.L3
[ ]+4:[ ]+R_LARCH_32_PCREL[ ]+.L3\+0x4
-
-0*00000008[ ]+<.L2>:
-[ ]+...
[ ]+8:[ ]+R_LARCH_64_PCREL[ ]+.L3
[ ]+10:[ ]+R_LARCH_64_PCREL[ ]+.L3\+0x8
Disassembly[ ]+of[ ]+section[ ]+sx:
-0*00000000[ ]+<.L3>:
+0*00000000[ ]+<.L3>:
[ ]+0:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
[ ]+4:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
[ ]+8:[ ]+ffffffff[ ]+.word[ ]+0xffffffff
-0*0000000c[ ]+<.L4>:
+0*0000000c[ ]+<.L4>:
[ ]+...
[ ]+c:[ ]+R_LARCH_ADD32[ ]+.L4
[ ]+c:[ ]+R_LARCH_SUB32[ ]+.L5
@@ -32,25 +29,25 @@ Disassembly[ ]+of[ ]+section[ ]+sx:
Disassembly[ ]+of[ ]+section[ ]+sy:
-0*00000000[ ]+<.L5>:
+0*00000000[ ]+<.L5>:
[ ]+...
[ ]+0:[ ]+R_LARCH_32_PCREL[ ]+.L1
-[ ]+4:[ ]+R_LARCH_32_PCREL[ ]+.L2\+0x4
+[ ]+4:[ ]+R_LARCH_32_PCREL[ ]+.L3\+0x4
[ ]+8:[ ]+R_LARCH_64_PCREL[ ]+.L1\+0x8
-[ ]+10:[ ]+R_LARCH_64_PCREL[ ]+.L2\+0x10
+[ ]+10:[ ]+R_LARCH_64_PCREL[ ]+.L3\+0x10
Disassembly[ ]+of[ ]+section[ ]+sz:
-0*00000000[ ]+<sz>:
+0*00000000[ ]+<sz>:
[ ]+0:[ ]+fffffff8[ ]+.word[ ]+0xfffffff8
[ ]+4:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
[ ]+8:[ ]+00000000[ ]+.word[ ]+0x00000000
-[ ]+8:[ ]+R_LARCH_ADD32[ ]+.L2
-[ ]+8:[ ]+R_LARCH_SUB32[ ]+.L3
+[ ]+8:[ ]+R_LARCH_ADD32[ ]+.L3
+[ ]+8:[ ]+R_LARCH_SUB32[ ]+.L5
[ ]+c:[ ]+fffffff8[ ]+.word[ ]+0xfffffff8
[ ]+10:[ ]+ffffffff[ ]+.word[ ]+0xffffffff
[ ]+14:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
[ ]+18:[ ]+ffffffff[ ]+.word[ ]+0xffffffff
[ ]+...
-[ ]+1c:[ ]+R_LARCH_ADD64[ ]+.L2
-[ ]+1c:[ ]+R_LARCH_SUB64[ ]+.L3
+[ ]+1c:[ ]+R_LARCH_ADD64[ ]+.L3
+[ ]+1c:[ ]+R_LARCH_SUB64[ ]+.L5
diff --git a/gas/testsuite/gas/loongarch/pcrel_norelax.s b/gas/testsuite/gas/loongarch/thin_add_sub_norelax.s
similarity index 87%
rename from gas/testsuite/gas/loongarch/pcrel_norelax.s
rename to gas/testsuite/gas/loongarch/thin_add_sub_norelax.s
index 09527f14..94cfd908 100644
--- a/gas/testsuite/gas/loongarch/pcrel_norelax.s
+++ b/gas/testsuite/gas/loongarch/thin_add_sub_norelax.s
@@ -23,20 +23,20 @@
.L5:
# 32_pcrel
.4byte .L1-.L5
- .4byte .L2-.L5
+ .4byte .L3-.L5
# 64_pcrel
.8byte .L1-.L5
- .8byte .L2-.L5
+ .8byte .L3-.L5
.section sz
# no relocation
.4byte .L1-.L2
.4byte .L3-.L4
# add32+sub32
- .4byte .L2-.L3
+ .4byte .L3-.L5
# no relocation
.8byte .L1-.L2
.8byte .L3-.L4
# add64+sub64
- .8byte .L2-.L3
+ .8byte .L3-.L5
diff --git a/gas/testsuite/gas/loongarch/pcrel_relax.d b/gas/testsuite/gas/loongarch/thin_add_sub_relax.d
similarity index 91%
rename from gas/testsuite/gas/loongarch/pcrel_relax.d
rename to gas/testsuite/gas/loongarch/thin_add_sub_relax.d
index d6f87525..9455c3e6 100644
--- a/gas/testsuite/gas/loongarch/pcrel_relax.d
+++ b/gas/testsuite/gas/loongarch/thin_add_sub_relax.d
@@ -1,4 +1,4 @@
-#as:
+#as: -mthin-add-sub
#objdump: -Dr
.*:[ ]+file format .*
@@ -12,7 +12,7 @@ Disassembly of section .text:
[ ]+4:[ ]+R_LARCH_ADD32[ ]+.L3
[ ]+4:[ ]+R_LARCH_SUB32[ ]+.L1
-0*00000008[ ]+<.L2>:
+0*00000008[ ]+<.L2>:
[ ]+...
[ ]+8:[ ]+R_LARCH_64_PCREL[ ]+.L3
[ ]+10:[ ]+R_LARCH_ADD64[ ]+.L3
@@ -20,12 +20,12 @@ Disassembly of section .text:
Disassembly[ ]+of[ ]+section[ ]+sx:
-0*00000000[ ]+<.L3>:
+0*00000000[ ]+<.L3>:
[ ]+0:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
[ ]+4:[ ]+fffffff4[ ]+.word[ ]+0xfffffff4
[ ]+8:[ ]+ffffffff[ ]+.word[ ]+0xffffffff
-0*0000000c[ ]+<.L4>:
+0*0000000c[ ]+<.L4>:
[ ]+...
[ ]+c:[ ]+R_LARCH_ADD32[ ]+.L4
[ ]+c:[ ]+R_LARCH_SUB32[ ]+.L5
@@ -34,7 +34,7 @@ Disassembly[ ]+of[ ]+section[ ]+sx:
Disassembly[ ]+of[ ]+section[ ]+sy:
-0*00000000[ ]+<.L5>:
+0*00000000[ ]+<.L5>:
[ ]+...
[ ]+0:[ ]+R_LARCH_32_PCREL[ ]+.L1
[ ]+4:[ ]+R_LARCH_32_PCREL[ ]+.L3\+0x4
@@ -43,7 +43,7 @@ Disassembly[ ]+of[ ]+section[ ]+sy:
Disassembly[ ]+of[ ]+section[ ]+sz:
-0*00000000[ ]+<sz>:
+0*00000000[ ]+<sz>:
[ ]+0:[ ]+00000000[ ]+.word[ ]+0x00000000
[ ]+0:[ ]+R_LARCH_ADD32[ ]+.L1
[ ]+0:[ ]+R_LARCH_SUB32[ ]+.L2
diff --git a/gas/testsuite/gas/loongarch/pcrel_relax.s b/gas/testsuite/gas/loongarch/thin_add_sub_relax.s
similarity index 100%
rename from gas/testsuite/gas/loongarch/pcrel_relax.s
rename to gas/testsuite/gas/loongarch/thin_add_sub_relax.s
--
2.33.0

View File

@ -0,0 +1,102 @@
From 79505ef8b8ccd844aee06cab4aec2404fb5e4475 Mon Sep 17 00:00:00 2001
From: Jinyang He <hejinyang@loongson.cn>
Date: Fri, 15 Sep 2023 11:52:14 +0800
Subject: [PATCH 060/123] Avoid unused space in .rela.dyn if sec was discarded
The relsec size is still increased although sec is discarded, which
cause a lot of unused space allocated. Avoid size increased if sec
was discarded.
bfd/ChangeLog:
* bfd/elfnn-loongarch.c: (allocate_dynrelocs): Do not increase
sreloc size when discarded_section.
ld/ChangeLog:
* ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp: Add test.
* ld/testsuite/ld-loongarch-elf/pie_discard.d: New test.
* ld/testsuite/ld-loongarch-elf/pie_discard.s: New test.
* ld/testsuite/ld-loongarch-elf/pie_discard.t: New test.
---
bfd/elfnn-loongarch.c | 2 ++
ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp | 1 +
ld/testsuite/ld-loongarch-elf/pie_discard.d | 10 ++++++++++
ld/testsuite/ld-loongarch-elf/pie_discard.s | 9 +++++++++
ld/testsuite/ld-loongarch-elf/pie_discard.t | 9 +++++++++
5 files changed, 31 insertions(+)
create mode 100644 ld/testsuite/ld-loongarch-elf/pie_discard.d
create mode 100644 ld/testsuite/ld-loongarch-elf/pie_discard.s
create mode 100644 ld/testsuite/ld-loongarch-elf/pie_discard.t
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 2e72fe5c..1693ad7e 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -1368,6 +1368,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
for (p = h->dyn_relocs; p != NULL; p = p->next)
{
+ if (discarded_section (p->sec))
+ continue;
asection *sreloc = elf_section_data (p->sec)->sreloc;
sreloc->size += p->count * sizeof (ElfNN_External_Rela);
}
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 7fc43d41..b3029e53 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -147,3 +147,4 @@ run_dump_test "underflow_b16"
run_dump_test "underflow_b21"
run_dump_test "underflow_b26"
run_dump_test "underflow_pcrel20"
+run_dump_test "pie_discard"
diff --git a/ld/testsuite/ld-loongarch-elf/pie_discard.d b/ld/testsuite/ld-loongarch-elf/pie_discard.d
new file mode 100644
index 00000000..7b863091
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/pie_discard.d
@@ -0,0 +1,10 @@
+#source: pie_discard.s
+#ld: -pie -e 0 -T pie_discard.t
+#readelf: -rW
+
+#...
+Relocation section '\.rela\.dyn' .* 1 .*
+#...
+.*R_LARCH_RELATIVE.*
+#pass
+
diff --git a/ld/testsuite/ld-loongarch-elf/pie_discard.s b/ld/testsuite/ld-loongarch-elf/pie_discard.s
new file mode 100644
index 00000000..82b88fc1
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/pie_discard.s
@@ -0,0 +1,9 @@
+ .text
+ .global sym
+sym: nop
+
+ .section .data,"aw"
+ .dword sym
+
+ .section .discard,"aw"
+ .dword sym
diff --git a/ld/testsuite/ld-loongarch-elf/pie_discard.t b/ld/testsuite/ld-loongarch-elf/pie_discard.t
new file mode 100644
index 00000000..49e52cdb
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/pie_discard.t
@@ -0,0 +1,9 @@
+SECTIONS
+{
+ . = SEGMENT_START("text-segment", 0) + SIZEOF_HEADERS;
+ .rela.dyn : { *(.rela.*) }
+ .text : { *(.text) }
+ . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
+ .data : { *(.data) }
+ /DISCARD/ : { *(.discard) }
+}
--
2.33.0

View File

@ -0,0 +1,226 @@
From aef05e9e774983b4d4a5a08ab7e172e1e678eff5 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Wed, 24 Jan 2024 14:34:26 +0800
Subject: [PATCH 075/123] BFD: Fix the bug of R_LARCH_AGLIN caused by discard
section
To represent the first and third expression of .align, R_LARCH_ALIGN need to
associate with a symbol. We define a local symbol for R_LARCH_AGLIN.
But if the section of the local symbol is discarded, it may result in
a undefined symbol error.
Instead, we use the section name symbols, and this does not need to
add extra symbols.
During partial linking (ld -r), if the symbol associated with a relocation is
STT_SECTION type, the addend of relocation needs to add the section output
offset. We prevent it for R_LARCH_ALIGN.
The elf_backend_data.rela_normal only can set all relocations of a target to
rela_normal. Add a new function is_rela_normal to elf_backend_data, it can
set part of relocations to rela_normal.
---
bfd/elf-bfd.h | 4 ++++
bfd/elflink.c | 5 ++++-
bfd/elfnn-loongarch.c | 16 ++++++++++++++++
bfd/elfxx-target.h | 5 +++++
gas/config/tc-loongarch.c | 5 +----
gas/testsuite/gas/loongarch/relax_align.d | 6 +++---
.../ld-loongarch-elf/relax-align-discard.lds | 4 ++++
.../ld-loongarch-elf/relax-align-discard.s | 17 +++++++++++++++++
ld/testsuite/ld-loongarch-elf/relax.exp | 12 ++++++++++++
9 files changed, 66 insertions(+), 8 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align-discard.lds
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align-discard.s
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index ec856764..074120a5 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1703,6 +1703,10 @@ struct elf_backend_data
backend relocate_section routine for relocatable linking. */
unsigned rela_normal : 1;
+ /* Whether a relocation is rela_normal. Compared with rela_normal,
+ is_rela_normal can set part of relocations to rela_normal. */
+ bool (*is_rela_normal) (Elf_Internal_Rela *);
+
/* Set if DT_REL/DT_RELA/DT_RELSZ/DT_RELASZ should not include PLT
relocations. */
unsigned dtrel_excludes_plt : 1;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 7217c2f0..cbf87d70 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11647,7 +11647,10 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
{
rel_hash = PTR_ADD (esdo->rela.hashes, esdo->rela.count);
rela_hash_list = rel_hash;
- rela_normal = bed->rela_normal;
+ if (bed->is_rela_normal != NULL)
+ rela_normal = bed->is_rela_normal (irela);
+ else
+ rela_normal = bed->rela_normal;
}
irela->r_offset = _bfd_elf_section_offset (output_bfd,
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 1c3295f4..f6975957 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -5454,6 +5454,21 @@ elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
return _bfd_elf_hash_symbol (h);
}
+/* If a relocation is rela_normal and the symbol associated with the
+ relocation is STT_SECTION type, the addend of the relocation would add
+ sec->output_offset when partial linking (ld -r).
+ See elf_backend_data.rela_normal and elf_link_input_bfd().
+ The addend of R_LARCH_ALIGN is used to represent the first and third
+ expression of .align, it should be a constant when linking. */
+
+static bool
+loongarch_elf_is_rela_normal (Elf_Internal_Rela *rel)
+{
+ if (R_LARCH_ALIGN == ELFNN_R_TYPE (rel->r_info))
+ return false;
+ return true;
+}
+
#define TARGET_LITTLE_SYM loongarch_elfNN_vec
#define TARGET_LITTLE_NAME "elfNN-loongarch"
#define ELF_ARCH bfd_arch_loongarch
@@ -5489,6 +5504,7 @@ elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
#define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
#define elf_backend_hash_symbol elf_loongarch64_hash_symbol
#define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
+#define elf_backend_is_rela_normal loongarch_elf_is_rela_normal
#define elf_backend_dtrel_excludes_plt 1
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index f8553006..385e40b7 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -703,6 +703,10 @@
#define elf_backend_rela_normal 0
#endif
+#ifndef elf_backend_is_rela_normal
+#define elf_backend_is_rela_normal NULL
+#endif
+
#ifndef elf_backend_dtrel_excludes_plt
#define elf_backend_dtrel_excludes_plt 0
#endif
@@ -948,6 +952,7 @@ static const struct elf_backend_data elfNN_bed =
elf_backend_default_use_rela_p,
elf_backend_rela_plts_and_copies_p,
elf_backend_rela_normal,
+ elf_backend_is_rela_normal,
elf_backend_dtrel_excludes_plt,
elf_backend_sign_extend_vma,
elf_backend_want_got_plt,
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 51575757..1e835f51 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -1791,10 +1791,7 @@ loongarch_frag_align_code (int n, int max)
if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype). */
if (max > 0 && (bfd_vma) max < worst_case_bytes)
{
- s = symbol_find (".Lla-relax-align");
- if (s == NULL)
- s = (symbolS *)local_symbol_make (".Lla-relax-align", now_seg,
- &zero_address_frag, 0);
+ s = symbol_find (now_seg->name);
ex.X_add_symbol = s;
ex.X_op = O_symbol;
ex.X_add_number = (max << 8) | n;
diff --git a/gas/testsuite/gas/loongarch/relax_align.d b/gas/testsuite/gas/loongarch/relax_align.d
index fc1fd032..acd215a4 100644
--- a/gas/testsuite/gas/loongarch/relax_align.d
+++ b/gas/testsuite/gas/loongarch/relax_align.d
@@ -7,7 +7,7 @@
Disassembly of section .text:
-[ ]*0000000000000000 <.Lla-relax-align>:
+[ ]*0000000000000000 <.text>:
[ ]+0:[ ]+4c000020[ ]+ret
[ ]+4:[ ]+03400000[ ]+nop
[ ]+4: R_LARCH_ALIGN[ ]+\*ABS\*\+0xc
@@ -20,12 +20,12 @@ Disassembly of section .text:
[ ]+1c:[ ]+03400000[ ]+nop
[ ]+20:[ ]+4c000020[ ]+ret
[ ]+24:[ ]+03400000[ ]+nop
-[ ]+24: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0x104
+[ ]+24: R_LARCH_ALIGN[ ]+.text\+0x104
[ ]+28:[ ]+03400000[ ]+nop
[ ]+2c:[ ]+03400000[ ]+nop
[ ]+30:[ ]+4c000020[ ]+ret
[ ]+34:[ ]+03400000[ ]+nop
-[ ]+34: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0xb04
+[ ]+34: R_LARCH_ALIGN[ ]+.text\+0xb04
[ ]+38:[ ]+03400000[ ]+nop
[ ]+3c:[ ]+03400000[ ]+nop
[ ]+40:[ ]+4c000020[ ]+ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-discard.lds b/ld/testsuite/ld-loongarch-elf/relax-align-discard.lds
new file mode 100644
index 00000000..4a81323d
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-align-discard.lds
@@ -0,0 +1,4 @@
+SECTIONS
+{
+ /DISCARD/ : { *(.another.*) }
+}
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-discard.s b/ld/testsuite/ld-loongarch-elf/relax-align-discard.s
new file mode 100644
index 00000000..b65d63f3
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-align-discard.s
@@ -0,0 +1,17 @@
+# Use the section name symbol for R_LARCH_ALIGN to avoid discard section problem
+.section ".another.text", "ax"
+.cfi_startproc
+break 0
+.cfi_def_cfa_offset 16
+.p2align 5
+break 1
+.cfi_endproc
+
+.text
+.cfi_startproc
+break 0
+.cfi_def_cfa_offset 16
+.p2align 5
+break 1
+.cfi_endproc
+
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index bca3e1bd..f378b93b 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -295,6 +295,18 @@ if [istarget loongarch64-*-*] {
"relax-align" \
] \
]
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch relax align discard" \
+ "-e 0x0 -T relax-align-discard.lds -r" "" \
+ "" \
+ {relax-align-discard.s} \
+ {} \
+ "relax-align-discard" \
+ ] \
+ ]
}
set objdump_flags "-s -j .data"
--
2.33.0

View File

@ -0,0 +1,25 @@
From 6a455ac82af2d8f5989f71df38f6e779ae202a48 Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Mon, 29 Apr 2024 09:02:43 +0100
Subject: [PATCH 084/123] Fix building Loongarch BFD with a 32-bit compiler
---
bfd/elfnn-loongarch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index ee708c7f..47fd08cd 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -782,7 +782,7 @@ bad_static_reloc (bfd *abfd, const Elf_Internal_Rela *rel, asection *sec,
(*_bfd_error_handler)
(_("%pB:(%pA+%#lx): relocation %s against `%s` can not be used when making "
"a shared object; recompile with -fPIC"),
- abfd, sec, rel->r_offset, r ? r->name : _("<unknown>"), name);
+ abfd, sec, (long) rel->r_offset, r ? r->name : _("<unknown>"), name);
bfd_set_error (bfd_error_bad_value);
return false;
}
--
2.33.0

View File

@ -0,0 +1,26 @@
From 00f4bdc23c28986e4bdff1385ab7c6456fe74a6a Mon Sep 17 00:00:00 2001
From: Xin Wang <wangxin03@loongson.cn>
Date: Thu, 24 Oct 2024 16:45:16 +0800
Subject: [PATCH 120/123] Include ldlex.h when compile eelfxxloongarch.c We did
not cherry-pick 8d10083c23b9415a6d645b44d136104fcf8ed176 of upstream:master
because that modified files which are not related to LoongArch
---
ld/emultempl/loongarchelf.em | 1 +
1 file changed, 1 insertion(+)
diff --git a/ld/emultempl/loongarchelf.em b/ld/emultempl/loongarchelf.em
index 2e6b8080..e50d85d0 100644
--- a/ld/emultempl/loongarchelf.em
+++ b/ld/emultempl/loongarchelf.em
@@ -24,6 +24,7 @@ fragment <<EOF
#include "ldctor.h"
#include "elf/loongarch.h"
#include "elfxx-loongarch.h"
+#include "ldlex.h"
EOF
--
2.33.0

View File

@ -0,0 +1,36 @@
From d1c8ef9a15ddaadd5848949b0958a803fc844674 Mon Sep 17 00:00:00 2001
From: Lulu Cheng <chenglulu@loongson.cn>
Date: Mon, 7 Aug 2023 13:07:05 +0200
Subject: [PATCH 003/123] Libvtv: Add loongarch support.
The loongarch64 specification permits page sizes of 4KiB, 16KiB and 64KiB,
but only 16KiB pages are supported for now.
Co-Authored-By: qijingwen <qijingwen@loongson.cn>
include/
* vtv-change-permission.h (defined): Determines whether the macro
__loongarch_lp64 is defined
(VTV_PAGE_SIZE): Set VTV_PAGE_SIZE to 16KiB for loongarch64.
---
include/vtv-change-permission.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/vtv-change-permission.h b/include/vtv-change-permission.h
index 5906e7d7..ffb53125 100644
--- a/include/vtv-change-permission.h
+++ b/include/vtv-change-permission.h
@@ -48,6 +48,10 @@ extern void __VLTChangePermission (int);
#else
#if defined(__sun__) && defined(__svr4__) && defined(__sparc__)
#define VTV_PAGE_SIZE 8192
+#elif defined(__loongarch_lp64)
+/* The page size is configurable by the kernel to be 4, 16 or 64 KiB.
+ For now, only the default page size of 16KiB is supported. */
+#define VTV_PAGE_SIZE 16384
#else
#define VTV_PAGE_SIZE 4096
#endif
--
2.33.0

View File

@ -0,0 +1,155 @@
From 2a9dd993a723726ccc6f5cfb4119ab6c8637c0d0 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Tue, 16 Jan 2024 15:00:16 +0800
Subject: [PATCH 044/123] LoongArch: Adapt
R_LARCH_{PCALA,GOT,TLS_IE,TLS_DESC}64_* handling per psABI v2.30
In LoongArch psABI v2.30, an offset (-8 for LO20 and -12 for HI12)
should be applied on PC for these reloc types to avoid wrong relocation
when the instruction sequence crosses a page boundary.
The lld linker has already adapted the change. Make it for the bfd
linker too.
Link: https://github.com/loongson/la-abi-specs/releases/v2.30
Link: https://github.com/loongson-community/discussions/issues/17
Link: https://github.com/llvm/llvm-project/pull/73387
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
bfd/elfnn-loongarch.c | 31 +++++++++++--------
.../ld-loongarch-elf/ld-loongarch-elf.exp | 1 +
ld/testsuite/ld-loongarch-elf/pcala64.d | 15 +++++++++
ld/testsuite/ld-loongarch-elf/pcala64.s | 8 +++++
4 files changed, 42 insertions(+), 13 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/pcala64.d
create mode 100644 ld/testsuite/ld-loongarch-elf/pcala64.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 8b71e836..b0ebe89e 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -2529,7 +2529,7 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
({ \
bfd_vma __lo = (relocation & (bfd_vma)0xfff); \
relocation = (relocation & ~(bfd_vma)0xfff) \
- - (pc & ~(bfd_vma)0xfff); \
+ - ((pc) & ~(bfd_vma)0xfff); \
if (__lo > 0x7ff) \
relocation += (0x1000 - 0x100000000); \
if (relocation & 0x80000000) \
@@ -3527,14 +3527,16 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
}
break;
- case R_LARCH_PCALA64_LO20:
case R_LARCH_PCALA64_HI12:
+ pc -= 4;
+ /* Fall through. */
+ case R_LARCH_PCALA64_LO20:
if (h && h->plt.offset != MINUS_ONE)
relocation = sec_addr (plt) + h->plt.offset;
else
relocation += rel->r_addend;
- RELOCATE_CALC_PC64_HI32 (relocation, pc);
+ RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
break;
@@ -3661,9 +3663,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
relocation = got_off + sec_addr (got);
}
- if (r_type == R_LARCH_GOT64_PC_HI12
- || r_type == R_LARCH_GOT64_PC_LO20)
- RELOCATE_CALC_PC64_HI32 (relocation, pc);
+ if (r_type == R_LARCH_GOT64_PC_HI12)
+ RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
+ else if (r_type == R_LARCH_GOT64_PC_LO20)
+ RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
break;
@@ -3864,13 +3867,14 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
/* Use both TLS_GD and TLS_DESC. */
if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
relocation += 2 * GOT_ENTRY_SIZE;
- }
- if (r_type == R_LARCH_TLS_DESC64_PC_LO20
- || r_type == R_LARCH_TLS_DESC64_PC_HI12)
- RELOCATE_CALC_PC64_HI32 (relocation, pc);
+ if (r_type == R_LARCH_TLS_DESC64_PC_LO20)
+ RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
+ else if (r_type == R_LARCH_TLS_DESC64_PC_HI12)
+ RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
break;
+ }
case R_LARCH_TLS_DESC_LD:
case R_LARCH_TLS_DESC_CALL:
@@ -3899,9 +3903,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
relocation += 2 * GOT_ENTRY_SIZE;
- if (r_type == R_LARCH_TLS_IE64_PC_LO20
- || r_type == R_LARCH_TLS_IE64_PC_HI12)
- RELOCATE_CALC_PC64_HI32 (relocation, pc);
+ if (r_type == R_LARCH_TLS_IE64_PC_LO20)
+ RELOCATE_CALC_PC64_HI32 (relocation, pc - 8);
+ else if (r_type == R_LARCH_TLS_IE64_PC_HI12)
+ RELOCATE_CALC_PC64_HI32 (relocation, pc - 12);
break;
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 64e644d3..c81f20af 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -33,6 +33,7 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "disas-jirl"
run_dump_test "local-ifunc-reloc"
run_dump_test "anno-sym"
+ run_dump_test "pcala64"
}
if [istarget "loongarch32-*-*"] {
diff --git a/ld/testsuite/ld-loongarch-elf/pcala64.d b/ld/testsuite/ld-loongarch-elf/pcala64.d
new file mode 100644
index 00000000..e0e9819d
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/pcala64.d
@@ -0,0 +1,15 @@
+#ld: -Ttext=0x180000ff8 -Tdata=0x1000000000
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0000000180000ff8 <_start>:
+[ ]+180000ff8:[ ]+1b000004[ ]+pcalau12i[ ]+\$a0,[ ]+-524288
+[ ]+180000ffc:[ ]+02c0000c[ ]+li.d[ ]+\$t0,[ ]+0
+[ ]+180001000:[ ]+160001ec[ ]+lu32i.d[ ]+\$t0,[ ]+15
+[ ]+180001004:[ ]+0300018c[ ]+lu52i.d[ ]+\$t0,[ ]+\$t0,[ ]+0
+[ ]+180001008:[ ]+0010b084[ ]+add.d[ ]+\$a0,[ ]+\$a0,[ ]+\$t0
+[ ]+18000100c:[ ]+4c000020[ ]+ret
diff --git a/ld/testsuite/ld-loongarch-elf/pcala64.s b/ld/testsuite/ld-loongarch-elf/pcala64.s
new file mode 100644
index 00000000..dfef0e2b
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/pcala64.s
@@ -0,0 +1,8 @@
+.text
+.globl _start
+_start:
+ la.pcrel $a0, $t0, sym
+ jr $ra
+.data
+sym:
+ .dword 0
--
2.33.0

View File

@ -0,0 +1,641 @@
From f0c66bc13d177150c3055cf7c321e48d0eb58b12 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Wed, 30 Oct 2024 18:32:50 +0800
Subject: [PATCH 098/123] LoongArch: Add DT_RELR support
The logic is same as a71d87680110 ("aarch64: Add DT_RELR support").
As LoongArch does not have -z dynamic-undefined-weak, we don't need to
consider UNDEFWEAK_NO_DYNAMIC_RELOC.
The linker relaxation adds another layer of complexity. When we delete
bytes in a section during relaxation, we need to fix up the offset in
the to-be-packed relative relocations against this section.
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
bfd/elfnn-loongarch.c | 488 ++++++++++++++++++++-
binutils/testsuite/lib/binutils-common.exp | 3 +-
ld/emulparams/elf64loongarch.sh | 1 +
3 files changed, 487 insertions(+), 5 deletions(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 2bdd7be2..d11189b4 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -84,6 +84,12 @@ struct _bfd_loongarch_elf_obj_tdata
&& elf_tdata (bfd) != NULL \
&& elf_object_id (bfd) == LARCH_ELF_DATA)
+struct relr_entry
+{
+ asection *sec;
+ bfd_vma off;
+};
+
struct loongarch_elf_link_hash_table
{
struct elf_link_hash_table elf;
@@ -104,8 +110,51 @@ struct loongarch_elf_link_hash_table
/* The data segment phase, don't relax the section
when it is exp_seg_relro_adjust. */
int *data_segment_phase;
+
+ /* Array of relative relocs to be emitted in DT_RELR format. */
+ bfd_size_type relr_alloc;
+ bfd_size_type relr_count;
+ struct relr_entry *relr;
+
+ /* Sorted output addresses of above relative relocs. */
+ bfd_vma *relr_sorted;
+
+ /* Layout recomputation count. */
+ bfd_size_type relr_layout_iter;
+};
+
+struct loongarch_elf_section_data
+{
+ struct bfd_elf_section_data elf;
+
+ /* &htab->relr[i] where i is the smallest number s.t.
+ elf_section_data (htab->relr[i].sec) == &elf.
+ NULL if there exists no such i. */
+ struct relr_entry *relr;
};
+/* We need an additional field in elf_section_data to handle complex
+ interactions between DT_RELR and relaxation. */
+static bool
+loongarch_elf_new_section_hook (bfd *abfd, asection *sec)
+{
+ if (!sec->used_by_bfd)
+ {
+ struct loongarch_elf_section_data *sdata;
+ size_t amt = sizeof (*sdata);
+
+ sdata = bfd_zalloc (abfd, amt);
+ if (!sdata)
+ return false;
+ sec->used_by_bfd = sdata;
+ }
+
+ return _bfd_elf_new_section_hook (abfd, sec);
+}
+
+#define loongarch_elf_section_data(x) \
+ ((struct loongarch_elf_section_data *) elf_section_data (x))
+
/* Get the LoongArch ELF linker hash table from a link_info structure. */
#define loongarch_elf_hash_table(p) \
(elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA \
@@ -927,6 +976,20 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
if (rel + 1 != relocs + sec->reloc_count
&& ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX)
r_type = loongarch_tls_transition (abfd, info, h, r_symndx, r_type);
+
+ /* I don't want to spend time supporting DT_RELR with old object
+ files doing stack-based relocs. */
+ if (info->enable_dt_relr
+ && r_type >= R_LARCH_SOP_PUSH_PCREL
+ && r_type <= R_LARCH_SOP_POP_32_U)
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (_("%pB: stack based reloc type (%u) is not "
+ "supported with -z pack-relative-relocs"),
+ abfd, r_type);
+ return false;
+ }
+
switch (r_type)
{
case R_LARCH_GOT_PC_HI20:
@@ -1143,6 +1206,20 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
return false;
break;
+ case R_LARCH_ALIGN:
+ /* Check against irrational R_LARCH_ALIGN relocs which may cause
+ removing an odd number of bytes and disrupt DT_RELR. */
+ if (rel->r_offset % 4 != 0)
+ {
+ /* xgettext:c-format */
+ _bfd_error_handler (
+ _("%pB: R_LARCH_ALIGN with offset %" PRId64 " not aligned "
+ "to instruction boundary"),
+ abfd, (uint64_t) rel->r_offset);
+ return false;
+ }
+ break;
+
default:
break;
}
@@ -1857,6 +1934,343 @@ maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
return true;
}
+static bool
+record_relr (struct loongarch_elf_link_hash_table *htab, asection *sec,
+ bfd_vma off, asection *sreloc)
+{
+ struct relr_entry **sec_relr = &loongarch_elf_section_data (sec)->relr;
+
+ /* Undo the relocation section size accounting. */
+ BFD_ASSERT (sreloc->size >= sizeof (ElfNN_External_Rela));
+ sreloc->size -= sizeof (ElfNN_External_Rela);
+
+ BFD_ASSERT (off % 2 == 0 && sec->alignment_power > 0);
+ if (htab->relr_count >= htab->relr_alloc)
+ {
+ if (htab->relr_alloc == 0)
+ htab->relr_alloc = 4096;
+ else
+ htab->relr_alloc *= 2;
+
+ htab->relr = bfd_realloc (htab->relr,
+ htab->relr_alloc * sizeof (*htab->relr));
+ if (!htab->relr)
+ return false;
+ }
+ htab->relr[htab->relr_count].sec = sec;
+ htab->relr[htab->relr_count].off = off;
+ if (*sec_relr == NULL)
+ *sec_relr = &htab->relr[htab->relr_count];
+ htab->relr_count++;
+ return true;
+}
+
+static bool
+record_relr_local_got_relocs (bfd *input_bfd, struct bfd_link_info *info)
+{
+ bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
+ char *local_tls_type = _bfd_loongarch_elf_local_got_tls_type (input_bfd);
+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
+ struct loongarch_elf_link_hash_table *htab =
+ loongarch_elf_hash_table (info);
+
+ if (!local_got_offsets || !local_tls_type || !bfd_link_pic (info))
+ return true;
+
+ for (unsigned i = 0; i < symtab_hdr->sh_info; i++)
+ {
+ bfd_vma off = local_got_offsets[i];
+
+ /* FIXME: If the local symbol is in SHN_ABS then emitting
+ a relative relocation is not correct, but it seems to be wrong
+ in loongarch_elf_relocate_section too. */
+ if (local_tls_type[i] == GOT_NORMAL
+ && !record_relr (htab, htab->elf.sgot, off, htab->elf.srelgot))
+ return false;
+ }
+
+ return true;
+}
+
+static bool
+record_relr_dyn_got_relocs (struct elf_link_hash_entry *h, void *inf)
+{
+ struct bfd_link_info *info = (struct bfd_link_info *) inf;
+ struct loongarch_elf_link_hash_table *htab =
+ loongarch_elf_hash_table (info);
+
+ if (h->root.type == bfd_link_hash_indirect)
+ return true;
+ if (h->type == STT_GNU_IFUNC && h->def_regular)
+ return true;
+ if (h->got.refcount <= 0)
+ return true;
+ if (loongarch_elf_hash_entry (h)->tls_type
+ & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
+ return true;
+ if (!bfd_link_pic (info))
+ return true;
+
+ /* On LoongArch a GOT entry for undefined weak symbol is never relocated
+ with R_LARCH_RELATIVE: we don't have -z dynamic-undefined-weak, thus
+ the GOT entry is either const 0 (if the symbol is LARCH_REF_LOCAL) or
+ relocated with R_LARCH_NN (otherwise). */
+ if (h->root.type == bfd_link_hash_undefweak)
+ return true;
+
+ if (!LARCH_REF_LOCAL (info, h))
+ return true;
+ if (bfd_is_abs_symbol (&h->root))
+ return true;
+
+ if (!record_relr (htab, htab->elf.sgot, h->got.offset,
+ htab->elf.srelgot))
+ return false;
+
+ return true;
+}
+
+static bool
+record_relr_non_got_relocs (bfd *input_bfd, struct bfd_link_info *info,
+ asection *sec)
+{
+ asection *sreloc;
+ struct loongarch_elf_link_hash_table *htab;
+ Elf_Internal_Rela *relocs, *rel, *rel_end;
+ Elf_Internal_Shdr *symtab_hdr;
+ struct elf_link_hash_entry **sym_hashes;
+
+ if (!bfd_link_pic (info))
+ return true;
+ if (sec->reloc_count == 0)
+ return true;
+ if ((sec->flags & (SEC_RELOC | SEC_ALLOC | SEC_DEBUGGING))
+ != (SEC_RELOC | SEC_ALLOC))
+ return true;
+ if (sec->alignment_power == 0)
+ return true;
+ if (discarded_section (sec))
+ return true;
+
+ sreloc = elf_section_data (sec)->sreloc;
+ if (sreloc == NULL)
+ return true;
+
+ htab = loongarch_elf_hash_table (info);
+ symtab_hdr = &elf_symtab_hdr (input_bfd);
+ sym_hashes = elf_sym_hashes (input_bfd);
+ relocs = _bfd_elf_link_info_read_relocs (input_bfd, info, sec, NULL,
+ NULL, info->keep_memory);
+ BFD_ASSERT (relocs != NULL);
+ rel_end = relocs + sec->reloc_count;
+ for (rel = relocs; rel < rel_end; rel++)
+ {
+ unsigned r_symndx = ELFNN_R_SYM (rel->r_info);
+ unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
+ struct elf_link_hash_entry *h = NULL;
+ asection *def_sec = NULL;
+
+ if ((r_type != R_LARCH_64 && r_type != R_LARCH_32)
+ || rel->r_offset % 2 != 0)
+ continue;
+
+ /* The logical below must match loongarch_elf_relocate_section. */
+ if (r_symndx < symtab_hdr->sh_info)
+ {
+ /* A local symbol. */
+ Elf_Internal_Sym *isym;
+ isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache, input_bfd,
+ r_symndx);
+ BFD_ASSERT(isym != NULL);
+
+ /* Local STT_GNU_IFUNC symbol uses R_LARCH_IRELATIVE for
+ R_LARCH_NN, not R_LARCH_RELATIVE. */
+ if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+ continue;
+ def_sec = bfd_section_from_elf_index (input_bfd, isym->st_shndx);
+ }
+ else
+ {
+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ /* Filter out symbols that cannot have a relative reloc. */
+ if (h->dyn_relocs == NULL)
+ continue;
+ if (bfd_is_abs_symbol (&h->root))
+ continue;
+ if (h->type == STT_GNU_IFUNC)
+ continue;
+
+ if (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak)
+ def_sec = h->root.u.def.section;
+
+ /* On LoongArch an R_LARCH_NN against undefined weak symbol
+ is never converted to R_LARCH_RELATIVE: we don't have
+ -z dynamic-undefined-weak, thus the reloc is either removed
+ (if the symbol is LARCH_REF_LOCAL) or kept (otherwise). */
+ if (h->root.type == bfd_link_hash_undefweak)
+ continue;
+
+ if (!LARCH_REF_LOCAL (info, h))
+ continue;
+ }
+
+ if (!def_sec || discarded_section (def_sec))
+ continue;
+
+ if (!record_relr (htab, sec, rel->r_offset, sreloc))
+ return false;
+ }
+
+ return true;
+}
+
+static int
+cmp_relr_addr (const void *p, const void *q)
+{
+ const bfd_vma *a = p, *b = q;
+ return (*a > *b) - (*a < *b);
+}
+
+static bool
+sort_relr (struct bfd_link_info *info,
+ struct loongarch_elf_link_hash_table *htab)
+{
+ if (htab->relr_count == 0)
+ return true;
+
+ bfd_vma *addr = htab->relr_sorted;
+ if (!addr)
+ {
+ addr = bfd_malloc (htab->relr_count * sizeof (*addr));
+ if (!addr)
+ return false;
+ htab->relr_sorted = addr;
+ }
+
+ for (bfd_size_type i = 0; i < htab->relr_count; i++)
+ {
+ bfd_vma off = _bfd_elf_section_offset (info->output_bfd, info,
+ htab->relr[i].sec,
+ htab->relr[i].off);
+ addr[i] = htab->relr[i].sec->output_section->vma
+ + htab->relr[i].sec->output_offset + off;
+ }
+ qsort(addr, htab->relr_count, sizeof (*addr), cmp_relr_addr);
+ return true;
+}
+
+static bool
+loongarch_elf_size_relative_relocs (struct bfd_link_info *info,
+ bool *need_layout)
+{
+ struct loongarch_elf_link_hash_table *htab =
+ loongarch_elf_hash_table (info);
+ asection *srelrdyn = htab->elf.srelrdyn;
+
+ *need_layout = false;
+
+ if (!sort_relr (info, htab))
+ return false;
+ bfd_vma *addr = htab->relr_sorted;
+
+ BFD_ASSERT (srelrdyn != NULL);
+ bfd_size_type oldsize = srelrdyn->size;
+ srelrdyn->size = 0;
+ for (bfd_size_type i = 0; i < htab->relr_count; )
+ {
+ bfd_vma base = addr[i];
+ i++;
+ srelrdyn->size += NN / 8;
+ base += NN / 8;
+ while (1)
+ {
+ bfd_size_type start_i = i;
+ while (i < htab->relr_count
+ && addr[i] - base < (NN - 1) * (NN / 8)
+ && (addr[i] - base) % (NN / 8) == 0)
+ i++;
+ if (i == start_i)
+ break;
+ srelrdyn->size += NN / 8;
+ base += (NN - 1) * (NN / 8);
+ }
+ }
+ if (srelrdyn->size != oldsize)
+ {
+ *need_layout = true;
+ /* Stop after a few iterations in case the layout does not converge,
+ but we can only stop when the size would shrink (and pad the
+ spare space with 1. */
+ if (htab->relr_layout_iter++ > 5 && srelrdyn->size < oldsize)
+ {
+ srelrdyn->size = oldsize;
+ *need_layout = false;
+ }
+ }
+ return true;
+}
+
+static bool
+loongarch_elf_finish_relative_relocs (struct bfd_link_info *info)
+{
+ struct loongarch_elf_link_hash_table *htab =
+ loongarch_elf_hash_table (info);
+ asection *srelrdyn = htab->elf.srelrdyn;
+ bfd *dynobj = htab->elf.dynobj;
+
+ if (!srelrdyn || srelrdyn->size == 0)
+ return true;
+
+ srelrdyn->contents = bfd_alloc (dynobj, srelrdyn->size);
+ if (!srelrdyn->contents)
+ return false;
+
+ bfd_vma *addr = htab->relr_sorted;
+ bfd_byte *loc = srelrdyn->contents;
+ for (bfd_size_type i = 0; i < htab->relr_count; )
+ {
+ bfd_vma base = addr[i];
+ i++;
+ bfd_put_NN (dynobj, base, loc);
+ loc += NN / 8;
+ base += NN / 8;
+ while (1)
+ {
+ uintNN_t bits = 0;
+ while (i < htab->relr_count)
+ {
+ bfd_vma delta = addr[i] - base;
+ if (delta >= (NN - 1) * (NN / 8) || delta % (NN / 8) != 0)
+ break;
+ bits |= (uintNN_t) 1 << (delta / (NN / 8));
+ i++;
+ }
+ if (bits == 0)
+ break;
+ bfd_put_NN (dynobj, (bits << 1) | 1, loc);
+ loc += NN / 8;
+ base += (NN - 1) * (NN / 8);
+ }
+ }
+
+ free (addr);
+ htab->relr_sorted = NULL;
+
+ /* Pad any excess with 1's, a do-nothing encoding. */
+ while (loc < srelrdyn->contents + srelrdyn->size)
+ {
+ bfd_put_NN (dynobj, 1, loc);
+ loc += NN / 8;
+ }
+
+ return true;
+}
+
static bool
loongarch_elf_size_dynamic_sections (bfd *output_bfd,
struct bfd_link_info *info)
@@ -2036,6 +2450,24 @@ loongarch_elf_size_dynamic_sections (bfd *output_bfd,
&& (htab->elf.splt == NULL || htab->elf.splt->size == 0))
htab->elf.sgotplt->size = 0;
+ if (info->enable_dt_relr && !bfd_link_relocatable (info))
+ {
+ elf_link_hash_traverse (&htab->elf, record_relr_dyn_got_relocs, info);
+
+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
+ {
+ if (!is_loongarch_elf (ibfd))
+ continue;
+
+ for (s = ibfd->sections; s != NULL; s = s->next)
+ if (!record_relr_non_got_relocs (ibfd, info, s))
+ return false;
+
+ if (!record_relr_local_got_relocs (ibfd, info))
+ return false;
+ }
+ }
+
/* The check_relocs and adjust_dynamic_symbol entry points have
determined the sizes of the various dynamic sections. Allocate
memory for them. */
@@ -2060,6 +2492,14 @@ loongarch_elf_size_dynamic_sections (bfd *output_bfd,
s->reloc_count = 0;
}
}
+ else if (s == htab->elf.srelrdyn && htab->relr_count == 0)
+ {
+ /* Remove .relr.dyn based on relr_count, not size, since
+ it is not sized yet. */
+ s->flags |= SEC_EXCLUDE;
+ /* Allocate contents later. */
+ continue;
+ }
else
{
/* It's not one of our sections. */
@@ -2976,7 +3416,21 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (unresolved_reloc
&& (ARCH_SIZE == 32 || r_type != R_LARCH_32)
&& !(h && (h->is_weakalias || !h->dyn_relocs)))
- loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
+ {
+ if (info->enable_dt_relr
+ && (ELFNN_R_TYPE (outrel.r_info) == R_LARCH_RELATIVE)
+ && input_section->alignment_power != 0
+ && rel->r_offset % 2 == 0)
+ /* Don't emit a relative relocation that is packed,
+ only apply the addend (as if we are applying the
+ original R_LARCH_NN reloc in a PDE). */
+ r = perform_relocation (rel, input_section, howto,
+ relocation, input_bfd,
+ contents);
+ else
+ loongarch_elf_append_rela (output_bfd, sreloc,
+ &outrel);
+ }
}
relocation += rel->r_addend;
@@ -3700,7 +4154,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
if ((local_got_offsets[r_symndx] & 1) == 0)
{
- if (bfd_link_pic (info))
+ if (bfd_link_pic (info) && !info->enable_dt_relr)
{
Elf_Internal_Rela rela;
rela.r_offset = sec_addr (got) + got_off;
@@ -4112,6 +4566,13 @@ loongarch_relax_delete_bytes (bfd *abfd,
unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
struct bfd_elf_section_data *data = elf_section_data (sec);
bfd_byte *contents = data->this_hdr.contents;
+ struct relr_entry *relr = loongarch_elf_section_data (sec)->relr;
+ struct loongarch_elf_link_hash_table *htab =
+ loongarch_elf_hash_table (link_info);
+ struct relr_entry *relr_end = NULL;
+
+ if (htab->relr_count)
+ relr_end = htab->relr + htab->relr_count;
/* Actually delete the bytes. */
sec->size -= count;
@@ -4124,6 +4585,11 @@ loongarch_relax_delete_bytes (bfd *abfd,
if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr)
data->relocs[i].r_offset -= count;
+ /* Likewise for relative relocs to be packed into .relr. */
+ for (; relr && relr < relr_end && relr->sec == sec; relr++)
+ if (relr->off > addr && relr->off < toaddr)
+ relr->off -= count;
+
/* Adjust the local symbols defined in this section. */
for (i = 0; i < symtab_hdr->sh_info; i++)
{
@@ -5212,9 +5678,18 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
else if (bfd_link_pic (info) && LARCH_REF_LOCAL (info, h))
{
asection *sec = h->root.u.def.section;
+ bfd_vma linkaddr = h->root.u.def.value + sec->output_section->vma
+ + sec->output_offset;
+
+ /* Don't emit relative relocs if they are packed, but we need
+ to write the addend (link-time addr) into the GOT then. */
+ if (info->enable_dt_relr)
+ {
+ bfd_put_NN (output_bfd, linkaddr, sgot->contents + off);
+ goto skip_got_reloc;
+ }
rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
- rela.r_addend = (h->root.u.def.value + sec->output_section->vma
- + sec->output_offset);
+ rela.r_addend = linkaddr;
}
else
{
@@ -5225,6 +5700,7 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
loongarch_elf_append_rela (output_bfd, srela, &rela);
}
+skip_got_reloc:
/* Mark some specially defined symbols as absolute. */
if (h == htab->elf.hdynamic || h == htab->elf.hgot || h == htab->elf.hplt)
@@ -5678,6 +6154,10 @@ elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
#define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
#define elf_backend_hash_symbol elf_loongarch64_hash_symbol
#define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
+#define elf_backend_size_relative_relocs loongarch_elf_size_relative_relocs
+#define elf_backend_finish_relative_relocs \
+ loongarch_elf_finish_relative_relocs
+#define bfd_elfNN_new_section_hook loongarch_elf_new_section_hook
#define elf_backend_dtrel_excludes_plt 1
diff --git a/binutils/testsuite/lib/binutils-common.exp b/binutils/testsuite/lib/binutils-common.exp
index 7e6bf16e..d006d30d 100644
--- a/binutils/testsuite/lib/binutils-common.exp
+++ b/binutils/testsuite/lib/binutils-common.exp
@@ -444,7 +444,8 @@ proc supports_persistent_section {} {
proc supports_dt_relr {} {
if { ([istarget x86_64-*-*]
|| [istarget i?86-*-*]
- || [istarget powerpc64*-*-*])
+ || [istarget powerpc64*-*-*]
+ || [istarget loongarch64*-*-*])
&& ([istarget *-*-linux*]
|| [istarget *-*-gnu*]) } {
return 1
diff --git a/ld/emulparams/elf64loongarch.sh b/ld/emulparams/elf64loongarch.sh
index d7b2229e..8c805da9 100644
--- a/ld/emulparams/elf64loongarch.sh
+++ b/ld/emulparams/elf64loongarch.sh
@@ -1,4 +1,5 @@
source_sh ${srcdir}/emulparams/elf64loongarch-defs.sh
+source_sh ${srcdir}/emulparams/dt-relr.sh
OUTPUT_FORMAT="elf64-loongarch"
case "$target" in
--
2.33.0

View File

@ -0,0 +1,663 @@
From c3d71bd5b8f0f949729025ad3338e3f93e5e0d77 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Sun, 30 Jun 2024 15:18:25 +0800
Subject: [PATCH 099/123] LoongArch: Add DT_RELR tests
Most tests are ported from AArch64.
The relr-addend test is added to make sure the addend (link-time address)
is correctly written into the relocated section. Doing so is not
strictly needed for RELA, but strictly needed for RELR).
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
.../ld-loongarch-elf/ld-loongarch-elf.exp | 10 ++
ld/testsuite/ld-loongarch-elf/relr-addend.d | 11 ++
ld/testsuite/ld-loongarch-elf/relr-addend.s | 17 +++
ld/testsuite/ld-loongarch-elf/relr-align.d | 22 ++++
ld/testsuite/ld-loongarch-elf/relr-align.s | 106 ++++++++++++++++++
ld/testsuite/ld-loongarch-elf/relr-data-pie.d | 18 +++
.../ld-loongarch-elf/relr-data-shared.d | 18 +++
ld/testsuite/ld-loongarch-elf/relr-data.s | 71 ++++++++++++
.../ld-loongarch-elf/relr-discard-pie.d | 8 ++
.../ld-loongarch-elf/relr-discard-shared.d | 11 ++
ld/testsuite/ld-loongarch-elf/relr-discard.ld | 13 +++
ld/testsuite/ld-loongarch-elf/relr-discard.s | 61 ++++++++++
ld/testsuite/ld-loongarch-elf/relr-got-pie.d | 15 +++
.../ld-loongarch-elf/relr-got-shared.d | 15 +++
ld/testsuite/ld-loongarch-elf/relr-got.s | 27 +++++
ld/testsuite/ld-loongarch-elf/relr-relocs.ld | 24 ++++
ld/testsuite/ld-loongarch-elf/relr-text-pie.d | 14 +++
.../ld-loongarch-elf/relr-text-shared.d | 14 +++
ld/testsuite/ld-loongarch-elf/relr-text.s | 10 ++
19 files changed, 485 insertions(+)
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-addend.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-addend.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-align.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-align.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-data-pie.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-data-shared.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-data.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-discard-pie.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-discard-shared.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-discard.ld
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-discard.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-got-pie.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-got-shared.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-got.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-relocs.ld
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-text-pie.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-text-shared.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-text.s
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 30d7bc03..2be67651 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -135,10 +135,20 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "r_larch_32_elf64"
run_dump_test "ifunc-reloc"
run_dump_test "protected-func"
+ run_dump_test "relr-addend"
+ run_dump_test "relr-align"
+ run_dump_test "relr-data-shared"
+ run_dump_test "relr-discard-shared"
+ run_dump_test "relr-got-shared"
+ run_dump_test "relr-text-shared"
}
if [check_pie_support] {
run_dump_test "pie_discard"
+ run_dump_test "relr-data-pie"
+ run_dump_test "relr-discard-pie"
+ run_dump_test "relr-got-pie"
+ run_dump_test "relr-text-pie"
}
run_dump_test "max_imm_b16"
diff --git a/ld/testsuite/ld-loongarch-elf/relr-addend.d b/ld/testsuite/ld-loongarch-elf/relr-addend.d
new file mode 100644
index 00000000..da13c2cf
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-addend.d
@@ -0,0 +1,11 @@
+#ld: -shared -z pack-relative-relocs -T relr-relocs.ld
+#objdump: -s -j.got -j.data
+
+.*: file format elf64-loongarch
+
+Contents of section \.got:
+ 20000 [0-9a-f]+ [0-9a-f]+ 00003412 00000000 .*
+ 20010 08003412 00000000 .*
+Contents of section \.data:
+ 12340000 14451100 00000000 10989101 00000000 .*
+ 12340010 00003412 00000000 08003412 00000000 .*
diff --git a/ld/testsuite/ld-loongarch-elf/relr-addend.s b/ld/testsuite/ld-loongarch-elf/relr-addend.s
new file mode 100644
index 00000000..3d08f6ca
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-addend.s
@@ -0,0 +1,17 @@
+.data
+.align 8
+x:
+ .quad 0x114514
+y:
+ .quad 0x1919810
+px:
+ .quad x
+py:
+ .quad y
+
+.text
+.align 2
+_start:
+ la.got $a0, x
+ la.got $a1, y
+ ret
diff --git a/ld/testsuite/ld-loongarch-elf/relr-align.d b/ld/testsuite/ld-loongarch-elf/relr-align.d
new file mode 100644
index 00000000..d534243b
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-align.d
@@ -0,0 +1,22 @@
+#source: relr-align.s
+#ld: -shared -z pack-relative-relocs -T relr-relocs.ld
+#readelf: -rW
+
+Relocation section '\.rela.dyn' at offset 0x[0-9a-f]+ contains 3 entries:
+ Offset Info Type Symbol's Value Symbol's Name \+ Addend
+0000000012340011 0000000000000003 R_LARCH_RELATIVE 10000
+0000000012340019 0000000000000003 R_LARCH_RELATIVE 10000
+0000000012340041 0000000000000003 R_LARCH_RELATIVE 10000
+
+Relocation section '\.relr.dyn' at offset 0x[0-9a-f]+ contains 9 entries which relocate 10 locations:
+Index: Entry Address Symbolic Address
+0000: 0000000012340000 0000000012340000 double_0
+0001: 0000000000000003 0000000012340008 double_0 \+ 0x8
+0002: 0000000012340022 0000000012340022 double_2
+0003: 0000000000000003 000000001234002a double_2 \+ 0x8
+0004: 0000000012340038 0000000012340038 single_0
+0005: 000000001234004a 000000001234004a single_2
+0006: 0000000012340058 0000000012340058 big
+0007: 8000000100000001 0000000012340158 big \+ 0x100
+ 0000000012340250 big \+ 0x1f8
+0008: 0000000000000003 0000000012340258 big \+ 0x200
diff --git a/ld/testsuite/ld-loongarch-elf/relr-align.s b/ld/testsuite/ld-loongarch-elf/relr-align.s
new file mode 100644
index 00000000..ddd055ab
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-align.s
@@ -0,0 +1,106 @@
+# Test DT_RELR with differently aligned relative relocs.
+
+.text
+.global _start
+_start:
+foo:
+
+.data
+.p2align 3
+double_0:
+.quad foo
+.quad foo
+.byte 0
+double_1:
+.quad foo
+.quad foo
+.byte 0
+double_2:
+.quad foo
+.quad foo
+.byte 0
+.byte 0
+.byte 0
+.byte 0
+.byte 0
+.byte 0
+single_0:
+.quad foo
+.byte 0
+single_1:
+.quad foo
+.byte 0
+single_2:
+.quad foo
+.byte 0
+.byte 0
+.byte 0
+.byte 0
+.byte 0
+.byte 0
+big:
+.quad foo
+.quad 1
+.quad 2
+.quad 3
+.quad 4
+.quad 5
+.quad 6
+.quad 7
+.quad 8
+.quad 9
+.quad 10
+.quad 11
+.quad 12
+.quad 13
+.quad 14
+.quad 15
+.quad 16
+.quad 17
+.quad 18
+.quad 19
+.quad 20
+.quad 21
+.quad 22
+.quad 23
+.quad 24
+.quad 25
+.quad 26
+.quad 27
+.quad 28
+.quad 29
+.quad 30
+.quad 31
+.quad foo + 32
+.quad 33
+.quad 34
+.quad 35
+.quad 36
+.quad 37
+.quad 38
+.quad 39
+.quad 40
+.quad 41
+.quad 42
+.quad 43
+.quad 44
+.quad 45
+.quad 46
+.quad 47
+.quad 48
+.quad 49
+.quad 50
+.quad 51
+.quad 52
+.quad 53
+.quad 54
+.quad 55
+.quad 56
+.quad 57
+.quad 58
+.quad 59
+.quad 60
+.quad 61
+.quad 62
+.quad foo + 63
+.quad foo + 64
diff --git a/ld/testsuite/ld-loongarch-elf/relr-data-pie.d b/ld/testsuite/ld-loongarch-elf/relr-data-pie.d
new file mode 100644
index 00000000..20ef9ac1
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-data-pie.d
@@ -0,0 +1,18 @@
+#source: relr-data.s
+#ld: -pie -z pack-relative-relocs -T relr-relocs.ld
+#readelf: -rW
+
+Relocation section '\.rela\.dyn' at offset 0x[0-9a-f]+ contains 5 entries:
+ Offset Info Type Symbol's Value Symbol's Name \+ Addend
+0000000012340000 0000000000000003 R_LARCH_RELATIVE 10004
+0000000012340008 0000000000000003 R_LARCH_RELATIVE 10008
+0000000012340010 0000000000000003 R_LARCH_RELATIVE 1000c
+0000000012340018 0000000000000003 R_LARCH_RELATIVE 12340050
+0000000012340040 0000000c00000002 R_LARCH_64 0000000000000000 sym_weak_undef \+ 0
+
+Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate 4 locations:
+Index: Entry Address Symbolic Address
+0000: 0000000012340020 0000000012340020 aligned_local
+0001: 0000000000000027 0000000012340028 aligned_hidden
+ 0000000012340030 aligned_global
+ 0000000012340048 aligned_DYNAMIC
diff --git a/ld/testsuite/ld-loongarch-elf/relr-data-shared.d b/ld/testsuite/ld-loongarch-elf/relr-data-shared.d
new file mode 100644
index 00000000..37e4c0da
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-data-shared.d
@@ -0,0 +1,18 @@
+#source: relr-data.s
+#ld: -shared -z pack-relative-relocs -T relr-relocs.ld
+#readelf: -rW
+
+Relocation section '\.rela\.dyn' at offset 0x[0-9a-f]+ contains 6 entries:
+ Offset Info Type Symbol's Value Symbol's Name \+ Addend
+0000000012340000 0000000000000003 R_LARCH_RELATIVE 10004
+0000000012340008 0000000000000003 R_LARCH_RELATIVE 10008
+0000000012340018 0000000000000003 R_LARCH_RELATIVE 12340050
+0000000012340010 0000000d00000002 R_LARCH_64 000000000001000c sym_global \+ 0
+0000000012340030 0000000d00000002 R_LARCH_64 000000000001000c sym_global \+ 0
+0000000012340040 0000000c00000002 R_LARCH_64 0000000000000000 sym_weak_undef \+ 0
+
+Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate 3 locations:
+Index: Entry Address Symbolic Address
+0000: 0000000012340020 0000000012340020 aligned_local
+0001: 0000000000000023 0000000012340028 aligned_hidden
+ 0000000012340048 aligned_DYNAMIC
diff --git a/ld/testsuite/ld-loongarch-elf/relr-data.s b/ld/testsuite/ld-loongarch-elf/relr-data.s
new file mode 100644
index 00000000..03673e0f
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-data.s
@@ -0,0 +1,71 @@
+# Test symbol references in .data when used with DT_RELR.
+# Relocations for unaligned sections are currently not packed.
+
+.text
+.global _start
+_start:
+ nop
+
+sym_local:
+ nop
+
+.global sym_hidden
+.hidden sym_hidden
+sym_hidden:
+ nop
+
+.global sym_global
+sym_global:
+ nop
+
+.global sym_global_abs
+.set sym_global_abs, 42
+
+.global sym_weak_undef
+.weak sym_weak_undef
+
+.section .data.unaligned_local
+unaligned_local:
+.quad sym_local
+
+.section .data.unaligned_hidden
+unaligned_hidden:
+.quad sym_hidden
+
+.section .data.unaligned_global
+unaligned_global:
+.quad sym_global
+
+.section .data.unaligned_DYNAMIC
+unaligned_DYNAMIC:
+.quad _DYNAMIC
+
+.section .data.aligned_local
+.p2align 1
+aligned_local:
+.quad sym_local
+
+.section .data.aligned_hidden
+.p2align 1
+aligned_hidden:
+.quad sym_hidden
+
+.section .data.aligned_global
+.p2align 1
+aligned_global:
+.quad sym_global
+
+.section .data.aligned_global_abs
+.p2align 1
+aligned_global_abs:
+.quad sym_global_abs
+
+.section .data.aligned_weak_undef
+.p2align 1
+aligned_weak_undef:
+.quad sym_weak_undef
+
+.section .data.aligned_DYNAMIC
+.p2align 1
+aligned_DYNAMIC:
+.quad _DYNAMIC
diff --git a/ld/testsuite/ld-loongarch-elf/relr-discard-pie.d b/ld/testsuite/ld-loongarch-elf/relr-discard-pie.d
new file mode 100644
index 00000000..4ea8ae5e
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-discard-pie.d
@@ -0,0 +1,8 @@
+#source: relr-discard.s
+#ld: -pie -z pack-relative-relocs -T relr-discard.ld
+#readelf: -rW
+
+Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate 2 locations:
+Index: Entry Address Symbolic Address
+0000: 0000000000020008 0000000000020008 _GLOBAL_OFFSET_TABLE_ \+ 0x8
+0001: 0000000000000003 0000000000020010 _GLOBAL_OFFSET_TABLE_ \+ 0x10
diff --git a/ld/testsuite/ld-loongarch-elf/relr-discard-shared.d b/ld/testsuite/ld-loongarch-elf/relr-discard-shared.d
new file mode 100644
index 00000000..8bfd8ba5
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-discard-shared.d
@@ -0,0 +1,11 @@
+#source: relr-discard.s
+#ld: -shared -z pack-relative-relocs -T relr-discard.ld
+#readelf: -rW
+
+Relocation section '\.rela\.dyn' at offset 0x[0-9a-f]+ contains 1 entry:
+ Offset Info Type Symbol's Value Symbol's Name \+ Addend
+0000000000020010 0000000300000002 R_LARCH_64 000000000001000c sym_global \+ 0
+
+Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 1 entry which relocates 1 location:
+Index: Entry Address Symbolic Address
+0000: 0000000000020008 0000000000020008 _GLOBAL_OFFSET_TABLE_ \+ 0x8
diff --git a/ld/testsuite/ld-loongarch-elf/relr-discard.ld b/ld/testsuite/ld-loongarch-elf/relr-discard.ld
new file mode 100644
index 00000000..165f1ed2
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-discard.ld
@@ -0,0 +1,13 @@
+OUTPUT_ARCH(loongarch64)
+ENTRY(_start)
+SECTIONS
+{
+ /DISCARD/ : { *(.discard.*) }
+
+ . = 0x10000;
+ .text : { *(.text) }
+ . = 0x20000;
+ .got : { *(.got) *(.got.plt)}
+ . = 0x30000;
+ .data : { *(.data) *(.data.*) }
+}
diff --git a/ld/testsuite/ld-loongarch-elf/relr-discard.s b/ld/testsuite/ld-loongarch-elf/relr-discard.s
new file mode 100644
index 00000000..b52374a5
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-discard.s
@@ -0,0 +1,61 @@
+# Test DT_RELR with references in discarded sections.
+
+.text
+.p2align 3
+.global _start
+_start:
+ nop
+
+sym_local:
+ nop
+
+.global sym_hidden
+.hidden sym_hidden
+sym_hidden:
+ nop
+
+.global sym_global
+sym_global:
+ nop
+
+.global sym_global_abs
+.set sym_global_abs, 42
+
+.global sym_weak_undef
+.weak sym_weak_undef
+
+.section .discard.got_local,"ax"
+ la.got $a0, sym_local
+
+.section .discard.got_global,"ax"
+ la.got $a0, sym_global
+
+.section .discard.local,"a"
+.p2align 1
+discard_local:
+.quad sym_local
+
+.section .discard.hidden,"a"
+.p2align 1
+discard_hidden:
+.quad sym_hidden
+
+.section .discard.global,"a"
+.p2align 1
+discard_global:
+.quad sym_global
+
+.section .discard.global_abs,"a"
+.p2align 1
+discard_global_abs:
+.quad sym_global_abs
+
+.section .discard.weak_undef,"a"
+.p2align 1
+discard_weak_undef:
+.quad sym_weak_undef
+
+.section .discard._DYNAMIC,"a"
+.p2align 1
+discard_DYNAMIC:
+.quad _DYNAMIC
diff --git a/ld/testsuite/ld-loongarch-elf/relr-got-pie.d b/ld/testsuite/ld-loongarch-elf/relr-got-pie.d
new file mode 100644
index 00000000..e994f2bf
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-got-pie.d
@@ -0,0 +1,15 @@
+#source: relr-got.s
+#ld: -pie -z pack-relative-relocs -T relr-relocs.ld
+#readelf: -rW
+
+Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 2 entries:
+ Offset Info Type Symbol's Value Symbol's Name \+ Addend
+0000000000000000 0000000000000000 R_LARCH_NONE 0
+0000000000020030 0000000200000002 R_LARCH_64 0000000000000000 sym_weak_undef \+ 0
+
+Relocation section '.relr.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate 4 locations:
+Index: Entry Address Symbolic Address
+0000: 0000000000020008 0000000000020008 _GLOBAL_OFFSET_TABLE_ \+ 0x8
+0001: 000000000000000f 0000000000020010 _GLOBAL_OFFSET_TABLE_ \+ 0x10
+ 0000000000020018 _GLOBAL_OFFSET_TABLE_ \+ 0x18
+ 0000000000020020 _GLOBAL_OFFSET_TABLE_ \+ 0x20
diff --git a/ld/testsuite/ld-loongarch-elf/relr-got-shared.d b/ld/testsuite/ld-loongarch-elf/relr-got-shared.d
new file mode 100644
index 00000000..169e0e5d
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-got-shared.d
@@ -0,0 +1,15 @@
+#source: relr-got.s
+#ld: -shared -z pack-relative-relocs -T relr-relocs.ld
+#readelf: -rW
+
+Relocation section '\.rela\.dyn' at offset 0x[0-9a-f]+ contains 3 entries:
+ Offset Info Type Symbol's Value Symbol's Name \+ Addend
+0000000000020020 0000000300000002 R_LARCH_64 0000000000010034 sym_global \+ 0
+0000000000020028 0000000500000002 R_LARCH_64 000000000000002a sym_global_abs \+ 0
+0000000000020030 0000000200000002 R_LARCH_64 0000000000000000 sym_weak_undef \+ 0
+
+Relocation section '\.relr\.dyn' at offset 0x[0-9a-f]+ contains 2 entries which relocate 3 locations:
+Index: Entry Address Symbolic Address
+0000: 0000000000020008 0000000000020008 _GLOBAL_OFFSET_TABLE_ \+ 0x8
+0001: 0000000000000007 0000000000020010 _GLOBAL_OFFSET_TABLE_ \+ 0x10
+ 0000000000020018 _GLOBAL_OFFSET_TABLE_ \+ 0x18
diff --git a/ld/testsuite/ld-loongarch-elf/relr-got.s b/ld/testsuite/ld-loongarch-elf/relr-got.s
new file mode 100644
index 00000000..162528bc
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-got.s
@@ -0,0 +1,27 @@
+.text
+.global _start
+_start:
+ la.got $a0, sym_local
+ la.got $a1, sym_hidden
+ la.got $a2, sym_global
+ la.got $a3, sym_global_abs
+ la.got $a4, sym_weak_undef
+ la.got $a5, _DYNAMIC
+
+sym_local:
+ nop
+
+.global sym_hidden
+.hidden sym_hidden
+sym_hidden:
+ nop
+
+.global sym_global
+sym_global:
+ nop
+
+.global sym_global_abs
+.set sym_global_abs, 42
+
+.global sym_weak_undef
+.weak sym_weak_undef
diff --git a/ld/testsuite/ld-loongarch-elf/relr-relocs.ld b/ld/testsuite/ld-loongarch-elf/relr-relocs.ld
new file mode 100644
index 00000000..ed83275b
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-relocs.ld
@@ -0,0 +1,24 @@
+/* Script for DT_RELR tests */
+OUTPUT_ARCH(loongarch64)
+ENTRY(_start)
+SECTIONS
+{
+ PROVIDE (__executable_start = 0x8000); . = 0x10000;
+ .text :
+ {
+ *(.before)
+ *(.text)
+ *(.after)
+ } =0
+ . = 0x20000;
+ .got :
+ {
+ *(.got)
+ *(.got.plt)
+ }
+ . = 0x12340000;
+ .data :
+ {
+ *(.data)
+ }
+}
diff --git a/ld/testsuite/ld-loongarch-elf/relr-text-pie.d b/ld/testsuite/ld-loongarch-elf/relr-text-pie.d
new file mode 100644
index 00000000..5121313e
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-text-pie.d
@@ -0,0 +1,14 @@
+#source: relr-text.s
+#ld: -pie -z pack-relative-relocs -T relr-relocs.ld
+#readelf: -drW
+
+#...
+ 0x0000000000000016 \(TEXTREL\) 0x0
+#...
+ 0x0000000000000024 \(RELR\) .*
+ 0x0000000000000023 \(RELRSZ\) 8 \(bytes\)
+ 0x0000000000000025 \(RELRENT\) 8 \(bytes\)
+#...
+Relocation section '\.relr\.dyn' .* contains 1 entry which relocates 1 location:
+Index: Entry Address Symbolic Address
+0000: 0000000000010000 0000000000010000 _start
diff --git a/ld/testsuite/ld-loongarch-elf/relr-text-shared.d b/ld/testsuite/ld-loongarch-elf/relr-text-shared.d
new file mode 100644
index 00000000..8e34500f
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-text-shared.d
@@ -0,0 +1,14 @@
+#source: relr-text.s
+#ld: -shared -z pack-relative-relocs -T relr-relocs.ld
+#readelf: -drW
+
+#...
+ 0x0000000000000016 \(TEXTREL\) 0x0
+#...
+ 0x0000000000000024 \(RELR\) .*
+ 0x0000000000000023 \(RELRSZ\) 8 \(bytes\)
+ 0x0000000000000025 \(RELRENT\) 8 \(bytes\)
+#...
+Relocation section '\.relr\.dyn' .* contains 1 entry which relocates 1 location:
+Index: Entry Address Symbolic Address
+0000: 0000000000010000 0000000000010000 _start
diff --git a/ld/testsuite/ld-loongarch-elf/relr-text.s b/ld/testsuite/ld-loongarch-elf/relr-text.s
new file mode 100644
index 00000000..47465f2d
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-text.s
@@ -0,0 +1,10 @@
+# Test DT_RELR with DT_TEXTREL and R_LARCH_ALIGN.
+
+.text
+.p2align 5
+.global _start
+_start:
+.global foo
+.hidden foo
+foo:
+.quad foo
--
2.33.0

View File

@ -0,0 +1,185 @@
From 3aeea61a3efc9a5535a2dcb9e938782ba3a60aa6 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Tue, 19 Mar 2024 17:51:19 +0800
Subject: [PATCH 082/123] LoongArch: Add bad static relocation check and output
more information to user
Absolute address symbols cannot be used with -shared.
We output more information to the user than just BFD_ASSETR.
---
bfd/elfnn-loongarch.c | 33 +++++++++++++++++--
.../ld-loongarch-elf/ld-loongarch-elf.exp | 3 ++
.../ld-loongarch-elf/reloc_abs_with_shared.d | 6 ++++
.../ld-loongarch-elf/reloc_abs_with_shared.s | 9 +++++
.../ld-loongarch-elf/reloc_le_with_shared.d | 6 ++++
.../ld-loongarch-elf/reloc_le_with_shared.s | 8 +++++
.../ld-loongarch-elf/reloc_ler_with_shared.d | 4 +++
.../ld-loongarch-elf/reloc_ler_with_shared.s | 9 +++++
8 files changed, 76 insertions(+), 2 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/reloc_abs_with_shared.d
create mode 100644 ld/testsuite/ld-loongarch-elf/reloc_abs_with_shared.s
create mode 100644 ld/testsuite/ld-loongarch-elf/reloc_le_with_shared.d
create mode 100644 ld/testsuite/ld-loongarch-elf/reloc_le_with_shared.s
create mode 100644 ld/testsuite/ld-loongarch-elf/reloc_ler_with_shared.d
create mode 100644 ld/testsuite/ld-loongarch-elf/reloc_ler_with_shared.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 0a7caa2a..ee708c7f 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -760,6 +760,33 @@ loongarch_tls_transition (bfd *input_bfd,
allocate space in the global offset table or procedure linkage
table. */
+static bool
+bad_static_reloc (bfd *abfd, const Elf_Internal_Rela *rel, asection *sec,
+ unsigned r_type, struct elf_link_hash_entry *h,
+ Elf_Internal_Sym *isym)
+{
+ /* We propably can improve the information to tell users that they should
+ be recompile the code with -fPIC or -fPIE, just like what x86 does. */
+ reloc_howto_type * r = loongarch_elf_rtype_to_howto (abfd, r_type);
+ const char *name = NULL;
+
+ if (h)
+ name = h->root.root.string;
+ else if (isym)
+ name = bfd_elf_string_from_elf_section (abfd,
+ elf_symtab_hdr (abfd).sh_link,
+ isym->st_name);
+ if (name == NULL || *name == '\0')
+ name ="<nameless>";
+
+ (*_bfd_error_handler)
+ (_("%pB:(%pA+%#lx): relocation %s against `%s` can not be used when making "
+ "a shared object; recompile with -fPIC"),
+ abfd, sec, rel->r_offset, r ? r->name : _("<unknown>"), name);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+}
+
static bool
loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
asection *sec, const Elf_Internal_Rela *relocs)
@@ -904,7 +931,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_LARCH_TLS_LE_HI20_R:
case R_LARCH_SOP_PUSH_TLS_TPREL:
if (!bfd_link_executable (info))
- return false;
+ return bad_static_reloc (abfd, rel, sec, r_type, h, isym);
if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
r_symndx,
@@ -922,6 +949,9 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_LARCH_ABS_HI20:
case R_LARCH_SOP_PUSH_ABSOLUTE:
+ if (bfd_link_pic (info))
+ return bad_static_reloc (abfd, rel, sec, r_type, h, isym);
+
if (h != NULL)
/* If this reloc is in a read-only section, we might
need a copy reloc. We can't check reliably at this
@@ -3397,7 +3427,6 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_LARCH_ABS_LO12:
case R_LARCH_ABS64_LO20:
case R_LARCH_ABS64_HI12:
- BFD_ASSERT (!is_pic);
if (is_undefweak)
{
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index fc7b5bfe..3c8e9195 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -134,6 +134,9 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "desc-norelax"
run_dump_test "desc-relax"
run_dump_test "data-got"
+ run_dump_test "reloc_le_with_shared"
+ run_dump_test "reloc_ler_with_shared"
+ run_dump_test "reloc_abs_with_shared"
}
if [check_pie_support] {
diff --git a/ld/testsuite/ld-loongarch-elf/reloc_abs_with_shared.d b/ld/testsuite/ld-loongarch-elf/reloc_abs_with_shared.d
new file mode 100644
index 00000000..532e84fb
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/reloc_abs_with_shared.d
@@ -0,0 +1,6 @@
+#source: reloc_abs_with_shared.s
+#as:
+#ld: -shared
+#error: .*relocation R_LARCH_ABS_HI20 against `s` can not be used when making a shared object; recompile with -fPIC
+#...
+#pass
diff --git a/ld/testsuite/ld-loongarch-elf/reloc_abs_with_shared.s b/ld/testsuite/ld-loongarch-elf/reloc_abs_with_shared.s
new file mode 100644
index 00000000..13341af2
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/reloc_abs_with_shared.s
@@ -0,0 +1,9 @@
+ .text
+ .globl s
+ .data
+ .type s, @object
+ s:
+ .word 123
+ .text
+ lu12i.w $r4,%abs_hi20(s)
+ addi.d $r4,$r4,%abs_lo12(s)
diff --git a/ld/testsuite/ld-loongarch-elf/reloc_le_with_shared.d b/ld/testsuite/ld-loongarch-elf/reloc_le_with_shared.d
new file mode 100644
index 00000000..562b079a
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/reloc_le_with_shared.d
@@ -0,0 +1,6 @@
+#source: reloc_le_with_shared.s
+#as:
+#ld: -shared
+#error: .*relocation R_LARCH_TLS_LE_HI20 against `s` can not be used when making a shared object; recompile with -fPIC
+#...
+#pass
diff --git a/ld/testsuite/ld-loongarch-elf/reloc_le_with_shared.s b/ld/testsuite/ld-loongarch-elf/reloc_le_with_shared.s
new file mode 100644
index 00000000..c7206650
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/reloc_le_with_shared.s
@@ -0,0 +1,8 @@
+ .text
+ .globl s
+ .section .tdata,"awT",@progbits
+ .type s, @object
+ s:
+ .word 123
+ .text
+ la.tls.le $r4, s
diff --git a/ld/testsuite/ld-loongarch-elf/reloc_ler_with_shared.d b/ld/testsuite/ld-loongarch-elf/reloc_ler_with_shared.d
new file mode 100644
index 00000000..7382d5b8
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/reloc_ler_with_shared.d
@@ -0,0 +1,4 @@
+#source: reloc_ler_with_shared.s
+#as:
+#ld: -shared
+#error: .*relocation R_LARCH_TLS_LE_HI20_R against `s` can not be used when making a shared object; recompile with -fPIC
diff --git a/ld/testsuite/ld-loongarch-elf/reloc_ler_with_shared.s b/ld/testsuite/ld-loongarch-elf/reloc_ler_with_shared.s
new file mode 100644
index 00000000..a9e56967
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/reloc_ler_with_shared.s
@@ -0,0 +1,9 @@
+ .text
+ .globl s
+ .section .tdata,"awT",@progbits
+ .type s, @object
+ s:
+ .word 123
+ .text
+ lu12i.w $r4,%le_hi20_r(s)
+ add.d $r4,$r4,$r2,%le_add_r(s)
--
2.33.0

View File

@ -0,0 +1,101 @@
From 205e07d68684bc331c16b7bcea44b8d5ca84f7e8 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Thu, 23 Nov 2023 15:42:49 +0800
Subject: [PATCH 021/123] LoongArch: Add call36 and tail36 pseudo instructions
for medium code model
For tail36, it is necessary to explicitly indicate the temporary register.
Therefore, the compiler and users will know that the tail will use a register.
call36 func
pcalau18i $ra, %call36(func)
jirl $ra, $ra, 0;
tail36 $t0, func
pcalau18i $t0, %call36(func)
jirl $zero, $t0, 0;
---
gas/testsuite/gas/loongarch/medium-call.d | 10 ++++++++--
gas/testsuite/gas/loongarch/medium-call.s | 2 ++
ld/testsuite/ld-loongarch-elf/medium-call.s | 2 ++
opcodes/loongarch-opc.c | 11 +++++++++++
4 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/gas/testsuite/gas/loongarch/medium-call.d b/gas/testsuite/gas/loongarch/medium-call.d
index 4183818c..3491760b 100644
--- a/gas/testsuite/gas/loongarch/medium-call.d
+++ b/gas/testsuite/gas/loongarch/medium-call.d
@@ -10,6 +10,12 @@ Disassembly of section .text:
[ ]+0:[ ]+1e000001[ ]+pcaddu18i[ ]+\$ra, 0
[ ]+0: R_LARCH_CALL36[ ]+a
[ ]+4:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
-[ ]+8:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
+[ ]+8:[ ]+1e000001[ ]+pcaddu18i[ ]+\$ra, 0
[ ]+8: R_LARCH_CALL36[ ]+a
-[ ]+c:[ ]+4c000180[ ]+jr[ ]+\$t0
+[ ]+c:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
+[ ]+10:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
+[ ]+10: R_LARCH_CALL36[ ]+a
+[ ]+14:[ ]+4c000180[ ]+jr[ ]+\$t0
+[ ]+18:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
+[ ]+18: R_LARCH_CALL36[ ]+a
+[ ]+1c:[ ]+4c000180[ ]+jr[ ]+\$t0
diff --git a/gas/testsuite/gas/loongarch/medium-call.s b/gas/testsuite/gas/loongarch/medium-call.s
index f2977d1c..74d15076 100644
--- a/gas/testsuite/gas/loongarch/medium-call.s
+++ b/gas/testsuite/gas/loongarch/medium-call.s
@@ -1,6 +1,8 @@
# call .L1, r1(ra) temp register, r1(ra) return register.
+ call36 a
pcaddu18i $r1, %call36(a)
jirl $r1, $r1, 0
# tail .L1, r12(t0) temp register, r0(zero) return register.
+ tail36 $r12, a
pcaddu18i $r12, %call36(a)
jirl $r0, $r12, 0
diff --git a/ld/testsuite/ld-loongarch-elf/medium-call.s b/ld/testsuite/ld-loongarch-elf/medium-call.s
index 4d1888b7..50a6b8e7 100644
--- a/ld/testsuite/ld-loongarch-elf/medium-call.s
+++ b/ld/testsuite/ld-loongarch-elf/medium-call.s
@@ -1,7 +1,9 @@
.L1:
# call .L1, r1(ra) temp register, r1(ra) return register.
+ call36 .L1
pcaddu18i $r1, %call36(.L1)
jirl $r1, $r1, 0
# tail .L1, r12(t0) temp register, r0(zero) return register.
+ tail36 $r12, .L1
pcaddu18i $r12, %call36(.L1)
jirl $r0, $r12, 0
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index 15c7da63..b47817f8 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -293,6 +293,15 @@ const char *const loongarch_x_normal_name[32] =
&LARCH_opts.ase_lp64, \
&LARCH_opts.ase_gpcr
+#define INSN_LA_CALL \
+ "pcaddu18i $ra,%%call36(%1);" \
+ "jirl $ra,$ra,0;", \
+ 0, 0
+
+#define INSN_LA_TAIL \
+ "pcaddu18i %1,%%call36(%2);" \
+ "jirl $zero,%1,0;", \
+ 0, 0
static struct loongarch_opcode loongarch_macro_opcodes[] =
{
@@ -340,6 +349,8 @@ static struct loongarch_opcode loongarch_macro_opcodes[] =
{ 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD64, 0 },
{ 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD64_LARGE_ABS, 0 },
{ 0, 0, "la.tls.gd", "r,r,l", INSN_LA_TLS_GD64_LARGE_PCREL, 0 },
+ { 0, 0, "call36", "la", INSN_LA_CALL, 0 },
+ { 0, 0, "tail36", "r,la", INSN_LA_TAIL, 0 },
{ 0, 0, "pcaddi", "r,la", "pcaddi %1, %%pcrel_20(%2)", &LARCH_opts.ase_ilp32, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminate the list. */
};
--
2.33.0

View File

@ -0,0 +1,44 @@
From 43fdb57b36afb8fd1d76f3dc7a9833d60ef90422 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Fri, 23 Feb 2024 16:28:22 +0800
Subject: [PATCH 070/123] LoongArch: Add dtpoff calculation function
When tls_sec is NULL, we should not access the virtual address
of tls_sec.
---
bfd/elfnn-loongarch.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index eea1839f..489ccbe0 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -2550,6 +2550,16 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
})
+static bfd_vma
+tls_dtpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
+
static int
loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bfd *input_bfd, asection *input_section,
@@ -3708,7 +3718,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
rela.r_offset = sec_addr (got) + got_off + desc_off;
rela.r_addend = 0;
if (indx == 0)
- rela.r_addend = relocation - elf_hash_table (info)->tls_sec->vma;
+ rela.r_addend = relocation - tls_dtpoff_base (info);
rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DESCNN);
loongarch_elf_append_rela (output_bfd, relgot, &rela);
--
2.33.0

View File

@ -0,0 +1,42 @@
From 5ba625b50145a8234129ab6b4a58a18e530ae9d7 Mon Sep 17 00:00:00 2001
From: Xin Wang <yw987194828@gmail.com>
Date: Fri, 6 Sep 2024 09:00:12 +0800
Subject: [PATCH 114/123] LoongArch: Add elfNN_loongarch_mkobject to initialize
LoongArch tdata
LoongArch: Add elfNN_loongarch_mkobject to initialize LoongArch tdata.
---
bfd/elfnn-loongarch.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 09a9513b..b6d7d1e8 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -84,6 +84,14 @@ struct _bfd_loongarch_elf_obj_tdata
&& elf_tdata (bfd) != NULL \
&& elf_object_id (bfd) == LARCH_ELF_DATA)
+static bool
+elfNN_loongarch_object (bfd *abfd)
+{
+ return bfd_elf_allocate_object (abfd,
+ sizeof (struct _bfd_loongarch_elf_obj_tdata),
+ LARCH_ELF_DATA);
+}
+
struct relr_entry
{
asection *sec;
@@ -6158,6 +6166,8 @@ elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
#define bfd_elfNN_bfd_reloc_name_lookup loongarch_reloc_name_lookup
#define elf_info_to_howto_rel NULL /* Fall through to elf_info_to_howto. */
#define elf_info_to_howto loongarch_info_to_howto_rela
+#define bfd_elfNN_mkobject \
+ elfNN_loongarch_object
#define bfd_elfNN_bfd_merge_private_bfd_data \
elfNN_loongarch_merge_private_bfd_data
--
2.33.0

View File

@ -0,0 +1,654 @@
From 1ced47506592c7724be57101d70254e826e833d1 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Wed, 10 Jan 2024 16:17:50 +0800
Subject: [PATCH 066/123] LoongArch: Add gas testsuit for LA32 int/float
instructions
Test the int/float instructions of LA32.
---
gas/testsuite/gas/loongarch/insn_float32.d | 157 +++++++++++++++++++++
gas/testsuite/gas/loongarch/insn_float32.s | 149 +++++++++++++++++++
gas/testsuite/gas/loongarch/insn_int32.d | 147 +++++++++++++++++++
gas/testsuite/gas/loongarch/insn_int32.s | 156 ++++++++++++++++++++
4 files changed, 609 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/insn_float32.d
create mode 100644 gas/testsuite/gas/loongarch/insn_float32.s
create mode 100644 gas/testsuite/gas/loongarch/insn_int32.d
create mode 100644 gas/testsuite/gas/loongarch/insn_int32.s
diff --git a/gas/testsuite/gas/loongarch/insn_float32.d b/gas/testsuite/gas/loongarch/insn_float32.d
new file mode 100644
index 00000000..ee2408af
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_float32.d
@@ -0,0 +1,157 @@
+#as-new:
+#objdump: -d
+#skip: loongarch64-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+ <.*>:
+ 0: 01008820 fadd.s \$fa0, \$fa1, \$fa2
+ 4: 01010820 fadd.d \$fa0, \$fa1, \$fa2
+ 8: 01028820 fsub.s \$fa0, \$fa1, \$fa2
+ c: 01030820 fsub.d \$fa0, \$fa1, \$fa2
+ 10: 01048820 fmul.s \$fa0, \$fa1, \$fa2
+ 14: 01050820 fmul.d \$fa0, \$fa1, \$fa2
+ 18: 01068820 fdiv.s \$fa0, \$fa1, \$fa2
+ 1c: 01070820 fdiv.d \$fa0, \$fa1, \$fa2
+ 20: 01088820 fmax.s \$fa0, \$fa1, \$fa2
+ 24: 01090820 fmax.d \$fa0, \$fa1, \$fa2
+ 28: 010a8820 fmin.s \$fa0, \$fa1, \$fa2
+ 2c: 010b0820 fmin.d \$fa0, \$fa1, \$fa2
+ 30: 010c8820 fmaxa.s \$fa0, \$fa1, \$fa2
+ 34: 010d0820 fmaxa.d \$fa0, \$fa1, \$fa2
+ 38: 010e8820 fmina.s \$fa0, \$fa1, \$fa2
+ 3c: 010f0820 fmina.d \$fa0, \$fa1, \$fa2
+ 40: 01108820 fscaleb.s \$fa0, \$fa1, \$fa2
+ 44: 01110820 fscaleb.d \$fa0, \$fa1, \$fa2
+ 48: 01128820 fcopysign.s \$fa0, \$fa1, \$fa2
+ 4c: 01130820 fcopysign.d \$fa0, \$fa1, \$fa2
+ 50: 01140420 fabs.s \$fa0, \$fa1
+ 54: 01140820 fabs.d \$fa0, \$fa1
+ 58: 01141420 fneg.s \$fa0, \$fa1
+ 5c: 01141820 fneg.d \$fa0, \$fa1
+ 60: 01142420 flogb.s \$fa0, \$fa1
+ 64: 01142820 flogb.d \$fa0, \$fa1
+ 68: 01143420 fclass.s \$fa0, \$fa1
+ 6c: 01143820 fclass.d \$fa0, \$fa1
+ 70: 01144420 fsqrt.s \$fa0, \$fa1
+ 74: 01144820 fsqrt.d \$fa0, \$fa1
+ 78: 01145420 frecip.s \$fa0, \$fa1
+ 7c: 01145820 frecip.d \$fa0, \$fa1
+ 80: 01146420 frsqrt.s \$fa0, \$fa1
+ 84: 01146820 frsqrt.d \$fa0, \$fa1
+ 88: 01149420 fmov.s \$fa0, \$fa1
+ 8c: 01149820 fmov.d \$fa0, \$fa1
+ 90: 0114a4a0 movgr2fr.w \$fa0, \$a1
+ 94: 0114a8a0 movgr2fr.d \$fa0, \$a1
+ 98: 0114aca0 movgr2frh.w \$fa0, \$a1
+ 9c: 0114b424 movfr2gr.s \$a0, \$fa1
+ a0: 0114b824 movfr2gr.d \$a0, \$fa1
+ a4: 0114bc24 movfrh2gr.s \$a0, \$fa1
+ a8: 0114c0a0 movgr2fcsr \$fcsr0, \$a1
+ ac: 0114c804 movfcsr2gr \$a0, \$fcsr0
+ b0: 0114d020 movfr2cf \$fcc0, \$fa1
+ b4: 0114d4a0 movcf2fr \$fa0, \$fcc5
+ b8: 0114d8a0 movgr2cf \$fcc0, \$a1
+ bc: 0114dca4 movcf2gr \$a0, \$fcc5
+ c0: 01191820 fcvt.s.d \$fa0, \$fa1
+ c4: 01192420 fcvt.d.s \$fa0, \$fa1
+ c8: 011a0420 ftintrm.w.s \$fa0, \$fa1
+ cc: 011a0820 ftintrm.w.d \$fa0, \$fa1
+ d0: 011a2420 ftintrm.l.s \$fa0, \$fa1
+ d4: 011a2820 ftintrm.l.d \$fa0, \$fa1
+ d8: 011a4420 ftintrp.w.s \$fa0, \$fa1
+ dc: 011a4820 ftintrp.w.d \$fa0, \$fa1
+ e0: 011a6420 ftintrp.l.s \$fa0, \$fa1
+ e4: 011a6820 ftintrp.l.d \$fa0, \$fa1
+ e8: 011a8420 ftintrz.w.s \$fa0, \$fa1
+ ec: 011a8820 ftintrz.w.d \$fa0, \$fa1
+ f0: 011aa420 ftintrz.l.s \$fa0, \$fa1
+ f4: 011aa820 ftintrz.l.d \$fa0, \$fa1
+ f8: 011ac420 ftintrne.w.s \$fa0, \$fa1
+ fc: 011ac820 ftintrne.w.d \$fa0, \$fa1
+ 100: 011ae420 ftintrne.l.s \$fa0, \$fa1
+ 104: 011ae820 ftintrne.l.d \$fa0, \$fa1
+ 108: 011b0420 ftint.w.s \$fa0, \$fa1
+ 10c: 011b0820 ftint.w.d \$fa0, \$fa1
+ 110: 011b2420 ftint.l.s \$fa0, \$fa1
+ 114: 011b2820 ftint.l.d \$fa0, \$fa1
+ 118: 011d1020 ffint.s.w \$fa0, \$fa1
+ 11c: 011d1820 ffint.s.l \$fa0, \$fa1
+ 120: 011d2020 ffint.d.w \$fa0, \$fa1
+ 124: 011d2820 ffint.d.l \$fa0, \$fa1
+ 128: 011e4420 frint.s \$fa0, \$fa1
+ 12c: 011e4820 frint.d \$fa0, \$fa1
+ 130: 01147420 frecipe.s \$fa0, \$fa1
+ 134: 01147820 frecipe.d \$fa0, \$fa1
+ 138: 01148420 frsqrte.s \$fa0, \$fa1
+ 13c: 01148820 frsqrte.d \$fa0, \$fa1
+ 140: 08118820 fmadd.s \$fa0, \$fa1, \$fa2, \$fa3
+ 144: 08218820 fmadd.d \$fa0, \$fa1, \$fa2, \$fa3
+ 148: 08518820 fmsub.s \$fa0, \$fa1, \$fa2, \$fa3
+ 14c: 08618820 fmsub.d \$fa0, \$fa1, \$fa2, \$fa3
+ 150: 08918820 fnmadd.s \$fa0, \$fa1, \$fa2, \$fa3
+ 154: 08a18820 fnmadd.d \$fa0, \$fa1, \$fa2, \$fa3
+ 158: 08d18820 fnmsub.s \$fa0, \$fa1, \$fa2, \$fa3
+ 15c: 08e18820 fnmsub.d \$fa0, \$fa1, \$fa2, \$fa3
+ 160: 0c100820 fcmp.caf.s \$fcc0, \$fa1, \$fa2
+ 164: 0c108820 fcmp.saf.s \$fcc0, \$fa1, \$fa2
+ 168: 0c110820 fcmp.clt.s \$fcc0, \$fa1, \$fa2
+ 16c: 0c118820 fcmp.slt.s \$fcc0, \$fa1, \$fa2
+ 170: 0c118820 fcmp.slt.s \$fcc0, \$fa1, \$fa2
+ 174: 0c120820 fcmp.ceq.s \$fcc0, \$fa1, \$fa2
+ 178: 0c128820 fcmp.seq.s \$fcc0, \$fa1, \$fa2
+ 17c: 0c130820 fcmp.cle.s \$fcc0, \$fa1, \$fa2
+ 180: 0c138820 fcmp.sle.s \$fcc0, \$fa1, \$fa2
+ 184: 0c138820 fcmp.sle.s \$fcc0, \$fa1, \$fa2
+ 188: 0c140820 fcmp.cun.s \$fcc0, \$fa1, \$fa2
+ 18c: 0c148820 fcmp.sun.s \$fcc0, \$fa1, \$fa2
+ 190: 0c150820 fcmp.cult.s \$fcc0, \$fa1, \$fa2
+ 194: 0c150820 fcmp.cult.s \$fcc0, \$fa1, \$fa2
+ 198: 0c158820 fcmp.sult.s \$fcc0, \$fa1, \$fa2
+ 19c: 0c160820 fcmp.cueq.s \$fcc0, \$fa1, \$fa2
+ 1a0: 0c168820 fcmp.sueq.s \$fcc0, \$fa1, \$fa2
+ 1a4: 0c170820 fcmp.cule.s \$fcc0, \$fa1, \$fa2
+ 1a8: 0c170820 fcmp.cule.s \$fcc0, \$fa1, \$fa2
+ 1ac: 0c178820 fcmp.sule.s \$fcc0, \$fa1, \$fa2
+ 1b0: 0c180820 fcmp.cne.s \$fcc0, \$fa1, \$fa2
+ 1b4: 0c188820 fcmp.sne.s \$fcc0, \$fa1, \$fa2
+ 1b8: 0c1a0820 fcmp.cor.s \$fcc0, \$fa1, \$fa2
+ 1bc: 0c1a8820 fcmp.sor.s \$fcc0, \$fa1, \$fa2
+ 1c0: 0c1c0820 fcmp.cune.s \$fcc0, \$fa1, \$fa2
+ 1c4: 0c1c8820 fcmp.sune.s \$fcc0, \$fa1, \$fa2
+ 1c8: 0c200820 fcmp.caf.d \$fcc0, \$fa1, \$fa2
+ 1cc: 0c208820 fcmp.saf.d \$fcc0, \$fa1, \$fa2
+ 1d0: 0c210820 fcmp.clt.d \$fcc0, \$fa1, \$fa2
+ 1d4: 0c218820 fcmp.slt.d \$fcc0, \$fa1, \$fa2
+ 1d8: 0c218820 fcmp.slt.d \$fcc0, \$fa1, \$fa2
+ 1dc: 0c220820 fcmp.ceq.d \$fcc0, \$fa1, \$fa2
+ 1e0: 0c228820 fcmp.seq.d \$fcc0, \$fa1, \$fa2
+ 1e4: 0c230820 fcmp.cle.d \$fcc0, \$fa1, \$fa2
+ 1e8: 0c238820 fcmp.sle.d \$fcc0, \$fa1, \$fa2
+ 1ec: 0c238820 fcmp.sle.d \$fcc0, \$fa1, \$fa2
+ 1f0: 0c240820 fcmp.cun.d \$fcc0, \$fa1, \$fa2
+ 1f4: 0c248820 fcmp.sun.d \$fcc0, \$fa1, \$fa2
+ 1f8: 0c250820 fcmp.cult.d \$fcc0, \$fa1, \$fa2
+ 1fc: 0c250820 fcmp.cult.d \$fcc0, \$fa1, \$fa2
+ 200: 0c258820 fcmp.sult.d \$fcc0, \$fa1, \$fa2
+ 204: 0c260820 fcmp.cueq.d \$fcc0, \$fa1, \$fa2
+ 208: 0c268820 fcmp.sueq.d \$fcc0, \$fa1, \$fa2
+ 20c: 0c270820 fcmp.cule.d \$fcc0, \$fa1, \$fa2
+ 210: 0c270820 fcmp.cule.d \$fcc0, \$fa1, \$fa2
+ 214: 0c278820 fcmp.sule.d \$fcc0, \$fa1, \$fa2
+ 218: 0c280820 fcmp.cne.d \$fcc0, \$fa1, \$fa2
+ 21c: 0c288820 fcmp.sne.d \$fcc0, \$fa1, \$fa2
+ 220: 0c2a0820 fcmp.cor.d \$fcc0, \$fa1, \$fa2
+ 224: 0c2a8820 fcmp.sor.d \$fcc0, \$fa1, \$fa2
+ 228: 0c2c0820 fcmp.cune.d \$fcc0, \$fa1, \$fa2
+ 22c: 0c2c8820 fcmp.sune.d \$fcc0, \$fa1, \$fa2
+ 230: 0d000820 fsel \$fa0, \$fa1, \$fa2, \$fcc0
+ 234: 2b00058a fld.s \$ft2, \$t0, 1
+ 238: 2b40058a fst.s \$ft2, \$t0, 1
+ 23c: 2b80058a fld.d \$ft2, \$t0, 1
+ 240: 2bc0058a fst.d \$ft2, \$t0, 1
+ 244: 48000000 bceqz \$fcc0, 0 # 0x244
+ 248: 48000100 bcnez \$fcc0, 0 # 0x248
diff --git a/gas/testsuite/gas/loongarch/insn_float32.s b/gas/testsuite/gas/loongarch/insn_float32.s
new file mode 100644
index 00000000..8465633b
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_float32.s
@@ -0,0 +1,149 @@
+fadd.s $f0,$f1,$f2
+fadd.d $f0,$f1,$f2
+fsub.s $f0,$f1,$f2
+fsub.d $f0,$f1,$f2
+fmul.s $f0,$f1,$f2
+fmul.d $f0,$f1,$f2
+fdiv.s $f0,$f1,$f2
+fdiv.d $f0,$f1,$f2
+fmax.s $f0,$f1,$f2
+fmax.d $f0,$f1,$f2
+fmin.s $f0,$f1,$f2
+fmin.d $f0,$f1,$f2
+fmaxa.s $f0,$f1,$f2
+fmaxa.d $f0,$f1,$f2
+fmina.s $f0,$f1,$f2
+fmina.d $f0,$f1,$f2
+fscaleb.s $f0,$f1,$f2
+fscaleb.d $f0,$f1,$f2
+fcopysign.s $f0,$f1,$f2
+fcopysign.d $f0,$f1,$f2
+fabs.s $f0,$f1
+fabs.d $f0,$f1
+fneg.s $f0,$f1
+fneg.d $f0,$f1
+flogb.s $f0,$f1
+flogb.d $f0,$f1
+fclass.s $f0,$f1
+fclass.d $f0,$f1
+fsqrt.s $f0,$f1
+fsqrt.d $f0,$f1
+frecip.s $f0,$f1
+frecip.d $f0,$f1
+frsqrt.s $f0,$f1
+frsqrt.d $f0,$f1
+fmov.s $f0,$f1
+fmov.d $f0,$f1
+movgr2fr.w $f0,$r5
+movgr2fr.d $f0,$r5
+movgr2frh.w $f0,$r5
+movfr2gr.s $r4,$f1
+movfr2gr.d $r4,$f1
+movfrh2gr.s $r4,$f1
+movgr2fcsr $fcsr0,$r5
+movfcsr2gr $r4,$fcsr0
+movfr2cf $fcc0,$f1
+movcf2fr $f0,$fcc5
+movgr2cf $fcc0,$r5
+movcf2gr $r4,$fcc5
+fcvt.s.d $f0,$f1
+fcvt.d.s $f0,$f1
+ftintrm.w.s $f0,$f1
+ftintrm.w.d $f0,$f1
+ftintrm.l.s $f0,$f1
+ftintrm.l.d $f0,$f1
+ftintrp.w.s $f0,$f1
+ftintrp.w.d $f0,$f1
+ftintrp.l.s $f0,$f1
+ftintrp.l.d $f0,$f1
+ftintrz.w.s $f0,$f1
+ftintrz.w.d $f0,$f1
+ftintrz.l.s $f0,$f1
+ftintrz.l.d $f0,$f1
+ftintrne.w.s $f0,$f1
+ftintrne.w.d $f0,$f1
+ftintrne.l.s $f0,$f1
+ftintrne.l.d $f0,$f1
+ftint.w.s $f0,$f1
+ftint.w.d $f0,$f1
+ftint.l.s $f0,$f1
+ftint.l.d $f0,$f1
+ffint.s.w $f0,$f1
+ffint.s.l $f0,$f1
+ffint.d.w $f0,$f1
+ffint.d.l $f0,$f1
+frint.s $f0,$f1
+frint.d $f0,$f1
+frecipe.s $f0,$f1
+frecipe.d $f0,$f1
+frsqrte.s $f0,$f1
+frsqrte.d $f0,$f1
+
+# 4_opt_op
+fmadd.s $f0,$f1,$f2,$f3
+fmadd.d $f0,$f1,$f2,$f3
+fmsub.s $f0,$f1,$f2,$f3
+fmsub.d $f0,$f1,$f2,$f3
+fnmadd.s $f0,$f1,$f2,$f3
+fnmadd.d $f0,$f1,$f2,$f3
+fnmsub.s $f0,$f1,$f2,$f3
+fnmsub.d $f0,$f1,$f2,$f3
+fcmp.caf.s $fcc0,$f1,$f2
+fcmp.saf.s $fcc0,$f1,$f2
+fcmp.clt.s $fcc0,$f1,$f2
+fcmp.slt.s $fcc0,$f1,$f2
+fcmp.sgt.s $fcc0,$f2,$f1
+fcmp.ceq.s $fcc0,$f1,$f2
+fcmp.seq.s $fcc0,$f1,$f2
+fcmp.cle.s $fcc0,$f1,$f2
+fcmp.sle.s $fcc0,$f1,$f2
+fcmp.sge.s $fcc0,$f2,$f1
+fcmp.cun.s $fcc0,$f1,$f2
+fcmp.sun.s $fcc0,$f1,$f2
+fcmp.cult.s $fcc0,$f1,$f2
+fcmp.cugt.s $fcc0,$f2,$f1
+fcmp.sult.s $fcc0,$f1,$f2
+fcmp.cueq.s $fcc0,$f1,$f2
+fcmp.sueq.s $fcc0,$f1,$f2
+fcmp.cule.s $fcc0,$f1,$f2
+fcmp.cuge.s $fcc0,$f2,$f1
+fcmp.sule.s $fcc0,$f1,$f2
+fcmp.cne.s $fcc0,$f1,$f2
+fcmp.sne.s $fcc0,$f1,$f2
+fcmp.cor.s $fcc0,$f1,$f2
+fcmp.sor.s $fcc0,$f1,$f2
+fcmp.cune.s $fcc0,$f1,$f2
+fcmp.sune.s $fcc0,$f1,$f2
+fcmp.caf.d $fcc0,$f1,$f2
+fcmp.saf.d $fcc0,$f1,$f2
+fcmp.clt.d $fcc0,$f1,$f2
+fcmp.slt.d $fcc0,$f1,$f2
+fcmp.sgt.d $fcc0,$f2,$f1
+fcmp.ceq.d $fcc0,$f1,$f2
+fcmp.seq.d $fcc0,$f1,$f2
+fcmp.cle.d $fcc0,$f1,$f2
+fcmp.sle.d $fcc0,$f1,$f2
+fcmp.sge.d $fcc0,$f2,$f1
+fcmp.cun.d $fcc0,$f1,$f2
+fcmp.sun.d $fcc0,$f1,$f2
+fcmp.cult.d $fcc0,$f1,$f2
+fcmp.cugt.d $fcc0,$f2,$f1
+fcmp.sult.d $fcc0,$f1,$f2
+fcmp.cueq.d $fcc0,$f1,$f2
+fcmp.sueq.d $fcc0,$f1,$f2
+fcmp.cule.d $fcc0,$f1,$f2
+fcmp.cuge.d $fcc0,$f2,$f1
+fcmp.sule.d $fcc0,$f1,$f2
+fcmp.cne.d $fcc0,$f1,$f2
+fcmp.sne.d $fcc0,$f1,$f2
+fcmp.cor.d $fcc0,$f1,$f2
+fcmp.sor.d $fcc0,$f1,$f2
+fcmp.cune.d $fcc0,$f1,$f2
+fcmp.sune.d $fcc0,$f1,$f2
+fsel $f0,$f1,$f2,$fcc0
+fld.s $f10,$r12,1
+fst.s $f10,$r12,1
+fld.d $f10,$r12,1
+fst.d $f10,$r12,1
+bceqz $fcc0,.L1
+bcnez $fcc0,.L1
diff --git a/gas/testsuite/gas/loongarch/insn_int32.d b/gas/testsuite/gas/loongarch/insn_int32.d
new file mode 100644
index 00000000..d90dbe40
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_int32.d
@@ -0,0 +1,147 @@
+#as-new:
+#objdump: -d -M no-aliases
+#skip: loongarch64-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+ <.*>:
+ 0: 020000a4 slti \$a0, \$a1, 0
+ 4: 021ffca4 slti \$a0, \$a1, 2047
+ 8: 022004a4 slti \$a0, \$a1, -2047
+ c: 024000a4 sltui \$a0, \$a1, 0
+ 10: 025ffca4 sltui \$a0, \$a1, 2047
+ 14: 026004a4 sltui \$a0, \$a1, -2047
+ 18: 028000a4 addi.w \$a0, \$a1, 0
+ 1c: 029ffca4 addi.w \$a0, \$a1, 2047
+ 20: 02a004a4 addi.w \$a0, \$a1, -2047
+ 24: 034000a4 andi \$a0, \$a1, 0x0
+ 28: 035ffca4 andi \$a0, \$a1, 0x7ff
+ 2c: 038000a4 ori \$a0, \$a1, 0x0
+ 30: 039ffca4 ori \$a0, \$a1, 0x7ff
+ 34: 03c000a4 xori \$a0, \$a1, 0x0
+ 38: 03dffca4 xori \$a0, \$a1, 0x7ff
+ 3c: 14000004 lu12i.w \$a0, 0
+ 40: 14ffffe4 lu12i.w \$a0, 524287
+ 44: 1c000004 pcaddu12i \$a0, 0
+ 48: 1cffffe4 pcaddu12i \$a0, 524287
+ 4c: 1d000024 pcaddu12i \$a0, -524287
+ 50: 0004b58b alsl.w \$a7, \$t0, \$t1, 0x2
+ 54: 0006b58b alsl.wu \$a7, \$t0, \$t1, 0x2
+ 58: 002a0002 break 0x2
+ 5c: 002a8002 dbcl 0x2
+ 60: 002b0002 syscall 0x2
+ 64: 0040898b slli.w \$a7, \$t0, 0x2
+ 68: 0044898b srli.w \$a7, \$t0, 0x2
+ 6c: 004889ac srai.w \$t0, \$t1, 0x2
+ 70: 02048dac slti \$t0, \$t1, 291
+ 74: 02448dac sltui \$t0, \$t1, 291
+ 78: 02848dac addi.w \$t0, \$t1, 291
+ 7c: 034009ac andi \$t0, \$t1, 0x2
+ 80: 038009ac ori \$t0, \$t1, 0x2
+ 84: 03c009ac xori \$t0, \$t1, 0x2
+ 88: 1400246c lu12i.w \$t0, 291
+ 8c: 1c00246c pcaddu12i \$t0, 291
+ 90: 04048c0c csrrd \$t0, 0x123
+ 94: 04048c2c csrwr \$t0, 0x123
+ 98: 040009ac csrxchg \$t0, \$t1, 0x2
+ 9c: 060009a2 cacop 0x2, \$t1, 2
+ a0: 064009ac lddir \$t0, \$t1, 0x2
+ a4: 06440980 ldpte \$t0, 0x2
+ a8: 0649b9a2 invtlb 0x2, \$t1, \$t2
+ ac: 000060a4 rdtimel.w \$a0, \$a1
+ b0: 000064a4 rdtimeh.w \$a0, \$a1
+ b4: 000418a4 alsl.w \$a0, \$a1, \$a2, 0x1
+ b8: 000598a4 alsl.w \$a0, \$a1, \$a2, 0x4
+ bc: 000618a4 alsl.wu \$a0, \$a1, \$a2, 0x1
+ c0: 000798a4 alsl.wu \$a0, \$a1, \$a2, 0x4
+ c4: 001018a4 add.w \$a0, \$a1, \$a2
+ c8: 001118a4 sub.w \$a0, \$a1, \$a2
+ cc: 001218a4 slt \$a0, \$a1, \$a2
+ d0: 001298a4 sltu \$a0, \$a1, \$a2
+ d4: 001418a4 nor \$a0, \$a1, \$a2
+ d8: 001498a4 and \$a0, \$a1, \$a2
+ dc: 001518a4 or \$a0, \$a1, \$a2
+ e0: 001598a4 xor \$a0, \$a1, \$a2
+ e4: 001718a4 sll.w \$a0, \$a1, \$a2
+ e8: 001798a4 srl.w \$a0, \$a1, \$a2
+ ec: 001818a4 sra.w \$a0, \$a1, \$a2
+ f0: 001c18a4 mul.w \$a0, \$a1, \$a2
+ f4: 001c98a4 mulh.w \$a0, \$a1, \$a2
+ f8: 001d18a4 mulh.wu \$a0, \$a1, \$a2
+ fc: 002018a4 div.w \$a0, \$a1, \$a2
+ 100: 002098a4 mod.w \$a0, \$a1, \$a2
+ 104: 002118a4 div.wu \$a0, \$a1, \$a2
+ 108: 002198a4 mod.wu \$a0, \$a1, \$a2
+ 10c: 002a0000 break 0x0
+ 110: 002a7fff break 0x7fff
+ 114: 002a8000 dbcl 0x0
+ 118: 002affff dbcl 0x7fff
+ 11c: 004080a4 slli.w \$a0, \$a1, 0x0
+ 120: 004084a4 slli.w \$a0, \$a1, 0x1
+ 124: 0040fca4 slli.w \$a0, \$a1, 0x1f
+ 128: 004480a4 srli.w \$a0, \$a1, 0x0
+ 12c: 004484a4 srli.w \$a0, \$a1, 0x1
+ 130: 0044fca4 srli.w \$a0, \$a1, 0x1f
+ 134: 004880a4 srai.w \$a0, \$a1, 0x0
+ 138: 004884a4 srai.w \$a0, \$a1, 0x1
+ 13c: 0048fca4 srai.w \$a0, \$a1, 0x1f
+ 140: 200000a4 ll.w \$a0, \$a1, 0
+ 144: 203ffca4 ll.w \$a0, \$a1, 16380
+ 148: 210000a4 sc.w \$a0, \$a1, 0
+ 14c: 213ffca4 sc.w \$a0, \$a1, 16380
+ 150: 280000a4 ld.b \$a0, \$a1, 0
+ 154: 281ffca4 ld.b \$a0, \$a1, 2047
+ 158: 282004a4 ld.b \$a0, \$a1, -2047
+ 15c: 284000a4 ld.h \$a0, \$a1, 0
+ 160: 285ffca4 ld.h \$a0, \$a1, 2047
+ 164: 286004a4 ld.h \$a0, \$a1, -2047
+ 168: 288000a4 ld.w \$a0, \$a1, 0
+ 16c: 289ffca4 ld.w \$a0, \$a1, 2047
+ 170: 28a004a4 ld.w \$a0, \$a1, -2047
+ 174: 290000a4 st.b \$a0, \$a1, 0
+ 178: 291ffca4 st.b \$a0, \$a1, 2047
+ 17c: 292004a4 st.b \$a0, \$a1, -2047
+ 180: 294000a4 st.h \$a0, \$a1, 0
+ 184: 295ffca4 st.h \$a0, \$a1, 2047
+ 188: 296004a4 st.h \$a0, \$a1, -2047
+ 18c: 298000a4 st.w \$a0, \$a1, 0
+ 190: 299ffca4 st.w \$a0, \$a1, 2047
+ 194: 29a004a4 st.w \$a0, \$a1, -2047
+ 198: 2a0000a4 ld.bu \$a0, \$a1, 0
+ 19c: 2a1ffca4 ld.bu \$a0, \$a1, 2047
+ 1a0: 2a2004a4 ld.bu \$a0, \$a1, -2047
+ 1a4: 2a4000a4 ld.hu \$a0, \$a1, 0
+ 1a8: 2a5ffca4 ld.hu \$a0, \$a1, 2047
+ 1ac: 2a6004a4 ld.hu \$a0, \$a1, -2047
+ 1b0: 2ac000a0 preld 0x0, \$a1, 0
+ 1b4: 2adffcbf preld 0x1f, \$a1, 2047
+ 1b8: 2ae004bf preld 0x1f, \$a1, -2047
+ 1bc: 385714c4 sc.q \$a0, \$a1, \$a2
+ 1c0: 385714c4 sc.q \$a0, \$a1, \$a2
+ 1c4: 385780a4 llacq.w \$a0, \$a1
+ 1c8: 385780a4 llacq.w \$a0, \$a1
+ 1cc: 385784a4 screl.w \$a0, \$a1
+ 1d0: 385784a4 screl.w \$a0, \$a1
+ 1d4: 38720000 dbar 0x0
+ 1d8: 38727fff dbar 0x7fff
+ 1dc: 38728000 ibar 0x0
+ 1e0: 3872ffff ibar 0x7fff
+
+0+1e4 <.L1>:
+ 1e4: 03400000 andi \$zero, \$zero, 0x0
+ 1e8: 53ffffff b -4 # 1e4 <.L1>
+ 1ec: 57fffbff bl -8 # 1e4 <.L1>
+ 1f0: 5bfff485 beq \$a0, \$a1, -12 # 1e4 <.L1>
+ 1f4: 5ffff085 bne \$a0, \$a1, -16 # 1e4 <.L1>
+ 1f8: 63ffec85 blt \$a0, \$a1, -20 # 1e4 <.L1>
+ 1fc: 63ffe8a4 blt \$a1, \$a0, -24 # 1e4 <.L1>
+ 200: 67ffe485 bge \$a0, \$a1, -28 # 1e4 <.L1>
+ 204: 67ffe0a4 bge \$a1, \$a0, -32 # 1e4 <.L1>
+ 208: 6bffdc85 bltu \$a0, \$a1, -36 # 1e4 <.L1>
+ 20c: 6bffd8a4 bltu \$a1, \$a0, -40 # 1e4 <.L1>
+ 210: 6fffd485 bgeu \$a0, \$a1, -44 # 1e4 <.L1>
+ 214: 6fffd0a4 bgeu \$a1, \$a0, -48 # 1e4 <.L1>
+ 218: 4c000080 jirl \$zero, \$a0, 0
diff --git a/gas/testsuite/gas/loongarch/insn_int32.s b/gas/testsuite/gas/loongarch/insn_int32.s
new file mode 100644
index 00000000..4889df1f
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_int32.s
@@ -0,0 +1,156 @@
+# imm_op
+slti $r4,$r5,0
+slti $r4,$r5,0x7ff
+slti $r4,$r5,-0x7ff
+sltui $r4,$r5,0
+sltui $r4,$r5,0x7ff
+sltui $r4,$r5,-0x7ff
+addi.w $r4,$r5,0
+addi.w $r4,$r5,0x7ff
+addi.w $r4,$r5,-0x7ff
+andi $r4,$r5,0
+andi $r4,$r5,0x7ff
+ori $r4,$r5,0
+ori $r4,$r5,0x7ff
+xori $r4,$r5,0
+xori $r4,$r5,0x7ff
+lu12i.w $r4,0
+lu12i.w $r4,0x7ffff
+pcaddu12i $r4,0
+pcaddu12i $r4,0x7ffff
+pcaddu12i $r4,-0x7ffff
+
+# imm_ins
+.equ a, 0x123
+.equ b, 0xfffff00000
+.equ c, 0xfffffffffff
+.equ d, 2
+.equ e,0x100
+
+alsl.w $r11,$r12,$r13,d
+alsl.wu $r11,$r12,$r13,d
+
+break d
+dbcl d
+syscall d
+
+slli.w $r11,$r12,d
+srli.w $r11,$r12,d
+srai.w $r12,$r13,d
+
+slti $r12,$r13,a
+sltui $r12,$r13,a
+addi.w $r12,$r13,a
+andi $r12,$r13,d
+ori $r12,$r13,d
+xori $r12,$r13,d
+lu12i.w $r12,a
+pcaddu12i $r12,a
+
+csrrd $r12,a
+csrwr $r12,a
+csrxchg $r12,$r13,d
+cacop d,$r13,d
+lddir $r12,$r13,d
+ldpte $r12,d
+
+invtlb d,$r13,$r14
+
+# fix_op
+rdtimel.w $r4,$r5
+rdtimeh.w $r4,$r5
+alsl.w $r4,$r5,$r6,1
+alsl.w $r4,$r5,$r6,4
+alsl.wu $r4,$r5,$r6,1
+alsl.wu $r4,$r5,$r6,4
+add.w $r4,$r5,$r6
+sub.w $r4,$r5,$r6
+slt $r4,$r5,$r6
+sltu $r4,$r5,$r6
+nor $r4,$r5,$r6
+and $r4,$r5,$r6
+or $r4,$r5,$r6
+xor $r4,$r5,$r6
+
+# load_store
+sll.w $r4,$r5,$r6
+srl.w $r4,$r5,$r6
+sra.w $r4,$r5,$r6
+mul.w $r4,$r5,$r6
+mulh.w $r4,$r5,$r6
+mulh.wu $r4,$r5,$r6
+div.w $r4,$r5,$r6
+mod.w $r4,$r5,$r6
+div.wu $r4,$r5,$r6
+mod.wu $r4,$r5,$r6
+break 0
+break 0x7fff
+dbcl 0
+dbcl 0x7fff
+slli.w $r4,$r5,0
+slli.w $r4,$r5,1
+slli.w $r4,$r5,0x1f
+srli.w $r4,$r5,0
+srli.w $r4,$r5,1
+srli.w $r4,$r5,0x1f
+srai.w $r4,$r5,0
+srai.w $r4,$r5,1
+srai.w $r4,$r5,0x1f
+ll.w $r4,$r5,0
+ll.w $r4,$r5,0x3ffc
+sc.w $r4,$r5,0
+sc.w $r4,$r5,0x3ffc
+ld.b $r4,$r5,0
+ld.b $r4,$r5,0x7ff
+ld.b $r4,$r5,-0x7ff
+ld.h $r4,$r5,0
+ld.h $r4,$r5,0x7ff
+ld.h $r4,$r5,-0x7ff
+ld.w $r4,$r5,0
+ld.w $r4,$r5,0x7ff
+ld.w $r4,$r5,-0x7ff
+st.b $r4,$r5,0
+st.b $r4,$r5,0x7ff
+st.b $r4,$r5,-0x7ff
+st.h $r4,$r5,0
+st.h $r4,$r5,0x7ff
+st.h $r4,$r5,-0x7ff
+st.w $r4,$r5,0
+st.w $r4,$r5,0x7ff
+st.w $r4,$r5,-0x7ff
+ld.bu $r4,$r5,0
+ld.bu $r4,$r5,0x7ff
+ld.bu $r4,$r5,-0x7ff
+ld.hu $r4,$r5,0
+ld.hu $r4,$r5,0x7ff
+ld.hu $r4,$r5,-0x7ff
+preld 0,$r5,0
+preld 31,$r5,0x7ff
+preld 31,$r5,-0x7ff
+sc.q $r4,$r5,$r6,0
+sc.q $r4,$r5,$r6
+llacq.w $r4,$r5,0
+llacq.w $r4,$r5
+screl.w $r4,$r5,0
+screl.w $r4,$r5
+dbar 0
+dbar 0x7fff
+ibar 0
+ibar 0x7fff
+
+# jmp_op
+.L1:
+nop
+b .L1
+bl .L1
+beq $r4,$r5,.L1
+bne $r4,$r5,.L1
+blt $r4,$r5,.L1
+bgt $r4,$r5,.L1
+bge $r4,$r5,.L1
+ble $r4,$r5,.L1
+bltu $r4,$r5,.L1
+bgtu $r4,$r5,.L1
+bgeu $r4,$r5,.L1
+bleu $r4,$r5,.L1
+jirl $zero,$r4,0
--
2.33.0

View File

@ -0,0 +1,164 @@
From bed92cdad966e2a7b9cfea8a5113187304255968 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Fri, 12 Jan 2024 11:15:10 +0800
Subject: [PATCH 068/123] LoongArch: Add gas testsuit for LA32 relocations
Test the relocation of the LA32 instruction set.
---
gas/testsuite/gas/loongarch/relocs_32.d | 75 +++++++++++++++++++++++++
gas/testsuite/gas/loongarch/relocs_32.s | 61 ++++++++++++++++++++
2 files changed, 136 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/relocs_32.d
create mode 100644 gas/testsuite/gas/loongarch/relocs_32.s
diff --git a/gas/testsuite/gas/loongarch/relocs_32.d b/gas/testsuite/gas/loongarch/relocs_32.d
new file mode 100644
index 00000000..3e1bb62e
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relocs_32.d
@@ -0,0 +1,75 @@
+#as: -mthin-add-sub
+#objdump: -dr
+#skip: loongarch64-*-*
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+ <.*>:
+ 0: 4c0050a4 jirl \$a0, \$a1, 80
+ 0: R_LARCH_B16 .L1
+ 4: 50004c00 b 76 # 50 <.L1>
+ 4: R_LARCH_B26 .L1
+ 8: 14000004 lu12i.w \$a0, 0
+ 8: R_LARCH_ABS_HI20 .L1
+ c: 038000a4 ori \$a0, \$a1, 0x0
+ c: R_LARCH_ABS_LO12 .L1
+ 10: 1a000004 pcalau12i \$a0, 0
+ 10: R_LARCH_PCALA_HI20 .L1
+ 14: 02800085 addi.w \$a1, \$a0, 0
+ 14: R_LARCH_PCALA_LO12 .L1
+ 18: 1a000004 pcalau12i \$a0, 0
+ 18: R_LARCH_GOT_PC_HI20 .L1
+ 1c: 28800085 ld.w \$a1, \$a0, 0
+ 1c: R_LARCH_GOT_PC_LO12 .L1
+ 20: 14000004 lu12i.w \$a0, 0
+ 20: R_LARCH_GOT_HI20 .L1
+ 24: 03800084 ori \$a0, \$a0, 0x0
+ 24: R_LARCH_GOT_LO12 .L1
+ 28: 14000004 lu12i.w \$a0, 0
+ 28: R_LARCH_TLS_LE_HI20 TLSL1
+ 2c: 03800085 ori \$a1, \$a0, 0x0
+ 2c: R_LARCH_TLS_LE_LO12 TLSL1
+ 30: 1a000004 pcalau12i \$a0, 0
+ 30: R_LARCH_TLS_IE_PC_HI20 TLSL1
+ 34: 02c00005 li.d \$a1, 0
+ 34: R_LARCH_TLS_IE_PC_LO12 TLSL1
+ 38: 14000004 lu12i.w \$a0, 0
+ 38: R_LARCH_TLS_IE_HI20 TLSL1
+ 3c: 03800084 ori \$a0, \$a0, 0x0
+ 3c: R_LARCH_TLS_IE_LO12 TLSL1
+ 40: 1a000004 pcalau12i \$a0, 0
+ 40: R_LARCH_TLS_LD_PC_HI20 TLSL1
+ 44: 14000004 lu12i.w \$a0, 0
+ 44: R_LARCH_TLS_LD_HI20 TLSL1
+ 48: 1a000004 pcalau12i \$a0, 0
+ 48: R_LARCH_TLS_GD_PC_HI20 TLSL1
+ 4c: 14000004 lu12i.w \$a0, 0
+ 4c: R_LARCH_TLS_GD_HI20 TLSL1
+
+0+50 <.L1>:
+ 50: 00000000 .word 0x00000000
+ 50: R_LARCH_32_PCREL .L2
+
+0+54 <.L2>:
+ 54: 03400000 nop
+ 58: 03400000 nop
+ 58: R_LARCH_ALIGN .*
+ 5c: 03400000 nop
+ 60: 03400000 nop
+ 64: 1800000c pcaddi \$t0, 0
+ 64: R_LARCH_PCREL20_S2 .L1
+ 68: 1a000004 pcalau12i \$a0, 0
+ 68: R_LARCH_TLS_DESC_PC_HI20 TLSL1
+ 6c: 028000a5 addi.w \$a1, \$a1, 0
+ 6c: R_LARCH_TLS_DESC_PC_LO12 TLSL1
+ 70: 14000004 lu12i.w \$a0, 0
+ 70: R_LARCH_TLS_DESC_HI20 TLSL1
+ 74: 03800084 ori \$a0, \$a0, 0x0
+ 74: R_LARCH_TLS_DESC_LO12 TLSL1
+ 78: 28800081 ld.w \$ra, \$a0, 0
+ 78: R_LARCH_TLS_DESC_LD TLSL1
+ 7c: 4c000021 jirl \$ra, \$ra, 0
+ 7c: R_LARCH_TLS_DESC_CALL TLSL1
diff --git a/gas/testsuite/gas/loongarch/relocs_32.s b/gas/testsuite/gas/loongarch/relocs_32.s
new file mode 100644
index 00000000..c5139a75
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relocs_32.s
@@ -0,0 +1,61 @@
+/* b16. */
+jirl $r4,$r5,%b16(.L1)
+
+/* b26. */
+b %b26(.L1)
+
+/* lu12i.w. */
+lu12i.w $r4,%abs_hi20(.L1)
+
+/* ori */
+ori $r4,$r5,%abs_lo12(.L1)
+
+pcalau12i $r4,%pc_hi20(.L1)
+addi.w $r5,$r4,%pc_lo12(.L1)
+
+pcalau12i $r4,%got_pc_hi20(.L1)
+ld.w $r5,$r4,%got_pc_lo12(.L1)
+
+lu12i.w $r4,%got_hi20(.L1)
+ori $r4,$r4,%got_lo12(.L1)
+
+/* TLS LE. */
+lu12i.w $r4,%le_hi20(TLSL1)
+ori $r5,$r4,%le_lo12(TLSL1)
+
+/* Part of IE relocs. */
+pcalau12i $r4,%ie_pc_hi20(TLSL1)
+addi.d $r5,$r0,%ie_pc_lo12(TLSL1)
+
+lu12i.w $r4,%ie_hi20(TLSL1)
+ori $r4,$r4,%ie_lo12(TLSL1)
+
+/* Part of LD relocs. */
+pcalau12i $r4,%ld_pc_hi20(TLSL1)
+lu12i.w $r4,%ld_hi20(TLSL1)
+
+/* Part of GD relocs. */
+pcalau12i $r4,%gd_pc_hi20(TLSL1)
+lu12i.w $r4,%gd_hi20(TLSL1)
+
+/* Test insn relocs. */
+.L1:
+/* 32-bit PC relative. */
+.4byte .L2-.L1
+.L2:
+nop
+
+/* R_LARCH_ALIGN. */
+.align 4
+
+/* R_LARCH_PCREL20_S2. */
+pcaddi $r12,.L1
+
+/* Part of DESC relocs. */
+pcalau12i $r4,%desc_pc_hi20(TLSL1)
+addi.w $r5,$r5,%desc_pc_lo12(TLSL1)
+
+lu12i.w $r4,%desc_hi20(TLSL1)
+ori $r4,$r4,%desc_lo12(TLSL1)
+ld.w $r1,$r4,%desc_ld(TLSL1)
+jirl $r1,$r1,%desc_call(TLSL1)
--
2.33.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,281 @@
From 6dbcb5e8afae6d282e0955fdbbc7732b10338902 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Thu, 11 Jan 2024 09:45:57 +0800
Subject: [PATCH 067/123] LoongArch: Add gas testsuit for LA64 relocations
Test the relocation of the LA64 instruction set.
---
gas/testsuite/gas/loongarch/relocs_64.d | 144 ++++++++++++++++++++++++
gas/testsuite/gas/loongarch/relocs_64.s | 109 ++++++++++++++++++
2 files changed, 253 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/relocs_64.d
create mode 100644 gas/testsuite/gas/loongarch/relocs_64.s
diff --git a/gas/testsuite/gas/loongarch/relocs_64.d b/gas/testsuite/gas/loongarch/relocs_64.d
new file mode 100644
index 00000000..631137eb
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relocs_64.d
@@ -0,0 +1,144 @@
+#as: -mthin-add-sub
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+ <.*>:
+ 0: 4c008ca4 jirl \$a0, \$a1, 140
+ 0: R_LARCH_B16 .L1
+ 4: 40008880 beqz \$a0, 136 # 8c <.L1>
+ 4: R_LARCH_B21 .L1
+ 8: 50008400 b 132 # 8c <.L1>
+ 8: R_LARCH_B26 .L1
+ c: 14000004 lu12i.w \$a0, 0
+ c: R_LARCH_ABS_HI20 .L1
+ 10: 038000a4 ori \$a0, \$a1, 0x0
+ 10: R_LARCH_ABS_LO12 .L1
+ 14: 16000004 lu32i.d \$a0, 0
+ 14: R_LARCH_ABS64_LO20 .L1
+ 18: 03000085 lu52i.d \$a1, \$a0, 0
+ 18: R_LARCH_ABS64_HI12 .L1
+ 1c: 1a000004 pcalau12i \$a0, 0
+ 1c: R_LARCH_PCALA_HI20 .L1
+ 20: 02c00085 addi.d \$a1, \$a0, 0
+ 20: R_LARCH_PCALA_LO12 .L1
+ 24: 16000004 lu32i.d \$a0, 0
+ 24: R_LARCH_PCALA64_LO20 .L1
+ 28: 03000085 lu52i.d \$a1, \$a0, 0
+ 28: R_LARCH_PCALA64_HI12 .L1
+ 2c: 1a000004 pcalau12i \$a0, 0
+ 2c: R_LARCH_GOT_PC_HI20 .L1
+ 30: 28c00085 ld.d \$a1, \$a0, 0
+ 30: R_LARCH_GOT_PC_LO12 .L1
+ 34: 16000004 lu32i.d \$a0, 0
+ 34: R_LARCH_GOT64_PC_LO20 .L1
+ 38: 03000085 lu52i.d \$a1, \$a0, 0
+ 38: R_LARCH_GOT64_PC_HI12 .L1
+ 3c: 14000004 lu12i.w \$a0, 0
+ 3c: R_LARCH_GOT_HI20 .L1
+ 40: 03800084 ori \$a0, \$a0, 0x0
+ 40: R_LARCH_GOT_LO12 .L1
+ 44: 16000004 lu32i.d \$a0, 0
+ 44: R_LARCH_GOT64_LO20 .L1
+ 48: 03000085 lu52i.d \$a1, \$a0, 0
+ 48: R_LARCH_GOT64_HI12 .L1
+ 4c: 14000004 lu12i.w \$a0, 0
+ 4c: R_LARCH_TLS_LE_HI20 TLSL1
+ 50: 03800085 ori \$a1, \$a0, 0x0
+ 50: R_LARCH_TLS_LE_LO12 TLSL1
+ 54: 16000004 lu32i.d \$a0, 0
+ 54: R_LARCH_TLS_LE64_LO20 TLSL1
+ 58: 03000085 lu52i.d \$a1, \$a0, 0
+ 58: R_LARCH_TLS_LE64_HI12 TLSL1
+ 5c: 1a000004 pcalau12i \$a0, 0
+ 5c: R_LARCH_TLS_IE_PC_HI20 TLSL1
+ 60: 02c00005 li.d \$a1, 0
+ 60: R_LARCH_TLS_IE_PC_LO12 TLSL1
+ 64: 16000005 lu32i.d \$a1, 0
+ 64: R_LARCH_TLS_IE64_PC_LO20 TLSL1
+ 68: 030000a5 lu52i.d \$a1, \$a1, 0
+ 68: R_LARCH_TLS_IE64_PC_HI12 TLSL1
+ 6c: 14000004 lu12i.w \$a0, 0
+ 6c: R_LARCH_TLS_IE_HI20 TLSL1
+ 70: 03800084 ori \$a0, \$a0, 0x0
+ 70: R_LARCH_TLS_IE_LO12 TLSL1
+ 74: 16000004 lu32i.d \$a0, 0
+ 74: R_LARCH_TLS_IE64_LO20 TLSL1
+ 78: 03000084 lu52i.d \$a0, \$a0, 0
+ 78: R_LARCH_TLS_IE64_HI12 TLSL1
+ 7c: 1a000004 pcalau12i \$a0, 0
+ 7c: R_LARCH_TLS_LD_PC_HI20 TLSL1
+ 80: 14000004 lu12i.w \$a0, 0
+ 80: R_LARCH_TLS_LD_HI20 TLSL1
+ 84: 1a000004 pcalau12i \$a0, 0
+ 84: R_LARCH_TLS_GD_PC_HI20 TLSL1
+ 88: 14000004 lu12i.w \$a0, 0
+ 88: R_LARCH_TLS_GD_HI20 TLSL1
+
+0+8c <.L1>:
+ 8c: 00000000 .word 0x00000000
+ 8c: R_LARCH_32_PCREL .L2
+
+0+90 <.L2>:
+ ...
+ 90: R_LARCH_64_PCREL .L3
+
+0+98 <.L3>:
+ 98: 03400000 nop
+ 9c: 03400000 nop
+ 9c: R_LARCH_ALIGN .*
+ a0: 03400000 nop
+ a4: 03400000 nop
+ a8: 1800000c pcaddi \$t0, 0
+ a8: R_LARCH_PCREL20_S2 .L1
+ ac: 1e000001 pcaddu18i \$ra, 0
+ ac: R_LARCH_CALL36 a
+ b0: 4c000021 jirl \$ra, \$ra, 0
+ b4: 1a000004 pcalau12i \$a0, 0
+ b4: R_LARCH_TLS_DESC_PC_HI20 TLSL1
+ b8: 02c000a5 addi.d \$a1, \$a1, 0
+ b8: R_LARCH_TLS_DESC_PC_LO12 TLSL1
+ bc: 16000005 lu32i.d \$a1, 0
+ bc: R_LARCH_TLS_DESC64_PC_LO20 TLSL1
+ c0: 030000a5 lu52i.d \$a1, \$a1, 0
+ c0: R_LARCH_TLS_DESC64_PC_HI12 TLSL1
+ c4: 14000004 lu12i.w \$a0, 0
+ c4: R_LARCH_TLS_DESC_HI20 TLSL1
+ c8: 03800084 ori \$a0, \$a0, 0x0
+ c8: R_LARCH_TLS_DESC_LO12 TLSL1
+ cc: 16000004 lu32i.d \$a0, 0
+ cc: R_LARCH_TLS_DESC64_LO20 TLSL1
+ d0: 03000084 lu52i.d \$a0, \$a0, 0
+ d0: R_LARCH_TLS_DESC64_HI12 TLSL1
+ d4: 28c00081 ld.d \$ra, \$a0, 0
+ d4: R_LARCH_TLS_DESC_LD TLSL1
+ d8: 4c000021 jirl \$ra, \$ra, 0
+ d8: R_LARCH_TLS_DESC_CALL TLSL1
+ dc: 14000004 lu12i.w \$a0, 0
+ dc: R_LARCH_TLS_LE_HI20_R TLSL1
+ dc: R_LARCH_RELAX \*ABS\*
+ e0: 001090a5 add.d \$a1, \$a1, \$a0
+ e0: R_LARCH_TLS_LE_ADD_R TLSL1
+ e0: R_LARCH_RELAX \*ABS\*
+ e4: 29800085 st.w \$a1, \$a0, 0
+ e4: R_LARCH_TLS_LE_LO12_R TLSL1
+ e4: R_LARCH_RELAX \*ABS\*
+ e8: 14000004 lu12i.w \$a0, 0
+ e8: R_LARCH_TLS_LE_HI20_R TLSL1
+ e8: R_LARCH_RELAX \*ABS\*
+ ec: 001090a5 add.d \$a1, \$a1, \$a0
+ ec: R_LARCH_TLS_LE_ADD_R TLSL1
+ ec: R_LARCH_RELAX \*ABS\*
+ f0: 29800085 st.w \$a1, \$a0, 0
+ f0: R_LARCH_TLS_LE_LO12_R TLSL1
+ f0: R_LARCH_RELAX \*ABS\*
+ f4: 18000004 pcaddi \$a0, 0
+ f4: R_LARCH_TLS_LD_PCREL20_S2 TLSL1
+ f8: 18000004 pcaddi \$a0, 0
+ f8: R_LARCH_TLS_GD_PCREL20_S2 TLSL1
+ fc: 18000004 pcaddi \$a0, 0
+ fc: R_LARCH_TLS_DESC_PCREL20_S2 TLSL1
diff --git a/gas/testsuite/gas/loongarch/relocs_64.s b/gas/testsuite/gas/loongarch/relocs_64.s
new file mode 100644
index 00000000..1d1548f5
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relocs_64.s
@@ -0,0 +1,109 @@
+/* b16. */
+jirl $r4,$r5,%b16(.L1)
+
+/* b21. */
+beqz $r4,%b21(.L1)
+
+/* b26. */
+b %b26(.L1)
+
+/* lu12i.w. */
+lu12i.w $r4,%abs_hi20(.L1)
+
+/* ori */
+ori $r4,$r5,%abs_lo12(.L1)
+
+/* lu32i.d. */
+lu32i.d $r4,%abs64_lo20(.L1)
+
+/* lu52i.d. */
+lu52i.d $r5,$r4,%abs64_hi12(.L1)
+
+pcalau12i $r4,%pc_hi20(.L1)
+addi.d $r5,$r4,%pc_lo12(.L1)
+lu32i.d $r4,%pc64_lo20(.L1)
+lu52i.d $r5,$r4,%pc64_hi12(.L1)
+
+pcalau12i $r4,%got_pc_hi20(.L1)
+ld.d $r5,$r4,%got_pc_lo12(.L1)
+lu32i.d $r4,%got64_pc_lo20(.L1)
+lu52i.d $r5,$r4,%got64_pc_hi12(.L1)
+
+lu12i.w $r4,%got_hi20(.L1)
+ori $r4,$r4,%got_lo12(.L1)
+lu32i.d $r4,%got64_lo20(.L1)
+lu52i.d $r5,$r4,%got64_hi12(.L1)
+
+/* TLS LE. */
+lu12i.w $r4,%le_hi20(TLSL1)
+ori $r5,$r4,%le_lo12(TLSL1)
+lu32i.d $r4,%le64_lo20(TLSL1)
+lu52i.d $r5,$r4,%le64_hi12(TLSL1)
+
+/* Part of IE relocs. */
+pcalau12i $r4,%ie_pc_hi20(TLSL1)
+addi.d $r5,$r0,%ie_pc_lo12(TLSL1)
+lu32i.d $r5,%ie64_pc_lo20(TLSL1)
+lu52i.d $r5,$r5,%ie64_pc_hi12(TLSL1)
+
+lu12i.w $r4,%ie_hi20(TLSL1)
+ori $r4,$r4,%ie_lo12(TLSL1)
+lu32i.d $r4,%ie64_lo20(TLSL1)
+lu52i.d $r4,$r4,%ie64_hi12(TLSL1)
+
+/* Part of LD relocs. */
+pcalau12i $r4,%ld_pc_hi20(TLSL1)
+lu12i.w $r4,%ld_hi20(TLSL1)
+
+/* Part of GD relocs. */
+pcalau12i $r4,%gd_pc_hi20(TLSL1)
+lu12i.w $r4,%gd_hi20(TLSL1)
+
+/* Test insn relocs. */
+.L1:
+/* 32-bit PC relative. */
+.4byte .L2-.L1
+.L2:
+/* 64-bit PC relative. */
+.8byte .L3-.L2
+
+.L3:
+nop
+
+/* R_LARCH_ALIGN. */
+.align 4
+
+/* R_LARCH_PCREL20_S2. */
+pcaddi $r12,.L1
+
+/* R_LARCH_ADD_CALL36 */
+pcaddu18i $r1, %call36(a)
+jirl $r1, $r1, 0
+
+/* Part of DESC relocs. */
+pcalau12i $r4,%desc_pc_hi20(TLSL1)
+addi.d $r5,$r5,%desc_pc_lo12(TLSL1)
+lu32i.d $r5,%desc64_pc_lo20(TLSL1)
+lu52i.d $r5,$r5,%desc64_pc_hi12(TLSL1)
+
+lu12i.w $r4,%desc_hi20(TLSL1)
+ori $r4,$r4,%desc_lo12(TLSL1)
+lu32i.d $r4,%desc64_lo20(TLSL1)
+lu52i.d $r4,$r4,%desc64_hi12(TLSL1)
+ld.d $r1,$r4,%desc_ld(TLSL1)
+jirl $r1,$r1,%desc_call(TLSL1)
+
+/* New TLS Insn. */
+lu12i.w $r4,%le_hi20_r(TLSL1)
+add.d $r5,$r5,$r4,%le_add_r(TLSL1)
+st.w $r5,$r4,%le_lo12_r(TLSL1)
+
+/* New TLS Insn with addend. */
+lu12i.w $r4,%le_hi20_r(TLSL1)
+add.d $r5,$r5,$r4,%le_add_r(TLSL1)
+st.w $r5,$r4,%le_lo12_r(TLSL1)
+
+/* Part of relaxed LD/GD/DESC insn sequence. */
+pcaddi $a0,%ld_pcrel_20(TLSL1)
+pcaddi $a0,%gd_pcrel_20(TLSL1)
+pcaddi $a0,%desc_pcrel_20(TLSL1)
--
2.33.0

View File

@ -0,0 +1,104 @@
From f2183b3edb1cee6d9fe0c3dbd26956501bcd6904 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Fri, 5 Jan 2024 11:41:27 +0800
Subject: [PATCH 062/123] LoongArch: Add gas testsuit for alias instructions
Test the alias instructions.
---
gas/testsuite/gas/loongarch/insn_alias_32.d | 19 +++++++++++++++++++
gas/testsuite/gas/loongarch/insn_alias_32.s | 10 ++++++++++
gas/testsuite/gas/loongarch/insn_alias_64.d | 20 ++++++++++++++++++++
gas/testsuite/gas/loongarch/insn_alias_64.s | 11 +++++++++++
4 files changed, 60 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/insn_alias_32.d
create mode 100644 gas/testsuite/gas/loongarch/insn_alias_32.s
create mode 100644 gas/testsuite/gas/loongarch/insn_alias_64.d
create mode 100644 gas/testsuite/gas/loongarch/insn_alias_64.s
diff --git a/gas/testsuite/gas/loongarch/insn_alias_32.d b/gas/testsuite/gas/loongarch/insn_alias_32.d
new file mode 100644
index 00000000..753eae7a
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_alias_32.d
@@ -0,0 +1,19 @@
+#as:
+#objdump: -d -M no-aliases
+#skip: loongarch64-*-*
+
+.* file format .*
+
+
+Disassembly of section .text:
+
+0+ <L1>:
+ 0: 001500a4 or \$a0, \$a1, \$zero
+ 4: 02bffc04 addi.w \$a0, \$zero, -1
+ 8: 03400000 andi \$zero, \$zero, 0x0
+ c: 03800404 ori \$a0, \$zero, 0x1
+ 10: 4c000020 jirl \$zero, \$ra, 0
+ 14: 4c000020 jirl \$zero, \$ra, 0
+ 18: 60000080 blt \$a0, \$zero, 0 # 18 <L1\+0x18>
+ 1c: 64000080 bge \$a0, \$zero, 0 # 1c <L1\+0x1c>
+ 20: 64000004 bge \$zero, \$a0, 0 # 20 <L1\+0x20>
diff --git a/gas/testsuite/gas/loongarch/insn_alias_32.s b/gas/testsuite/gas/loongarch/insn_alias_32.s
new file mode 100644
index 00000000..8027e32a
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_alias_32.s
@@ -0,0 +1,10 @@
+L1:
+ move $a0,$a1
+ li.w $a0,-1
+ nop
+ li.w $a0,1
+ ret
+ jr $ra
+ bltz $a0,.L1
+ bgez $a0,.L1
+ blez $a0,.L1
diff --git a/gas/testsuite/gas/loongarch/insn_alias_64.d b/gas/testsuite/gas/loongarch/insn_alias_64.d
new file mode 100644
index 00000000..8d3ed7bc
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_alias_64.d
@@ -0,0 +1,20 @@
+#as-new:
+#objdump: -d -M no-aliases
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+ <L1>:
+ 0: 001500a4 or \$a0, \$a1, \$zero
+ 4: 02bffc04 addi.w \$a0, \$zero, -1
+ 8: 02bffc04 addi.w \$a0, \$zero, -1
+ c: 03400000 andi \$zero, \$zero, 0x0
+ 10: 03800404 ori \$a0, \$zero, 0x1
+ 14: 4c000020 jirl \$zero, \$ra, 0
+ 18: 4c000020 jirl \$zero, \$ra, 0
+ 1c: 60000080 blt \$a0, \$zero, 0 # 1c <L1\+0x1c>
+ 20: 64000080 bge \$a0, \$zero, 0 # 20 <L1\+0x20>
+ 24: 64000004 bge \$zero, \$a0, 0 # 24 <L1\+0x24>
diff --git a/gas/testsuite/gas/loongarch/insn_alias_64.s b/gas/testsuite/gas/loongarch/insn_alias_64.s
new file mode 100644
index 00000000..e7e42638
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_alias_64.s
@@ -0,0 +1,11 @@
+L1:
+ move $a0,$a1
+ li.w $a0,-1
+ li.d $a0,-1
+ nop
+ li.w $a0,1
+ ret
+ jr $ra
+ bltz $a0,.L1
+ bgez $a0,.L1
+ blez $a0,.L1
--
2.33.0

View File

@ -0,0 +1,427 @@
From 8b2478a4eab5b880516b32b5d478a1eab5be1f4c Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Fri, 5 Jan 2024 11:58:34 +0800
Subject: [PATCH 063/123] LoongArch: Add gas testsuit for lbt/lvz instructions
Test the LBT/LVZ instructions. Only LA64 supports
these instructions.
---
gas/testsuite/gas/loongarch/insn_lbt.d | 186 +++++++++++++++++++++++++
gas/testsuite/gas/loongarch/insn_lbt.s | 176 +++++++++++++++++++++++
gas/testsuite/gas/loongarch/insn_lvz.d | 15 ++
gas/testsuite/gas/loongarch/insn_lvz.s | 5 +
4 files changed, 382 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/insn_lbt.d
create mode 100644 gas/testsuite/gas/loongarch/insn_lbt.s
create mode 100644 gas/testsuite/gas/loongarch/insn_lvz.d
create mode 100644 gas/testsuite/gas/loongarch/insn_lvz.s
diff --git a/gas/testsuite/gas/loongarch/insn_lbt.d b/gas/testsuite/gas/loongarch/insn_lbt.d
new file mode 100644
index 00000000..7d80fb89
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_lbt.d
@@ -0,0 +1,186 @@
+#as:
+#objdump: -d
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+ <.*>:
+ 0: 00000820 movgr2scr \$scr0, \$ra
+ 4: 00000c20 movscr2gr \$zero, \$scr1
+ 8: 48006600 jiscr0 100
+ c: 48006700 jiscr1 100
+ 10: 00290420 addu12i.w \$zero, \$ra, 1
+ 14: 00298420 addu12i.d \$zero, \$ra, 1
+ 18: 00300820 adc.b \$zero, \$ra, \$tp
+ 1c: 00308820 adc.h \$zero, \$ra, \$tp
+ 20: 00310820 adc.w \$zero, \$ra, \$tp
+ 24: 00318820 adc.d \$zero, \$ra, \$tp
+ 28: 00320820 sbc.b \$zero, \$ra, \$tp
+ 2c: 00328820 sbc.h \$zero, \$ra, \$tp
+ 30: 00330820 sbc.w \$zero, \$ra, \$tp
+ 34: 00338820 sbc.d \$zero, \$ra, \$tp
+ 38: 001a0820 rotr.b \$zero, \$ra, \$tp
+ 3c: 001a8820 rotr.h \$zero, \$ra, \$tp
+ 40: 004c2420 rotri.b \$zero, \$ra, 0x1
+ 44: 004c4420 rotri.h \$zero, \$ra, 0x1
+ 48: 00340820 rcr.b \$zero, \$ra, \$tp
+ 4c: 00348820 rcr.h \$zero, \$ra, \$tp
+ 50: 00350820 rcr.w \$zero, \$ra, \$tp
+ 54: 00358820 rcr.d \$zero, \$ra, \$tp
+ 58: 00502420 rcri.b \$zero, \$ra, 0x1
+ 5c: 00504420 rcri.h \$zero, \$ra, 0x1
+ 60: 00508420 rcri.w \$zero, \$ra, 0x1
+ 64: 00510420 rcri.d \$zero, \$ra, 0x1
+ 68: 0114e420 fcvt.ud.d \$fa0, \$fa1
+ 6c: 0114e020 fcvt.ld.d \$fa0, \$fa1
+ 70: 01150820 fcvt.d.ld \$fa0, \$fa1, \$fa2
+ 74: 2e800420 ldl.d \$zero, \$ra, 1
+ 78: 2e000420 ldl.w \$zero, \$ra, 1
+ 7c: 2e400420 ldr.w \$zero, \$ra, 1
+ 80: 2ec00420 ldr.d \$zero, \$ra, 1
+ 84: 2f000420 stl.w \$zero, \$ra, 1
+ 88: 2f800420 stl.d \$zero, \$ra, 1
+ 8c: 2f400420 str.w \$zero, \$ra, 1
+ 90: 2fc00420 str.d \$zero, \$ra, 1
+ 94: 003f040c x86adc.b \$zero, \$ra
+ 98: 003f040d x86adc.h \$zero, \$ra
+ 9c: 003f040e x86adc.w \$zero, \$ra
+ a0: 003f040f x86adc.d \$zero, \$ra
+ a4: 003f0404 x86add.b \$zero, \$ra
+ a8: 003f0405 x86add.h \$zero, \$ra
+ ac: 003f0406 x86add.w \$zero, \$ra
+ b0: 003f0407 x86add.d \$zero, \$ra
+ b4: 003f0400 x86add.wu \$zero, \$ra
+ b8: 003f0401 x86add.du \$zero, \$ra
+ bc: 00008000 x86inc.b \$zero
+ c0: 00008001 x86inc.h \$zero
+ c4: 00008002 x86inc.w \$zero
+ c8: 00008003 x86inc.d \$zero
+ cc: 003f0410 x86sbc.b \$zero, \$ra
+ d0: 003f0411 x86sbc.h \$zero, \$ra
+ d4: 003f0412 x86sbc.w \$zero, \$ra
+ d8: 003f0413 x86sbc.d \$zero, \$ra
+ dc: 003f0408 x86sub.b \$zero, \$ra
+ e0: 003f0409 x86sub.h \$zero, \$ra
+ e4: 003f040a x86sub.w \$zero, \$ra
+ e8: 003f040b x86sub.d \$zero, \$ra
+ ec: 003f0402 x86sub.wu \$zero, \$ra
+ f0: 003f0403 x86sub.du \$zero, \$ra
+ f4: 00008004 x86dec.b \$zero
+ f8: 00008005 x86dec.h \$zero
+ fc: 00008006 x86dec.w \$zero
+ 100: 00008007 x86dec.d \$zero
+ 104: 003f8410 x86and.b \$zero, \$ra
+ 108: 003f8411 x86and.h \$zero, \$ra
+ 10c: 003f8412 x86and.w \$zero, \$ra
+ 110: 003f8413 x86and.d \$zero, \$ra
+ 114: 003f8414 x86or.b \$zero, \$ra
+ 118: 003f8415 x86or.h \$zero, \$ra
+ 11c: 003f8416 x86or.w \$zero, \$ra
+ 120: 003f8417 x86or.d \$zero, \$ra
+ 124: 003f8418 x86xor.b \$zero, \$ra
+ 128: 003f8419 x86xor.h \$zero, \$ra
+ 12c: 003f841a x86xor.w \$zero, \$ra
+ 130: 003f841b x86xor.d \$zero, \$ra
+ 134: 003e8400 x86mul.b \$zero, \$ra
+ 138: 003e8401 x86mul.h \$zero, \$ra
+ 13c: 003e8402 x86mul.w \$zero, \$ra
+ 140: 003e8403 x86mul.d \$zero, \$ra
+ 144: 003e8404 x86mul.bu \$zero, \$ra
+ 148: 003e8405 x86mul.hu \$zero, \$ra
+ 14c: 003e8406 x86mul.wu \$zero, \$ra
+ 150: 003e8407 x86mul.du \$zero, \$ra
+ 154: 003f840c x86rcl.b \$zero, \$ra
+ 158: 003f840d x86rcl.h \$zero, \$ra
+ 15c: 003f840e x86rcl.w \$zero, \$ra
+ 160: 003f840f x86rcl.d \$zero, \$ra
+ 164: 00542418 x86rcli.b \$zero, 0x1
+ 168: 00544419 x86rcli.h \$zero, 0x1
+ 16c: 0054841a x86rcli.w \$zero, 0x1
+ 170: 0055041b x86rcli.d \$zero, 0x1
+ 174: 003f8408 x86rcr.b \$zero, \$ra
+ 178: 003f8409 x86rcr.h \$zero, \$ra
+ 17c: 003f840a x86rcr.w \$zero, \$ra
+ 180: 003f840b x86rcr.d \$zero, \$ra
+ 184: 00542410 x86rcri.b \$zero, 0x1
+ 188: 00544411 x86rcri.h \$zero, 0x1
+ 18c: 00548412 x86rcri.w \$zero, 0x1
+ 190: 00550413 x86rcri.d \$zero, 0x1
+ 194: 003f8404 x86rotl.b \$zero, \$ra
+ 198: 003f8405 x86rotl.h \$zero, \$ra
+ 19c: 003f8406 x86rotl.w \$zero, \$ra
+ 1a0: 003f8407 x86rotl.d \$zero, \$ra
+ 1a4: 00542414 x86rotli.b \$zero, 0x1
+ 1a8: 00544415 x86rotli.h \$zero, 0x1
+ 1ac: 00548416 x86rotli.w \$zero, 0x1
+ 1b0: 00550417 x86rotli.d \$zero, 0x1
+ 1b4: 003f8400 x86rotr.b \$zero, \$ra
+ 1b8: 003f8401 x86rotr.h \$zero, \$ra
+ 1bc: 003f8402 x86rotr.d \$zero, \$ra
+ 1c0: 003f8403 x86rotr.w \$zero, \$ra
+ 1c4: 0054240c x86rotri.b \$zero, 0x1
+ 1c8: 0054440d x86rotri.h \$zero, 0x1
+ 1cc: 0054840e x86rotri.w \$zero, 0x1
+ 1d0: 0055040f x86rotri.d \$zero, 0x1
+ 1d4: 003f0414 x86sll.b \$zero, \$ra
+ 1d8: 003f0415 x86sll.h \$zero, \$ra
+ 1dc: 003f0416 x86sll.w \$zero, \$ra
+ 1e0: 003f0417 x86sll.d \$zero, \$ra
+ 1e4: 00542400 x86slli.b \$zero, 0x1
+ 1e8: 00544401 x86slli.h \$zero, 0x1
+ 1ec: 00548402 x86slli.w \$zero, 0x1
+ 1f0: 00550403 x86slli.d \$zero, 0x1
+ 1f4: 003f0418 x86srl.b \$zero, \$ra
+ 1f8: 003f0419 x86srl.h \$zero, \$ra
+ 1fc: 003f041a x86srl.w \$zero, \$ra
+ 200: 003f041b x86srl.d \$zero, \$ra
+ 204: 00542404 x86srli.b \$zero, 0x1
+ 208: 00544405 x86srli.h \$zero, 0x1
+ 20c: 00548406 x86srli.w \$zero, 0x1
+ 210: 00550407 x86srli.d \$zero, 0x1
+ 214: 003f041c x86sra.b \$zero, \$ra
+ 218: 003f041d x86sra.h \$zero, \$ra
+ 21c: 003f041e x86sra.w \$zero, \$ra
+ 220: 003f041f x86sra.d \$zero, \$ra
+ 224: 00542408 x86srai.b \$zero, 0x1
+ 228: 00544409 x86srai.h \$zero, 0x1
+ 22c: 0054840a x86srai.w \$zero, 0x1
+ 230: 0055040b x86srai.d \$zero, 0x1
+ 234: 00368400 setx86j \$zero, 0x1
+ 238: 00007820 setx86loope \$zero, \$ra
+ 23c: 00007c20 setx86loopne \$zero, \$ra
+ 240: 005c0400 x86mfflag \$zero, 0x1
+ 244: 005c0420 x86mtflag \$zero, 0x1
+ 248: 00007400 x86mftop \$zero
+ 24c: 00007020 x86mttop 0x1
+ 250: 00008009 x86inctop
+ 254: 00008029 x86dectop
+ 258: 00008008 x86settm
+ 25c: 00008028 x86clrtm
+ 260: 00580420 x86settag \$zero, 0x1, 0x1
+ 264: 00370411 armadd.w \$zero, \$ra, 0x1
+ 268: 00378411 armsub.w \$zero, \$ra, 0x1
+ 26c: 00380411 armadc.w \$zero, \$ra, 0x1
+ 270: 00388411 armsbc.w \$zero, \$ra, 0x1
+ 274: 00390411 armand.w \$zero, \$ra, 0x1
+ 278: 00398411 armor.w \$zero, \$ra, 0x1
+ 27c: 003a0411 armxor.w \$zero, \$ra, 0x1
+ 280: 003fc41c armnot.w \$zero, 0x1
+ 284: 003a8411 armsll.w \$zero, \$ra, 0x1
+ 288: 003b0411 armsrl.w \$zero, \$ra, 0x1
+ 28c: 003b8411 armsra.w \$zero, \$ra, 0x1
+ 290: 003c0411 armrotr.w \$zero, \$ra, 0x1
+ 294: 003c8411 armslli.w \$zero, 0x1, 0x1
+ 298: 003d0411 armsrli.w \$zero, 0x1, 0x1
+ 29c: 003d8411 armsrai.w \$zero, 0x1, 0x1
+ 2a0: 003e0411 armrotri.w \$zero, 0x1, 0x1
+ 2a4: 003fc41f armrrx.w \$zero, 0x1
+ 2a8: 00364420 armmove \$zero, \$ra, 0x1
+ 2ac: 003fc41d armmov.w \$zero, 0x1
+ 2b0: 003fc41e armmov.d \$zero, 0x1
+ 2b4: 005c0440 armmfflag \$zero, 0x1
+ 2b8: 005c0460 armmtflag \$zero, 0x1
+ 2bc: 0036c400 setarmj \$zero, 0x1
diff --git a/gas/testsuite/gas/loongarch/insn_lbt.s b/gas/testsuite/gas/loongarch/insn_lbt.s
new file mode 100644
index 00000000..e49453c0
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_lbt.s
@@ -0,0 +1,176 @@
+movgr2scr $scr0, $r1
+movscr2gr $r0, $scr1
+jiscr0 100
+jiscr1 100
+addu12i.w $r0, $r1, 1
+addu12i.d $r0, $r1, 1
+adc.b $r0, $r1, $r2
+adc.h $r0, $r1, $r2
+adc.w $r0, $r1, $r2
+adc.d $r0, $r1, $r2
+sbc.b $r0, $r1, $r2
+sbc.h $r0, $r1, $r2
+sbc.w $r0, $r1, $r2
+sbc.d $r0, $r1, $r2
+rotr.b $r0, $r1, $r2
+rotr.h $r0, $r1, $r2
+rotri.b $r0, $r1, 1
+rotri.h $r0, $r1, 1
+rcr.b $r0, $r1, $r2
+rcr.h $r0, $r1, $r2
+rcr.w $r0, $r1, $r2
+rcr.d $r0, $r1, $r2
+rcri.b $r0, $r1, 1
+rcri.h $r0, $r1, 1
+rcri.w $r0, $r1, 1
+rcri.d $r0, $r1, 1
+fcvt.ud.d $f0, $f1
+fcvt.ld.d $f0, $f1
+fcvt.d.ld $f0, $f1, $f2
+ldl.d $r0, $r1, 1
+ldl.w $r0, $r1, 1
+ldr.w $r0, $r1, 1
+ldr.d $r0, $r1, 1
+stl.w $r0, $r1, 1
+stl.d $r0, $r1, 1
+str.w $r0, $r1, 1
+str.d $r0, $r1, 1
+x86adc.b $r0, $r1
+x86adc.h $r0, $r1
+x86adc.w $r0, $r1
+x86adc.d $r0, $r1
+x86add.b $r0, $r1
+x86add.h $r0, $r1
+x86add.w $r0, $r1
+x86add.d $r0, $r1
+x86add.wu $r0, $r1
+x86add.du $r0, $r1
+x86inc.b $r0
+x86inc.h $r0
+x86inc.w $r0
+x86inc.d $r0
+x86sbc.b $r0, $r1
+x86sbc.h $r0, $r1
+x86sbc.w $r0, $r1
+x86sbc.d $r0, $r1
+x86sub.b $r0, $r1
+x86sub.h $r0, $r1
+x86sub.w $r0, $r1
+x86sub.d $r0, $r1
+x86sub.wu $r0, $r1
+x86sub.du $r0, $r1
+x86dec.b $r0
+x86dec.h $r0
+x86dec.w $r0
+x86dec.d $r0
+x86and.b $r0, $r1
+x86and.h $r0, $r1
+x86and.w $r0, $r1
+x86and.d $r0, $r1
+x86or.b $r0, $r1
+x86or.h $r0, $r1
+x86or.w $r0, $r1
+x86or.d $r0, $r1
+x86xor.b $r0, $r1
+x86xor.h $r0, $r1
+x86xor.w $r0, $r1
+x86xor.d $r0, $r1
+x86mul.b $r0, $r1
+x86mul.h $r0, $r1
+x86mul.w $r0, $r1
+x86mul.d $r0, $r1
+x86mul.bu $r0, $r1
+x86mul.hu $r0, $r1
+x86mul.wu $r0, $r1
+x86mul.du $r0, $r1
+x86rcl.b $r0, $r1
+x86rcl.h $r0, $r1
+x86rcl.w $r0, $r1
+x86rcl.d $r0, $r1
+x86rcli.b $r0, 1
+x86rcli.h $r0, 1
+x86rcli.w $r0, 1
+x86rcli.d $r0, 1
+x86rcr.b $r0, $r1
+x86rcr.h $r0, $r1
+x86rcr.w $r0, $r1
+x86rcr.d $r0, $r1
+x86rcri.b $r0, 1
+x86rcri.h $r0, 1
+x86rcri.w $r0, 1
+x86rcri.d $r0, 1
+x86rotl.b $r0, $r1
+x86rotl.h $r0, $r1
+x86rotl.w $r0, $r1
+x86rotl.d $r0, $r1
+x86rotli.b $r0, 1
+x86rotli.h $r0, 1
+x86rotli.w $r0, 1
+x86rotli.d $r0, 1
+x86rotr.b $r0, $r1
+x86rotr.h $r0, $r1
+x86rotr.d $r0, $r1
+x86rotr.w $r0, $r1
+x86rotri.b $r0, 1
+x86rotri.h $r0, 1
+x86rotri.w $r0, 1
+x86rotri.d $r0, 1
+x86sll.b $r0, $r1
+x86sll.h $r0, $r1
+x86sll.w $r0, $r1
+x86sll.d $r0, $r1
+x86slli.b $r0, 1
+x86slli.h $r0, 1
+x86slli.w $r0, 1
+x86slli.d $r0, 1
+x86srl.b $r0, $r1
+x86srl.h $r0, $r1
+x86srl.w $r0, $r1
+x86srl.d $r0, $r1
+x86srli.b $r0, 1
+x86srli.h $r0, 1
+x86srli.w $r0, 1
+x86srli.d $r0, 1
+x86sra.b $r0, $r1
+x86sra.h $r0, $r1
+x86sra.w $r0, $r1
+x86sra.d $r0, $r1
+x86srai.b $r0, 1
+x86srai.h $r0, 1
+x86srai.w $r0, 1
+x86srai.d $r0, 1
+setx86j $r0, 1
+setx86loope $r0, $r1
+setx86loopne $r0, $r1
+x86mfflag $r0, 1
+x86mtflag $r0, 1
+x86mftop $r0
+x86mttop 1
+x86inctop
+x86dectop
+x86settm
+x86clrtm
+x86settag $r0, 1, 1
+armadd.w $r0, $r1, 1
+armsub.w $r0, $r1, 1
+armadc.w $r0, $r1, 1
+armsbc.w $r0, $r1, 1
+armand.w $r0, $r1, 1
+armor.w $r0, $r1, 1
+armxor.w $r0, $r1, 1
+armnot.w $r0, 1
+armsll.w $r0, $r1, 1
+armsrl.w $r0, $r1, 1
+armsra.w $r0, $r1, 1
+armrotr.w $r0, $r1, 1
+armslli.w $r0, 1, 1
+armsrli.w $r0, 1, 1
+armsrai.w $r0, 1, 1
+armrotri.w $r0, 1, 1
+armrrx.w $r0, 1
+armmove $r0, $r1, 1
+armmov.w $r0, 1
+armmov.d $r0, 1
+armmfflag $r0, 1
+armmtflag $r0, 1
+setarmj $r0, 1
diff --git a/gas/testsuite/gas/loongarch/insn_lvz.d b/gas/testsuite/gas/loongarch/insn_lvz.d
new file mode 100644
index 00000000..547091ed
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_lvz.d
@@ -0,0 +1,15 @@
+#as:
+#objdump: -d
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+ <.*>:
+ 0: 05000400 gcsrrd \$zero, 0x1
+ 4: 05000420 gcsrwr \$zero, 0x1
+ 8: 05000483 gcsrxchg \$sp, \$a0, 0x1
+ c: 06482401 gtlbflush
+ 10: 002b8001 hvcl 0x1
diff --git a/gas/testsuite/gas/loongarch/insn_lvz.s b/gas/testsuite/gas/loongarch/insn_lvz.s
new file mode 100644
index 00000000..1b1a5940
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_lvz.s
@@ -0,0 +1,5 @@
+gcsrrd $r0, 1
+gcsrwr $r0, 1
+gcsrxchg $r3, $r4, 1
+gtlbflush
+hvcl 1
--
2.33.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,316 @@
From 5b5553b3a8d81b48b5b6829165173fe158c3fe8f Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Sun, 7 Apr 2024 16:34:42 +0800
Subject: [PATCH 080/123] LoongArch: Add -mignore-start-align option
Ignore .align at the start of a section may result in misalignment when
partial linking. Manually add -mignore-start-align option without partial
linking.
Gcc -falign-functions add .align 5 to the start of a section, it causes some
error message mismatch. Set these testcases to xfail on LoongArch target.
---
gas/config/tc-loongarch.c | 70 +++++++++++++------
...ign-first.d => relax-align-ignore-start.d} | 2 +-
...ign-first.s => relax-align-ignore-start.s} | 0
include/opcode/loongarch.h | 1 +
ld/testsuite/ld-elf/dwarf.exp | 5 ++
.../ld-loongarch-elf/partial-link-align-a.s | 2 +
.../ld-loongarch-elf/partial-link-align-b.s | 3 +
...ign-first.d => relax-align-ignore-start.d} | 1 +
...ign-first.s => relax-align-ignore-start.s} | 0
ld/testsuite/ld-loongarch-elf/relax.exp | 32 ++++++++-
ld/testsuite/ld-undefined/undefined.exp | 2 +
11 files changed, 95 insertions(+), 23 deletions(-)
rename gas/testsuite/gas/loongarch/{relax-align-first.d => relax-align-ignore-start.d} (87%)
rename gas/testsuite/gas/loongarch/{relax-align-first.s => relax-align-ignore-start.s} (100%)
create mode 100644 ld/testsuite/ld-loongarch-elf/partial-link-align-a.s
create mode 100644 ld/testsuite/ld-loongarch-elf/partial-link-align-b.s
rename ld/testsuite/ld-loongarch-elf/{relax-align-first.d => relax-align-ignore-start.d} (92%)
rename ld/testsuite/ld-loongarch-elf/{relax-align-first.s => relax-align-ignore-start.s} (100%)
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 110b92e4..f030fd07 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -139,15 +139,17 @@ enum options
OPTION_ABI,
OPTION_FLOAT_ABI,
-
OPTION_FLOAT_ISA,
OPTION_LA_LOCAL_WITH_ABS,
OPTION_LA_GLOBAL_WITH_PCREL,
OPTION_LA_GLOBAL_WITH_ABS,
+
OPTION_RELAX,
OPTION_NO_RELAX,
+
OPTION_THIN_ADD_SUB,
+ OPTION_IGNORE_START_ALIGN,
OPTION_END_OF_ENUM,
};
@@ -165,6 +167,7 @@ struct option md_longopts[] =
{ "mrelax", no_argument, NULL, OPTION_RELAX },
{ "mno-relax", no_argument, NULL, OPTION_NO_RELAX },
{ "mthin-add-sub", no_argument, NULL, OPTION_THIN_ADD_SUB},
+ { "mignore-start-align", no_argument, NULL, OPTION_IGNORE_START_ALIGN},
{ NULL, no_argument, NULL, 0 }
};
@@ -247,6 +250,10 @@ md_parse_option (int c, const char *arg)
LARCH_opts.thin_add_sub = 1;
break;
+ case OPTION_IGNORE_START_ALIGN:
+ LARCH_opts.ignore_start_align = 1;
+ break;
+
case OPTION_IGNORE:
break;
@@ -1772,7 +1779,9 @@ md_show_usage (FILE *stream)
-mthin-add-sub Convert a pair of R_LARCH_ADD32/64 and R_LARCH_SUB32/64 to\n\
R_LARCH_32/64_PCREL as much as possible\n\
The option does not affect the generation of R_LARCH_32_PCREL\n\
- relocations in .eh_frame\n"));
+ relocations in .eh_frame\n\
+ -mignore-start-align Ignore .align if it is at the start of a section. This option\n\
+ can't be used when partial linking (ld -r).\n"));
}
static void
@@ -1794,39 +1803,60 @@ bool
loongarch_frag_align_code (int n, int max)
{
char *nops;
+ expressionS ex;
symbolS *s = NULL;
- bfd_vma insn_alignment = 4;
- bfd_vma bytes = (bfd_vma) 1 << n;
- bfd_vma worst_case_bytes = bytes - insn_alignment;
+ /* When not relaxing, loongarch_handle_align handles code alignment. */
+ if (!LARCH_opts.relax)
+ return false;
+
+ bfd_vma align_bytes = (bfd_vma) 1 << n;
+ bfd_vma worst_case_bytes = align_bytes - 4;
+ bfd_vma addend = worst_case_bytes;
+ bool align_max = max > 0 && (bfd_vma) max < worst_case_bytes;
/* If we are moving to a smaller alignment than the instruction size, then no
alignment is required. */
- if (bytes <= insn_alignment)
+ if (align_bytes <= 4)
return true;
- /* When not relaxing, loongarch_handle_align handles code alignment. */
- if (!LARCH_opts.relax)
- return false;
-
/* If max <= 0, ignore max.
If max >= worst_case_bytes, max has no effect.
Similar to gas/write.c relax_segment function rs_align_code case:
if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype). */
- if (max > 0 && (bfd_vma) max < worst_case_bytes)
+ if (align_max)
{
s = symbol_find (now_seg->name);
- worst_case_bytes = ALIGN_MAX_ADDEND (n, max);
+ addend = ALIGN_MAX_ADDEND (n, max);
+ }
+
+ if (LARCH_opts.ignore_start_align)
+ {
+ frag_grow (worst_case_bytes);
+ /* Use relaxable frag for .align.
+ If .align at the start of section, do nothing. Section alignment can
+ ensure correct alignment.
+ If .align is not at the start of a section, reserve NOP instructions
+ and R_LARCH_ALIGN relocation. */
+ nops = frag_var (rs_machine_dependent, worst_case_bytes, worst_case_bytes,
+ rs_align_code, s, addend, NULL);
}
+ else
+ {
+ nops = frag_more (worst_case_bytes);
+ if (align_max)
+ {
+ ex.X_add_symbol = s;
+ ex.X_op = O_symbol;
+ }
+ else
+ ex.X_op = O_constant;
+
+ ex.X_add_number = addend;
- frag_grow (worst_case_bytes);
- /* Use relaxable frag for .align.
- If .align at the start of section, do nothing. Section alignment can
- ensure correct alignment.
- If .align is not at the start of a section, reserve NOP instructions
- and R_LARCH_ALIGN relocation. */
- nops = frag_var (rs_machine_dependent, worst_case_bytes, worst_case_bytes,
- rs_align_code, s, worst_case_bytes, NULL);
+ fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
+ &ex, false, BFD_RELOC_LARCH_ALIGN);
+ }
/* Default write NOP for aligned bytes. */
loongarch_make_nops (nops, worst_case_bytes);
diff --git a/gas/testsuite/gas/loongarch/relax-align-first.d b/gas/testsuite/gas/loongarch/relax-align-ignore-start.d
similarity index 87%
rename from gas/testsuite/gas/loongarch/relax-align-first.d
rename to gas/testsuite/gas/loongarch/relax-align-ignore-start.d
index ec0698b6..0a67392d 100644
--- a/gas/testsuite/gas/loongarch/relax-align-first.d
+++ b/gas/testsuite/gas/loongarch/relax-align-ignore-start.d
@@ -1,4 +1,4 @@
-#as:
+#as: -mignore-start-align
#objdump: -dr
.*:[ ]+file format .*
diff --git a/gas/testsuite/gas/loongarch/relax-align-first.s b/gas/testsuite/gas/loongarch/relax-align-ignore-start.s
similarity index 100%
rename from gas/testsuite/gas/loongarch/relax-align-first.s
rename to gas/testsuite/gas/loongarch/relax-align-ignore-start.s
diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
index 5fc6e190..024ba99c 100644
--- a/include/opcode/loongarch.h
+++ b/include/opcode/loongarch.h
@@ -256,6 +256,7 @@ dec2 : [1-9][0-9]?
int relax;
int thin_add_sub;
+ int ignore_start_align;
} LARCH_opts;
extern size_t loongarch_insn_length (insn_t insn);
diff --git a/ld/testsuite/ld-elf/dwarf.exp b/ld/testsuite/ld-elf/dwarf.exp
index 3d1b99ac..5cb2aab9 100644
--- a/ld/testsuite/ld-elf/dwarf.exp
+++ b/ld/testsuite/ld-elf/dwarf.exp
@@ -52,6 +52,9 @@ set build_tests {
{"DWARF parse during linker error"
"" "-fno-toplevel-reorder"
{dwarf2a.c dwarf2b.c} {{error_output "dwarf2.err"}} "dwarf2.x"}
+}
+
+set build_tests_dwarf3 {
{"Handle no DWARF information"
"" "-g0"
{dwarf3.c} {{error_output "dwarf3.err"}} "dwarf3.x"}
@@ -72,6 +75,8 @@ set run_tests {
set old_CFLAGS "$CFLAGS_FOR_TARGET"
append CFLAGS_FOR_TARGET " $NOSANITIZE_CFLAGS"
run_cc_link_tests $build_tests
+setup_xfail loongarch*-*-*
+run_cc_link_tests $build_tests_dwarf3
run_ld_link_exec_tests $run_tests
set CFLAGS_FOR_TARGET "$old_CFLAGS"
diff --git a/ld/testsuite/ld-loongarch-elf/partial-link-align-a.s b/ld/testsuite/ld-loongarch-elf/partial-link-align-a.s
new file mode 100644
index 00000000..a8b4f295
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/partial-link-align-a.s
@@ -0,0 +1,2 @@
+.text
+la.local $t0, .text
diff --git a/ld/testsuite/ld-loongarch-elf/partial-link-align-b.s b/ld/testsuite/ld-loongarch-elf/partial-link-align-b.s
new file mode 100644
index 00000000..46fa058b
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/partial-link-align-b.s
@@ -0,0 +1,3 @@
+.text
+.align 4
+ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-first.d b/ld/testsuite/ld-loongarch-elf/relax-align-ignore-start.d
similarity index 92%
rename from ld/testsuite/ld-loongarch-elf/relax-align-first.d
rename to ld/testsuite/ld-loongarch-elf/relax-align-ignore-start.d
index 9a4fad8e..939cf427 100644
--- a/ld/testsuite/ld-loongarch-elf/relax-align-first.d
+++ b/ld/testsuite/ld-loongarch-elf/relax-align-ignore-start.d
@@ -1,3 +1,4 @@
+#as: -mignore-start-align
#ld: -e0
#objdump: -d
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-first.s b/ld/testsuite/ld-loongarch-elf/relax-align-ignore-start.s
similarity index 100%
rename from ld/testsuite/ld-loongarch-elf/relax-align-first.s
rename to ld/testsuite/ld-loongarch-elf/relax-align-ignore-start.s
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index 7274218f..bfd6d1c0 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -19,10 +19,38 @@
# MA 02110-1301, USA.
#
-if [istarget loongarch64-*-*] {
- run_dump_test "relax-align-first"
+proc run_partial_linking_align_test {} {
+ global as
+ global ld
+ global srcdir
+ global subdir
+ global runtests
+
+ set testname "partial-link-align"
+ if ![runtest_file_p $runtests $testname] then {
+ return
+ }
+ if { ![ld_assemble $as "$srcdir/$subdir/$testname-a.s" tmpdir/a.o]
+ || ![ld_assemble $as "$srcdir/$subdir/$testname-b.s" tmpdir/b.o]
+ || ![ld_link $ld tmpdir/$testname.os "tmpdir/a.o tmpdir/b.o -r"]
+ || ![ld_link $ld tmpdir/$testname "tmpdir/$testname.os -e0 -Ttext 0x1000"] } {
+ fail $testname
+ } else {
+ set objdump_output [run_host_cmd "objdump" "-d tmpdir/$testname"]
+ if { [ regexp ".*1010:\\s*4c000020\\s*jirl.*" $objdump_output ] } {
+ pass $testname
+ } else {
+ fail $testname
+ }
+ }
+}
+
+if [istarget loongarch64-*-*] {
if [isbuild loongarch64-*-*] {
+ run_dump_test "relax-align-ignore-start"
+ run_partial_linking_align_test
+
set testname "loongarch relax .exe build"
set pre_builds [list \
[list \
diff --git a/ld/testsuite/ld-undefined/undefined.exp b/ld/testsuite/ld-undefined/undefined.exp
index c0479a22..97bdd92d 100644
--- a/ld/testsuite/ld-undefined/undefined.exp
+++ b/ld/testsuite/ld-undefined/undefined.exp
@@ -74,6 +74,7 @@ if { ![check_compiler_available] } {
# in a literal pool outside the function, so that both the
# "undefined function" and "undefined line" tests fail.
setup_xfail xtensa*-*-linux*
+ setup_xfail loongarch*-*-*
set mf "tmpdir/undefined.o* in function `function':"
checkund $mf $testfn
@@ -154,6 +155,7 @@ if { ![check_compiler_available] } {
# eBPF doesn't support dwarf yet.
setup_xfail bpf-*-*
+ setup_xfail loongarch*-*-*
checkund $ml $testline
}
--
2.33.0

View File

@ -0,0 +1,266 @@
From 0638980f66ece88b89b96746aba82c1f5cd6d6eb Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Thu, 10 Oct 2024 16:23:30 +0800
Subject: [PATCH 117/123] LoongArch: Add more relaxation support for call36
Add relaxation support for call36 that jump to PLT entry.
Add relaxation support for call36 with IFUNC symbol.
Add relaxation support for call36 that jump to undefweak symbol.
For undefweak symbol, it can always be relaxed if it have no PLT entry.
Because we set the address of undefweak symbol without PLT entry to PC
like relocate_section.
---
bfd/elfnn-loongarch.c | 21 +++-
.../ld-loongarch-elf/relax-call36-exe.s | 32 ++++++
.../ld-loongarch-elf/relax-call36-so.s | 35 ++++++
ld/testsuite/ld-loongarch-elf/relax.exp | 105 ++++++++++++++++++
4 files changed, 190 insertions(+), 3 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-call36-exe.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-call36-so.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 70522fae..890233d1 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -5434,7 +5434,8 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
+ r_symndx;
- if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+ if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ && r_type != R_LARCH_CALL36)
continue;
/* Only TLS instruction sequences that are accompanied by
@@ -5467,8 +5468,8 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
}
else
{
- /* Disable the relaxation for ifunc. */
- if (h != NULL && h->type == STT_GNU_IFUNC)
+ if (h != NULL && h->type == STT_GNU_IFUNC
+ && r_type != R_LARCH_CALL36)
continue;
/* The GOT entry of tls symbols must in current execute file or
@@ -5485,6 +5486,20 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
&& GOT_TLS_GD_BOTH_P (tls_type))
symval += 2 * GOT_ENTRY_SIZE;
}
+ else if (h->plt.offset != MINUS_ONE)
+ {
+ sym_sec = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
+ symval = h->plt.offset;
+ }
+ /* Like loongarch_elf_relocate_section, set relocation(offset) to 0.
+ Undefweak for other relocations handing in the future. */
+ else if (h->root.type == bfd_link_hash_undefweak
+ && !h->root.linker_def
+ && r_type == R_LARCH_CALL36)
+ {
+ sym_sec = sec;
+ symval = rel->r_offset;
+ }
else if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
&& h->root.u.def.section != NULL
diff --git a/ld/testsuite/ld-loongarch-elf/relax-call36-exe.s b/ld/testsuite/ld-loongarch-elf/relax-call36-exe.s
new file mode 100644
index 00000000..26cff4df
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-call36-exe.s
@@ -0,0 +1,32 @@
+ldd: # local define default
+call36 ldd # ldd
+
+ldh: # local define hidden
+.hidden ldh
+call36 ldh # ldh
+
+gdd:
+.global gdd # global define default
+call36 gdd # gdd@plt
+
+gdh:
+.global gdh # global define hidden
+.hidden gdh
+call36 gdh # gdh
+
+wdd:
+.weak wdd # weak define default
+call36 wdd # wdd@plt
+
+.weak wud # weak undefine default
+call36 wud # wud@plt
+
+wdh:
+.weak wdh # weak define hidden
+.hidden wdh
+call36 wdh # wdh
+
+.weak wuh # weak undefine hidden
+.hidden wuh
+call36 wuh # wuh
+
diff --git a/ld/testsuite/ld-loongarch-elf/relax-call36-so.s b/ld/testsuite/ld-loongarch-elf/relax-call36-so.s
new file mode 100644
index 00000000..050273b0
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-call36-so.s
@@ -0,0 +1,35 @@
+ldd: # local define default
+call36 ldd # ldd
+
+ldh: # local define hidden
+.hidden ldh
+call36 ldh # ldh
+
+gdd:
+.global gdd # global define default
+call36 gdd # gdd@plt
+
+.global gud # global undefine default
+call36 gud # gud@plt
+
+gdh:
+.global gdh # global define hidden
+.hidden gdh
+call36 gdh # gdh
+
+wdd:
+.weak wdd # weak define default
+call36 wdd # wdd@plt
+
+.weak wud # weak undefine default
+call36 wud # wud@plt
+
+wdh:
+.weak wdh # weak define hidden
+.hidden wdh
+call36 wdh # wdh
+
+.weak wuh # weak undefine hidden
+.hidden wuh
+call36 wuh # wuh
+
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index 05b268f4..57ea3877 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -51,6 +51,111 @@ if [istarget loongarch64-*-*] {
run_dump_test "relax-align-ignore-start"
run_partial_linking_align_test
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch relax call36 .so build" \
+ "-shared" "" \
+ "" \
+ {relax-call36-so.s} \
+ {} \
+ "relax-call36.so" \
+ ] \
+ ]
+
+ if [file exist "tmpdir/relax-call36.so"] {
+ set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-call36.so"]
+ if { [ regexp "pcaddu18i" $objdump_output] } {
+ fail "loongarch relax call36 so"
+ } {
+ pass "loongarch relax call36 so"
+ }
+ }
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch relax call36 dyn exe build" \
+ "-pie -e 0" "" \
+ "" \
+ {relax-call36-exe.s} \
+ {} \
+ "relax-call36-d.exe" \
+ ] \
+ ]
+
+ if [file exist "tmpdir/relax-call36-d.exe"] {
+ set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-call36-d.exe"]
+ if { [ regexp "pcaddu18i" $objdump_output] } {
+ fail "loongarch relax call36 dyn exe"
+ } {
+ pass "loongarch relax call36 dyn exe"
+ }
+ }
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch relax call36 dyn-pie exe build" \
+ "-pie -e 0" "" \
+ "" \
+ {relax-call36-exe.s} \
+ {} \
+ "relax-call36-dp.exe" \
+ ] \
+ ]
+
+ if [file exist "tmpdir/relax-call36-dp.exe"] {
+ set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-call36-dp.exe"]
+ if { [ regexp "pcaddu18i" $objdump_output] } {
+ fail "loongarch relax call36 dyn-pie exe"
+ } {
+ pass "loongarch relax call36 dyn-pie exe"
+ }
+ }
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch relax call36 static exe build" \
+ "-static -e 0" "" \
+ "" \
+ {relax-call36-exe.s} \
+ {} \
+ "relax-call36-s.exe" \
+ ] \
+ ]
+
+ if [file exist "tmpdir/relax-call36-s.exe"] {
+ set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-call36-s.exe"]
+ if { [ regexp "pcaddu18i" $objdump_output] } {
+ fail "loongarch relax call36 static exe"
+ } {
+ pass "loongarch relax call36 static exe"
+ }
+ }
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch relax call36 static-pie exe build" \
+ "-static -pie --no-dynamic-linker -e 0" "" \
+ "" \
+ {relax-call36-exe.s} \
+ {} \
+ "relax-call36-sp.exe" \
+ ] \
+ ]
+
+ if [file exist "tmpdir/relax-call36-sp.exe"] {
+ set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax-call36-sp.exe"]
+ if { [ regexp "pcaddu18i" $objdump_output] } {
+ fail "loongarch relax call36 static-pie exe"
+ } {
+ pass "loongarch relax call36 static-pie exe"
+ }
+ }
+
run_ld_link_tests \
[list \
[list \
--
2.33.0

View File

@ -0,0 +1,278 @@
From 27daffe58e9d1494a1e3c66813526ec4e8e8480b Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Thu, 28 Sep 2023 16:41:15 +0800
Subject: [PATCH 020/123] LoongArch: Add new relocation R_LARCH_CALL36
R_LARCH_CALL36 is used for medium code model function call pcaddu18i+jirl, and
these two instructions must adjacent.
The LoongArch ABI v2.20 at here: https://github.com/loongson/la-abi-specs.
---
bfd/bfd-in2.h | 4 +++-
bfd/elfnn-loongarch.c | 19 ++++++++++-----
bfd/elfxx-loongarch.c | 24 +++++++++++++++++++
bfd/libbfd.h | 1 +
bfd/reloc.c | 3 +++
gas/config/tc-loongarch.c | 6 ++++-
gas/testsuite/gas/loongarch/medium-call.d | 15 ++++++++++++
gas/testsuite/gas/loongarch/medium-call.s | 6 +++++
include/elf/loongarch.h | 2 ++
.../ld-loongarch-elf/ld-loongarch-elf.exp | 12 ++++++++++
ld/testsuite/ld-loongarch-elf/medium-call.s | 7 ++++++
11 files changed, 91 insertions(+), 8 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/medium-call.d
create mode 100644 gas/testsuite/gas/loongarch/medium-call.s
create mode 100644 ld/testsuite/ld-loongarch-elf/medium-call.s
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 933b8ec2..86e7139f 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7343,7 +7343,9 @@ assembler and not (currently) written to any object files. */
BFD_RELOC_LARCH_ADD_ULEB128,
BFD_RELOC_LARCH_SUB_ULEB128,
BFD_RELOC_LARCH_64_PCREL,
- BFD_RELOC_UNUSED };
+ BFD_RELOC_LARCH_CALL36,
+ BFD_RELOC_UNUSED
+};
typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
reloc_howto_type *bfd_reloc_type_lookup
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 09c98713..20dd0640 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -780,6 +780,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_LARCH_B16:
case R_LARCH_B21:
case R_LARCH_B26:
+ case R_LARCH_CALL36:
if (h != NULL)
{
h->needs_plt = 1;
@@ -1884,20 +1885,24 @@ loongarch_check_offset (const Elf_Internal_Rela *rel,
ret; \
})
+/* Write immediate to instructions. */
+
static bfd_reloc_status_type
loongarch_reloc_rewrite_imm_insn (const Elf_Internal_Rela *rel,
const asection *input_section ATTRIBUTE_UNUSED,
reloc_howto_type *howto, bfd *input_bfd,
bfd_byte *contents, bfd_vma reloc_val)
{
- int bits = bfd_get_reloc_size (howto) * 8;
- uint32_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
-
+ /* Adjust the immediate based on alignment and
+ its position in the instruction. */
if (!loongarch_adjust_reloc_bitsfield (input_bfd, howto, &reloc_val))
return bfd_reloc_overflow;
- insn = (insn & (uint32_t)howto->src_mask)
- | ((insn & (~(uint32_t)howto->dst_mask)) | reloc_val);
+ int bits = bfd_get_reloc_size (howto) * 8;
+ uint64_t insn = bfd_get (bits, input_bfd, contents + rel->r_offset);
+
+ /* Write immediate to instruction. */
+ insn = (insn & ~howto->dst_mask) | (reloc_val & howto->dst_mask);
bfd_put (bits, input_bfd, insn, contents + rel->r_offset);
@@ -2120,6 +2125,7 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
case R_LARCH_TLS_GD_PC_HI20:
case R_LARCH_TLS_GD_HI20:
case R_LARCH_PCREL20_S2:
+ case R_LARCH_CALL36:
r = loongarch_check_offset (rel, input_section);
if (r != bfd_reloc_ok)
break;
@@ -3120,9 +3126,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
break;
/* New reloc types. */
+ case R_LARCH_B16:
case R_LARCH_B21:
case R_LARCH_B26:
- case R_LARCH_B16:
+ case R_LARCH_CALL36:
unresolved_reloc = false;
if (is_undefweak)
{
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 7f298c08..d93b7904 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -1547,6 +1547,24 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
NULL, /* adjust_reloc_bits */
NULL), /* larch_reloc_type_name */
+ /* Used for medium code model function call pcaddu18i+jirl,
+ these two instructions must adjacent. */
+ LOONGARCH_HOWTO (R_LARCH_CALL36, /* type (110). */
+ 2, /* rightshift. */
+ 8, /* size. */
+ 36, /* bitsize. */
+ true, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_CALL36", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x03fffc0001ffffe0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_CALL36, /* bfd_reloc_code_real_type. */
+ reloc_sign_bits, /* adjust_reloc_bits. */
+ "call36"), /* larch_reloc_type_name. */
};
reloc_howto_type *
@@ -1726,6 +1744,12 @@ reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val)
/* Perform insn bits field. 15:0<<10, 20:16>>16. */
val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f);
break;
+ case R_LARCH_CALL36:
+ /* 0x8000: If low 16-bit immediate greater than 0x7fff,
+ it become to a negative number due to sign-extended,
+ so the high part need to add 0x8000. */
+ val = (((val + 0x8000) >> 16) << 5) | (((val & 0xffff) << 10) << 32);
+ break;
default:
val <<= howto->bitpos;
break;
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index d4fb3107..297f3048 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3525,6 +3525,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_LARCH_ADD_ULEB128",
"BFD_RELOC_LARCH_SUB_ULEB128",
"BFD_RELOC_LARCH_64_PCREL",
+ "BFD_RELOC_LARCH_CALL36",
"@@overflow: BFD_RELOC_UNUSED@@",
};
#endif
diff --git a/bfd/reloc.c b/bfd/reloc.c
index fbc67ac7..70004f04 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -8156,6 +8156,9 @@ ENUMX
ENUMX
BFD_RELOC_LARCH_64_PCREL
+ENUMX
+ BFD_RELOC_LARCH_CALL36
+
ENUMDOC
LARCH relocations.
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 59232832..367a0b6c 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -682,7 +682,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_64_PCREL)
+ && ip->reloc_info[0].type < BFD_RELOC_UNUSED)
{
/* As we compact stack-relocs, it is no need for pop operation.
But break out until here in order to check the imm field.
@@ -956,6 +956,10 @@ move_insn (struct loongarch_cl_insn *insn, fragS *frag, long where)
static void
append_fixed_insn (struct loongarch_cl_insn *insn)
{
+ /* Ensure the jirl is emitted to the same frag as the pcaddu18i. */
+ if (BFD_RELOC_LARCH_CALL36 == insn->reloc_info[0].type)
+ frag_grow (8);
+
char *f = frag_more (insn->insn_length);
move_insn (insn, frag_now, f - frag_now->fr_literal);
}
diff --git a/gas/testsuite/gas/loongarch/medium-call.d b/gas/testsuite/gas/loongarch/medium-call.d
new file mode 100644
index 00000000..4183818c
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/medium-call.d
@@ -0,0 +1,15 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+.* <.text>:
+[ ]+0:[ ]+1e000001[ ]+pcaddu18i[ ]+\$ra, 0
+[ ]+0: R_LARCH_CALL36[ ]+a
+[ ]+4:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
+[ ]+8:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
+[ ]+8: R_LARCH_CALL36[ ]+a
+[ ]+c:[ ]+4c000180[ ]+jr[ ]+\$t0
diff --git a/gas/testsuite/gas/loongarch/medium-call.s b/gas/testsuite/gas/loongarch/medium-call.s
new file mode 100644
index 00000000..f2977d1c
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/medium-call.s
@@ -0,0 +1,6 @@
+ # call .L1, r1(ra) temp register, r1(ra) return register.
+ pcaddu18i $r1, %call36(a)
+ jirl $r1, $r1, 0
+ # tail .L1, r12(t0) temp register, r0(zero) return register.
+ pcaddu18i $r12, %call36(a)
+ jirl $r0, $r12, 0
diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
index e31395e1..34719ee8 100644
--- a/include/elf/loongarch.h
+++ b/include/elf/loongarch.h
@@ -251,6 +251,8 @@ RELOC_NUMBER (R_LARCH_SUB_ULEB128, 108)
RELOC_NUMBER (R_LARCH_64_PCREL, 109)
+RELOC_NUMBER (R_LARCH_CALL36, 110)
+
END_RELOC_NUMBERS (R_LARCH_count)
/* Processor specific flags for the ELF header e_flags field. */
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index b95cc53e..1fc70d0a 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -55,4 +55,16 @@ if [istarget "loongarch64-*-*"] {
"64_pcrel" \
] \
]
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "medium code model call" \
+ "-e 0x0" "" \
+ "" \
+ {medium-call.s} \
+ {} \
+ "medium-call" \
+ ] \
+ ]
}
diff --git a/ld/testsuite/ld-loongarch-elf/medium-call.s b/ld/testsuite/ld-loongarch-elf/medium-call.s
new file mode 100644
index 00000000..4d1888b7
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/medium-call.s
@@ -0,0 +1,7 @@
+.L1:
+ # call .L1, r1(ra) temp register, r1(ra) return register.
+ pcaddu18i $r1, %call36(.L1)
+ jirl $r1, $r1, 0
+ # tail .L1, r12(t0) temp register, r0(zero) return register.
+ pcaddu18i $r12, %call36(.L1)
+ jirl $r0, $r12, 0
--
2.33.0

View File

@ -0,0 +1,510 @@
From a7cc512b2871a9ba63967eaa9f7b91f41baed858 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Tue, 31 Oct 2023 16:11:29 +0800
Subject: [PATCH 025/123] LoongArch: Add new relocs and macro for TLSDESC.
The normal DESC instruction sequence is:
pcalau12i $a0,%desc_pc_hi20(var) #R_LARCH_TLS_DESC_PC_HI20
addi.d $a0,$a0,%desc_pc_lo12(var) #R_LARCH_TLS_DESC_PC_LO12
ld.d $ra,$a0,%desc_ld(var) #R_LARCH_TLS_DESC_LD
jirl $ra,$ra,%desc_call(var) #R_LARCH_TLS_DESC_CALL
add.d $a0,$a0,$tp
---
bfd/bfd-in2.h | 12 +++
bfd/elfxx-loongarch.c | 210 +++++++++++++++++++++++++++++++++++++-
bfd/libbfd.h | 12 +++
bfd/reloc.c | 29 ++++++
gas/config/tc-loongarch.c | 14 ++-
include/elf/loongarch.h | 22 +++-
opcodes/loongarch-opc.c | 54 ++++++++++
7 files changed, 349 insertions(+), 4 deletions(-)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 86e7139f..d210e71b 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7260,6 +7260,8 @@ assembler and not (currently) written to any object files. */
BFD_RELOC_LARCH_TLS_DTPREL64,
BFD_RELOC_LARCH_TLS_TPREL32,
BFD_RELOC_LARCH_TLS_TPREL64,
+ BFD_RELOC_LARCH_TLS_DESC32,
+ BFD_RELOC_LARCH_TLS_DESC64,
BFD_RELOC_LARCH_MARK_LA,
BFD_RELOC_LARCH_MARK_PCREL,
BFD_RELOC_LARCH_SOP_PUSH_PCREL,
@@ -7344,6 +7346,16 @@ assembler and not (currently) written to any object files. */
BFD_RELOC_LARCH_SUB_ULEB128,
BFD_RELOC_LARCH_64_PCREL,
BFD_RELOC_LARCH_CALL36,
+ BFD_RELOC_LARCH_TLS_DESC_PC_HI20,
+ BFD_RELOC_LARCH_TLS_DESC_PC_LO12,
+ BFD_RELOC_LARCH_TLS_DESC64_PC_LO20,
+ BFD_RELOC_LARCH_TLS_DESC64_PC_HI12,
+ BFD_RELOC_LARCH_TLS_DESC_HI20,
+ BFD_RELOC_LARCH_TLS_DESC_LO12,
+ BFD_RELOC_LARCH_TLS_DESC64_LO20,
+ BFD_RELOC_LARCH_TLS_DESC64_HI12,
+ BFD_RELOC_LARCH_TLS_DESC_LD,
+ BFD_RELOC_LARCH_TLS_DESC_CALL,
BFD_RELOC_UNUSED
};
typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 679b79f3..30a941a8 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -293,8 +293,40 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
NULL, /* adjust_reloc_bits */
NULL), /* larch_reloc_type_name */
- LOONGARCH_EMPTY_HOWTO (13),
- LOONGARCH_EMPTY_HOWTO (14),
+ LOONGARCH_HOWTO (R_LARCH_TLS_DESC32, /* type (13). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 32, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_DESC32", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ ALL_ONES, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_DESC32, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_DESC64, /* type (14). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 64, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_DESC64", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ ALL_ONES, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_DESC64, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ NULL), /* larch_reloc_type_name. */
+
LOONGARCH_EMPTY_HOWTO (15),
LOONGARCH_EMPTY_HOWTO (16),
LOONGARCH_EMPTY_HOWTO (17),
@@ -1569,6 +1601,180 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
BFD_RELOC_LARCH_CALL36, /* bfd_reloc_code_real_type. */
reloc_sign_bits, /* adjust_reloc_bits. */
"call36"), /* larch_reloc_type_name. */
+
+ /* TLS_DESC PCREL. */
+ LOONGARCH_HOWTO (R_LARCH_TLS_DESC_PC_HI20, /* type (111). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ true, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_DESC_PC_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x1ffffe0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_DESC_PC_HI20, /* bfd_reloc_code_real_type. */
+ reloc_bits, /* adjust_reloc_bits. */
+ "desc_pc_hi20"), /* larch_reloc_type_name. */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_DESC_PC_LO12, /* type (112). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ true, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_DESC_PC_LO12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x3ffc00, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_DESC_PC_LO12, /* bfd_reloc_code_real_type. */
+ reloc_bits, /* adjust_reloc_bits. */
+ "desc_pc_lo12"), /* larch_reloc_type_name. */
+
+ /* TLS_DESC64 LARGE PCREL. */
+ LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_PC_LO20, /* type (113). */
+ 32, /* rightshift. */
+ 8, /* size. */
+ 20, /* bitsize. */
+ true, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_DESC64_PC_LO20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x1ffffe0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_DESC64_PC_LO20, /* bfd_reloc_code_real_type. */
+ reloc_bits, /* adjust_reloc_bits. */
+ "desc64_pc_lo20"), /* larch_reloc_type_name. */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_PC_HI12, /* type (114). */
+ 52, /* rightshift. */
+ 8, /* size. */
+ 12, /* bitsize. */
+ true, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_DESC64_PC_HI12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x3ffc00, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_DESC64_PC_HI12, /* bfd_reloc_code_real_type. */
+ reloc_bits, /* adjust_reloc_bits. */
+ "desc64_pc_hi12"), /* larch_reloc_type_name. */
+
+ /* TLS_DESC ABS. */
+ LOONGARCH_HOWTO (R_LARCH_TLS_DESC_HI20, /* type (115). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_DESC_HI20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x1ffffe0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_DESC_HI20, /* bfd_reloc_code_real_type. */
+ reloc_bits, /* adjust_reloc_bits. */
+ "desc_hi20"), /* larch_reloc_type_name. */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_DESC_LO12, /* type (116). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_DESC_LO12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x3ffc00, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_DESC_LO12, /* bfd_reloc_code_real_type. */
+ reloc_bits, /* adjust_reloc_bits. */
+ "desc_lo12"), /* larch_reloc_type_name. */
+
+ /* TLS_DESC64 LARGE ABS. */
+ LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_LO20, /* type (117). */
+ 32, /* rightshift. */
+ 8, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_DESC64_LO20", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x1ffffe0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_DESC64_LO20, /* bfd_reloc_code_real_type. */
+ reloc_bits, /* adjust_reloc_bits. */
+ "desc64_lo20"), /* larch_reloc_type_name. */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_HI12, /* type (118). */
+ 52, /* rightshift. */
+ 8, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_DESC64_HI12", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x3ffc00, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_DESC64_HI12, /* bfd_reloc_code_real_type. */
+ reloc_bits, /* adjust_reloc_bits. */
+ "desc64_hi12"), /* larch_reloc_type_name. */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_DESC_LD, /* type (119). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 0, /* bitsize. */
+ true, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_DESC_LD", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_DESC_LD, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ "desc_ld"), /* larch_reloc_type_name. */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_DESC_CALL, /* type (120). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 0, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_DESC_CALL", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_DESC_CALL, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ "desc_call"), /* larch_reloc_type_name. */
};
reloc_howto_type *
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 297f3048..a474b971 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3442,6 +3442,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_LARCH_TLS_DTPREL64",
"BFD_RELOC_LARCH_TLS_TPREL32",
"BFD_RELOC_LARCH_TLS_TPREL64",
+ "BFD_RELOC_LARCH_TLS_DESC32",
+ "BFD_RELOC_LARCH_TLS_DESC64",
"BFD_RELOC_LARCH_MARK_LA",
"BFD_RELOC_LARCH_MARK_PCREL",
"BFD_RELOC_LARCH_SOP_PUSH_PCREL",
@@ -3526,6 +3528,16 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_LARCH_SUB_ULEB128",
"BFD_RELOC_LARCH_64_PCREL",
"BFD_RELOC_LARCH_CALL36",
+ "BFD_RELOC_LARCH_TLS_DESC_PC_HI20",
+ "BFD_RELOC_LARCH_TLS_DESC_PC_LO12",
+ "BFD_RELOC_LARCH_TLS_DESC64_PC_LO20",
+ "BFD_RELOC_LARCH_TLS_DESC64_PC_HI12",
+ "BFD_RELOC_LARCH_TLS_DESC_HI20",
+ "BFD_RELOC_LARCH_TLS_DESC_LO12",
+ "BFD_RELOC_LARCH_TLS_DESC64_LO20",
+ "BFD_RELOC_LARCH_TLS_DESC64_HI12",
+ "BFD_RELOC_LARCH_TLS_DESC_LD",
+ "BFD_RELOC_LARCH_TLS_DESC_CALL",
"@@overflow: BFD_RELOC_UNUSED@@",
};
#endif
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 70004f04..5af98afb 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -7975,6 +7975,10 @@ ENUMX
BFD_RELOC_LARCH_TLS_TPREL32
ENUMX
BFD_RELOC_LARCH_TLS_TPREL64
+ENUMX
+ BFD_RELOC_LARCH_TLS_DESC32
+ENUMX
+ BFD_RELOC_LARCH_TLS_DESC64
ENUMX
BFD_RELOC_LARCH_MARK_LA
ENUMX
@@ -8159,6 +8163,31 @@ ENUMX
ENUMX
BFD_RELOC_LARCH_CALL36
+ENUMX
+ BFD_RELOC_LARCH_TLS_DESC_PC_HI20
+ENUMX
+ BFD_RELOC_LARCH_TLS_DESC_PC_LO12
+
+ENUMX
+ BFD_RELOC_LARCH_TLS_DESC64_PC_LO20
+ENUMX
+ BFD_RELOC_LARCH_TLS_DESC64_PC_HI12
+
+ENUMX
+ BFD_RELOC_LARCH_TLS_DESC_HI20
+ENUMX
+ BFD_RELOC_LARCH_TLS_DESC_LO12
+
+ENUMX
+ BFD_RELOC_LARCH_TLS_DESC64_LO20
+ENUMX
+ BFD_RELOC_LARCH_TLS_DESC64_HI12
+
+ENUMX
+ BFD_RELOC_LARCH_TLS_DESC_LD
+ENUMX
+ BFD_RELOC_LARCH_TLS_DESC_CALL
+
ENUMDOC
LARCH relocations.
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 9b912daf..1658025f 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -682,7 +682,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_UNUSED)
+ && ip->reloc_info[0].type <= BFD_RELOC_LARCH_TLS_DESC_CALL)
{
/* As we compact stack-relocs, it is no need for pop operation.
But break out until here in order to check the imm field.
@@ -1274,6 +1274,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_LARCH_TLS_LD_HI20:
case BFD_RELOC_LARCH_TLS_GD_PC_HI20:
case BFD_RELOC_LARCH_TLS_GD_HI20:
+ case BFD_RELOC_LARCH_TLS_DESC_PC_HI20:
+ case BFD_RELOC_LARCH_TLS_DESC_PC_LO12:
+ case BFD_RELOC_LARCH_TLS_DESC64_PC_LO20:
+ case BFD_RELOC_LARCH_TLS_DESC64_PC_HI12:
+ case BFD_RELOC_LARCH_TLS_DESC_HI20:
+ case BFD_RELOC_LARCH_TLS_DESC_LO12:
+ case BFD_RELOC_LARCH_TLS_DESC64_LO20:
+ case BFD_RELOC_LARCH_TLS_DESC64_HI12:
/* Add tls lo (got_lo reloc type). */
if (fixP->fx_addsy == NULL)
as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -1294,6 +1302,10 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
stack_top = 0;
break;
+ case BFD_RELOC_LARCH_TLS_DESC_LD:
+ case BFD_RELOC_LARCH_TLS_DESC_CALL:
+ break;
+
case BFD_RELOC_LARCH_SOP_POP_32_S_10_5:
case BFD_RELOC_LARCH_SOP_POP_32_S_10_12:
case BFD_RELOC_LARCH_SOP_POP_32_U_10_12:
diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
index 34719ee8..41e9fe4d 100644
--- a/include/elf/loongarch.h
+++ b/include/elf/loongarch.h
@@ -38,7 +38,8 @@ RELOC_NUMBER (R_LARCH_TLS_DTPREL64, 9)
RELOC_NUMBER (R_LARCH_TLS_TPREL32, 10)
RELOC_NUMBER (R_LARCH_TLS_TPREL64, 11)
RELOC_NUMBER (R_LARCH_IRELATIVE, 12)
-
+RELOC_NUMBER (R_LARCH_TLS_DESC32, 13)
+RELOC_NUMBER (R_LARCH_TLS_DESC64, 14)
/* Reserved for future relocs that the dynamic linker must understand. */
/* Used by the static linker for relocating .text. */
@@ -253,6 +254,25 @@ RELOC_NUMBER (R_LARCH_64_PCREL, 109)
RELOC_NUMBER (R_LARCH_CALL36, 110)
+/* TLS_DESC PCREL. */
+RELOC_NUMBER (R_LARCH_TLS_DESC_PC_HI20, 111)
+RELOC_NUMBER (R_LARCH_TLS_DESC_PC_LO12, 112)
+
+/* TLS_DESC LARGE PCREL. */
+RELOC_NUMBER (R_LARCH_TLS_DESC64_PC_LO20, 113)
+RELOC_NUMBER (R_LARCH_TLS_DESC64_PC_HI12, 114)
+
+/* TLS_DESC ABS. */
+RELOC_NUMBER (R_LARCH_TLS_DESC_HI20, 115)
+RELOC_NUMBER (R_LARCH_TLS_DESC_LO12, 116)
+
+/* TLSDESC LARGE ABS. */
+RELOC_NUMBER (R_LARCH_TLS_DESC64_LO20, 117)
+RELOC_NUMBER (R_LARCH_TLS_DESC64_HI12, 118)
+
+RELOC_NUMBER (R_LARCH_TLS_DESC_LD, 119)
+RELOC_NUMBER (R_LARCH_TLS_DESC_CALL, 120)
+
END_RELOC_NUMBERS (R_LARCH_count)
/* Processor specific flags for the ELF header e_flags field. */
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index b47817f8..a632373f 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -303,6 +303,55 @@ const char *const loongarch_x_normal_name[32] =
"jirl $zero,%1,0;", \
0, 0
+/* For TLS_DESC32 pcrel. */
+#define INSN_LA_TLS_DESC32 \
+ "pcalau12i $r4,%%desc_pc_hi20(%2);" \
+ "addi.w $r4,$r4,%%desc_pc_lo12(%2);" \
+ "ld.w $r1,$r4,%%desc_ld(%2);" \
+ "jirl $r1,$r1,%%desc_call(%2);", \
+ &LARCH_opts.ase_ilp32, \
+ &LARCH_opts.ase_lp64
+
+/* For TLS_DESC32 abs. */
+#define INSN_LA_TLS_DESC32_ABS \
+ "lu12i.w $r4,%%desc_hi20(%2);" \
+ "ori $r4,$r4,%%desc_lo12(%2);" \
+ "ld.w $r1,$r4,%%desc_ld(%2);" \
+ "jirl $r1,$r1,%%desc_call(%2);", \
+ &LARCH_opts.ase_gabs, \
+ &LARCH_opts.ase_lp64
+
+/* For TLS_DESC64 pcrel. */
+#define INSN_LA_TLS_DESC64 \
+ "pcalau12i $r4,%%desc_pc_hi20(%2);" \
+ "addi.d $r4,$r4,%%desc_pc_lo12(%2);" \
+ "ld.d $r1,$r4,%%desc_ld(%2);" \
+ "jirl $r1,$r1,%%desc_call(%2);", \
+ &LARCH_opts.ase_lp64, 0
+
+/* For TLS_DESC64 large pcrel. */
+#define INSN_LA_TLS_DESC64_LARGE_PCREL \
+ "pcalau12i $r4,%%desc_pc_hi20(%3);" \
+ "addi.d %2,$r0,%%desc_pc_lo12(%3);" \
+ "lu32i.d %2,%%desc64_pc_lo20(%3);" \
+ "lu52i.d %2,%2,%%desc64_pc_hi12(%3);" \
+ "add.d $r4,$r4,%2;" \
+ "ld.d $r1,$r4,%%desc_ld(%3);" \
+ "jirl $r1,$r1,%%desc_call(%3);", \
+ &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gabs
+
+/* For TLS_DESC64 large abs. */
+#define INSN_LA_TLS_DESC64_LARGE_ABS \
+ "lu12i.w $r4,%%desc_hi20(%2);" \
+ "ori $r4,$r4,%%desc_lo12(%2);" \
+ "lu32i.d $r4,%%desc64_lo20(%2);" \
+ "lu52i.d $r4,$r4,%%desc64_hi12(%2);" \
+ "ld.d $r1,$r4,%%desc_ld(%2);" \
+ "jirl $r1,$r1,%%desc_call(%2);", \
+ &LARCH_opts.ase_gabs, \
+ &LARCH_opts.ase_gpcr
+
static struct loongarch_opcode loongarch_macro_opcodes[] =
{
/* match, mask, name, format, macro, include, exclude, pinfo. */
@@ -352,6 +401,11 @@ static struct loongarch_opcode loongarch_macro_opcodes[] =
{ 0, 0, "call36", "la", INSN_LA_CALL, 0 },
{ 0, 0, "tail36", "r,la", INSN_LA_TAIL, 0 },
{ 0, 0, "pcaddi", "r,la", "pcaddi %1, %%pcrel_20(%2)", &LARCH_opts.ase_ilp32, 0, 0 },
+ { 0, 0, "la.tls.desc", "r,l", INSN_LA_TLS_DESC32_ABS, 0 },
+ { 0, 0, "la.tls.desc", "r,l", INSN_LA_TLS_DESC32, 0 },
+ { 0, 0, "la.tls.desc", "r,l", INSN_LA_TLS_DESC64_LARGE_ABS, 0 },
+ { 0, 0, "la.tls.desc", "r,l", INSN_LA_TLS_DESC64, 0 },
+ { 0, 0, "la.tls.desc", "r,r,l", INSN_LA_TLS_DESC64_LARGE_PCREL,0 },
{ 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminate the list. */
};
--
2.33.0

View File

@ -0,0 +1,684 @@
From 1ac9f2fb1378c35c8d75b54b82a34a5e560b6ad3 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Wed, 28 Feb 2024 17:42:36 +0800
Subject: [PATCH 074/123] LoongArch: Add relaxation for R_LARCH_CALL36
This relaxation is effective for both macro instructions (call36, tail36)
and explicit relocation instructions (pcaddu18i + jirl).
call36 f -> bl f
R_LARCH_CALL36 -> R_LARCH_B26
tail36 $t0, f -> b f
R_LARCH_CALL36 -> R_LARCH_B26
---
bfd/elfnn-loongarch.c | 59 ++++
gas/config/tc-loongarch.c | 19 +-
gas/testsuite/gas/loongarch/medium-call.d | 7 +-
.../relax-cfi-fde-DW_CFA_advance_loc.d | 10 +-
.../relax-cfi-fde-DW_CFA_advance_loc.s | 4 +
gas/testsuite/gas/loongarch/relocs_64.d | 282 +++++++++---------
.../ld-loongarch-elf/ld-loongarch-elf.exp | 2 +
.../ld-loongarch-elf/relax-medium-call-1.d | 21 ++
.../ld-loongarch-elf/relax-medium-call-1.s | 43 +++
.../ld-loongarch-elf/relax-medium-call.d | 21 ++
.../ld-loongarch-elf/relax-medium-call.s | 35 +++
11 files changed, 356 insertions(+), 147 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-medium-call.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-medium-call.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 489ccbe0..1c3295f4 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -4334,6 +4334,60 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
return true;
}
+/* call36 f -> bl f
+ tail36 $t0, f -> b f. */
+static bool
+loongarch_relax_call36 (bfd *abfd, asection *sec,
+ Elf_Internal_Rela *rel, bfd_vma symval,
+ struct bfd_link_info *info, bool *again,
+ bfd_vma max_alignment)
+{
+ bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
+ uint32_t jirl = bfd_get (32, abfd, contents + rel->r_offset + 4);
+ uint32_t rd = jirl & 0x1f;
+
+ /* This section's output_offset need to subtract the bytes of instructions
+ relaxed by the previous sections, so it needs to be updated beforehand.
+ size_input_section already took care of updating it after relaxation,
+ so we additionally update once here. */
+ sec->output_offset = sec->output_section->size;
+ bfd_vma pc = sec_addr (sec) + rel->r_offset;
+
+ /* If pc and symbol not in the same segment, add/sub segment alignment.
+ FIXME: if there are multiple readonly segments? How to determine if
+ two sections are in the same segment. */
+ if (symval > pc)
+ pc -= (max_alignment > 4 ? max_alignment : 0);
+ else if (symval < pc)
+ pc += (max_alignment > 4 ? max_alignment : 0);
+
+ const uint32_t jirl_opcode = 0x4c000000;
+
+ /* Is pcalau12i + addi.d insns? */
+ if ((ELFNN_R_TYPE ((rel + 1)->r_info) != R_LARCH_RELAX)
+ || ((jirl & jirl_opcode) != jirl_opcode)
+ || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xf8000000)
+ || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x7fffffc))
+ return false;
+
+ /* Continue next relax trip. */
+ *again = true;
+
+ const uint32_t bl = 0x54000000;
+ const uint32_t b = 0x50000000;
+
+ if (rd)
+ bfd_put (32, abfd, bl, contents + rel->r_offset);
+ else
+ bfd_put (32, abfd, b, contents + rel->r_offset);
+
+ /* Adjust relocations. */
+ rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), R_LARCH_B26);
+ /* Delete jirl instruction. */
+ loongarch_relax_delete_bytes (abfd, sec, rel->r_offset + 4, 4, info);
+ return true;
+}
+
/* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
static bool
loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
@@ -4752,6 +4806,11 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
}
break;
+ case R_LARCH_CALL36:
+ if (0 == info->relax_pass && (i + 2) <= sec->reloc_count)
+ loongarch_relax_call36 (abfd, sec, rel, symval, info, again,
+ max_alignment);
+ break;
case R_LARCH_TLS_LE_HI20_R:
case R_LARCH_TLS_LE_LO12_R:
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index ff126d56..51575757 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -116,6 +116,8 @@ const char *md_shortopts = "O::g::G:";
static const char default_arch[] = DEFAULT_ARCH;
+static bool call36 = 0;
+
/* The lowest 4-bit is the bytes of instructions. */
#define RELAX_BRANCH_16 0xc0000014
#define RELAX_BRANCH_21 0xc0000024
@@ -720,7 +722,8 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
|| BFD_RELOC_LARCH_TLS_LE_HI20 == reloc_type
|| BFD_RELOC_LARCH_TLS_LE_LO12 == reloc_type
|| BFD_RELOC_LARCH_TLS_LE64_LO20 == reloc_type
- || BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_type))
+ || BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_type
+ || BFD_RELOC_LARCH_CALL36 == reloc_type))
{
ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
ip->reloc_info[ip->reloc_num].value = const_0;
@@ -1016,6 +1019,20 @@ append_fixed_insn (struct loongarch_cl_insn *insn)
char *f = frag_more (insn->insn_length);
move_insn (insn, frag_now, f - frag_now->fr_literal);
+
+ if (call36)
+ {
+ if (strcmp (insn->name, "jirl") == 0)
+ {
+ /* See comment at end of append_fixp_and_insn. */
+ frag_wane (frag_now);
+ frag_new (0);
+ }
+ call36 = 0;
+ }
+
+ if (BFD_RELOC_LARCH_CALL36 == insn->reloc_info[0].type)
+ call36 = 1;
}
/* Add instructions based on the worst-case scenario firstly. */
diff --git a/gas/testsuite/gas/loongarch/medium-call.d b/gas/testsuite/gas/loongarch/medium-call.d
index 3491760b..79d74ba3 100644
--- a/gas/testsuite/gas/loongarch/medium-call.d
+++ b/gas/testsuite/gas/loongarch/medium-call.d
@@ -1,21 +1,26 @@
#as:
#objdump: -dr
+#skip: loongarch32-*-*
.*:[ ]+file format .*
Disassembly of section .text:
-.* <.text>:
+[ ]*0000000000000000 <.text>:
[ ]+0:[ ]+1e000001[ ]+pcaddu18i[ ]+\$ra, 0
[ ]+0: R_LARCH_CALL36[ ]+a
+[ ]+0: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+4:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
[ ]+8:[ ]+1e000001[ ]+pcaddu18i[ ]+\$ra, 0
[ ]+8: R_LARCH_CALL36[ ]+a
+[ ]+8: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+c:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
[ ]+10:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
[ ]+10: R_LARCH_CALL36[ ]+a
+[ ]+10: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+14:[ ]+4c000180[ ]+jr[ ]+\$t0
[ ]+18:[ ]+1e00000c[ ]+pcaddu18i[ ]+\$t0, 0
[ ]+18: R_LARCH_CALL36[ ]+a
+[ ]+18: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+1c:[ ]+4c000180[ ]+jr[ ]+\$t0
diff --git a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
index 6b164cfb..d685bd86 100644
--- a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
+++ b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
@@ -26,7 +26,7 @@ Disassembly of section .eh_frame:
[ ]+2c:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
[ ]+2e: R_LARCH_ADD6[ ]+L0\^A
[ ]+2e: R_LARCH_SUB6[ ]+L0\^A
-[ ]+30:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300044 <L0\^A\+0x2ffffc>
+[ ]+30:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300044 <L0\^A\+0x2ffff4>
[ ]+33: R_LARCH_ADD6[ ]+L0\^A
[ ]+33: R_LARCH_SUB6[ ]+L0\^A
[ ]+34:[ ]+00160cd6[ ]+orn[ ]+\$fp, \$a2, \$sp
@@ -39,14 +39,16 @@ Disassembly of section .eh_frame:
[ ]+40:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
[ ]+42: R_LARCH_ADD6[ ]+L0\^A
[ ]+42: R_LARCH_SUB6[ ]+L0\^A
-[ ]+44:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300058 <L0\^A\+0x300010>
+[ ]+44:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300058 <L0\^A\+0x300008>
[ ]+47: R_LARCH_ADD6[ ]+L0\^A
[ ]+47: R_LARCH_SUB6[ ]+L0\^A
[ ]+48:[ ]+00160cd6[ ]+orn[ ]+\$fp, \$a2, \$sp
[ ]+4c:[ ]+160cd640[ ]+lu32i.d[ ]+\$zero, 26290
[ ]+4c: R_LARCH_ADD6[ ]+L0\^A
[ ]+4c: R_LARCH_SUB6[ ]+L0\^A
-[ ]+50:[ ]+00d64000[ ]+bstrpick.d[ ]+\$zero, \$zero, 0x16, 0x10
+[ ]+50:[ ]+0cd64000[ ]+.word[ ]+[ ]+0x0cd64000
[ ]+51: R_LARCH_ADD6[ ]+L0\^A
[ ]+51: R_LARCH_SUB6[ ]+L0\^A
-[ ]+54:[ ]+00000000[ ]+.word[ ]+[ ]+0x00000000
+[ ]+54:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
+[ ]+56: R_LARCH_ADD6[ ]+L0\^A
+[ ]+56: R_LARCH_SUB6[ ]+L0\^A
diff --git a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
index 2c67587b..021d296a 100644
--- a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
+++ b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
@@ -38,4 +38,8 @@ la.tls.ie $t0, a
la.tls.le $t0, a
.cfi_restore 22
+.cfi_def_cfa 22, 0
+call36 f
+.cfi_restore 22
+
.cfi_endproc
diff --git a/gas/testsuite/gas/loongarch/relocs_64.d b/gas/testsuite/gas/loongarch/relocs_64.d
index 35dde02f..ce5216a2 100644
--- a/gas/testsuite/gas/loongarch/relocs_64.d
+++ b/gas/testsuite/gas/loongarch/relocs_64.d
@@ -1,148 +1,148 @@
-#as: -mthin-add-sub
+#as:
#objdump: -dr
#skip: loongarch32-*-*
-.*: file format .*
+.*:[ ]+file format .*
Disassembly of section .text:
-0+ <.*>:
- 0: 4c008ca4 jirl \$a0, \$a1, 140
- 0: R_LARCH_B16 .L1
- 4: 40008880 beqz \$a0, 136 # 8c <.L1>
- 4: R_LARCH_B21 .L1
- 8: 50008400 b 132 # 8c <.L1>
- 8: R_LARCH_B26 .L1
- c: 14000004 lu12i.w \$a0, 0
- c: R_LARCH_ABS_HI20 .L1
- 10: 038000a4 ori \$a0, \$a1, 0x0
- 10: R_LARCH_ABS_LO12 .L1
- 14: 16000004 lu32i.d \$a0, 0
- 14: R_LARCH_ABS64_LO20 .L1
- 18: 03000085 lu52i.d \$a1, \$a0, 0
- 18: R_LARCH_ABS64_HI12 .L1
- 1c: 1a000004 pcalau12i \$a0, 0
- 1c: R_LARCH_PCALA_HI20 .L1
- 20: 02c00085 addi.d \$a1, \$a0, 0
- 20: R_LARCH_PCALA_LO12 .L1
- 24: 16000004 lu32i.d \$a0, 0
- 24: R_LARCH_PCALA64_LO20 .L1
- 28: 03000085 lu52i.d \$a1, \$a0, 0
- 28: R_LARCH_PCALA64_HI12 .L1
- 2c: 1a000004 pcalau12i \$a0, 0
- 2c: R_LARCH_GOT_PC_HI20 .L1
- 30: 28c00085 ld.d \$a1, \$a0, 0
- 30: R_LARCH_GOT_PC_LO12 .L1
- 34: 16000004 lu32i.d \$a0, 0
- 34: R_LARCH_GOT64_PC_LO20 .L1
- 38: 03000085 lu52i.d \$a1, \$a0, 0
- 38: R_LARCH_GOT64_PC_HI12 .L1
- 3c: 14000004 lu12i.w \$a0, 0
- 3c: R_LARCH_GOT_HI20 .L1
- 40: 03800084 ori \$a0, \$a0, 0x0
- 40: R_LARCH_GOT_LO12 .L1
- 44: 16000004 lu32i.d \$a0, 0
- 44: R_LARCH_GOT64_LO20 .L1
- 48: 03000085 lu52i.d \$a1, \$a0, 0
- 48: R_LARCH_GOT64_HI12 .L1
- 4c: 14000004 lu12i.w \$a0, 0
- 4c: R_LARCH_TLS_LE_HI20 TLSL1
- 4c: R_LARCH_RELAX \*ABS\*
- 50: 03800085 ori \$a1, \$a0, 0x0
- 50: R_LARCH_TLS_LE_LO12 TLSL1
- 50: R_LARCH_RELAX \*ABS\*
- 54: 16000004 lu32i.d \$a0, 0
- 54: R_LARCH_TLS_LE64_LO20 TLSL1
- 54: R_LARCH_RELAX \*ABS\*
- 58: 03000085 lu52i.d \$a1, \$a0, 0
- 58: R_LARCH_TLS_LE64_HI12 TLSL1
- 58: R_LARCH_RELAX \*ABS\*
- 5c: 1a000004 pcalau12i \$a0, 0
- 5c: R_LARCH_TLS_IE_PC_HI20 TLSL1
- 60: 02c00005 li.d \$a1, 0
- 60: R_LARCH_TLS_IE_PC_LO12 TLSL1
- 64: 16000005 lu32i.d \$a1, 0
- 64: R_LARCH_TLS_IE64_PC_LO20 TLSL1
- 68: 030000a5 lu52i.d \$a1, \$a1, 0
- 68: R_LARCH_TLS_IE64_PC_HI12 TLSL1
- 6c: 14000004 lu12i.w \$a0, 0
- 6c: R_LARCH_TLS_IE_HI20 TLSL1
- 70: 03800084 ori \$a0, \$a0, 0x0
- 70: R_LARCH_TLS_IE_LO12 TLSL1
- 74: 16000004 lu32i.d \$a0, 0
- 74: R_LARCH_TLS_IE64_LO20 TLSL1
- 78: 03000084 lu52i.d \$a0, \$a0, 0
- 78: R_LARCH_TLS_IE64_HI12 TLSL1
- 7c: 1a000004 pcalau12i \$a0, 0
- 7c: R_LARCH_TLS_LD_PC_HI20 TLSL1
- 80: 14000004 lu12i.w \$a0, 0
- 80: R_LARCH_TLS_LD_HI20 TLSL1
- 84: 1a000004 pcalau12i \$a0, 0
- 84: R_LARCH_TLS_GD_PC_HI20 TLSL1
- 88: 14000004 lu12i.w \$a0, 0
- 88: R_LARCH_TLS_GD_HI20 TLSL1
-
-0+8c <.L1>:
- 8c: 00000000 .word 0x00000000
- 8c: R_LARCH_32_PCREL .L2
-
-0+90 <.L2>:
- ...
- 90: R_LARCH_64_PCREL .L3
-
-0+98 <.L3>:
- 98: 03400000 nop
- 9c: 03400000 nop
- 9c: R_LARCH_ALIGN .*
- a0: 03400000 nop
- a4: 03400000 nop
- a8: 1800000c pcaddi \$t0, 0
- a8: R_LARCH_PCREL20_S2 .L1
- ac: 1e000001 pcaddu18i \$ra, 0
- ac: R_LARCH_CALL36 a
- b0: 4c000021 jirl \$ra, \$ra, 0
- b4: 1a000004 pcalau12i \$a0, 0
- b4: R_LARCH_TLS_DESC_PC_HI20 TLSL1
- b8: 02c000a5 addi.d \$a1, \$a1, 0
- b8: R_LARCH_TLS_DESC_PC_LO12 TLSL1
- bc: 16000005 lu32i.d \$a1, 0
- bc: R_LARCH_TLS_DESC64_PC_LO20 TLSL1
- c0: 030000a5 lu52i.d \$a1, \$a1, 0
- c0: R_LARCH_TLS_DESC64_PC_HI12 TLSL1
- c4: 14000004 lu12i.w \$a0, 0
- c4: R_LARCH_TLS_DESC_HI20 TLSL1
- c8: 03800084 ori \$a0, \$a0, 0x0
- c8: R_LARCH_TLS_DESC_LO12 TLSL1
- cc: 16000004 lu32i.d \$a0, 0
- cc: R_LARCH_TLS_DESC64_LO20 TLSL1
- d0: 03000084 lu52i.d \$a0, \$a0, 0
- d0: R_LARCH_TLS_DESC64_HI12 TLSL1
- d4: 28c00081 ld.d \$ra, \$a0, 0
- d4: R_LARCH_TLS_DESC_LD TLSL1
- d8: 4c000021 jirl \$ra, \$ra, 0
- d8: R_LARCH_TLS_DESC_CALL TLSL1
- dc: 14000004 lu12i.w \$a0, 0
- dc: R_LARCH_TLS_LE_HI20_R TLSL1
- dc: R_LARCH_RELAX \*ABS\*
- e0: 001090a5 add.d \$a1, \$a1, \$a0
- e0: R_LARCH_TLS_LE_ADD_R TLSL1
- e0: R_LARCH_RELAX \*ABS\*
- e4: 29800085 st.w \$a1, \$a0, 0
- e4: R_LARCH_TLS_LE_LO12_R TLSL1
- e4: R_LARCH_RELAX \*ABS\*
- e8: 14000004 lu12i.w \$a0, 0
- e8: R_LARCH_TLS_LE_HI20_R TLSL1
- e8: R_LARCH_RELAX \*ABS\*
- ec: 001090a5 add.d \$a1, \$a1, \$a0
- ec: R_LARCH_TLS_LE_ADD_R TLSL1
- ec: R_LARCH_RELAX \*ABS\*
- f0: 29800085 st.w \$a1, \$a0, 0
- f0: R_LARCH_TLS_LE_LO12_R TLSL1
- f0: R_LARCH_RELAX \*ABS\*
- f4: 18000004 pcaddi \$a0, 0
- f4: R_LARCH_TLS_LD_PCREL20_S2 TLSL1
- f8: 18000004 pcaddi \$a0, 0
- f8: R_LARCH_TLS_GD_PCREL20_S2 TLSL1
- fc: 18000004 pcaddi \$a0, 0
- fc: R_LARCH_TLS_DESC_PCREL20_S2 TLSL1
+[ ]*0000000000000000 <.L1-0x8c>:
+[ ]+0:[ ]+4c008ca4[ ]+jirl[ ]+\$a0, \$a1, 140
+[ ]+0: R_LARCH_B16[ ]+.L1
+[ ]+4:[ ]+40008880[ ]+beqz[ ]+\$a0, 136[ ]+# 8c <.L1>
+[ ]+4: R_LARCH_B21[ ]+.L1
+[ ]+8:[ ]+50008400[ ]+b[ ]+132[ ]+# 8c <.L1>
+[ ]+8: R_LARCH_B26[ ]+.L1
+[ ]+c:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+c: R_LARCH_ABS_HI20[ ]+.L1
+[ ]+10:[ ]+038000a4[ ]+ori[ ]+\$a0, \$a1, 0x0
+[ ]+10: R_LARCH_ABS_LO12[ ]+.L1
+[ ]+14:[ ]+16000004[ ]+lu32i.d[ ]+\$a0, 0
+[ ]+14: R_LARCH_ABS64_LO20[ ]+.L1
+[ ]+18:[ ]+03000085[ ]+lu52i.d[ ]+\$a1, \$a0, 0
+[ ]+18: R_LARCH_ABS64_HI12[ ]+.L1
+[ ]+1c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+1c: R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+20:[ ]+02c00085[ ]+addi.d[ ]+\$a1, \$a0, 0
+[ ]+20: R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+24:[ ]+16000004[ ]+lu32i.d[ ]+\$a0, 0
+[ ]+24: R_LARCH_PCALA64_LO20[ ]+.L1
+[ ]+28:[ ]+03000085[ ]+lu52i.d[ ]+\$a1, \$a0, 0
+[ ]+28: R_LARCH_PCALA64_HI12[ ]+.L1
+[ ]+2c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+2c: R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+30:[ ]+28c00085[ ]+ld.d[ ]+\$a1, \$a0, 0
+[ ]+30: R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+34:[ ]+16000004[ ]+lu32i.d[ ]+\$a0, 0
+[ ]+34: R_LARCH_GOT64_PC_LO20[ ]+.L1
+[ ]+38:[ ]+03000085[ ]+lu52i.d[ ]+\$a1, \$a0, 0
+[ ]+38: R_LARCH_GOT64_PC_HI12[ ]+.L1
+[ ]+3c:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+3c: R_LARCH_GOT_HI20[ ]+.L1
+[ ]+40:[ ]+03800084[ ]+ori[ ]+\$a0, \$a0, 0x0
+[ ]+40: R_LARCH_GOT_LO12[ ]+.L1
+[ ]+44:[ ]+16000004[ ]+lu32i.d[ ]+\$a0, 0
+[ ]+44: R_LARCH_GOT64_LO20[ ]+.L1
+[ ]+48:[ ]+03000085[ ]+lu52i.d[ ]+\$a1, \$a0, 0
+[ ]+48: R_LARCH_GOT64_HI12[ ]+.L1
+[ ]+4c:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+4c: R_LARCH_TLS_LE_HI20[ ]+TLSL1
+[ ]+4c: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+50:[ ]+03800085[ ]+ori[ ]+\$a1, \$a0, 0x0
+[ ]+50: R_LARCH_TLS_LE_LO12[ ]+TLSL1
+[ ]+50: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+54:[ ]+16000004[ ]+lu32i.d[ ]+\$a0, 0
+[ ]+54: R_LARCH_TLS_LE64_LO20[ ]+TLSL1
+[ ]+54: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+58:[ ]+03000085[ ]+lu52i.d[ ]+\$a1, \$a0, 0
+[ ]+58: R_LARCH_TLS_LE64_HI12[ ]+TLSL1
+[ ]+58: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+5c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+5c: R_LARCH_TLS_IE_PC_HI20[ ]+TLSL1
+[ ]+60:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+60: R_LARCH_TLS_IE_PC_LO12[ ]+TLSL1
+[ ]+64:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+64: R_LARCH_TLS_IE64_PC_LO20[ ]+TLSL1
+[ ]+68:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+68: R_LARCH_TLS_IE64_PC_HI12[ ]+TLSL1
+[ ]+6c:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+6c: R_LARCH_TLS_IE_HI20[ ]+TLSL1
+[ ]+70:[ ]+03800084[ ]+ori[ ]+\$a0, \$a0, 0x0
+[ ]+70: R_LARCH_TLS_IE_LO12[ ]+TLSL1
+[ ]+74:[ ]+16000004[ ]+lu32i.d[ ]+\$a0, 0
+[ ]+74: R_LARCH_TLS_IE64_LO20[ ]+TLSL1
+[ ]+78:[ ]+03000084[ ]+lu52i.d[ ]+\$a0, \$a0, 0
+[ ]+78: R_LARCH_TLS_IE64_HI12[ ]+TLSL1
+[ ]+7c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+7c: R_LARCH_TLS_LD_PC_HI20[ ]+TLSL1
+[ ]+80:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+80: R_LARCH_TLS_LD_HI20[ ]+TLSL1
+[ ]+84:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+84: R_LARCH_TLS_GD_PC_HI20[ ]+TLSL1
+[ ]+88:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+88: R_LARCH_TLS_GD_HI20[ ]+TLSL1
+000000000000008c <.L1>:
+[ ]+8c:[ ]+00000000[ ]+.word[ ]+[ ]+0x00000000
+[ ]+8c: R_LARCH_ADD32[ ]+.L2
+[ ]+8c: R_LARCH_SUB32[ ]+.L1
+0000000000000090 <.L2>:
+[ ]+...
+[ ]+90: R_LARCH_ADD64[ ]+.L3
+[ ]+90: R_LARCH_SUB64[ ]+.L2
+0000000000000098 <.L3>:
+[ ]+98:[ ]+03400000[ ]+nop
+[ ]+9c:[ ]+03400000[ ]+nop
+[ ]+9c: R_LARCH_ALIGN[ ]+\*ABS\*\+0xc
+[ ]+a0:[ ]+03400000[ ]+nop
+[ ]+a4:[ ]+03400000[ ]+nop
+[ ]+a8:[ ]+1800000c[ ]+pcaddi[ ]+\$t0, 0
+[ ]+a8: R_LARCH_PCREL20_S2[ ]+.L1
+[ ]+ac:[ ]+1e000001[ ]+pcaddu18i[ ]+\$ra, 0
+[ ]+ac: R_LARCH_CALL36[ ]+a
+[ ]+ac: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+b0:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
+[ ]+b4:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+b4: R_LARCH_TLS_DESC_PC_HI20[ ]+TLSL1
+[ ]+b8:[ ]+02c000a5[ ]+addi.d[ ]+\$a1, \$a1, 0
+[ ]+b8: R_LARCH_TLS_DESC_PC_LO12[ ]+TLSL1
+[ ]+bc:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+bc: R_LARCH_TLS_DESC64_PC_LO20[ ]+TLSL1
+[ ]+c0:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+c0: R_LARCH_TLS_DESC64_PC_HI12[ ]+TLSL1
+[ ]+c4:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+c4: R_LARCH_TLS_DESC_HI20[ ]+TLSL1
+[ ]+c8:[ ]+03800084[ ]+ori[ ]+\$a0, \$a0, 0x0
+[ ]+c8: R_LARCH_TLS_DESC_LO12[ ]+TLSL1
+[ ]+cc:[ ]+16000004[ ]+lu32i.d[ ]+\$a0, 0
+[ ]+cc: R_LARCH_TLS_DESC64_LO20[ ]+TLSL1
+[ ]+d0:[ ]+03000084[ ]+lu52i.d[ ]+\$a0, \$a0, 0
+[ ]+d0: R_LARCH_TLS_DESC64_HI12[ ]+TLSL1
+[ ]+d4:[ ]+28c00081[ ]+ld.d[ ]+\$ra, \$a0, 0
+[ ]+d4: R_LARCH_TLS_DESC_LD[ ]+TLSL1
+[ ]+d8:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
+[ ]+d8: R_LARCH_TLS_DESC_CALL[ ]+TLSL1
+[ ]+dc:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+dc: R_LARCH_TLS_LE_HI20_R[ ]+TLSL1
+[ ]+dc: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+e0:[ ]+001090a5[ ]+add.d[ ]+\$a1, \$a1, \$a0
+[ ]+e0: R_LARCH_TLS_LE_ADD_R[ ]+TLSL1
+[ ]+e0: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+e4:[ ]+29800085[ ]+st.w[ ]+\$a1, \$a0, 0
+[ ]+e4: R_LARCH_TLS_LE_LO12_R[ ]+TLSL1
+[ ]+e4: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+e8:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+e8: R_LARCH_TLS_LE_HI20_R[ ]+TLSL1
+[ ]+e8: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+ec:[ ]+001090a5[ ]+add.d[ ]+\$a1, \$a1, \$a0
+[ ]+ec: R_LARCH_TLS_LE_ADD_R[ ]+TLSL1
+[ ]+ec: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+f0:[ ]+29800085[ ]+st.w[ ]+\$a1, \$a0, 0
+[ ]+f0: R_LARCH_TLS_LE_LO12_R[ ]+TLSL1
+[ ]+f0: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+f4:[ ]+18000004[ ]+pcaddi[ ]+\$a0, 0
+[ ]+f4: R_LARCH_TLS_LD_PCREL20_S2[ ]+TLSL1
+[ ]+f8:[ ]+18000004[ ]+pcaddi[ ]+\$a0, 0
+[ ]+f8: R_LARCH_TLS_GD_PCREL20_S2[ ]+TLSL1
+[ ]+fc:[ ]+18000004[ ]+pcaddi[ ]+\$a0, 0
+[ ]+fc: R_LARCH_TLS_DESC_PCREL20_S2[ ]+TLSL1
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index c839f525..0121cad9 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -52,6 +52,8 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "underflow_s_5_20"
run_dump_test "tls-le-norelax"
run_dump_test "tls-le-relax"
+ run_dump_test "relax-medium-call"
+ run_dump_test "relax-medium-call-1"
}
if [istarget "loongarch32-*-*"] {
diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d
new file mode 100644
index 00000000..c8ee9333
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d
@@ -0,0 +1,21 @@
+#ld: -e0 -Ttext=0x120000000 --section-start=ta=0x118000000 --section-start=tb=0x127fffffc
+#objdump: -d -j .text
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+[ ]*0000000120000000 <__bss_start-0x4030>:
+[ ]+120000000:[ ]+54000200[ ]+bl[ ]+-134217728[ ]+# 118000000 <a>
+[ ]+120000004:[ ]+1fffc001[ ]+pcaddu18i[ ]+\$ra, -512
+[ ]+120000008:[ ]+4ffffc21[ ]+jirl[ ]+\$ra, \$ra, -4
+[ ]+12000000c:[ ]+50000200[ ]+b[ ]+-134217728[ ]+# 11800000c <b>
+[ ]+120000010:[ ]+1fffc00c[ ]+pcaddu18i[ ]+\$t0, -512
+[ ]+120000014:[ ]+4ffffd80[ ]+jirl[ ]+\$zero, \$t0, -4
+[ ]+120000018:[ ]+1e004001[ ]+pcaddu18i[ ]+\$ra, 512
+[ ]+12000001c:[ ]+4c000421[ ]+jirl[ ]+\$ra, \$ra, 4
+[ ]+120000020:[ ]+57fffdff[ ]+bl[ ]+134217724[ ]+# 12800001c <c>
+[ ]+120000024:[ ]+1e00400c[ ]+pcaddu18i[ ]+\$t0, 512
+[ ]+120000028:[ ]+4c000580[ ]+jirl[ ]+\$zero, \$t0, 4
+[ ]+12000002c:[ ]+53fffdff[ ]+b[ ]+134217724[ ]+# 128000028 <d>
diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s
new file mode 100644
index 00000000..5266fdab
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s
@@ -0,0 +1,43 @@
+.section "ta", "ax"
+a:
+ ret
+ ret
+ ret
+b:
+ ret
+
+.text
+ pcaddu18i $ra, %call36(a) # min offset, can relax
+ jirl $ra, $ra, 0
+ pcaddu18i $ra, %call36(a) # overflow, not relax
+ jirl $ra, $ra, 0
+ pcaddu18i $t0, %call36(b) # min offset, can relax
+ jirl $zero, $t0, 0
+ pcaddu18i $t0, %call36(b) # overflow, not relax
+ jirl $zero, $t0, 0
+
+ pcaddu18i $ra, %call36(c) # overflow, not relax
+ jirl $ra, $ra, 0
+ pcaddu18i $ra, %call36(c) # max offset, can relax
+ jirl $ra, $ra, 0
+ pcaddu18i $t0, %call36(d) # overflow, no relax
+ jirl $zero, $t0, 0
+ pcaddu18i $t0, %call36(d) # max offset, can relax
+ jirl $zero, $t0, 0
+
+.section "tb", "ax"
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+c:
+ ret
+ ret
+ ret
+d:
+ ret
+
diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call.d b/ld/testsuite/ld-loongarch-elf/relax-medium-call.d
new file mode 100644
index 00000000..c8ee9333
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call.d
@@ -0,0 +1,21 @@
+#ld: -e0 -Ttext=0x120000000 --section-start=ta=0x118000000 --section-start=tb=0x127fffffc
+#objdump: -d -j .text
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+[ ]*0000000120000000 <__bss_start-0x4030>:
+[ ]+120000000:[ ]+54000200[ ]+bl[ ]+-134217728[ ]+# 118000000 <a>
+[ ]+120000004:[ ]+1fffc001[ ]+pcaddu18i[ ]+\$ra, -512
+[ ]+120000008:[ ]+4ffffc21[ ]+jirl[ ]+\$ra, \$ra, -4
+[ ]+12000000c:[ ]+50000200[ ]+b[ ]+-134217728[ ]+# 11800000c <b>
+[ ]+120000010:[ ]+1fffc00c[ ]+pcaddu18i[ ]+\$t0, -512
+[ ]+120000014:[ ]+4ffffd80[ ]+jirl[ ]+\$zero, \$t0, -4
+[ ]+120000018:[ ]+1e004001[ ]+pcaddu18i[ ]+\$ra, 512
+[ ]+12000001c:[ ]+4c000421[ ]+jirl[ ]+\$ra, \$ra, 4
+[ ]+120000020:[ ]+57fffdff[ ]+bl[ ]+134217724[ ]+# 12800001c <c>
+[ ]+120000024:[ ]+1e00400c[ ]+pcaddu18i[ ]+\$t0, 512
+[ ]+120000028:[ ]+4c000580[ ]+jirl[ ]+\$zero, \$t0, 4
+[ ]+12000002c:[ ]+53fffdff[ ]+b[ ]+134217724[ ]+# 128000028 <d>
diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call.s b/ld/testsuite/ld-loongarch-elf/relax-medium-call.s
new file mode 100644
index 00000000..c0521b65
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call.s
@@ -0,0 +1,35 @@
+.section "ta", "ax"
+a:
+ ret
+ ret
+ ret
+b:
+ ret
+
+.text
+ call36 a # min offset, can relax
+ call36 a # overflow, not relax
+ tail36 $t0, b # min offset, can relax
+ tail36 $t0, b # overflow, not relax
+
+ call36 c # overflow, not relax
+ call36 c # max offset, can relax
+ tail36 $t0, d # overflow, no relax
+ tail36 $t0, d # max offset, can relax
+
+.section "tb", "ax"
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+ ret
+c:
+ ret
+ ret
+ ret
+d:
+ ret
+
--
2.33.0

View File

@ -0,0 +1,124 @@
From 2d1db1c7427598dbabc93b7d47b01a1aa5e2cec0 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Fri, 28 Jun 2024 14:24:19 +0800
Subject: [PATCH 105/123] LoongArch: Add support for OUTPUT_FORMAT("binary")
In binary output format, loongarch_elf_hash_table return NULL and result
in segment fault.
When ld output binary file, it seems that elf related functions should
not be called. But loongarch_elf_relax_section be called and
loongarch_elf_hash_table cause segment fault.
Just redefined loongarch_elf_hash_table and always return
link_info->hash.
The tests of binutils, glibc and gcc is ok.
0 loongarch_elf_relax_section ()
1 0x000055555557ab28 in lang_size_sections_1 ()
2 0x000055555557a16c in lang_size_sections_1 ()
3 0x000055555557b0a8 in one_lang_size_sections_pass ()
4 0x000055555557b478 in lang_size_sections ()
5 0x000055555557e65c in lang_relax_sections ()
6 0x000055555559f9c8 in ldelf_map_segments ()
7 0x000055555559783c in gldelf64loongarch_after_allocation ()
8 0x000055555558dac0 in ldemul_after_allocation ()
9 0x000055555557f6c0 in lang_process ()
10 0x0000555555585314 in main ()
---
bfd/elfnn-loongarch.c | 4 +---
ld/emultempl/loongarchelf.em | 16 ----------------
ld/testsuite/ld-loongarch-elf/binary.ld | 1 +
ld/testsuite/ld-loongarch-elf/binary.s | 4 ++++
.../ld-loongarch-elf/ld-loongarch-elf.exp | 12 ++++++++++++
5 files changed, 18 insertions(+), 19 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/binary.ld
create mode 100644 ld/testsuite/ld-loongarch-elf/binary.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index af4d8baa..c2468443 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -157,9 +157,7 @@ loongarch_elf_new_section_hook (bfd *abfd, asection *sec)
/* Get the LoongArch ELF linker hash table from a link_info structure. */
#define loongarch_elf_hash_table(p) \
- (elf_hash_table_id (elf_hash_table (p)) == LARCH_ELF_DATA \
- ? ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \
- : NULL)
+ ((struct loongarch_elf_link_hash_table *) ((p)->hash)) \
#define MINUS_ONE ((bfd_vma) 0 - 1)
diff --git a/ld/emultempl/loongarchelf.em b/ld/emultempl/loongarchelf.em
index 13f8dacb..2e6b8080 100644
--- a/ld/emultempl/loongarchelf.em
+++ b/ld/emultempl/loongarchelf.em
@@ -102,23 +102,7 @@ gld${EMULATION_NAME}_after_allocation (void)
ldelf_map_segments (need_layout);
}
-/* This is a convenient point to tell BFD about target specific flags.
- After the output has been created, but before inputs are read. */
-
-static void
-larch_create_output_section_statements (void)
-{
- /* See PR 22920 for an example of why this is necessary. */
- if (strstr (bfd_get_target (link_info.output_bfd), "loong") == NULL)
- {
- einfo (_("%F%P: error: cannot change output format"
- " whilst linking %s binaries\n"), "LoongArch");
- return;
- }
-}
-
EOF
LDEMUL_BEFORE_ALLOCATION=larch_elf_before_allocation
LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
-LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=larch_create_output_section_statements
diff --git a/ld/testsuite/ld-loongarch-elf/binary.ld b/ld/testsuite/ld-loongarch-elf/binary.ld
new file mode 100644
index 00000000..73cd4f2c
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/binary.ld
@@ -0,0 +1 @@
+OUTPUT_FORMAT(binary);
diff --git a/ld/testsuite/ld-loongarch-elf/binary.s b/ld/testsuite/ld-loongarch-elf/binary.s
new file mode 100644
index 00000000..b0aeb62a
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/binary.s
@@ -0,0 +1,4 @@
+.text
+ ret
+.data
+ .4byte 0x12345678
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 032b9bad..232e7c20 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -118,6 +118,18 @@ if [istarget "loongarch64-*-*"] {
"abi1_max_imm" \
] \
]
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "binary output format" \
+ "-T binary.ld" "" \
+ "" \
+ {binary.s} \
+ {} \
+ "a.binary" \
+ ] \
+ ]
}
if [istarget "loongarch64-*-*"] {
--
2.33.0

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,331 @@
From b6d513ce677d288d470740a2a150a68a961e07cd Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Tue, 31 Oct 2023 16:11:56 +0800
Subject: [PATCH 026/123] LoongArch: Add support for TLSDESC in ld.
1.The linker for each DESC generates a R_LARCH_TLS_DESC64 dynamic
relocation, which relocation is placed at .rela.dyn.
TLSDESC always allocates two GOT slots and one dynamic relocation
space to TLSDESC.
2. When using multiple ways to access the same TLS variable, a
maximum of 5 GOT slots are used. For example, using GD, TLSDESC,
and IE to access the same TLS variable, GD always uses the first
two of the five GOT, TLSDESC uses the third and fourth, and IE
uses the last.
---
bfd/elfnn-loongarch.c | 168 ++++++++++++++++++++++++++++++++++++------
1 file changed, 146 insertions(+), 22 deletions(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 8e61d8d2..31dde892 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -48,6 +48,12 @@ struct loongarch_elf_link_hash_entry
#define GOT_TLS_GD 2
#define GOT_TLS_IE 4
#define GOT_TLS_LE 8
+#define GOT_TLS_GDESC 16
+
+#define GOT_TLS_GD_BOTH_P(tls_type) \
+ ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
+#define GOT_TLS_GD_ANY_P(tls_type) \
+ ((tls_type & GOT_TLS_GD) || (tls_type & GOT_TLS_GDESC))
char tls_type;
};
@@ -563,6 +569,7 @@ loongarch_elf_record_tls_and_got_reference (bfd *abfd,
case GOT_NORMAL:
case GOT_TLS_GD:
case GOT_TLS_IE:
+ case GOT_TLS_GDESC:
/* Need GOT. */
if (htab->elf.sgot == NULL
&& !loongarch_elf_create_got_section (htab->elf.dynobj, info))
@@ -750,6 +757,14 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
return false;
break;
+ case R_LARCH_TLS_DESC_PC_HI20:
+ case R_LARCH_TLS_DESC_HI20:
+ if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
+ r_symndx,
+ GOT_TLS_GDESC))
+ return false;
+ break;
+
case R_LARCH_ABS_HI20:
case R_LARCH_SOP_PUSH_ABSOLUTE:
if (h != NULL)
@@ -1130,7 +1145,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
s = htab->elf.sgot;
h->got.offset = s->size;
- if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+ if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
{
/* TLS_GD needs two dynamic relocs and two GOT slots. */
if (tls_type & GOT_TLS_GD)
@@ -1167,7 +1182,15 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
}
}
+
+ /* TLS_DESC needs one dynamic reloc and two GOT slot. */
+ if (tls_type & GOT_TLS_GDESC)
+ {
+ s->size += GOT_ENTRY_SIZE * 2;
+ htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
+ }
}
+
else
{
s->size += GOT_ENTRY_SIZE;
@@ -1670,19 +1693,34 @@ loongarch_elf_size_dynamic_sections (bfd *output_bfd,
if (0 < *local_got)
{
*local_got = s->size;
+ if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
+ {
+ /* TLS gd use two got. */
+ if (*local_tls_type & GOT_TLS_GD)
+ {
+ s->size += 2 * GOT_ENTRY_SIZE;
+ if (!bfd_link_executable (info))
+ srel->size += sizeof (ElfNN_External_Rela);
+ }
- /* TLS gd use two got. */
- if (*local_tls_type & GOT_TLS_GD)
- s->size += GOT_ENTRY_SIZE * 2;
- else
- /* Normal got, tls ie/ld use one got. */
- s->size += GOT_ENTRY_SIZE;
+ /* TLS_DESC use two got. */
+ if (*local_tls_type & GOT_TLS_GDESC)
+ {
+ s->size += 2 * GOT_ENTRY_SIZE;
+ srel->size += sizeof (ElfNN_External_Rela);
+ }
- if (bfd_link_executable (info)
- && (*local_tls_type & (GOT_TLS_GD| GOT_TLS_IE)))
- ;/* Do nothing. */
+ /* TLS ie and use one got. */
+ if (*local_tls_type & GOT_TLS_IE)
+ {
+ s->size += GOT_ENTRY_SIZE;
+ if (!bfd_link_executable (info))
+ srel->size += sizeof (ElfNN_External_Rela);
+ }
+ }
else
{
+ s->size += GOT_ENTRY_SIZE;
srel->size += sizeof (ElfNN_External_Rela);
}
}
@@ -2126,6 +2164,15 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
case R_LARCH_TLS_GD_HI20:
case R_LARCH_PCREL20_S2:
case R_LARCH_CALL36:
+ case R_LARCH_TLS_DESC_PC_HI20:
+ case R_LARCH_TLS_DESC_PC_LO12:
+ case R_LARCH_TLS_DESC64_PC_LO20:
+ case R_LARCH_TLS_DESC64_PC_HI12:
+ case R_LARCH_TLS_DESC_HI20:
+ case R_LARCH_TLS_DESC_LO12:
+ case R_LARCH_TLS_DESC64_LO20:
+ case R_LARCH_TLS_DESC64_HI12:
+
r = loongarch_check_offset (rel, input_section);
if (r != bfd_reloc_ok)
break;
@@ -2135,6 +2182,11 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
contents, value);
break;
+ case R_LARCH_TLS_DESC_LD:
+ case R_LARCH_TLS_DESC_CALL:
+ r = bfd_reloc_ok;
+ break;
+
case R_LARCH_RELAX:
break;
@@ -2383,10 +2435,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
struct elf_link_hash_entry *h = NULL;
const char *name;
bfd_reloc_status_type r = bfd_reloc_ok;
- bool is_ie, is_undefweak, unresolved_reloc, defined_local;
+ bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local;
bool resolved_local, resolved_dynly, resolved_to_const;
char tls_type;
- bfd_vma relocation, off, ie_off;
+ bfd_vma relocation, off, ie_off, desc_off;
int i, j;
howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
@@ -2515,6 +2567,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (!resolved_local || defined_local);
+ is_desc = false;
is_ie = false;
switch (r_type)
{
@@ -3398,6 +3451,8 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_LARCH_TLS_LD_HI20:
case R_LARCH_TLS_GD_PC_HI20:
case R_LARCH_TLS_GD_HI20:
+ case R_LARCH_TLS_DESC_PC_HI20:
+ case R_LARCH_TLS_DESC_HI20:
BFD_ASSERT (rel->r_addend == 0);
unresolved_reloc = false;
@@ -3405,6 +3460,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|| r_type == R_LARCH_TLS_IE_HI20)
is_ie = true;
+ if (r_type == R_LARCH_TLS_DESC_PC_HI20
+ || r_type == R_LARCH_TLS_DESC_HI20)
+ is_desc = true;
+
bfd_vma got_off = 0;
if (h != NULL)
{
@@ -3419,9 +3478,19 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (got_off != MINUS_ONE);
- ie_off = 0;
tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
- if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
+
+ /* If a tls variable is accessed in multiple ways, GD uses
+ the first two slots of GOT, desc follows with two slots,
+ and IE uses one slot at the end. */
+ desc_off = 0;
+ if (GOT_TLS_GD_BOTH_P (tls_type))
+ desc_off = 2 * GOT_ENTRY_SIZE;
+
+ ie_off = 0;
+ if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
+ ie_off = 4 * GOT_ENTRY_SIZE;
+ else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
ie_off = 2 * GOT_ENTRY_SIZE;
if ((got_off & 1) == 0)
@@ -3470,6 +3539,21 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
loongarch_elf_append_rela (output_bfd, relgot, &rela);
}
}
+ if (tls_type & GOT_TLS_GDESC)
+ {
+ /* Unless it is a static link, DESC always emits a
+ dynamic relocation. */
+ int indx = h && h->dynindx != -1 ? h->dynindx : 0;
+ rela.r_offset = sec_addr (got) + got_off + desc_off;
+ rela.r_addend = 0;
+ if (indx == 0)
+ rela.r_addend = relocation - elf_hash_table (info)->tls_sec->vma;
+
+ rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DESCNN);
+ loongarch_elf_append_rela (output_bfd, relgot, &rela);
+ bfd_put_NN (output_bfd, 0,
+ got->contents + got_off + desc_off);
+ }
if (tls_type & GOT_TLS_IE)
{
rela.r_offset = sec_addr (got) + got_off + ie_off;
@@ -3497,16 +3581,52 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
}
}
}
- relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got)
- + (is_ie ? ie_off : 0);
+ relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got);
+ if (is_desc)
+ relocation += desc_off;
+ else if (is_ie)
+ relocation += ie_off;
if (r_type == R_LARCH_TLS_LD_PC_HI20
|| r_type == R_LARCH_TLS_GD_PC_HI20
- || r_type == R_LARCH_TLS_IE_PC_HI20)
+ || r_type == R_LARCH_TLS_IE_PC_HI20
+ || r_type == R_LARCH_TLS_DESC_PC_HI20)
RELOCATE_CALC_PC32_HI20 (relocation, pc);
break;
+ case R_LARCH_TLS_DESC_PC_LO12:
+ case R_LARCH_TLS_DESC64_PC_LO20:
+ case R_LARCH_TLS_DESC64_PC_HI12:
+ case R_LARCH_TLS_DESC_LO12:
+ case R_LARCH_TLS_DESC64_LO20:
+ case R_LARCH_TLS_DESC64_HI12:
+ {
+ unresolved_reloc = false;
+
+ if (h)
+ relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
+ else
+ relocation = sec_addr (got)
+ + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
+
+ tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
+ /* Use both TLS_GD and TLS_DESC. */
+ if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
+ relocation += 2 * GOT_ENTRY_SIZE;
+ }
+
+ if (r_type == R_LARCH_TLS_DESC64_PC_LO20
+ || r_type == R_LARCH_TLS_DESC64_PC_HI12)
+ RELOCATE_CALC_PC64_HI32 (relocation, pc);
+
+ break;
+
+ case R_LARCH_TLS_DESC_LD:
+ case R_LARCH_TLS_DESC_CALL:
+ unresolved_reloc = false;
+ break;
+
case R_LARCH_TLS_IE_PC_LO12:
case R_LARCH_TLS_IE64_PC_LO20:
case R_LARCH_TLS_IE64_PC_HI12:
@@ -3516,14 +3636,17 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
unresolved_reloc = false;
if (h)
- relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)3));
+ relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
else
relocation = sec_addr (got)
- + (local_got_offsets[r_symndx] & (~(bfd_vma)3));
+ + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
- /* Use both TLS_GD and TLS_IE. */
- if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
+ /* Use TLS_GD TLS_DESC and TLS_IE. */
+ if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
+ relocation += 4 * GOT_ENTRY_SIZE;
+ /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE. */
+ else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
relocation += 2 * GOT_ENTRY_SIZE;
if (r_type == R_LARCH_TLS_IE64_PC_LO20
@@ -4167,7 +4290,8 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
if (h->got.offset != MINUS_ONE
/* TLS got entry have been handled in elf_relocate_section. */
- && !(loongarch_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+ && !(loongarch_elf_hash_entry (h)->tls_type
+ & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
/* Have allocated got entry but not allocated rela before. */
&& !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
{
--
2.33.0

View File

@ -0,0 +1,63 @@
From 114ab354c7fd16678578031340437b60e7b36e53 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Sun, 10 Dec 2023 17:41:32 +0800
Subject: [PATCH 019/123] LoongArch: Add support for <b ".L1"> and <beq, $t0,
$t1, ".L1">
Support symbol names enclosed in double quotation marks.
---
.../gas/loongarch/double_quotation_marks.d | 13 +++++++++++++
.../gas/loongarch/double_quotation_marks.s | 2 ++
opcodes/loongarch-coder.c | 7 +++++++
3 files changed, 22 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/double_quotation_marks.d
create mode 100644 gas/testsuite/gas/loongarch/double_quotation_marks.s
diff --git a/gas/testsuite/gas/loongarch/double_quotation_marks.d b/gas/testsuite/gas/loongarch/double_quotation_marks.d
new file mode 100644
index 00000000..a42534b9
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/double_quotation_marks.d
@@ -0,0 +1,13 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+.* <.text>:
+[ ]+0:[ ]+50000000[ ]+b[ ]+0[ ]+# 0x0
+[ ]+0: R_LARCH_B26[ ]+.L1
+[ ]+4:[ ]+5800018d[ ]+beq[ ]+\$t0, \$t1, 0[ ]+# 0x4
+[ ]+4: R_LARCH_B16[ ]+.L1
diff --git a/gas/testsuite/gas/loongarch/double_quotation_marks.s b/gas/testsuite/gas/loongarch/double_quotation_marks.s
new file mode 100644
index 00000000..f8b63074
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/double_quotation_marks.s
@@ -0,0 +1,2 @@
+b ".L1"
+beq $r12, $r13, ".L1"
diff --git a/opcodes/loongarch-coder.c b/opcodes/loongarch-coder.c
index a68ae1c3..672a468b 100644
--- a/opcodes/loongarch-coder.c
+++ b/opcodes/loongarch-coder.c
@@ -264,6 +264,13 @@ loongarch_split_args_by_comma (char *args, const char *arg_strs[])
else
*args = '\0', arg_strs[num++] = args + 1;
}
+
+ if (*(args-1) == '"')
+ {
+ *(args-1) = '\0';
+ arg_strs[num-1] = arg_strs[num-1] + 1;
+ }
+
arg_strs[num] = NULL;
return num;
}
--
2.33.0

View File

@ -0,0 +1,445 @@
From 3df3fec5862a2d6adec7dc469e7c53596e0ca464 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Fri, 8 Dec 2023 15:15:50 +0800
Subject: [PATCH 023/123] LoongArch: Add support for the third expression of
.align for R_LARCH_ALIGN
If the symbol index is not zero, the addend is used to represent
the first and the third expressions of the .align.
The lowest 8 bits are used to represent the first expression.
Other bits are used to represent the third expression.
The addend of R_LARCH_ALIGN for ".align 5, ,4" is 0x405.
The addend of R_LARCH_ALIGN for ".balign 32, ,4" is 0x405.
---
bfd/elfnn-loongarch.c | 71 ++++++++++++-------
bfd/elfxx-loongarch.c | 10 ++-
gas/config/tc-loongarch.c | 20 ++++--
gas/config/tc-loongarch.h | 4 +-
gas/testsuite/gas/loongarch/relax_align.d | 46 +++++++-----
gas/testsuite/gas/loongarch/relax_align.s | 4 +-
ld/testsuite/ld-elf/anno-sym.d | 2 +
ld/testsuite/ld-loongarch-elf/anno-sym.d | 7 ++
ld/testsuite/ld-loongarch-elf/anno-sym.l | 4 ++
ld/testsuite/ld-loongarch-elf/anno-sym.s | 13 ++++
.../ld-loongarch-elf/ld-loongarch-elf.exp | 1 +
ld/testsuite/ld-loongarch-elf/relax-align.dd | 5 +-
ld/testsuite/ld-loongarch-elf/relax-align.s | 5 +-
ld/testsuite/ld-loongarch-elf/relax.exp | 2 +-
14 files changed, 134 insertions(+), 60 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/anno-sym.d
create mode 100644 ld/testsuite/ld-loongarch-elf/anno-sym.l
create mode 100644 ld/testsuite/ld-loongarch-elf/anno-sym.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 6fd6a04d..8e61d8d2 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3851,44 +3851,53 @@ loongarch_relax_align (bfd *abfd, asection *sec,
Elf_Internal_Rela *rel,
bfd_vma symval)
{
- bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
- bfd_vma alignment = 1, pos;
- while (alignment <= rel->r_addend)
- alignment *= 2;
+ bfd_vma addend, max = 0, alignment = 1;
- symval -= rel->r_addend;
- bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
- bfd_vma nop_bytes = aligned_addr - symval;
+ int index = ELFNN_R_SYM (rel->r_info);
+ if (index > 0)
+ {
+ alignment = 1 << (rel->r_addend & 0xff);
+ max = rel->r_addend >> 8;
+ }
+ else
+ alignment = rel->r_addend + 4;
- /* Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
- sec->sec_flg0 = true;
+ addend = alignment - 4; /* The bytes of NOPs added by R_LARCH_ALIGN. */
+ symval -= addend; /* The address of first NOP added by R_LARCH_ALIGN. */
+ bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
+ bfd_vma need_nop_bytes = aligned_addr - symval; /* */
/* Make sure there are enough NOPs to actually achieve the alignment. */
- if (rel->r_addend < nop_bytes)
+ if (addend < need_nop_bytes)
{
_bfd_error_handler
(_("%pB(%pA+%#" PRIx64 "): %" PRId64 " bytes required for alignment "
"to %" PRId64 "-byte boundary, but only %" PRId64 " present"),
abfd, sym_sec, (uint64_t) rel->r_offset,
- (int64_t) nop_bytes, (int64_t) alignment, (int64_t) rel->r_addend);
+ (int64_t) need_nop_bytes, (int64_t) alignment, (int64_t) addend);
bfd_set_error (bfd_error_bad_value);
return false;
}
- /* Delete the reloc. */
+ /* Once we've handled an R_LARCH_ALIGN in a section,
+ we can't relax anything else in this section. */
+ sec->sec_flg0 = true;
rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
+ /* If skipping more bytes than the specified maximum,
+ then the alignment is not done at all and delete all NOPs. */
+ if (max > 0 && need_nop_bytes > max)
+ return loongarch_relax_delete_bytes (abfd, sec, rel->r_offset,
+ addend, link_info);
+
/* If the number of NOPs is already correct, there's nothing to do. */
- if (nop_bytes == rel->r_addend)
+ if (need_nop_bytes == addend)
return true;
- /* Write as many LOONGARCH NOPs as we need. */
- for (pos = 0; pos < (nop_bytes & -4); pos += 4)
- bfd_putl32 (LARCH_NOP, contents + rel->r_offset + pos);
-
/* Delete the excess NOPs. */
- return loongarch_relax_delete_bytes (abfd, sec, rel->r_offset + nop_bytes,
- rel->r_addend - nop_bytes, link_info);
+ return loongarch_relax_delete_bytes (abfd, sec,
+ rel->r_offset + need_nop_bytes,
+ addend - need_nop_bytes, link_info);
}
static bool
@@ -3897,8 +3906,8 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
bool *again)
{
struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
- Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
struct bfd_elf_section_data *data = elf_section_data (sec);
+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
Elf_Internal_Rela *relocs;
*again = false;
@@ -3931,7 +3940,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
0, NULL, NULL, NULL)))
return true;
- data->relocs = relocs;
+ data->relocs = relocs;
for (unsigned int i = 0; i < sec->reloc_count; i++)
{
@@ -3939,6 +3948,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
asection *sym_sec;
bfd_vma symval;
unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
+ unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
bool local_got = false;
char symtype;
struct elf_link_hash_entry *h = NULL;
@@ -3950,7 +3960,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
continue;
- if (sym->st_shndx == SHN_UNDEF)
+ if (sym->st_shndx == SHN_UNDEF || R_LARCH_ALIGN == r_type)
{
sym_sec = sec;
symval = rel->r_offset;
@@ -3976,9 +3986,9 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
continue;
if ((h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- && h->root.u.def.section != NULL
- && h->root.u.def.section->output_section != NULL)
+ || h->root.type == bfd_link_hash_defweak)
+ && h->root.u.def.section != NULL
+ && h->root.u.def.section->output_section != NULL)
{
symval = h->root.u.def.value;
sym_sec = h->root.u.def.section;
@@ -4004,12 +4014,21 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
if (symtype != STT_SECTION)
symval += rel->r_addend;
}
+ /* For R_LARCH_ALIGN, symval is sec_addr (sym_sec) + rel->r_offset
+ + (alingmeng - 4).
+ If r_symndx is 0, alignmeng-4 is r_addend.
+ If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */
+ else if (R_LARCH_ALIGN == r_type)
+ if (r_symndx > 0)
+ symval += ((1 << (rel->r_addend & 0xff)) - 4);
+ else
+ symval += rel->r_addend;
else
symval += rel->r_addend;
symval += sec_addr (sym_sec);
- switch (ELFNN_R_TYPE (rel->r_info))
+ switch (r_type)
{
case R_LARCH_ALIGN:
if (1 == info->relax_pass)
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index d93b7904..679b79f3 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -1395,9 +1395,13 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
NULL, /* adjust_reloc_bits. */
NULL), /* larch_reloc_type_name. */
- /* Indicates an alignment statement. The addend field encodes how many
- bytes of NOPs follow the statement. The desired alignment is the
- addend rounded up to the next power of two. */
+ /* Indicates an alignment statement. f the symbol index is 0,
+ the addend indicates the number of bytes occupied by nop instructions
+ at the relocation offset. The alignment boundary is specified by the
+ addend rounded up to the next power of two.
+ If the symbol index is not 0, the addend indicates the first and third
+ expressions of .align. The lowest 8 bits are used to represent the first
+ expression, other bits are used to represent the third expression. */
LOONGARCH_HOWTO (R_LARCH_ALIGN, /* type (102). */
0, /* rightshift. */
0, /* size. */
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 367a0b6c..9b912daf 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -1652,14 +1652,16 @@ loongarch_make_nops (char *buf, bfd_vma bytes)
the correct alignment now because of other linker relaxations. */
bool
-loongarch_frag_align_code (int n)
+loongarch_frag_align_code (int n, int max)
{
- bfd_vma bytes = (bfd_vma) 1 << n;
- bfd_vma insn_alignment = 4;
- bfd_vma worst_case_bytes = bytes - insn_alignment;
char *nops;
+ symbolS *s;
expressionS ex;
+ bfd_vma insn_alignment = 4;
+ bfd_vma bytes = (bfd_vma) 1 << n;
+ bfd_vma worst_case_bytes = bytes - insn_alignment;
+
/* If we are moving to a smaller alignment than the instruction size, then no
alignment is required. */
if (bytes <= insn_alignment)
@@ -1671,8 +1673,14 @@ loongarch_frag_align_code (int n)
nops = frag_more (worst_case_bytes);
- ex.X_op = O_constant;
- ex.X_add_number = worst_case_bytes;
+ s = symbol_find (".Lla-relax-align");
+ if (s == NULL)
+ s = (symbolS *)local_symbol_make (".Lla-relax-align", now_seg,
+ &zero_address_frag, 0);
+
+ ex.X_add_symbol = s;
+ ex.X_op = O_symbol;
+ ex.X_add_number = (max << 8) | n;
loongarch_make_nops (nops, worst_case_bytes);
diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h
index 4afa3842..194ee107 100644
--- a/gas/config/tc-loongarch.h
+++ b/gas/config/tc-loongarch.h
@@ -49,11 +49,11 @@ extern int loongarch_relax_frag (asection *, struct frag *, long);
#define md_undefined_symbol(name) (0)
#define md_operand(x)
-extern bool loongarch_frag_align_code (int);
+extern bool loongarch_frag_align_code (int, int);
#define md_do_align(N, FILL, LEN, MAX, LABEL) \
if ((N) != 0 && !(FILL) && !need_pass_2 && subseg_text_p (now_seg)) \
{ \
- if (loongarch_frag_align_code (N)) \
+ if (loongarch_frag_align_code (N, MAX)) \
goto LABEL; \
}
diff --git a/gas/testsuite/gas/loongarch/relax_align.d b/gas/testsuite/gas/loongarch/relax_align.d
index 1810eb4c..2cc6c86d 100644
--- a/gas/testsuite/gas/loongarch/relax_align.d
+++ b/gas/testsuite/gas/loongarch/relax_align.d
@@ -1,4 +1,4 @@
-#as:
+#as: --no-warn
#objdump: -dr
#skip: loongarch32-*-*
@@ -7,20 +7,30 @@
Disassembly of section .text:
-00000000.* <L1>:
-[ ]+0:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+0:[ ]+R_LARCH_PCALA_HI20[ ]+L1
-[ ]+0:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
-[ ]+4:[ ]+02c00084[ ]+addi\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+4:[ ]+R_LARCH_PCALA_LO12[ ]+L1
-[ ]+4:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
-[ ]+8:[ ]+03400000[ ]+nop[ ]+
-[ ]+8:[ ]+R_LARCH_ALIGN[ ]+\*ABS\*\+0xc
-[ ]+c:[ ]+03400000[ ]+nop[ ]+
-[ ]+10:[ ]+03400000[ ]+nop[ ]+
-[ ]+14:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0,[ ]+0
-[ ]+14:[ ]+R_LARCH_PCALA_HI20[ ]+L1
-[ ]+14:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
-[ ]+18:[ ]+02c00084[ ]+addi\.d[ ]+\$a0,[ ]+\$a0,[ ]+0
-[ ]+18:[ ]+R_LARCH_PCALA_LO12[ ]+L1
-[ ]+18:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]*0000000000000000 <.Lla-relax-align>:
+[ ]+0:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+0: R_LARCH_PCALA_HI20[ ]+L1
+[ ]+0: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+4:[ ]+02c00084[ ]+addi.d[ ]+\$a0, \$a0, 0
+[ ]+4: R_LARCH_PCALA_LO12[ ]+L1
+[ ]+4: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+8:[ ]+03400000[ ]+nop.*
+[ ]+8: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0x4
+[ ]+c:[ ]+03400000[ ]+nop.*
+[ ]+10:[ ]+03400000[ ]+nop.*
+[ ]+14:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+14: R_LARCH_PCALA_HI20[ ]+L1
+[ ]+14: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+18:[ ]+02c00084[ ]+addi.d[ ]+\$a0, \$a0, 0
+[ ]+18: R_LARCH_PCALA_LO12[ ]+L1
+[ ]+18: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+1c:[ ]+03400000[ ]+nop.*
+[ ]+1c: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0x404
+[ ]+20:[ ]+03400000[ ]+nop.*
+[ ]+24:[ ]+03400000[ ]+nop.*
+[ ]+28:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+28: R_LARCH_PCALA_HI20[ ]+L1
+[ ]+28: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+2c:[ ]+02c00084[ ]+addi.d[ ]+\$a0, \$a0, 0
+[ ]+2c: R_LARCH_PCALA_LO12[ ]+L1
+[ ]+2c: R_LARCH_RELAX[ ]+\*ABS\*
diff --git a/gas/testsuite/gas/loongarch/relax_align.s b/gas/testsuite/gas/loongarch/relax_align.s
index 3880d783..c0177c88 100644
--- a/gas/testsuite/gas/loongarch/relax_align.s
+++ b/gas/testsuite/gas/loongarch/relax_align.s
@@ -1,5 +1,7 @@
.text
-L1:
+.L1:
la.local $a0, L1
.align 4
la.local $a0, L1
+ .align 4, , 4
+ la.local $a0, L1
diff --git a/ld/testsuite/ld-elf/anno-sym.d b/ld/testsuite/ld-elf/anno-sym.d
index 9e53c4a9..f1ce21f9 100644
--- a/ld/testsuite/ld-elf/anno-sym.d
+++ b/ld/testsuite/ld-elf/anno-sym.d
@@ -3,3 +3,5 @@
#error_output: anno-sym.l
# The mips-irix6 target fails this test because it does not find any function symbols. Not sure why.
#skip: *-*-irix*
+# The .align generate a local symbol .Lla-relax-align.
+#skip: loongarch*-*-*
diff --git a/ld/testsuite/ld-loongarch-elf/anno-sym.d b/ld/testsuite/ld-loongarch-elf/anno-sym.d
new file mode 100644
index 00000000..a58f4a6c
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/anno-sym.d
@@ -0,0 +1,7 @@
+# Copied from ld-elf, add -mno-relax to prevent generate .Lla-relax-align symbol
+# Check that linking anno-sym.o produces an undefined reference message referring to '_start' and not 'annobin_hello.c'
+#as: -mno-relax
+#ld: -e _start
+#error_output: anno-sym.l
+# The mips-irix6 target fails this test because it does not find any function symbols. Not sure why.
+#skip: *-*-irix*
diff --git a/ld/testsuite/ld-loongarch-elf/anno-sym.l b/ld/testsuite/ld-loongarch-elf/anno-sym.l
new file mode 100644
index 00000000..ee9611ae
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/anno-sym.l
@@ -0,0 +1,4 @@
+#...
+.*: in function `(|_)start':
+.*: undefined reference to `foo'
+#pass
diff --git a/ld/testsuite/ld-loongarch-elf/anno-sym.s b/ld/testsuite/ld-loongarch-elf/anno-sym.s
new file mode 100644
index 00000000..92016a80
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/anno-sym.s
@@ -0,0 +1,13 @@
+ .text
+
+ .hidden .annobin_hello.c
+ .type .annobin_hello.c, STT_NOTYPE
+ .equiv .annobin_hello.c, .
+ .size .annobin_hello.c, 0
+
+ .global _start
+_start:
+ .nop
+ .align 4
+ .dc.a foo
+
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 1fc70d0a..b43a518a 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -32,6 +32,7 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "syscall"
run_dump_test "disas-jirl"
run_dump_test "local-ifunc-reloc"
+ run_dump_test "anno-sym"
}
if [istarget "loongarch32-*-*"] {
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align.dd b/ld/testsuite/ld-loongarch-elf/relax-align.dd
index 5fce2255..37fdab18 100644
--- a/ld/testsuite/ld-loongarch-elf/relax-align.dd
+++ b/ld/testsuite/ld-loongarch-elf/relax-align.dd
@@ -1,7 +1,8 @@
#...
.*pcaddi.*
-.*pcaddi.*
.*nop.*
+.*pcaddi.*
.*nop.*
-.*0:.*pcaddi.*
+.*pcaddi.*
+.*pcaddi.*
#pass
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align.s b/ld/testsuite/ld-loongarch-elf/relax-align.s
index 9617c02d..66dfea8f 100644
--- a/ld/testsuite/ld-loongarch-elf/relax-align.s
+++ b/ld/testsuite/ld-loongarch-elf/relax-align.s
@@ -4,6 +4,9 @@
.text
L1:
la.local $a0, L1
+ .align 3
la.local $a0, L1
- .align 4
+ .align 3, ,4
+ la.local $a0, L1
+ .align 3, ,2
la.local $a0, L1
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index 24d79ed5..77323d8d 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -121,7 +121,7 @@ if [istarget loongarch64-*-*] {
[list \
"loongarch relax-align" \
"-e 0x0 -z relro" "" \
- "" \
+ "--no-warn" \
{relax-align.s} \
[list \
[list objdump -d relax-align.dd] \
--
2.33.0

View File

@ -0,0 +1,669 @@
From aaab3bca7ff42e982134fd638ad1ae8324260a8f Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Wed, 13 Dec 2023 11:34:56 +0800
Subject: [PATCH 029/123] LoongArch: Add testsuit for DESC and tls transition
and tls relaxation.
---
gas/testsuite/gas/loongarch/tlsdesc_32.d | 27 ++++++++
gas/testsuite/gas/loongarch/tlsdesc_32.s | 12 ++++
gas/testsuite/gas/loongarch/tlsdesc_32_abs.d | 26 ++++++++
gas/testsuite/gas/loongarch/tlsdesc_32_abs.s | 8 +++
gas/testsuite/gas/loongarch/tlsdesc_64.d | 28 ++++++++
gas/testsuite/gas/loongarch/tlsdesc_64.s | 12 ++++
.../gas/loongarch/tlsdesc_large_abs.d | 34 ++++++++++
.../gas/loongarch/tlsdesc_large_abs.s | 12 ++++
.../gas/loongarch/tlsdesc_large_pc.d | 38 +++++++++++
.../gas/loongarch/tlsdesc_large_pc.s | 17 +++++
ld/testsuite/ld-loongarch-elf/desc-ie.d | 16 +++++
ld/testsuite/ld-loongarch-elf/desc-ie.s | 18 +++++
ld/testsuite/ld-loongarch-elf/desc-le.d | 15 +++++
ld/testsuite/ld-loongarch-elf/desc-le.s | 14 ++++
ld/testsuite/ld-loongarch-elf/desc-norelax.d | 16 +++++
ld/testsuite/ld-loongarch-elf/desc-norelax.s | 5 ++
ld/testsuite/ld-loongarch-elf/desc-relax.d | 15 +++++
ld/testsuite/ld-loongarch-elf/desc-relax.s | 5 ++
ld/testsuite/ld-loongarch-elf/ie-le.d | 13 ++++
ld/testsuite/ld-loongarch-elf/ie-le.s | 11 ++++
.../ld-loongarch-elf/ld-loongarch-elf.exp | 9 +++
ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d | 56 ++++++++++++++++
ld/testsuite/ld-loongarch-elf/tlsdesc-dso.s | 65 +++++++++++++++++++
23 files changed, 472 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32.d
create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32.s
create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32_abs.d
create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32_abs.s
create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_64.d
create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_64.s
create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_abs.d
create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_abs.s
create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_pc.d
create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_pc.s
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-ie.d
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-ie.s
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-le.d
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-le.s
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-norelax.d
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-norelax.s
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-relax.d
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-relax.s
create mode 100644 ld/testsuite/ld-loongarch-elf/ie-le.d
create mode 100644 ld/testsuite/ld-loongarch-elf/ie-le.s
create mode 100644 ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
create mode 100644 ld/testsuite/ld-loongarch-elf/tlsdesc-dso.s
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_32.d b/gas/testsuite/gas/loongarch/tlsdesc_32.d
new file mode 100644
index 00000000..eddcc5ed
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_32.d
@@ -0,0 +1,27 @@
+#as:
+#objdump: -dr
+#skip: loongarch64-*-*
+
+.*:[ ]+file format .*
+
+Disassembly of section .text:
+
+0+ <.*>:
+ 0: 1a000004 pcalau12i \$a0, 0
+ 0: R_LARCH_TLS_DESC_PC_HI20 var
+ 4: 02800084 addi.w \$a0, \$a0, 0
+ 4: R_LARCH_TLS_DESC_PC_LO12 var
+ 8: 28800081 ld.w \$ra, \$a0, 0
+ 8: R_LARCH_TLS_DESC_LD var
+ c: 4c000021 jirl \$ra, \$ra, 0
+ c: R_LARCH_TLS_DESC_CALL var
+ 10: 1a000004 pcalau12i \$a0, 0
+ 10: R_LARCH_TLS_DESC_PC_HI20 var
+ 10: R_LARCH_RELAX \*ABS\*
+ 14: 02800084 addi.w \$a0, \$a0, 0
+ 14: R_LARCH_TLS_DESC_PC_LO12 var
+ 14: R_LARCH_RELAX \*ABS\*
+ 18: 28800081 ld.w \$ra, \$a0, 0
+ 18: R_LARCH_TLS_DESC_LD var
+ 1c: 4c000021 jirl \$ra, \$ra, 0
+ 1c: R_LARCH_TLS_DESC_CALL var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_32.s b/gas/testsuite/gas/loongarch/tlsdesc_32.s
new file mode 100644
index 00000000..ef6aee94
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_32.s
@@ -0,0 +1,12 @@
+.L1:
+ # R_LARCH_TLS_DESC_PC_HI20 var
+ pcalau12i $a0,%desc_pc_hi20(var)
+ # R_LARCH_TLS_DESC_PC_LO12 var
+ addi.w $a0,$a0,%desc_pc_lo12(var)
+ # R_LARCH_TLS_DESC_LD var
+ ld.w $ra,$a0,%desc_ld(var)
+ # R_LARCH_TLS_DESC_CALL var
+ jirl $ra,$ra,%desc_call(var)
+
+ # test macro, pcalau12i + addi.w => pcaddi
+ la.tls.desc $a0,var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_32_abs.d b/gas/testsuite/gas/loongarch/tlsdesc_32_abs.d
new file mode 100644
index 00000000..e787e409
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_32_abs.d
@@ -0,0 +1,26 @@
+#as: -mla-global-with-abs
+#objdump: -dr
+#skip: loongarch64-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+ <.*>:
+ 0: 14000004 lu12i.w \$a0, 0
+ 0: R_LARCH_TLS_DESC_HI20 var
+ 4: 03800084 ori \$a0, \$a0, 0x0
+ 4: R_LARCH_TLS_DESC_LO12 var
+ 8: 28800081 ld.w \$ra, \$a0, 0
+ 8: R_LARCH_TLS_DESC_LD var
+ c: 4c000021 jirl \$ra, \$ra, 0
+ c: R_LARCH_TLS_DESC_CALL var
+ 10: 14000004 lu12i.w \$a0, 0
+ 10: R_LARCH_TLS_DESC_HI20 var
+ 14: 03800084 ori \$a0, \$a0, 0x0
+ 14: R_LARCH_TLS_DESC_LO12 var
+ 18: 28800081 ld.w \$ra, \$a0, 0
+ 18: R_LARCH_TLS_DESC_LD var
+ 1c: 4c000021 jirl \$ra, \$ra, 0
+ 1c: R_LARCH_TLS_DESC_CALL var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_32_abs.s b/gas/testsuite/gas/loongarch/tlsdesc_32_abs.s
new file mode 100644
index 00000000..65d096ea
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_32_abs.s
@@ -0,0 +1,8 @@
+.L1:
+ lu12i.w $a0,%desc_hi20(var)
+ ori $a0,$a0,%desc_lo12(var)
+ ld.w $ra,$a0,%desc_ld(var)
+ jirl $ra,$ra,%desc_call(var)
+
+ # Test macro expansion
+ la.tls.desc $a0,var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_64.d b/gas/testsuite/gas/loongarch/tlsdesc_64.d
new file mode 100644
index 00000000..2a2829c9
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_64.d
@@ -0,0 +1,28 @@
+#as:
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+ <.*>:
+ 0: 1a000004 pcalau12i \$a0, 0
+ 0: R_LARCH_TLS_DESC_PC_HI20 var
+ 4: 02c00084 addi.d \$a0, \$a0, 0
+ 4: R_LARCH_TLS_DESC_PC_LO12 var
+ 8: 28c00081 ld.d \$ra, \$a0, 0
+ 8: R_LARCH_TLS_DESC_LD var
+ c: 4c000021 jirl \$ra, \$ra, 0
+ c: R_LARCH_TLS_DESC_CALL var
+ 10: 1a000004 pcalau12i \$a0, 0
+ 10: R_LARCH_TLS_DESC_PC_HI20 var
+ 10: R_LARCH_RELAX \*ABS\*
+ 14: 02c00084 addi.d \$a0, \$a0, 0
+ 14: R_LARCH_TLS_DESC_PC_LO12 var
+ 14: R_LARCH_RELAX \*ABS\*
+ 18: 28c00081 ld.d \$ra, \$a0, 0
+ 18: R_LARCH_TLS_DESC_LD var
+ 1c: 4c000021 jirl \$ra, \$ra, 0
+ 1c: R_LARCH_TLS_DESC_CALL var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_64.s b/gas/testsuite/gas/loongarch/tlsdesc_64.s
new file mode 100644
index 00000000..9d0ccb17
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_64.s
@@ -0,0 +1,12 @@
+.L1:
+ # R_LARCH_TLS_DESC_PC_HI20 var
+ pcalau12i $a0,%desc_pc_hi20(var)
+ # R_LARCH_TLS_DESC_PC_LO12 var
+ addi.d $a0,$a0,%desc_pc_lo12(var)
+ # R_LARCH_TLS_DESC_LD var
+ ld.d $ra,$a0,%desc_ld(var)
+ # R_LARCH_TLS_DESC_CALL var
+ jirl $ra,$ra,%desc_call(var)
+
+ # test macro, pcalau12i + addi.d => pcaddi
+ la.tls.desc $a0,var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_large_abs.d b/gas/testsuite/gas/loongarch/tlsdesc_large_abs.d
new file mode 100644
index 00000000..5411a3ac
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_large_abs.d
@@ -0,0 +1,34 @@
+#as: -mla-global-with-abs
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+ <.*>:
+ 0: 14000004 lu12i.w \$a0, 0
+ 0: R_LARCH_TLS_DESC_HI20 var
+ 4: 03800084 ori \$a0, \$a0, 0x0
+ 4: R_LARCH_TLS_DESC_LO12 var
+ 8: 16000004 lu32i.d \$a0, 0
+ 8: R_LARCH_TLS_DESC64_LO20 var
+ c: 03000084 lu52i.d \$a0, \$a0, 0
+ c: R_LARCH_TLS_DESC64_HI12 var
+ 10: 28c00081 ld.d \$ra, \$a0, 0
+ 10: R_LARCH_TLS_DESC_LD var
+ 14: 4c000021 jirl \$ra, \$ra, 0
+ 14: R_LARCH_TLS_DESC_CALL var
+ 18: 14000004 lu12i.w \$a0, 0
+ 18: R_LARCH_TLS_DESC_HI20 var
+ 1c: 03800084 ori \$a0, \$a0, 0x0
+ 1c: R_LARCH_TLS_DESC_LO12 var
+ 20: 16000004 lu32i.d \$a0, 0
+ 20: R_LARCH_TLS_DESC64_LO20 var
+ 24: 03000084 lu52i.d \$a0, \$a0, 0
+ 24: R_LARCH_TLS_DESC64_HI12 var
+ 28: 28c00081 ld.d \$ra, \$a0, 0
+ 28: R_LARCH_TLS_DESC_LD var
+ 2c: 4c000021 jirl \$ra, \$ra, 0
+ 2c: R_LARCH_TLS_DESC_CALL var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_large_abs.s b/gas/testsuite/gas/loongarch/tlsdesc_large_abs.s
new file mode 100644
index 00000000..27a52620
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_large_abs.s
@@ -0,0 +1,12 @@
+.L1:
+ .global var
+ #TLSDESC large abs
+ lu12i.w $a0,%desc_hi20(var)
+ ori $a0,$a0,%desc_lo12(var)
+ lu32i.d $a0,%desc64_lo20(var)
+ lu52i.d $a0,$a0,%desc64_hi12(var)
+ ld.d $ra,$a0,%desc_ld(var)
+ jirl $ra,$ra,%desc_call(var)
+
+ # Test macro expansion
+ la.tls.desc $a0,var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_large_pc.d b/gas/testsuite/gas/loongarch/tlsdesc_large_pc.d
new file mode 100644
index 00000000..2b7a4660
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_large_pc.d
@@ -0,0 +1,38 @@
+#as:
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+ <.*>:
+ 0: 1a000004 pcalau12i \$a0, 0
+ 0: R_LARCH_TLS_DESC_PC_HI20 var
+ 4: 02c00005 li.d \$a1, 0
+ 4: R_LARCH_TLS_DESC_PC_LO12 var
+ 8: 16000005 lu32i.d \$a1, 0
+ 8: R_LARCH_TLS_DESC64_PC_LO20 var
+ c: 030000a5 lu52i.d \$a1, \$a1, 0
+ c: R_LARCH_TLS_DESC64_PC_HI12 var
+ 10: 00109484 add.d \$a0, \$a0, \$a1
+ 14: 28c00081 ld.d \$ra, \$a0, 0
+ 14: R_LARCH_TLS_DESC_LD var
+ 18: 4c000021 jirl \$ra, \$ra, 0
+ 18: R_LARCH_TLS_DESC_CALL var
+ 1c: 1a000004 pcalau12i \$a0, 0
+ 1c: R_LARCH_TLS_DESC_PC_HI20 var
+ 1c: R_LARCH_RELAX \*ABS\*
+ 20: 02c00001 li.d \$ra, 0
+ 20: R_LARCH_TLS_DESC_PC_LO12 var
+ 20: R_LARCH_RELAX \*ABS\*
+ 24: 16000001 lu32i.d \$ra, 0
+ 24: R_LARCH_TLS_DESC64_PC_LO20 var
+ 28: 03000021 lu52i.d \$ra, \$ra, 0
+ 28: R_LARCH_TLS_DESC64_PC_HI12 var
+ 2c: 00108484 add.d \$a0, \$a0, \$ra
+ 30: 28c00081 ld.d \$ra, \$a0, 0
+ 30: R_LARCH_TLS_DESC_LD var
+ 34: 4c000021 jirl \$ra, \$ra, 0
+ 34: R_LARCH_TLS_DESC_CALL var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_large_pc.s b/gas/testsuite/gas/loongarch/tlsdesc_large_pc.s
new file mode 100644
index 00000000..0d0839a7
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tlsdesc_large_pc.s
@@ -0,0 +1,17 @@
+.L1:
+ # R_LARCH_TLS_DESC_PC_HI20 var
+ pcalau12i $a0,%desc_pc_hi20(var)
+ # R_LARCH_TLS_DESC_PC_LO12
+ addi.d $a1,$zero,%desc_pc_lo12(var)
+ # R_LARCH_TLS_DESC64_PC_LO20
+ lu32i.d $a1,%desc64_pc_lo20(var)
+ # R_LARCH_TLS_DESC64_PC_HI12
+ lu52i.d $a1,$a1,%desc64_pc_hi12(var)
+ add.d $a0,$a0,$a1
+ # R_LARCH_TLS_DESC_LD
+ ld.d $ra,$a0,%desc_ld(var)
+ # R_LARCH_TLS_DESC
+ jirl $ra,$ra,%desc_call(var)
+
+ # Test macro expansion
+ la.tls.desc $a0,$ra,var
diff --git a/ld/testsuite/ld-loongarch-elf/desc-ie.d b/ld/testsuite/ld-loongarch-elf/desc-ie.d
new file mode 100644
index 00000000..d1acbfc6
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-ie.d
@@ -0,0 +1,16 @@
+#as:
+#ld: -shared -z norelro -e 0x0
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+Disassembly of section .text:
+
+0+230 <fn1>:
+ 230: 1a000084 pcalau12i \$a0, 4
+ 234: 28cd6084 ld.d \$a0, \$a0, 856
+ 238: 03400000 nop.*
+ 23c: 03400000 nop.*
+ 240: 1a000084 pcalau12i \$a0, 4
+ 244: 28cd6081 ld.d \$ra, \$a0, 856
diff --git a/ld/testsuite/ld-loongarch-elf/desc-ie.s b/ld/testsuite/ld-loongarch-elf/desc-ie.s
new file mode 100644
index 00000000..7f5772bc
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-ie.s
@@ -0,0 +1,18 @@
+ .global v1
+ .section .tdata,"awT",@progbits
+v1:
+ .word 1
+ .text
+ .global fn1
+ .type fn1,@function
+fn1:
+
+ # Use DESC and IE to access the same symbol,
+ # DESC will relax to IE.
+ pcalau12i $a0,%desc_pc_hi20(var)
+ addi.d $a0,$a0,%desc_pc_lo12(var)
+ ld.d $ra,$a0,%desc_ld(var)
+ jirl $ra,$ra,%desc_call(var)
+
+ pcalau12i $a0,%ie_pc_hi20(var)
+ ld.d $ra,$a0,%ie_pc_lo12(var)
diff --git a/ld/testsuite/ld-loongarch-elf/desc-le.d b/ld/testsuite/ld-loongarch-elf/desc-le.d
new file mode 100644
index 00000000..b4ca9f82
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-le.d
@@ -0,0 +1,15 @@
+#as:
+#ld: -z norelro -e 0x0
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+1200000e8 <fn1>:
+ 1200000e8: 14000004 lu12i.w \$a0, 0
+ 1200000ec: 03800084 ori \$a0, \$a0, 0x0
+ 1200000f0: 03400000 nop.*
+ 1200000f4: 03400000 nop.*
diff --git a/ld/testsuite/ld-loongarch-elf/desc-le.s b/ld/testsuite/ld-loongarch-elf/desc-le.s
new file mode 100644
index 00000000..9ffaa2d6
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-le.s
@@ -0,0 +1,14 @@
+ .global var
+ .section .tdata,"awT",@progbits
+var:
+ .word 1
+ .text
+ .global fn1
+ .type fn1,@function
+fn1:
+
+ # DESC will relax to LE.
+ pcalau12i $a0,%desc_pc_hi20(var)
+ addi.d $a0,$a0,%desc_pc_lo12(var)
+ ld.d $ra,$a0,%desc_ld(var)
+ jirl $ra,$ra,%desc_call(var)
diff --git a/ld/testsuite/ld-loongarch-elf/desc-norelax.d b/ld/testsuite/ld-loongarch-elf/desc-norelax.d
new file mode 100644
index 00000000..32ce3e5e
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-norelax.d
@@ -0,0 +1,16 @@
+#as:
+#ld: -z norelro -shared --section-start=.got=0x1ff000
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+1c0 <.*>:
+ 1c0: 1a003fe4 pcalau12i \$a0, 511
+ 1c4: 02c02084 addi.d \$a0, \$a0, 8
+ 1c8: 28c00081 ld.d \$ra, \$a0, 0
+ 1cc: 4c000021 jirl \$ra, \$ra, 0
+ 1d0: 0010888c add.d \$t0, \$a0, \$tp
diff --git a/ld/testsuite/ld-loongarch-elf/desc-norelax.s b/ld/testsuite/ld-loongarch-elf/desc-norelax.s
new file mode 100644
index 00000000..9aa7f552
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-norelax.s
@@ -0,0 +1,5 @@
+.L1:
+# The got address of the symbol exceeds the
+# range of pcaddi, do not relax.
+la.tls.desc $a0,var
+add.d $t0,$a0,$tp
diff --git a/ld/testsuite/ld-loongarch-elf/desc-relax.d b/ld/testsuite/ld-loongarch-elf/desc-relax.d
new file mode 100644
index 00000000..ce53d317
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-relax.d
@@ -0,0 +1,15 @@
+#as:
+#ld: -z norelro -shared
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+188 <.*>:
+ 188: 18020844 pcaddi \$a0, 4162
+ 18c: 28c00081 ld.d \$ra, \$a0, 0
+ 190: 4c000021 jirl \$ra, \$ra, 0
+ 194: 0010888c add.d \$t0, \$a0, \$tp
diff --git a/ld/testsuite/ld-loongarch-elf/desc-relax.s b/ld/testsuite/ld-loongarch-elf/desc-relax.s
new file mode 100644
index 00000000..4a993a5c
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-relax.s
@@ -0,0 +1,5 @@
+.L1:
+# A UND symbol but no more than the range of pcaddi,
+# do pcalau12i + addi => pcaddi
+la.tls.desc $a0,var
+add.d $t0,$a0,$tp
diff --git a/ld/testsuite/ld-loongarch-elf/ie-le.d b/ld/testsuite/ld-loongarch-elf/ie-le.d
new file mode 100644
index 00000000..42694d7f
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/ie-le.d
@@ -0,0 +1,13 @@
+#as:
+#ld: -z norelro -e 0x0
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+1200000e8 <fn1>:
+ 1200000e8: 14000004 lu12i.w \$a0, 0
+ 1200000ec: 03800084 ori \$a0, \$a0, 0x0
diff --git a/ld/testsuite/ld-loongarch-elf/ie-le.s b/ld/testsuite/ld-loongarch-elf/ie-le.s
new file mode 100644
index 00000000..795c7ce4
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/ie-le.s
@@ -0,0 +1,11 @@
+ .data
+ .section .tdata,"awT",@progbits
+var:
+ .word 1
+ .text
+ .global fn1
+ .type gn1,@function
+fn1:
+ # expect IE to relax LE.
+ pcalau12i $a0,%ie_pc_hi20(var)
+ ld.d $a0,$a0,%ie_pc_lo12(var)
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index b43a518a..2a5709a5 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -69,3 +69,12 @@ if [istarget "loongarch64-*-*"] {
] \
]
}
+
+if [istarget "loongarch64-*-*"] {
+ run_dump_test "desc-ie"
+ run_dump_test "desc-le"
+ run_dump_test "ie-le"
+ run_dump_test "tlsdesc-dso"
+ run_dump_test "desc-norelax"
+ run_dump_test "desc-relax"
+}
diff --git a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
new file mode 100644
index 00000000..667ad746
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
@@ -0,0 +1,56 @@
+#as:
+#ld: -shared -z norelro
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+418 <fun_gl1>:
+ 418: 180214c4 pcaddi \$a0, 4262
+ 41c: 1a000084 pcalau12i \$a0, 4
+ 420: 28db0084 ld.d \$a0, \$a0, 1728
+ 424: 180212a4 pcaddi \$a0, 4245
+ 428: 18021304 pcaddi \$a0, 4248
+ 42c: 28c00081 ld.d \$ra, \$a0, 0
+ 430: 4c000021 jirl \$ra, \$ra, 0
+ 434: 1a000084 pcalau12i \$a0, 4
+ 438: 28d9c084 ld.d \$a0, \$a0, 1648
+ 43c: 03400000 nop.*
+ 440: 03400000 nop.*
+ 444: 1a000084 pcalau12i \$a0, 4
+ 448: 28d9c084 ld.d \$a0, \$a0, 1648
+ 44c: 18021264 pcaddi \$a0, 4243
+ 450: 18021244 pcaddi \$a0, 4242
+ 454: 28c00081 ld.d \$ra, \$a0, 0
+ 458: 4c000021 jirl \$ra, \$ra, 0
+ 45c: 1a000084 pcalau12i \$a0, 4
+ 460: 28daa084 ld.d \$a0, \$a0, 1704
+
+0+464 <fun_lo>:
+ 464: 1a000084 pcalau12i \$a0, 4
+ 468: 28d86084 ld.d \$a0, \$a0, 1560
+ 46c: 18020ce4 pcaddi \$a0, 4199
+ 470: 18020e04 pcaddi \$a0, 4208
+ 474: 28c00081 ld.d \$ra, \$a0, 0
+ 478: 4c000021 jirl \$ra, \$ra, 0
+ 47c: 18020d24 pcaddi \$a0, 4201
+ 480: 1a000084 pcalau12i \$a0, 4
+ 484: 28d90084 ld.d \$a0, \$a0, 1600
+ 488: 03400000 nop.*
+ 48c: 03400000 nop.*
+ 490: 1a000084 pcalau12i \$a0, 4
+ 494: 28d90084 ld.d \$a0, \$a0, 1600
+ 498: 18020d84 pcaddi \$a0, 4204
+ 49c: 28c00081 ld.d \$ra, \$a0, 0
+ 4a0: 4c000021 jirl \$ra, \$ra, 0
+ 4a4: 18020d24 pcaddi \$a0, 4201
+ 4a8: 1a000084 pcalau12i \$a0, 4
+ 4ac: 28d96084 ld.d \$a0, \$a0, 1624
+
+0+4b0 <fun_external>:
+ 4b0: 18020d84 pcaddi \$a0, 4204
+ 4b4: 28c00081 ld.d \$ra, \$a0, 0
+ 4b8: 4c000021 jirl \$ra, \$ra, 0
diff --git a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.s b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.s
new file mode 100644
index 00000000..936bbcea
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.s
@@ -0,0 +1,65 @@
+ .data
+ .section .tdata,"awT",@progbits
+ .global gl1, gl2, gl3, gl4
+gl1: .dword 1
+gl2: .dword 2
+gl3: .dword 3
+gl4: .dword 4
+lo1: .dword 10
+lo2: .dword 20
+lo3: .dword 30
+lo4: .dword 40
+ .text
+# Access global symbol
+fun_gl1:
+ # GD + IE
+ # GD: pcaddi + addi.d => pcaddi
+ la.tls.gd $a0, gl1
+ la.tls.ie $a0, gl1
+
+ # GD + DESC
+ # GD: pcaddi + addi.d => pcaddi
+ la.tls.gd $a0, gl2
+ # DESC: pcaddi + addi.d => pcaddi
+ la.tls.desc $a0, gl2
+
+ # DESC + IE
+ # DESC -> IE
+ la.tls.desc $a0, gl3
+ la.tls.ie $a0, gl3
+
+ # GD + DESC + IE
+ # GD: pcaddi + addi.d => pcaddi
+ la.tls.gd $a0, gl4
+ # DESC: pcaddi + addi.d => pcaddi
+ la.tls.desc $a0, gl4
+ la.tls.ie $a0, gl4
+
+# Access local symbol
+fun_lo:
+ # IE + GD
+ la.tls.ie $a0, lo1
+ # GD: pcaddi + addi.d => pcaddi
+ la.tls.gd $a0, lo1
+
+ # DESC + GD
+ # DESC: pcaddi + addi.d => pcaddi
+ la.tls.desc $a0, lo2
+ # GD: pcaddi + addi.d => pcaddi
+ la.tls.gd $a0, lo2
+
+ # DESC + IE
+ # DESC: DESC -> IE
+ la.tls.desc $a0, lo3
+ la.tls.ie $a0, lo3
+
+ # DESC + GD + IE
+ # DESC: pcaddi + addi.d => pcaddi
+ la.tls.desc $a0, lo4
+ # GD: pcaddi + addi.d => pcaddi
+ la.tls.gd $a0, lo4
+ la.tls.ie $a0, lo4
+
+# Access external undef symbol
+fun_external:
+ la.tls.desc $a0, sH1
--
2.33.0

View File

@ -0,0 +1,325 @@
From c5c96dc807dbb67b601ff90fb9976dc123d5b7af Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Sun, 26 Nov 2023 14:25:26 +0800
Subject: [PATCH 027/123] LoongArch: Add tls transition support.
Transitions between DESC->IE/LE and IE->LE are supported now.
1. For DESC -> LE:
pcalau12i $a0,%desc_pc_hi20(var) => lu12i.w $a0,%le_hi20(var)
addi.d $a0,$a0,%desc_pc_lo12(var) => ori $a0,$a0,%le_lo12(var)
ld.d $a1,$a0,%desc_ld(var) => NOP
jirl $ra,$a1,%desc_call(var) => NOP
add.d $a0,$a0,$tp
2. For DESC -> IE:
pcalau12i $a0,%desc_pc_hi20(var) => pcalau12i $a0,%ie_pc_hi20(var)
addi.d $a0,$a0,%desc_pc_lo12(var) => ld.d $a0,$a0,%ie_pc_lo12(var)
ld.d $a1,$a0,%desc_ld(var) => NOP
jirl $ra,$a1,%desc_call(var) => NOP
add.d $a0,$a0,$tp
3. For IE -> LE:
pcalau12i $a0,%ie_pc_hi20(var) => lu12i.w $a0,%le_hi20(var)
ld.d $a0,$a0,%ie_pc_lo12(var) => ori $a0,$a0,%le_lo12(var)
add.d $a0,$a0,$tp
4. When a tls variable is accessed using both DESC and IE, DESC transitions
to IE and uses the same GOT entry as IE.
---
bfd/elfnn-loongarch.c | 216 ++++++++++++++++++++++++++++++++++++-
include/opcode/loongarch.h | 6 ++
2 files changed, 221 insertions(+), 1 deletion(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 31dde892..13fddd63 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -145,6 +145,16 @@ struct loongarch_elf_link_hash_table
#define elf_backend_rela_normal 1
#define elf_backend_default_execstack 0
+#define IS_LOONGARCH_TLS_DESC_RELOC(R_TYPE) \
+ ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20 \
+ || (R_TYPE) == R_LARCH_TLS_DESC_PC_LO12 \
+ || (R_TYPE) == R_LARCH_TLS_DESC_LD \
+ || (R_TYPE) == R_LARCH_TLS_DESC_CALL)
+
+#define IS_LOONGARCH_TLS_IE_RELOC(R_TYPE) \
+ ((R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \
+ || (R_TYPE) == R_LARCH_TLS_IE_PC_LO12)
+
/* Generate a PLT header. */
static bool
@@ -593,6 +603,10 @@ loongarch_elf_record_tls_and_got_reference (bfd *abfd,
char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx);
*new_tls_type |= tls_type;
+
+ /* If a symbol is accessed by both IE and DESC, relax DESC to IE. */
+ if ((*new_tls_type & GOT_TLS_IE) && (*new_tls_type & GOT_TLS_GDESC))
+ *new_tls_type &= ~ (GOT_TLS_GDESC);
if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
{
_bfd_error_handler (_("%pB: `%s' accessed both as normal and "
@@ -605,6 +619,104 @@ loongarch_elf_record_tls_and_got_reference (bfd *abfd,
return true;
}
+static unsigned int
+loongarch_reloc_got_type (unsigned int r_type)
+{
+ switch (r_type)
+ {
+ case R_LARCH_TLS_DESC_PC_HI20:
+ case R_LARCH_TLS_DESC_PC_LO12:
+ case R_LARCH_TLS_DESC_LD:
+ case R_LARCH_TLS_DESC_CALL:
+ return GOT_TLS_GDESC;
+
+ case R_LARCH_TLS_IE_PC_HI20:
+ case R_LARCH_TLS_IE_PC_LO12:
+ return GOT_TLS_IE;
+
+ default:
+ break;
+ }
+ return GOT_UNKNOWN;
+}
+
+/* Return true if tls type transition can be performed. */
+static bool
+loongarch_can_relax_tls (struct bfd_link_info *info, unsigned int r_type,
+ struct elf_link_hash_entry *h, bfd *input_bfd,
+ unsigned long r_symndx)
+{
+ char symbol_tls_type;
+ unsigned int reloc_got_type;
+
+ if (! (IS_LOONGARCH_TLS_DESC_RELOC (r_type)
+ || IS_LOONGARCH_TLS_IE_RELOC (r_type)))
+ return false;
+
+ symbol_tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
+ reloc_got_type = loongarch_reloc_got_type (r_type);
+
+ if (symbol_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
+ return true;
+
+ if (! bfd_link_executable (info))
+ return false;
+
+ if (h && h->root.type == bfd_link_hash_undefweak)
+ return false;
+
+ return true;
+}
+
+/* The type of relocation that can be transitioned. */
+static unsigned int
+loongarch_tls_transition_without_check (struct bfd_link_info *info,
+ unsigned int r_type,
+ struct elf_link_hash_entry *h)
+{
+ bool local_exec = bfd_link_executable (info)
+ && SYMBOL_REFERENCES_LOCAL (info, h);
+
+ switch (r_type)
+ {
+ case R_LARCH_TLS_DESC_PC_HI20:
+ return (local_exec
+ ? R_LARCH_TLS_LE_HI20
+ : R_LARCH_TLS_IE_PC_HI20);
+
+ case R_LARCH_TLS_DESC_PC_LO12:
+ return (local_exec
+ ? R_LARCH_TLS_LE_LO12
+ : R_LARCH_TLS_IE_PC_LO12);
+
+ case R_LARCH_TLS_DESC_LD:
+ case R_LARCH_TLS_DESC_CALL:
+ return R_LARCH_NONE;
+
+ case R_LARCH_TLS_IE_PC_HI20:
+ return local_exec ? R_LARCH_TLS_LE_HI20 : r_type;
+
+ case R_LARCH_TLS_IE_PC_LO12:
+ return local_exec ? R_LARCH_TLS_LE_LO12 : r_type;
+
+ default:
+ break;
+ }
+
+ return r_type;
+}
+
+static unsigned int
+loongarch_tls_transition (struct bfd_link_info *info, unsigned int r_type,
+ struct elf_link_hash_entry *h, bfd *input_bfd,
+ unsigned long r_symndx)
+{
+ if (! loongarch_can_relax_tls (info, r_type, h, input_bfd,r_symndx))
+ return r_type;
+
+ return loongarch_tls_transition_without_check (info, r_type, h);
+}
+
/* Look through the relocs for a section during the first phase, and
allocate space in the global offset table or procedure linkage
table. */
@@ -706,6 +818,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
int need_dynreloc = 0;
int only_need_pcrel = 0;
+ r_type = loongarch_tls_transition (info, r_type, h, abfd, r_symndx);
switch (r_type)
{
case R_LARCH_GOT_PC_HI20:
@@ -2403,6 +2516,96 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
relocation += 0x100000000; \
})
+/* Transition instruction sequence to relax instruction sequence. */
+static bool
+loongarch_tls_relax (bfd *abfd, asection *sec, Elf_Internal_Rela *rel,
+ int r_type, struct elf_link_hash_entry *h,
+ struct bfd_link_info *info)
+{
+ bool local_exec = bfd_link_executable (info)
+ && SYMBOL_REFERENCES_LOCAL (info, h);
+ bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
+ unsigned long insn;
+
+ switch (r_type)
+ {
+ case R_LARCH_TLS_DESC_PC_HI20:
+ if (local_exec)
+ /* DESC -> LE relaxation:
+ pcalalau12i $a0,%desc_pc_hi20(var) =>
+ lu12i.w $a0,%le_hi20(var)
+ */
+ bfd_put (32, abfd, LARCH_LU12I_W | LARCH_RD_A0,
+ contents + rel->r_offset);
+
+ /* DESC -> IE relaxation:
+ pcalalau12i $a0,%desc_pc_hi20(var) =>
+ pcalalau12i $a0,%ie_pc_hi20(var)
+ */
+ return true;
+
+ case R_LARCH_TLS_DESC_PC_LO12:
+ if (local_exec)
+ {
+ /* DESC -> LE relaxation:
+ addi.d $a0,$a0,%desc_pc_lo12(var) =>
+ ori $a0,$a0,le_lo12(var)
+ */
+ insn = LARCH_ORI | LARCH_RD_RJ_A0;
+ bfd_put (32, abfd, LARCH_ORI | LARCH_RD_RJ_A0,
+ contents + rel->r_offset);
+ }
+ else
+ {
+ /* DESC -> IE relaxation:
+ addi.d $a0,$a0,%desc_pc_lo12(var) =>
+ ld.d $a0,$a0,%%ie_pc_lo12
+ */
+ bfd_put (32, abfd, LARCH_LD_D | LARCH_RD_RJ_A0,
+ contents + rel->r_offset);
+ }
+ return true;
+
+ case R_LARCH_TLS_DESC_LD:
+ case R_LARCH_TLS_DESC_CALL:
+ /* DESC -> LE/IE relaxation:
+ ld.d $ra,$a0,%desc_ld(var) => NOP
+ jirl $ra,$ra,%desc_call(var) => NOP
+ */
+ bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset);
+ return true;
+
+ case R_LARCH_TLS_IE_PC_HI20:
+ if (local_exec)
+ {
+ /* IE -> LE relaxation:
+ pcalalau12i $rd,%ie_pc_hi20(var) =>
+ lu12i.w $rd,%le_hi20(var)
+ */
+ insn = bfd_getl32 (contents + rel->r_offset);
+ bfd_put (32, abfd, LARCH_LU12I_W | (insn & 0x1f),
+ contents + rel->r_offset);
+ }
+ return true;
+
+ case R_LARCH_TLS_IE_PC_LO12:
+ if (local_exec)
+ {
+ /* IE -> LE relaxation:
+ ld.d $rd,$rj,%%ie_pc_lo12 =>
+ ori $rd,$rj,le_lo12(var)
+ */
+ insn = bfd_getl32 (contents + rel->r_offset);
+ bfd_put (32, abfd, LARCH_ORI | (insn & 0x3ff),
+ contents + rel->r_offset);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+
static int
loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bfd *input_bfd, asection *input_section,
@@ -2426,7 +2629,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
relend = relocs + input_section->reloc_count;
for (rel = relocs; rel < relend; rel++)
{
- int r_type = ELFNN_R_TYPE (rel->r_info);
+ unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
bfd_vma pc = sec_addr (input_section) + rel->r_offset;
reloc_howto_type *howto = NULL;
@@ -2436,6 +2639,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
const char *name;
bfd_reloc_status_type r = bfd_reloc_ok;
bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local;
+ unsigned int relaxed_r_type;
bool resolved_local, resolved_dynly, resolved_to_const;
char tls_type;
bfd_vma relocation, off, ie_off, desc_off;
@@ -2567,6 +2771,16 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (!resolved_local || defined_local);
+ relaxed_r_type = loongarch_tls_transition (info, r_type, h, input_bfd, r_symndx);
+ if (relaxed_r_type != r_type)
+ {
+ howto = loongarch_elf_rtype_to_howto (input_bfd, relaxed_r_type);
+ BFD_ASSERT (howto != NULL);
+
+ if (loongarch_tls_relax (input_bfd, input_section, rel, r_type, h, info))
+ r_type = relaxed_r_type;
+ }
+
is_desc = false;
is_ie = false;
switch (r_type)
diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
index da936f79..32ff4d8a 100644
--- a/include/opcode/loongarch.h
+++ b/include/opcode/loongarch.h
@@ -42,6 +42,12 @@ extern "C"
((value) < (-(1 << ((bits) - 1) << align)) \
|| (value) > ((((1 << ((bits) - 1)) - 1) << align)))
+ #define LARCH_LU12I_W 0x14000000
+ #define LARCH_ORI 0x03800000
+ #define LARCH_LD_D 0x28c00000
+ #define LARCH_RD_A0 0x04
+ #define LARCH_RD_RJ_A0 0x084
+
typedef uint32_t insn_t;
struct loongarch_opcode
--
2.33.0

View File

@ -0,0 +1,68 @@
From f1cef8611e241100dc6da362d27382b7fd543143 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Wed, 6 Dec 2023 03:05:47 +0800
Subject: [PATCH 022/123] LoongArch: Allow la.got -> la.pcrel relaxation for
shared object
Even in shared objects, la.got -> la.pcrel relaxation can still be
performed for symbols with hidden visibility. For example, if a.c is:
extern int x;
int f() { return x++; }
and b.c is:
int x = 114514;
If compiling and linking with:
gcc -shared -fPIC -O2 -fvisibility=hidden a.c b.c
Then the la.got in a.o should be relaxed to la.pcrel, and the resulted f
should be like:
pcaddi $t0, x
ldptr.w $a0, $t0, 0
addi.w $t1, $a0, 1
stptr.w $t1, $t0, 0
ret
Remove bfd_link_executable from the condition of la.got -> la.pcrel
relaxation so this will really happen. The SYMBOL_REFERENCES_LOCAL
check is enough not to wrongly relax preemptable symbols (for e.g.
when -fvisibility=hidden is not used).
Note that on x86_64 this is also relaxed and the produced code is like:
lea x(%rip), %rdx
mov (%rdx), %rax
lea 1(%rax), %ecx
mov %ecx, (%rdx)
ret
Tested by running ld test suite, bootstrapping and regtesting GCC with
the patched ld, and building and testing Glibc with the patched ld. No
regression is observed.
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
bfd/elfnn-loongarch.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 20dd0640..6fd6a04d 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3986,8 +3986,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
else
continue;
- if (h && bfd_link_executable (info)
- && SYMBOL_REFERENCES_LOCAL (info, h))
+ if (h && SYMBOL_REFERENCES_LOCAL (info, h))
local_got = true;
symtype = h->type;
}
--
2.33.0

View File

@ -0,0 +1,43 @@
From 0f5ce25e8a67bb55de5de18e02c8c9afe2a31ec7 Mon Sep 17 00:00:00 2001
From: Alan Modra <amodra@gmail.com>
Date: Thu, 28 Dec 2023 22:12:17 +1030
Subject: [PATCH 036/123] LoongArch: Commas inside double quotes
This adds an extra feature: Commas inside double quotes are not an
arg delimiter, and thus can be part of the arg.
* loongarch-coder.c (loongarch_split_args_by_comma): Commas
inside quotes are not arg delimiters.
---
opcodes/loongarch-coder.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/opcodes/loongarch-coder.c b/opcodes/loongarch-coder.c
index b6835276..c5b09509 100644
--- a/opcodes/loongarch-coder.c
+++ b/opcodes/loongarch-coder.c
@@ -18,6 +18,7 @@
along with this program; see the file COPYING3. If not,
see <http://www.gnu.org/licenses/>. */
#include "sysdep.h"
+#include <stdbool.h>
#include "opcode/loongarch.h"
int
@@ -256,9 +257,12 @@ loongarch_split_args_by_comma (char *args, const char *arg_strs[])
if (*args)
{
+ bool inquote = false;
arg_strs[num++] = args;
for (; *args; args++)
- if (*args == ',')
+ if (*args == '"')
+ inquote = !inquote;
+ else if (*args == ',' && !inquote)
{
if (MAX_ARG_NUM_PLUS_2 - 1 == num)
goto out;
--
2.33.0

View File

@ -0,0 +1,25 @@
From 4744da32d9f3c4fb37f4ddf4019a514bbbbd5220 Mon Sep 17 00:00:00 2001
From: caiyinyu <caiyinyu@loongson.cn>
Date: Tue, 17 Oct 2023 20:58:40 +0800
Subject: [PATCH 015/123] LoongArch: Correct comments.
---
bfd/elfnn-loongarch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 7dbe31eb..09c98713 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -2325,7 +2325,7 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
addi.d $t0, $zero, lo12 (0x812)
$t0 = 0xfffffffffffff812 (if lo12 > 0x7ff, because sign-extend,
lo20 need to sub 0x1)
- lu32i.d $t0, lo12 (0x71234)
+ lu32i.d $t0, lo20 (0x71234)
$t0 = {0x71234, 0xfffff812}
= 0x71234fffff812
lu52i.d $t0, hi12 (0x0)
--
2.33.0

View File

@ -0,0 +1,652 @@
From 2bd49b44dfe938623456d4abfef7f0c5f5b3b81f Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Wed, 24 Jan 2024 17:43:20 +0800
Subject: [PATCH 069/123] LoongArch: Delete extra instructions when TLS type
transition
This modification mainly changes the timing of type transition,
adds relaxation to the old LE instruction sequence, and fixes
bugs in extreme code models.
We strictly distinguish between type transition and relaxation.
Type transition is from one type to another, while relaxation
is the removal of instructions under the same TLS type. Detailed
instructions are as follows:
1. For type transition, only the normal code model of DESC/IE
does type transition, and each relocation is accompanied by a
RELAX relocation. Neither abs nor extreme will do type transition,
and no RELAX relocation will be generated.
The extra instructions when DESC transitions to other TLS types
will be deleted during the type transition.
2. Implemented relaxation for the old LE instruction sequence.
The first two instructions of LE's 32-bit and 64-bit models
use the same relocations and cannot be distinguished based on
relocations. Therefore, for LE's instruction sequence, any code
model will try to relax.
3. Some function names have been adjusted to facilitate understanding,
parameters have been adjusted, and unused macros have been deleted.
---
bfd/elfnn-loongarch.c | 420 +++++++++++++++++++++++---------------
gas/config/tc-loongarch.c | 31 ++-
2 files changed, 279 insertions(+), 172 deletions(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 1693ad7e..eea1839f 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -145,16 +145,20 @@ struct loongarch_elf_link_hash_table
#define elf_backend_rela_normal 1
#define elf_backend_default_execstack 0
-#define IS_LOONGARCH_TLS_DESC_RELOC(R_TYPE) \
- ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20 \
- || (R_TYPE) == R_LARCH_TLS_DESC_PC_LO12 \
- || (R_TYPE) == R_LARCH_TLS_DESC_LD \
- || (R_TYPE) == R_LARCH_TLS_DESC_CALL)
-
-#define IS_LOONGARCH_TLS_IE_RELOC(R_TYPE) \
- ((R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \
+#define IS_LOONGARCH_TLS_TRANS_RELOC(R_TYPE) \
+ ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20 \
+ || (R_TYPE) == R_LARCH_TLS_DESC_PC_LO12 \
+ || (R_TYPE) == R_LARCH_TLS_DESC_LD \
+ || (R_TYPE) == R_LARCH_TLS_DESC_CALL \
+ || (R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \
|| (R_TYPE) == R_LARCH_TLS_IE_PC_LO12)
+#define IS_OUTDATED_TLS_LE_RELOC(R_TYPE) \
+ ((R_TYPE) == R_LARCH_TLS_LE_HI20 \
+ || (R_TYPE) == R_LARCH_TLS_LE_LO12 \
+ || (R_TYPE) == R_LARCH_TLS_LE64_LO20 \
+ || (R_TYPE) == R_LARCH_TLS_LE64_HI12)
+
/* Generate a PLT header. */
static bool
@@ -642,15 +646,18 @@ loongarch_reloc_got_type (unsigned int r_type)
/* Return true if tls type transition can be performed. */
static bool
-loongarch_can_relax_tls (struct bfd_link_info *info, unsigned int r_type,
- struct elf_link_hash_entry *h, bfd *input_bfd,
- unsigned long r_symndx)
+loongarch_can_trans_tls (bfd *input_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ unsigned int r_symndx,
+ unsigned int r_type)
{
char symbol_tls_type;
unsigned int reloc_got_type;
- if (! (IS_LOONGARCH_TLS_DESC_RELOC (r_type)
- || IS_LOONGARCH_TLS_IE_RELOC (r_type)))
+ /* Only TLS DESC/IE in normal code mode will perform type
+ transition. */
+ if (! IS_LOONGARCH_TLS_TRANS_RELOC (r_type))
return false;
symbol_tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
@@ -707,11 +714,13 @@ loongarch_tls_transition_without_check (struct bfd_link_info *info,
}
static unsigned int
-loongarch_tls_transition (struct bfd_link_info *info, unsigned int r_type,
- struct elf_link_hash_entry *h, bfd *input_bfd,
- unsigned long r_symndx)
+loongarch_tls_transition (bfd *input_bfd,
+ struct bfd_link_info *info,
+ struct elf_link_hash_entry *h,
+ unsigned int r_symndx,
+ unsigned int r_type)
{
- if (! loongarch_can_relax_tls (info, r_type, h, input_bfd,r_symndx))
+ if (! loongarch_can_trans_tls (input_bfd, info, h, r_symndx, r_type))
return r_type;
return loongarch_tls_transition_without_check (info, r_type, h);
@@ -818,7 +827,11 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
int need_dynreloc = 0;
int only_need_pcrel = 0;
- r_type = loongarch_tls_transition (info, r_type, h, abfd, r_symndx);
+ /* Type transitions are only possible with relocations accompanied
+ by R_LARCH_RELAX. */
+ if (rel + 1 != relocs + sec->reloc_count
+ && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX)
+ r_type = loongarch_tls_transition (abfd, info, h, r_symndx, r_type);
switch (r_type)
{
case R_LARCH_GOT_PC_HI20:
@@ -2536,95 +2549,6 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
relocation += 0x100000000; \
})
-/* Transition instruction sequence to relax instruction sequence. */
-static bool
-loongarch_tls_relax (bfd *abfd, asection *sec, Elf_Internal_Rela *rel,
- int r_type, struct elf_link_hash_entry *h,
- struct bfd_link_info *info)
-{
- bool local_exec = bfd_link_executable (info)
- && SYMBOL_REFERENCES_LOCAL (info, h);
- bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
- unsigned long insn;
-
- switch (r_type)
- {
- case R_LARCH_TLS_DESC_PC_HI20:
- if (local_exec)
- /* DESC -> LE relaxation:
- pcalalau12i $a0,%desc_pc_hi20(var) =>
- lu12i.w $a0,%le_hi20(var)
- */
- bfd_put (32, abfd, LARCH_LU12I_W | LARCH_RD_A0,
- contents + rel->r_offset);
-
- /* DESC -> IE relaxation:
- pcalalau12i $a0,%desc_pc_hi20(var) =>
- pcalalau12i $a0,%ie_pc_hi20(var)
- */
- return true;
-
- case R_LARCH_TLS_DESC_PC_LO12:
- if (local_exec)
- {
- /* DESC -> LE relaxation:
- addi.d $a0,$a0,%desc_pc_lo12(var) =>
- ori $a0,$a0,le_lo12(var)
- */
- insn = LARCH_ORI | LARCH_RD_RJ_A0;
- bfd_put (32, abfd, LARCH_ORI | LARCH_RD_RJ_A0,
- contents + rel->r_offset);
- }
- else
- {
- /* DESC -> IE relaxation:
- addi.d $a0,$a0,%desc_pc_lo12(var) =>
- ld.d $a0,$a0,%%ie_pc_lo12
- */
- bfd_put (32, abfd, LARCH_LD_D | LARCH_RD_RJ_A0,
- contents + rel->r_offset);
- }
- return true;
-
- case R_LARCH_TLS_DESC_LD:
- case R_LARCH_TLS_DESC_CALL:
- /* DESC -> LE/IE relaxation:
- ld.d $ra,$a0,%desc_ld(var) => NOP
- jirl $ra,$ra,%desc_call(var) => NOP
- */
- bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset);
- return true;
-
- case R_LARCH_TLS_IE_PC_HI20:
- if (local_exec)
- {
- /* IE -> LE relaxation:
- pcalalau12i $rd,%ie_pc_hi20(var) =>
- lu12i.w $rd,%le_hi20(var)
- */
- insn = bfd_getl32 (contents + rel->r_offset);
- bfd_put (32, abfd, LARCH_LU12I_W | (insn & 0x1f),
- contents + rel->r_offset);
- }
- return true;
-
- case R_LARCH_TLS_IE_PC_LO12:
- if (local_exec)
- {
- /* IE -> LE relaxation:
- ld.d $rd,$rj,%%ie_pc_lo12 =>
- ori $rd,$rj,le_lo12(var)
- */
- insn = bfd_getl32 (contents + rel->r_offset);
- bfd_put (32, abfd, LARCH_ORI | (insn & 0x3ff),
- contents + rel->r_offset);
- }
- return true;
- }
-
- return false;
-}
-
static int
loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
@@ -2659,7 +2583,6 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
const char *name;
bfd_reloc_status_type r = bfd_reloc_ok;
bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local;
- unsigned int relaxed_r_type;
bool resolved_local, resolved_dynly, resolved_to_const;
char tls_type;
bfd_vma relocation, off, ie_off, desc_off;
@@ -2791,16 +2714,6 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (!resolved_local || defined_local);
- relaxed_r_type = loongarch_tls_transition (info, r_type, h, input_bfd, r_symndx);
- if (relaxed_r_type != r_type)
- {
- howto = loongarch_elf_rtype_to_howto (input_bfd, relaxed_r_type);
- BFD_ASSERT (howto != NULL);
-
- if (loongarch_tls_relax (input_bfd, input_section, rel, r_type, h, info))
- r_type = relaxed_r_type;
- }
-
is_desc = false;
is_ie = false;
switch (r_type)
@@ -4112,6 +4025,116 @@ loongarch_relax_delete_bytes (bfd *abfd,
return true;
}
+
+/* Start perform TLS type transition.
+ Currently there are three cases of relocation handled here:
+ DESC -> IE, DEC -> LE and IE -> LE. */
+static bool
+loongarch_tls_perform_trans (bfd *abfd, asection *sec,
+ Elf_Internal_Rela *rel,
+ struct elf_link_hash_entry *h,
+ struct bfd_link_info *info)
+{
+ unsigned long insn;
+ bool local_exec = bfd_link_executable (info)
+ && SYMBOL_REFERENCES_LOCAL (info, h);
+ bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
+ unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
+ unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
+
+ switch (r_type)
+ {
+ case R_LARCH_TLS_DESC_PC_HI20:
+ if (local_exec)
+ {
+ /* DESC -> LE relaxation:
+ pcalalau12i $a0,%desc_pc_hi20(var) =>
+ lu12i.w $a0,%le_hi20(var)
+ */
+ bfd_put (32, abfd, LARCH_LU12I_W | LARCH_RD_A0,
+ contents + rel->r_offset);
+ rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_HI20);
+ }
+ else
+ {
+ /* DESC -> IE relaxation:
+ pcalalau12i $a0,%desc_pc_hi20(var) =>
+ pcalalau12i $a0,%ie_pc_hi20(var)
+ */
+ rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_IE_PC_HI20);
+ }
+ return true;
+
+ case R_LARCH_TLS_DESC_PC_LO12:
+ if (local_exec)
+ {
+ /* DESC -> LE relaxation:
+ addi.d $a0,$a0,%desc_pc_lo12(var) =>
+ ori $a0,$a0,le_lo12(var)
+ */
+ insn = LARCH_ORI | LARCH_RD_RJ_A0;
+ bfd_put (32, abfd, LARCH_ORI | LARCH_RD_RJ_A0,
+ contents + rel->r_offset);
+ rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_LO12);
+ }
+ else
+ {
+ /* DESC -> IE relaxation:
+ addi.d $a0,$a0,%desc_pc_lo12(var) =>
+ ld.d $a0,$a0,%ie_pc_lo12(var)
+ */
+ bfd_put (32, abfd, LARCH_LD_D | LARCH_RD_RJ_A0,
+ contents + rel->r_offset);
+ rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_IE_PC_LO12);
+ }
+ return true;
+
+ case R_LARCH_TLS_DESC_LD:
+ case R_LARCH_TLS_DESC_CALL:
+ /* DESC -> LE/IE relaxation:
+ ld.d $ra,$a0,%desc_ld(var) => NOP
+ jirl $ra,$ra,%desc_call(var) => NOP
+ */
+ rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
+ bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset);
+ /* link with -relax option will delete NOP. */
+ if (!info->disable_target_specific_optimizations)
+ loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, info);
+ return true;
+
+ case R_LARCH_TLS_IE_PC_HI20:
+ if (local_exec)
+ {
+ /* IE -> LE relaxation:
+ pcalalau12i $rd,%ie_pc_hi20(var) =>
+ lu12i.w $rd,%le_hi20(var)
+ */
+ insn = bfd_getl32 (contents + rel->r_offset);
+ bfd_put (32, abfd, LARCH_LU12I_W | (insn & 0x1f),
+ contents + rel->r_offset);
+ rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_HI20);
+ }
+ return true;
+
+ case R_LARCH_TLS_IE_PC_LO12:
+ if (local_exec)
+ {
+ /* IE -> LE relaxation:
+ ld.d $rd,$rj,%%ie_pc_lo12(var) =>
+ ori $rd,$rj,le_lo12(var)
+ */
+ insn = bfd_getl32 (contents + rel->r_offset);
+ bfd_put (32, abfd, LARCH_ORI | (insn & 0x3ff),
+ contents + rel->r_offset);
+ rel->r_info = ELFNN_R_INFO (r_symndx, R_LARCH_TLS_LE_LO12);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+
/* Relax tls le, mainly relax the process of getting TLS le symbolic addresses.
there are three situations in which an assembly instruction sequence needs to
be relaxed:
@@ -4148,6 +4171,21 @@ loongarch_relax_delete_bytes (bfd *abfd,
lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
addi.{w/d} $rs,$rd,%le_lo12_r (sym) ==> addi.{w/d} $rs,$tp,%le_lo12_r (sym)
+
+
+ For relocation of all old LE instruction sequences, whether it is
+ a normal code model or an extreme code model, relaxation will be
+ performed when the relaxation conditions are met.
+
+ nomal code model:
+ lu12i.w $rd,%le_hi20(sym) => (deleted)
+ ori $rd,$rd,le_lo12(sym) => ori $rd,$zero,le_lo12(sym)
+
+ extreme code model:
+ lu12i.w $rd,%le_hi20(sym) => (deleted)
+ ori $rd,$rd,%le_lo12(sym) => ori $rd,$zero,le_lo12(sym)
+ lu32i.d $rd,%le64_lo20(sym) => (deleted)
+ lu52i.d $rd,$rd,%le64_hi12(sym) => (deleted)
*/
static bool
loongarch_relax_tls_le (bfd *abfd, asection *sec,
@@ -4159,31 +4197,56 @@ loongarch_relax_tls_le (bfd *abfd, asection *sec,
uint32_t insn = bfd_get (32, abfd, contents + rel->r_offset);
static uint32_t insn_rj,insn_rd;
symval = symval - elf_hash_table (link_info)->tls_sec->vma;
- /* Whether the symbol offset is in the interval (offset < 0x800). */
- if (ELFNN_R_TYPE ((rel + 1)->r_info) == R_LARCH_RELAX && (symval < 0x800))
+ /* The old LE instruction sequence can be relaxed when the symbol offset
+ is smaller than the 12-bit range. */
+ if (ELFNN_R_TYPE ((rel + 1)->r_info) == R_LARCH_RELAX && (symval <= 0xfff))
{
switch (ELFNN_R_TYPE (rel->r_info))
{
- case R_LARCH_TLS_LE_HI20_R:
- case R_LARCH_TLS_LE_ADD_R:
- /* delete insn. */
- rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
- loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, link_info);
- break;
- case R_LARCH_TLS_LE_LO12_R:
- /* Change rj to $tp. */
- insn_rj = 0x2 << 5;
- /* Get rd register. */
- insn_rd = insn & 0x1f;
- /* Write symbol offset. */
- symval <<= 10;
- /* Writes the modified instruction. */
- insn = insn & 0xffc00000;
- insn = insn | symval | insn_rj | insn_rd;
- bfd_put (32, abfd, insn, contents + rel->r_offset);
- break;
- default:
- break;
+ /*if offset < 0x800, then perform the new le instruction
+ sequence relax. */
+ case R_LARCH_TLS_LE_HI20_R:
+ case R_LARCH_TLS_LE_ADD_R:
+ /* delete insn. */
+ if (symval < 0x800)
+ {
+ rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
+ loongarch_relax_delete_bytes (abfd, sec, rel->r_offset,
+ 4, link_info);
+ }
+ break;
+
+ case R_LARCH_TLS_LE_LO12_R:
+ if (symval < 0x800)
+ {
+ /* Change rj to $tp. */
+ insn_rj = 0x2 << 5;
+ /* Get rd register. */
+ insn_rd = insn & 0x1f;
+ /* Write symbol offset. */
+ symval <<= 10;
+ /* Writes the modified instruction. */
+ insn = insn & 0xffc00000;
+ insn = insn | symval | insn_rj | insn_rd;
+ bfd_put (32, abfd, insn, contents + rel->r_offset);
+ }
+ break;
+
+ case R_LARCH_TLS_LE_HI20:
+ case R_LARCH_TLS_LE64_LO20:
+ case R_LARCH_TLS_LE64_HI12:
+ rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
+ loongarch_relax_delete_bytes (abfd, sec, rel->r_offset,
+ 4, link_info);
+ break;
+
+ case R_LARCH_TLS_LE_LO12:
+ bfd_put (32, abfd, LARCH_ORI | (insn & 0x1f),
+ contents + rel->r_offset);
+ break;
+
+ default:
+ break;
}
}
return true;
@@ -4534,7 +4597,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
R_LARCH_CALL36: symval is the symbol address for local symbols,
or the PLT entry address of the symbol. (Todo)
R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address
- of the symbol. */
+ of the symbol if transition is not possible. */
if (r_symndx < symtab_hdr->sh_info)
{
Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
@@ -4542,22 +4605,24 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
continue;
+ /* Only TLS instruction sequences that are accompanied by
+ R_LARCH_RELAX and cannot perform type transition can be
+ relaxed. */
if (R_LARCH_TLS_LD_PC_HI20 == r_type
|| R_LARCH_TLS_GD_PC_HI20 == r_type
- || R_LARCH_TLS_DESC_PC_HI20 == r_type)
+ || (R_LARCH_TLS_DESC_PC_HI20 == r_type
+ && (i + 1 != sec->reloc_count)
+ && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX
+ && ! loongarch_can_trans_tls (abfd, info, h,
+ r_symndx, r_type)))
{
- if (loongarch_can_relax_tls (info, r_type, h, abfd, r_symndx))
- continue;
- else
- {
- sym_sec = htab->elf.sgot;
- symval = elf_local_got_offsets (abfd)[r_symndx];
- char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
- r_symndx);
- if (R_LARCH_TLS_DESC_PC_HI20 == r_type
- && GOT_TLS_GD_BOTH_P (tls_type))
- symval += 2 * GOT_ENTRY_SIZE;
- }
+ sym_sec = htab->elf.sgot;
+ symval = elf_local_got_offsets (abfd)[r_symndx];
+ char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
+ r_symndx);
+ if (R_LARCH_TLS_DESC_PC_HI20 == r_type
+ && GOT_TLS_GD_BOTH_P (tls_type))
+ symval += 2 * GOT_ENTRY_SIZE;
}
else if (sym->st_shndx == SHN_UNDEF || R_LARCH_ALIGN == r_type)
{
@@ -4588,20 +4653,19 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
shared object. */
if (R_LARCH_TLS_LD_PC_HI20 == r_type
|| R_LARCH_TLS_GD_PC_HI20 == r_type
- || R_LARCH_TLS_DESC_PC_HI20 == r_type)
+ || (R_LARCH_TLS_DESC_PC_HI20 == r_type
+ && (i + 1 != sec->reloc_count)
+ && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX
+ && !loongarch_can_trans_tls (abfd, info, h,
+ r_symndx, r_type)))
{
- if (loongarch_can_relax_tls (info, r_type, h, abfd, r_symndx))
- continue;
- else
- {
- sym_sec = htab->elf.sgot;
- symval = h->got.offset;
- char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
- r_symndx);
- if (R_LARCH_TLS_DESC_PC_HI20 == r_type
- && GOT_TLS_GD_BOTH_P (tls_type))
- symval += 2 * GOT_ENTRY_SIZE;
- }
+ sym_sec = htab->elf.sgot;
+ symval = h->got.offset;
+ char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
+ r_symndx);
+ if (R_LARCH_TLS_DESC_PC_HI20 == r_type
+ && GOT_TLS_GD_BOTH_P (tls_type))
+ symval += 2 * GOT_ENTRY_SIZE;
}
else if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
@@ -4646,6 +4710,24 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
symval += sec_addr (sym_sec);
+ /* If the conditions for tls type transition are met, type
+ transition is performed instead of relax.
+ During the transition from DESC->IE/LE, there are 2 situations
+ depending on the different configurations of the relax/norelax
+ option.
+ If the -relax option is used, the extra nops will be removed,
+ and this transition is performed in pass 0.
+ If the --no-relax option is used, nop will be retained, and
+ this transition is performed in pass 1. */
+ if (IS_LOONGARCH_TLS_TRANS_RELOC (r_type)
+ && (i + 1 != sec->reloc_count)
+ && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX
+ && loongarch_can_trans_tls (abfd, info, h, r_symndx, r_type))
+ {
+ loongarch_tls_perform_trans (abfd, sec, rel, h, info);
+ r_type = ELFNN_R_TYPE (rel->r_info);
+ }
+
switch (r_type)
{
case R_LARCH_ALIGN:
@@ -4664,6 +4746,10 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
case R_LARCH_TLS_LE_HI20_R:
case R_LARCH_TLS_LE_LO12_R:
case R_LARCH_TLS_LE_ADD_R:
+ case R_LARCH_TLS_LE_HI20:
+ case R_LARCH_TLS_LE_LO12:
+ case R_LARCH_TLS_LE64_LO20:
+ case R_LARCH_TLS_LE64_HI12:
if (0 == info->relax_pass && (i + 2) <= sec->reloc_count)
loongarch_relax_tls_le (abfd, sec, rel, info, symval);
break;
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index e6da4e1e..b510d228 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -716,7 +716,11 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
if (LARCH_opts.relax
&& (BFD_RELOC_LARCH_TLS_LE_HI20_R == reloc_type
- || BFD_RELOC_LARCH_TLS_LE_LO12_R == reloc_type))
+ || BFD_RELOC_LARCH_TLS_LE_LO12_R == reloc_type
+ || BFD_RELOC_LARCH_TLS_LE_HI20 == reloc_type
+ || BFD_RELOC_LARCH_TLS_LE_LO12 == reloc_type
+ || BFD_RELOC_LARCH_TLS_LE64_LO20 == reloc_type
+ || BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_type))
{
ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
ip->reloc_info[ip->reloc_num].value = const_0;
@@ -724,8 +728,12 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
}
/* Only one register macros (used in normal code model)
- emit R_LARCH_RELAX. */
+ emit R_LARCH_RELAX.
+ LARCH_opts.ase_labs and LARCH_opts.ase_gabs are used
+ to generate the code model of absolute addresses, and
+ we do not relax this code model. */
if (LARCH_opts.relax && (ip->expand_from_macro & 1)
+ && !(LARCH_opts.ase_labs | LARCH_opts.ase_gabs)
&& (BFD_RELOC_LARCH_PCALA_HI20 == reloc_type
|| BFD_RELOC_LARCH_PCALA_LO12 == reloc_type
|| BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_type
@@ -733,7 +741,11 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
|| BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_type
|| BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_type
|| BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_type
- || BFD_RELOC_LARCH_TLS_DESC_PC_LO12 == reloc_type))
+ || BFD_RELOC_LARCH_TLS_DESC_PC_LO12 == reloc_type
+ || BFD_RELOC_LARCH_TLS_DESC_LD == reloc_type
+ || BFD_RELOC_LARCH_TLS_DESC_CALL == reloc_type
+ || BFD_RELOC_LARCH_TLS_IE_PC_HI20 == reloc_type
+ || BFD_RELOC_LARCH_TLS_IE_PC_LO12 == reloc_type))
{
ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
ip->reloc_info[ip->reloc_num].value = const_0;
@@ -1080,7 +1092,11 @@ append_fixp_and_insn (struct loongarch_cl_insn *ip)
if (symbol_get_frag (to) == symbol_get_frag (from)))
For macro instructions, only the first instruction expanded from macro
- need to start a new frag. */
+ need to start a new frag.
+ Since the relocations of the normal code model and the extreme code model
+ of the old LE instruction sequence are the same, it is impossible to
+ distinguish which code model it is based on relocation alone, so the
+ extreme code model has to be relaxed. */
if (LARCH_opts.relax
&& (BFD_RELOC_LARCH_PCALA_HI20 == reloc_info[0].type
|| BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_info[0].type
@@ -1088,7 +1104,12 @@ append_fixp_and_insn (struct loongarch_cl_insn *ip)
|| BFD_RELOC_LARCH_TLS_LE_ADD_R == reloc_info[0].type
|| BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_info[0].type
|| BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_info[0].type
- || BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_info[0].type))
+ || BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_info[0].type
+ || BFD_RELOC_LARCH_TLS_IE_PC_HI20 == reloc_info[0].type
+ || BFD_RELOC_LARCH_TLS_LE_HI20 == reloc_info[0].type
+ || BFD_RELOC_LARCH_TLS_LE_LO12 == reloc_info[0].type
+ || BFD_RELOC_LARCH_TLS_LE64_LO20 == reloc_info[0].type
+ || BFD_RELOC_LARCH_TLS_LE64_HI12 == reloc_info[0].type))
{
frag_wane (frag_now);
frag_new (0);
--
2.33.0

View File

@ -0,0 +1,87 @@
From 9bdf2be420d4477838bfb11d9cd4c2d6ad257119 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Thu, 30 May 2024 19:52:34 +0800
Subject: [PATCH 090/123] LoongArch: Disable linker relaxation if set the
address of section or segment
If set the address of section or segment, the offset from pc to symbol
may become bigger and cause overflow.
---
ld/emultempl/loongarchelf.em | 16 ++++++++++++++++
ld/testsuite/ld-loongarch-elf/relax-ttext.s | 13 +++++++++++++
ld/testsuite/ld-loongarch-elf/relax.exp | 12 ++++++++++++
3 files changed, 41 insertions(+)
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-ttext.s
diff --git a/ld/emultempl/loongarchelf.em b/ld/emultempl/loongarchelf.em
index 99749894..13f8dacb 100644
--- a/ld/emultempl/loongarchelf.em
+++ b/ld/emultempl/loongarchelf.em
@@ -25,6 +25,22 @@ fragment <<EOF
#include "elf/loongarch.h"
#include "elfxx-loongarch.h"
+EOF
+
+# Disable linker relaxation if set address of section or segment.
+PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
+ case OPTION_SECTION_START:
+ case OPTION_TTEXT:
+ case OPTION_TBSS:
+ case OPTION_TDATA:
+ case OPTION_TTEXT_SEGMENT:
+ case OPTION_TRODATA_SEGMENT:
+ case OPTION_TLDATA_SEGMENT:
+ link_info.disable_target_specific_optimizations = 2;
+ return false;
+'
+
+fragment <<EOF
static void
larch_elf_before_allocation (void)
{
diff --git a/ld/testsuite/ld-loongarch-elf/relax-ttext.s b/ld/testsuite/ld-loongarch-elf/relax-ttext.s
new file mode 100644
index 00000000..1bbd85a0
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-ttext.s
@@ -0,0 +1,13 @@
+# At relax pass 0, offset is 0x120204000-0x12000bff8=0x1f8008 < 0x200000
+# At relax pass 1, delete 0x7ff8 bytes NOP,
+# offset is 0x120204000-0x120004000=0x200000 >= 0x200000, overflow
+.text
+.align 14 # delete at relax pass 1
+.fill 0x4000
+.align 14 # delete at relax pass 1
+la.local $t2, a # relax to pcaddi at relax pass 0
+
+.section ".text1", "ax"
+ .fill 0x4000
+a: # 0x120204000
+ ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index 05c4ed0a..05b268f4 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -51,6 +51,18 @@ if [istarget loongarch64-*-*] {
run_dump_test "relax-align-ignore-start"
run_partial_linking_align_test
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch relax ttext" \
+ "" "" \
+ "" \
+ {relax-ttext.s} \
+ {} \
+ "relax-ttext" \
+ ] \
+ ]
+
set testname "loongarch relax .exe build"
set pre_builds [list \
[list \
--
2.33.0

View File

@ -0,0 +1,131 @@
From c65840dfbeb0e2b292439b3627a0a29436649845 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Wed, 3 Jan 2024 19:57:10 +0800
Subject: [PATCH 041/123] LoongArch: Discard extra spaces in objdump output
Due to the formatted output of objdump, some instructions
that do not require output operands (such as nop/ret) will
have extra spaces added after them.
Determine whether to output operands through the format
of opcodes. When opc->format is an empty string, no extra
spaces are output.
---
gas/testsuite/gas/loongarch/64_pcrel.d | 2 +-
.../gas/loongarch/deprecated_reg_aliases.d | 2 +-
gas/testsuite/gas/loongarch/jmp_op.d | 4 ++--
gas/testsuite/gas/loongarch/nop.d | 2 +-
gas/testsuite/gas/loongarch/privilege_op.d | 14 +++++++-------
gas/testsuite/gas/loongarch/reloc.d | 2 +-
opcodes/loongarch-dis.c | 7 ++++++-
7 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/gas/testsuite/gas/loongarch/64_pcrel.d b/gas/testsuite/gas/loongarch/64_pcrel.d
index 66b80a39..642e3079 100644
--- a/gas/testsuite/gas/loongarch/64_pcrel.d
+++ b/gas/testsuite/gas/loongarch/64_pcrel.d
@@ -7,5 +7,5 @@
Disassembly of section .text:
00000000.* <.text>:
-[ ]+0:[ ]+03400000[ ]+nop[ ]+
+[ ]+0:[ ]+03400000[ ]+nop
[ ]+0:[ ]+R_LARCH_64_PCREL[ ]+\*ABS\*
diff --git a/gas/testsuite/gas/loongarch/deprecated_reg_aliases.d b/gas/testsuite/gas/loongarch/deprecated_reg_aliases.d
index 3ea08067..01e593fb 100644
--- a/gas/testsuite/gas/loongarch/deprecated_reg_aliases.d
+++ b/gas/testsuite/gas/loongarch/deprecated_reg_aliases.d
@@ -15,4 +15,4 @@ Disassembly of section .text:
[ ]+8:[ ]+16024685[ ]+lu32i\.d[ ]+\$a1, 4660
[ ]+c:[ ]+08200420[ ]+fmadd\.d[ ]+\$fa0, \$fa1, \$fa1, \$fa0
[ ]+10:[ ]+380c16a4[ ]+ldx\.d[ ]+\$a0, \$r21, \$a1
-[ ]+14:[ ]+4c000020[ ]+ret[ ]+
+[ ]+14:[ ]+4c000020[ ]+ret
diff --git a/gas/testsuite/gas/loongarch/jmp_op.d b/gas/testsuite/gas/loongarch/jmp_op.d
index cc544f11..21576072 100644
--- a/gas/testsuite/gas/loongarch/jmp_op.d
+++ b/gas/testsuite/gas/loongarch/jmp_op.d
@@ -7,7 +7,7 @@
Disassembly of section .text:
00000000.* <.L1>:
-[ ]+0:[ ]+03400000[ ]+nop[ ]+
+[ ]+0:[ ]+03400000[ ]+nop
[ ]+4:[ ]+63fffc04[ ]+bgtz[ ]+\$a0,[ ]+-4[ ]+#[ ]+0[ ]+<\.L1>
[ ]+4:[ ]+R_LARCH_B16[ ]+\.L1
[ ]+8:[ ]+67fff880[ ]+bgez[ ]+\$a0,[ ]+-8[ ]+#[ ]+0[ ]+<\.L1>
@@ -47,4 +47,4 @@ Disassembly of section .text:
[ ]+4c:[ ]+R_LARCH_B16[ ]+\.L1
[ ]+50:[ ]+6fffb0a4[ ]+bgeu[ ]+\$a1,[ ]+\$a0,[ ]+-80[ ]+#[ ]+0[ ]+<\.L1>
[ ]+50:[ ]+R_LARCH_B16[ ]+\.L1
-[ ]+54:[ ]+4c000020[ ]+ret[ ]+
+[ ]+54:[ ]+4c000020[ ]+ret
diff --git a/gas/testsuite/gas/loongarch/nop.d b/gas/testsuite/gas/loongarch/nop.d
index 222456e8..ca8c5630 100644
--- a/gas/testsuite/gas/loongarch/nop.d
+++ b/gas/testsuite/gas/loongarch/nop.d
@@ -7,4 +7,4 @@
Disassembly of section .text:
0+000 <target>:
-[ ]+0:[ ]+03400000[ ]+nop[ ]+
+[ ]+0:[ ]+03400000[ ]+nop
diff --git a/gas/testsuite/gas/loongarch/privilege_op.d b/gas/testsuite/gas/loongarch/privilege_op.d
index 73925f21..e9ca60b2 100644
--- a/gas/testsuite/gas/loongarch/privilege_op.d
+++ b/gas/testsuite/gas/loongarch/privilege_op.d
@@ -31,13 +31,13 @@ Disassembly of section .text:
[ ]+54:[ ]+064814a4 [ ]+iocsrwr.h[ ]+[ ]+\$a0, \$a1
[ ]+58:[ ]+064818a4 [ ]+iocsrwr.w[ ]+[ ]+\$a0, \$a1
[ ]+5c:[ ]+06481ca4 [ ]+iocsrwr.d[ ]+[ ]+\$a0, \$a1
-[ ]+60:[ ]+06482000 [ ]+tlbclr[ ]+
-[ ]+64:[ ]+06482400 [ ]+tlbflush[ ]+
-[ ]+68:[ ]+06482800 [ ]+tlbsrch[ ]+
-[ ]+6c:[ ]+06482c00 [ ]+tlbrd[ ]+
-[ ]+70:[ ]+06483000 [ ]+tlbwr[ ]+
-[ ]+74:[ ]+06483400 [ ]+tlbfill[ ]+
-[ ]+78:[ ]+06483800 [ ]+ertn[ ]+
+[ ]+60:[ ]+06482000 [ ]+tlbclr
+[ ]+64:[ ]+06482400 [ ]+tlbflush
+[ ]+68:[ ]+06482800 [ ]+tlbsrch
+[ ]+6c:[ ]+06482c00 [ ]+tlbrd
+[ ]+70:[ ]+06483000 [ ]+tlbwr
+[ ]+74:[ ]+06483400 [ ]+tlbfill
+[ ]+78:[ ]+06483800 [ ]+ertn
[ ]+7c:[ ]+06488000 [ ]+idle[ ]+[ ]+0x0
[ ]+80:[ ]+0648ffff [ ]+idle[ ]+[ ]+0x7fff
[ ]+84:[ ]+064998a0 [ ]+invtlb[ ]+[ ]+0x0, \$a1, \$a2
diff --git a/gas/testsuite/gas/loongarch/reloc.d b/gas/testsuite/gas/loongarch/reloc.d
index 0458830f..fa249c58 100644
--- a/gas/testsuite/gas/loongarch/reloc.d
+++ b/gas/testsuite/gas/loongarch/reloc.d
@@ -8,7 +8,7 @@
Disassembly of section .text:
00000000.* <.text>:
-[ ]+0:[ ]+03400000[ ]+nop[ ]+
+[ ]+0:[ ]+03400000[ ]+nop
[ ]+4:[ ]+58000085[ ]+beq[ ]+\$a0,[ ]+\$a1,[ ]+0[ ]+#[ ]+0x4
[ ]+4:[ ]+R_LARCH_B16[ ]+.L1
[ ]+8:[ ]+5c000085[ ]+bne[ ]+\$a0,[ ]+\$a1,[ ]+0[ ]+#[ ]+0x8
diff --git a/opcodes/loongarch-dis.c b/opcodes/loongarch-dis.c
index 969ea28f..941bf363 100644
--- a/opcodes/loongarch-dis.c
+++ b/opcodes/loongarch-dis.c
@@ -267,7 +267,12 @@ disassemble_one (insn_t insn, struct disassemble_info *info)
}
info->insn_type = dis_nonbranch;
- info->fprintf_styled_func (info->stream, dis_style_mnemonic, "%-12s", opc->name);
+ if (opc->format == NULL || opc->format[0] == '\0')
+ info->fprintf_styled_func (info->stream, dis_style_mnemonic,
+ "%s", opc->name);
+ else
+ info->fprintf_styled_func (info->stream, dis_style_mnemonic,
+ "%-12s", opc->name);
{
char *fake_args = xmalloc (strlen (opc->format) + 1);
--
2.33.0

View File

@ -0,0 +1,27 @@
From 85e65d5f829b23397ad39ad610589421e29c0e32 Mon Sep 17 00:00:00 2001
From: Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
Date: Thu, 28 Dec 2023 23:58:00 +0900
Subject: [PATCH 047/123] LoongArch: Do not add DF_STATIC_TLS for TLS LE
TLS LE is exclusively for executables, while DF_STATIC_TLS is for DLLs.
DF_STATIC_TLS should only be set for TLS IE (and when it's DLL), not LE.
---
bfd/elfnn-loongarch.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index b0ebe89e..f57b6152 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -863,8 +863,6 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
if (!bfd_link_executable (info))
return false;
- info->flags |= DF_STATIC_TLS;
-
if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
r_symndx,
GOT_TLS_LE))
--
2.33.0

View File

@ -0,0 +1,55 @@
From 1f00570084528ffcc4764a7f31307e2b5d233301 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Wed, 19 Jun 2024 11:00:36 +0800
Subject: [PATCH 093/123] LoongArch: Do not check R_LARCH_SOP_PUSH_ABSOLUTE to
avoid broken links to old object files
R_LARCH_SOP_PUSH_ABSOLUTE with -fPIC was heavily used in the era of gas-2.38.
We do not check this relocation to prevent broken links with old object
files.
---
bfd/elfnn-loongarch.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 51e3d311..840cdd35 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -756,10 +756,6 @@ loongarch_tls_transition (bfd *input_bfd,
return loongarch_tls_transition_without_check (info, r_type, h);
}
-/* Look through the relocs for a section during the first phase, and
- allocate space in the global offset table or procedure linkage
- table. */
-
static bool
bad_static_reloc (bfd *abfd, const Elf_Internal_Rela *rel, asection *sec,
unsigned r_type, struct elf_link_hash_entry *h,
@@ -787,6 +783,10 @@ bad_static_reloc (bfd *abfd, const Elf_Internal_Rela *rel, asection *sec,
return false;
}
+/* Look through the relocs for a section during the first phase, and
+ allocate space in the global offset table or procedure linkage
+ table. */
+
static bool
loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
asection *sec, const Elf_Internal_Rela *relocs)
@@ -948,10 +948,11 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
break;
case R_LARCH_ABS_HI20:
- case R_LARCH_SOP_PUSH_ABSOLUTE:
if (bfd_link_pic (info))
return bad_static_reloc (abfd, rel, sec, r_type, h, isym);
+ /* Fall through. */
+ case R_LARCH_SOP_PUSH_ABSOLUTE:
if (h != NULL)
/* If this reloc is in a read-only section, we might
need a copy reloc. We can't check reliably at this
--
2.33.0

View File

@ -0,0 +1,754 @@
From ef4712b21aa2ab233282bc3aa38f21e6957a9db9 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Wed, 10 Jan 2024 09:55:13 +0800
Subject: [PATCH 045/123] LoongArch: Do not emit R_LARCH_RELAX for two register
macros
For two register macros (e.g. la.local $t0, $t1, symbol) used in extreme code
model, do not emit R_LARCH_RELAX relocations.
---
gas/config/tc-loongarch.c | 45 ++-
.../gas/loongarch/macro_op_extreme_pc.d | 151 ++++---
.../gas/loongarch/tlsdesc_large_pc.d | 58 ++-
ld/testsuite/ld-loongarch-elf/macro_op.d | 376 +++++++++---------
4 files changed, 311 insertions(+), 319 deletions(-)
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index fad18fcd..1ae57b45 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -71,7 +71,17 @@ struct loongarch_cl_insn
long where;
/* The relocs associated with the instruction, if any. */
fixS *fixp[MAX_RELOC_NUMBER_A_INSN];
- long macro_id;
+ /* Represents macros or instructions expanded from macro.
+ For la.local -> la.pcrel or la.pcrel -> pcalau12i + addi.d, la.pcrel,
+ pcalau12i and addi.d are expanded from macro.
+ The first bit represents expanded from one register macro (e.g.
+ la.local $t0, symbol) and emit R_LARCH_RELAX relocations.
+ The second bit represents expanded from two registers macro (e.g.
+ la.local $t0, $t1, symbol) and not emit R_LARCH_RELAX relocations.
+
+ The macros or instructions expanded from macros do not output register
+ deprecated warning. */
+ unsigned int expand_from_macro;
};
#ifndef DEFAULT_ARCH
@@ -722,7 +732,10 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
ip->reloc_info[ip->reloc_num].value = const_0;
ip->reloc_num++;
}
- if (LARCH_opts.relax && ip->macro_id
+
+ /* Only one register macros (used in normal code model)
+ emit R_LARCH_RELAX. */
+ if (LARCH_opts.relax && (ip->expand_from_macro & 1)
&& (BFD_RELOC_LARCH_PCALA_HI20 == reloc_type
|| BFD_RELOC_LARCH_PCALA_LO12 == reloc_type
|| BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_type
@@ -754,7 +767,9 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
imm = (intptr_t) str_hash_find (r_deprecated_htab, arg);
ip->match_now = 0 < imm;
ret = imm - 1;
- if (ip->match_now && !ip->macro_id)
+ /* !ip->expand_from_macro: avoiding duplicate output warnings,
+ only the first macro output warning. */
+ if (ip->match_now && !ip->expand_from_macro)
as_warn (_("register alias %s is deprecated, use %s instead"),
arg, r_abi_names[ret]);
break;
@@ -773,7 +788,7 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
}
ip->match_now = 0 < imm;
ret = imm - 1;
- if (ip->match_now && !ip->macro_id)
+ if (ip->match_now && !ip->expand_from_macro)
break;
/* Handle potential usage of deprecated register aliases. */
imm = (intptr_t) str_hash_find (f_deprecated_htab, arg);
@@ -1172,7 +1187,7 @@ assember_macro_helper (const char *const args[], void *context_ptr)
* assuming 'not starting with space and not ending with space' or pass in
* empty c_str. */
static void
-loongarch_assemble_INSNs (char *str, struct loongarch_cl_insn *ctx)
+loongarch_assemble_INSNs (char *str, unsigned int expand_from_macro)
{
char *rest;
size_t len_str = strlen(str);
@@ -1195,7 +1210,7 @@ loongarch_assemble_INSNs (char *str, struct loongarch_cl_insn *ctx)
struct loongarch_cl_insn the_one = { 0 };
the_one.name = str;
- the_one.macro_id = ctx->macro_id;
+ the_one.expand_from_macro = expand_from_macro;
for (; *str && *str != ' '; str++)
;
@@ -1217,29 +1232,37 @@ loongarch_assemble_INSNs (char *str, struct loongarch_cl_insn *ctx)
break;
append_fixp_and_insn (&the_one);
+
+ /* Expanding macro instructions. */
if (the_one.insn_length == 0 && the_one.insn->macro)
{
- the_one.macro_id = 1;
+ unsigned int new_expand_from_macro = 0;
+ if (2 == the_one.arg_num)
+ new_expand_from_macro |= 1;
+ else if (3 == the_one.arg_num)
+ new_expand_from_macro |= 2;
char *c_str = loongarch_expand_macro (the_one.insn->macro,
the_one.arg_strs,
assember_macro_helper,
&the_one, len_str);
- loongarch_assemble_INSNs (c_str, &the_one);
+ /* The first instruction expanded from macro. */
+ loongarch_assemble_INSNs (c_str, new_expand_from_macro);
free (c_str);
}
}
while (0);
+ /* The rest instructions expanded from macro, split by semicolon(;),
+ assembly one by one. */
if (*rest != '\0')
- loongarch_assemble_INSNs (rest, ctx);
+ loongarch_assemble_INSNs (rest, expand_from_macro);
}
void
md_assemble (char *str)
{
- struct loongarch_cl_insn the_one = { 0 };
- loongarch_assemble_INSNs (str, &the_one);
+ loongarch_assemble_INSNs (str, 0);
}
const char *
diff --git a/gas/testsuite/gas/loongarch/macro_op_extreme_pc.d b/gas/testsuite/gas/loongarch/macro_op_extreme_pc.d
index 8e4b6e6c..68fbb338 100644
--- a/gas/testsuite/gas/loongarch/macro_op_extreme_pc.d
+++ b/gas/testsuite/gas/loongarch/macro_op_extreme_pc.d
@@ -2,87 +2,76 @@
#objdump: -dr
#skip: loongarch32-*-*
-.*: file format .*
+.*:[ ]+file format .*
+
Disassembly of section .text:
-0+ <.L1>:
- 0: 1a000004 pcalau12i \$a0, 0
- 0: R_LARCH_PCALA_HI20 .L1
- 0: R_LARCH_RELAX \*ABS\*
- 4: 02c00005 li.d \$a1, 0
- 4: R_LARCH_PCALA_LO12 .L1
- 4: R_LARCH_RELAX \*ABS\*
- 8: 16000005 lu32i.d \$a1, 0
- 8: R_LARCH_PCALA64_LO20 .L1
- c: 030000a5 lu52i.d \$a1, \$a1, 0
- c: R_LARCH_PCALA64_HI12 .L1
- 10: 00109484 add.d \$a0, \$a0, \$a1
- 14: 1a000004 pcalau12i \$a0, 0
- 14: R_LARCH_PCALA_HI20 .L1
- 14: R_LARCH_RELAX \*ABS\*
- 18: 02c00005 li.d \$a1, 0
- 18: R_LARCH_PCALA_LO12 .L1
- 18: R_LARCH_RELAX \*ABS\*
- 1c: 16000005 lu32i.d \$a1, 0
- 1c: R_LARCH_PCALA64_LO20 .L1
- 20: 030000a5 lu52i.d \$a1, \$a1, 0
- 20: R_LARCH_PCALA64_HI12 .L1
- 24: 00109484 add.d \$a0, \$a0, \$a1
- 28: 1a000004 pcalau12i \$a0, 0
- 28: R_LARCH_PCALA_HI20 .L1
- 28: R_LARCH_RELAX \*ABS\*
- 2c: 02c00005 li.d \$a1, 0
- 2c: R_LARCH_PCALA_LO12 .L1
- 2c: R_LARCH_RELAX \*ABS\*
- 30: 16000005 lu32i.d \$a1, 0
- 30: R_LARCH_PCALA64_LO20 .L1
- 34: 030000a5 lu52i.d \$a1, \$a1, 0
- 34: R_LARCH_PCALA64_HI12 .L1
- 38: 00109484 add.d \$a0, \$a0, \$a1
- 3c: 1a000004 pcalau12i \$a0, 0
- 3c: R_LARCH_GOT_PC_HI20 .L1
- 3c: R_LARCH_RELAX \*ABS\*
- 40: 02c00005 li.d \$a1, 0
- 40: R_LARCH_GOT_PC_LO12 .L1
- 40: R_LARCH_RELAX \*ABS\*
- 44: 16000005 lu32i.d \$a1, 0
- 44: R_LARCH_GOT64_PC_LO20 .L1
- 48: 030000a5 lu52i.d \$a1, \$a1, 0
- 48: R_LARCH_GOT64_PC_HI12 .L1
- 4c: 380c1484 ldx.d \$a0, \$a0, \$a1
- 50: 14000004 lu12i.w \$a0, 0
- 50: R_LARCH_TLS_LE_HI20 TLS1
- 54: 03800084 ori \$a0, \$a0, 0x0
- 54: R_LARCH_TLS_LE_LO12 TLS1
- 58: 1a000004 pcalau12i \$a0, 0
- 58: R_LARCH_TLS_IE_PC_HI20 TLS1
- 5c: 02c00005 li.d \$a1, 0
- 5c: R_LARCH_TLS_IE_PC_LO12 TLS1
- 60: 16000005 lu32i.d \$a1, 0
- 60: R_LARCH_TLS_IE64_PC_LO20 TLS1
- 64: 030000a5 lu52i.d \$a1, \$a1, 0
- 64: R_LARCH_TLS_IE64_PC_HI12 TLS1
- 68: 380c1484 ldx.d \$a0, \$a0, \$a1
- 6c: 1a000004 pcalau12i \$a0, 0
- 6c: R_LARCH_TLS_LD_PC_HI20 TLS1
- 6c: R_LARCH_RELAX \*ABS\*
- 70: 02c00005 li.d \$a1, 0
- 70: R_LARCH_GOT_PC_LO12 TLS1
- 70: R_LARCH_RELAX \*ABS\*
- 74: 16000005 lu32i.d \$a1, 0
- 74: R_LARCH_GOT64_PC_LO20 TLS1
- 78: 030000a5 lu52i.d \$a1, \$a1, 0
- 78: R_LARCH_GOT64_PC_HI12 TLS1
- 7c: 00109484 add.d \$a0, \$a0, \$a1
- 80: 1a000004 pcalau12i \$a0, 0
- 80: R_LARCH_TLS_GD_PC_HI20 TLS1
- 80: R_LARCH_RELAX \*ABS\*
- 84: 02c00005 li.d \$a1, 0
- 84: R_LARCH_GOT_PC_LO12 TLS1
- 84: R_LARCH_RELAX \*ABS\*
- 88: 16000005 lu32i.d \$a1, 0
- 88: R_LARCH_GOT64_PC_LO20 TLS1
- 8c: 030000a5 lu52i.d \$a1, \$a1, 0
- 8c: R_LARCH_GOT64_PC_HI12 TLS1
- 90: 00109484 add.d \$a0, \$a0, \$a1
+[ ]*0000000000000000 <.L1>:
+[ ]+0:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+0: R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+4:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+4: R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+8:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+8: R_LARCH_PCALA64_LO20[ ]+.L1
+[ ]+c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+c: R_LARCH_PCALA64_HI12[ ]+.L1
+[ ]+10:[ ]+00109484[ ]+add.d[ ]+\$a0, \$a0, \$a1
+[ ]+14:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+14: R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+18:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+18: R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+1c:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+1c: R_LARCH_PCALA64_LO20[ ]+.L1
+[ ]+20:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+20: R_LARCH_PCALA64_HI12[ ]+.L1
+[ ]+24:[ ]+00109484[ ]+add.d[ ]+\$a0, \$a0, \$a1
+[ ]+28:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+28: R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+2c:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+2c: R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+30:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+30: R_LARCH_PCALA64_LO20[ ]+.L1
+[ ]+34:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+34: R_LARCH_PCALA64_HI12[ ]+.L1
+[ ]+38:[ ]+00109484[ ]+add.d[ ]+\$a0, \$a0, \$a1
+[ ]+3c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+3c: R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+40:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+40: R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+44:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+44: R_LARCH_GOT64_PC_LO20[ ]+.L1
+[ ]+48:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+48: R_LARCH_GOT64_PC_HI12[ ]+.L1
+[ ]+4c:[ ]+380c1484[ ]+ldx.d[ ]+\$a0, \$a0, \$a1
+[ ]+50:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+50: R_LARCH_TLS_LE_HI20[ ]+TLS1
+[ ]+54:[ ]+03800084[ ]+ori[ ]+\$a0, \$a0, 0x0
+[ ]+54: R_LARCH_TLS_LE_LO12[ ]+TLS1
+[ ]+58:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+58: R_LARCH_TLS_IE_PC_HI20[ ]+TLS1
+[ ]+5c:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+5c: R_LARCH_TLS_IE_PC_LO12[ ]+TLS1
+[ ]+60:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+60: R_LARCH_TLS_IE64_PC_LO20[ ]+TLS1
+[ ]+64:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+64: R_LARCH_TLS_IE64_PC_HI12[ ]+TLS1
+[ ]+68:[ ]+380c1484[ ]+ldx.d[ ]+\$a0, \$a0, \$a1
+[ ]+6c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+6c: R_LARCH_TLS_LD_PC_HI20[ ]+TLS1
+[ ]+70:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+70: R_LARCH_GOT_PC_LO12[ ]+TLS1
+[ ]+74:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+74: R_LARCH_GOT64_PC_LO20[ ]+TLS1
+[ ]+78:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+78: R_LARCH_GOT64_PC_HI12[ ]+TLS1
+[ ]+7c:[ ]+00109484[ ]+add.d[ ]+\$a0, \$a0, \$a1
+[ ]+80:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+80: R_LARCH_TLS_GD_PC_HI20[ ]+TLS1
+[ ]+84:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+84: R_LARCH_GOT_PC_LO12[ ]+TLS1
+[ ]+88:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+88: R_LARCH_GOT64_PC_LO20[ ]+TLS1
+[ ]+8c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+8c: R_LARCH_GOT64_PC_HI12[ ]+TLS1
+[ ]+90:[ ]+00109484[ ]+add.d[ ]+\$a0, \$a0, \$a1
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_large_pc.d b/gas/testsuite/gas/loongarch/tlsdesc_large_pc.d
index 2b7a4660..a7fcce31 100644
--- a/gas/testsuite/gas/loongarch/tlsdesc_large_pc.d
+++ b/gas/testsuite/gas/loongarch/tlsdesc_large_pc.d
@@ -2,37 +2,35 @@
#objdump: -dr
#skip: loongarch32-*-*
-.*: file format .*
+.*:[ ]+file format .*
Disassembly of section .text:
-0+ <.*>:
- 0: 1a000004 pcalau12i \$a0, 0
- 0: R_LARCH_TLS_DESC_PC_HI20 var
- 4: 02c00005 li.d \$a1, 0
- 4: R_LARCH_TLS_DESC_PC_LO12 var
- 8: 16000005 lu32i.d \$a1, 0
- 8: R_LARCH_TLS_DESC64_PC_LO20 var
- c: 030000a5 lu52i.d \$a1, \$a1, 0
- c: R_LARCH_TLS_DESC64_PC_HI12 var
- 10: 00109484 add.d \$a0, \$a0, \$a1
- 14: 28c00081 ld.d \$ra, \$a0, 0
- 14: R_LARCH_TLS_DESC_LD var
- 18: 4c000021 jirl \$ra, \$ra, 0
- 18: R_LARCH_TLS_DESC_CALL var
- 1c: 1a000004 pcalau12i \$a0, 0
- 1c: R_LARCH_TLS_DESC_PC_HI20 var
- 1c: R_LARCH_RELAX \*ABS\*
- 20: 02c00001 li.d \$ra, 0
- 20: R_LARCH_TLS_DESC_PC_LO12 var
- 20: R_LARCH_RELAX \*ABS\*
- 24: 16000001 lu32i.d \$ra, 0
- 24: R_LARCH_TLS_DESC64_PC_LO20 var
- 28: 03000021 lu52i.d \$ra, \$ra, 0
- 28: R_LARCH_TLS_DESC64_PC_HI12 var
- 2c: 00108484 add.d \$a0, \$a0, \$ra
- 30: 28c00081 ld.d \$ra, \$a0, 0
- 30: R_LARCH_TLS_DESC_LD var
- 34: 4c000021 jirl \$ra, \$ra, 0
- 34: R_LARCH_TLS_DESC_CALL var
+[ ]*0000000000000000 <.text>:
+[ ]+0:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+0: R_LARCH_TLS_DESC_PC_HI20[ ]+var
+[ ]+4:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+4: R_LARCH_TLS_DESC_PC_LO12[ ]+var
+[ ]+8:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+8: R_LARCH_TLS_DESC64_PC_LO20[ ]+var
+[ ]+c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+c: R_LARCH_TLS_DESC64_PC_HI12[ ]+var
+[ ]+10:[ ]+00109484[ ]+add.d[ ]+\$a0, \$a0, \$a1
+[ ]+14:[ ]+28c00081[ ]+ld.d[ ]+\$ra, \$a0, 0
+[ ]+14: R_LARCH_TLS_DESC_LD[ ]+var
+[ ]+18:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
+[ ]+18: R_LARCH_TLS_DESC_CALL[ ]+var
+[ ]+1c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+1c: R_LARCH_TLS_DESC_PC_HI20[ ]+var
+[ ]+20:[ ]+02c00001[ ]+li.d[ ]+\$ra, 0
+[ ]+20: R_LARCH_TLS_DESC_PC_LO12[ ]+var
+[ ]+24:[ ]+16000001[ ]+lu32i.d[ ]+\$ra, 0
+[ ]+24: R_LARCH_TLS_DESC64_PC_LO20[ ]+var
+[ ]+28:[ ]+03000021[ ]+lu52i.d[ ]+\$ra, \$ra, 0
+[ ]+28: R_LARCH_TLS_DESC64_PC_HI12[ ]+var
+[ ]+2c:[ ]+00108484[ ]+add.d[ ]+\$a0, \$a0, \$ra
+[ ]+30:[ ]+28c00081[ ]+ld.d[ ]+\$ra, \$a0, 0
+[ ]+30: R_LARCH_TLS_DESC_LD[ ]+var
+[ ]+34:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
+[ ]+34: R_LARCH_TLS_DESC_CALL[ ]+var
diff --git a/ld/testsuite/ld-loongarch-elf/macro_op.d b/ld/testsuite/ld-loongarch-elf/macro_op.d
index f0d87c03..c9493918 100644
--- a/ld/testsuite/ld-loongarch-elf/macro_op.d
+++ b/ld/testsuite/ld-loongarch-elf/macro_op.d
@@ -2,204 +2,186 @@
#objdump: -dr
#skip: loongarch32-*-*
-.*: file format .*
+.*:[ ]+file format .*
Disassembly of section .text:
-0+ <.L1>:
- 0: 00150004 move \$a0, \$zero
- 4: 02bffc04 li.w \$a0, -1
- 8: 00150004 move \$a0, \$zero
- c: 02bffc04 li.w \$a0, -1
- 10: 1a000004 pcalau12i \$a0, 0
- 10: R_LARCH_GOT_PC_HI20 .L1
- 10: R_LARCH_RELAX \*ABS\*
- 14: 28c00084 ld.d \$a0, \$a0, 0
- 14: R_LARCH_GOT_PC_LO12 .L1
- 14: R_LARCH_RELAX \*ABS\*
- 18: 1a000004 pcalau12i \$a0, 0
- 18: R_LARCH_GOT_PC_HI20 .L1
- 18: R_LARCH_RELAX \*ABS\*
- 1c: 28c00084 ld.d \$a0, \$a0, 0
- 1c: R_LARCH_GOT_PC_LO12 .L1
- 1c: R_LARCH_RELAX \*ABS\*
- 20: 1a000004 pcalau12i \$a0, 0
- 20: R_LARCH_GOT_PC_HI20 .L1
- 20: R_LARCH_RELAX \*ABS\*
- 24: 02c00005 li.d \$a1, 0
- 24: R_LARCH_GOT_PC_LO12 .L1
- 24: R_LARCH_RELAX \*ABS\*
- 28: 16000005 lu32i.d \$a1, 0
- 28: R_LARCH_GOT64_PC_LO20 .L1
- 2c: 030000a5 lu52i.d \$a1, \$a1, 0
- 2c: R_LARCH_GOT64_PC_HI12 .L1
- 30: 380c1484 ldx.d \$a0, \$a0, \$a1
- 34: 1a000004 pcalau12i \$a0, 0
- 34: R_LARCH_GOT_PC_HI20 .L1
- 34: R_LARCH_RELAX \*ABS\*
- 38: 28c00084 ld.d \$a0, \$a0, 0
- 38: R_LARCH_GOT_PC_LO12 .L1
- 38: R_LARCH_RELAX \*ABS\*
- 3c: 1a000004 pcalau12i \$a0, 0
- 3c: R_LARCH_GOT_PC_HI20 .L1
- 3c: R_LARCH_RELAX \*ABS\*
- 40: 02c00005 li.d \$a1, 0
- 40: R_LARCH_GOT_PC_LO12 .L1
- 40: R_LARCH_RELAX \*ABS\*
- 44: 16000005 lu32i.d \$a1, 0
- 44: R_LARCH_GOT64_PC_LO20 .L1
- 48: 030000a5 lu52i.d \$a1, \$a1, 0
- 48: R_LARCH_GOT64_PC_HI12 .L1
- 4c: 380c1484 ldx.d \$a0, \$a0, \$a1
- 50: 1a000004 pcalau12i \$a0, 0
- 50: R_LARCH_GOT_PC_HI20 .L1
- 50: R_LARCH_RELAX \*ABS\*
- 54: 28c00084 ld.d \$a0, \$a0, 0
- 54: R_LARCH_GOT_PC_LO12 .L1
- 54: R_LARCH_RELAX \*ABS\*
- 58: 1a000004 pcalau12i \$a0, 0
- 58: R_LARCH_GOT_PC_HI20 .L1
- 58: R_LARCH_RELAX \*ABS\*
- 5c: 02c00005 li.d \$a1, 0
- 5c: R_LARCH_GOT_PC_LO12 .L1
- 5c: R_LARCH_RELAX \*ABS\*
- 60: 16000005 lu32i.d \$a1, 0
- 60: R_LARCH_GOT64_PC_LO20 .L1
- 64: 030000a5 lu52i.d \$a1, \$a1, 0
- 64: R_LARCH_GOT64_PC_HI12 .L1
- 68: 380c1484 ldx.d \$a0, \$a0, \$a1
- 6c: 1a000004 pcalau12i \$a0, 0
- 6c: R_LARCH_PCALA_HI20 .L1
- 6c: R_LARCH_RELAX \*ABS\*
- 70: 02c00084 addi.d \$a0, \$a0, 0
- 70: R_LARCH_PCALA_LO12 .L1
- 70: R_LARCH_RELAX \*ABS\*
- 74: 1a000004 pcalau12i \$a0, 0
- 74: R_LARCH_PCALA_HI20 .L1
- 74: R_LARCH_RELAX \*ABS\*
- 78: 02c00005 li.d \$a1, 0
- 78: R_LARCH_PCALA_LO12 .L1
- 78: R_LARCH_RELAX \*ABS\*
- 7c: 16000005 lu32i.d \$a1, 0
- 7c: R_LARCH_PCALA64_LO20 .L1
- 80: 030000a5 lu52i.d \$a1, \$a1, 0
- 80: R_LARCH_PCALA64_HI12 .L1
- 84: 00109484 add.d \$a0, \$a0, \$a1
- 88: 1a000004 pcalau12i \$a0, 0
- 88: R_LARCH_PCALA_HI20 .L1
- 88: R_LARCH_RELAX \*ABS\*
- 8c: 02c00084 addi.d \$a0, \$a0, 0
- 8c: R_LARCH_PCALA_LO12 .L1
- 8c: R_LARCH_RELAX \*ABS\*
- 90: 1a000004 pcalau12i \$a0, 0
- 90: R_LARCH_PCALA_HI20 .L1
- 90: R_LARCH_RELAX \*ABS\*
- 94: 02c00005 li.d \$a1, 0
- 94: R_LARCH_PCALA_LO12 .L1
- 94: R_LARCH_RELAX \*ABS\*
- 98: 16000005 lu32i.d \$a1, 0
- 98: R_LARCH_PCALA64_LO20 .L1
- 9c: 030000a5 lu52i.d \$a1, \$a1, 0
- 9c: R_LARCH_PCALA64_HI12 .L1
- a0: 00109484 add.d \$a0, \$a0, \$a1
- a4: 14000004 lu12i.w \$a0, 0
- a4: R_LARCH_MARK_LA \*ABS\*
- a4: R_LARCH_ABS_HI20 .L1
- a8: 03800084 ori \$a0, \$a0, 0x0
- a8: R_LARCH_ABS_LO12 .L1
- ac: 16000004 lu32i.d \$a0, 0
- ac: R_LARCH_ABS64_LO20 .L1
- b0: 03000084 lu52i.d \$a0, \$a0, 0
- b0: R_LARCH_ABS64_HI12 .L1
- b4: 1a000004 pcalau12i \$a0, 0
- b4: R_LARCH_PCALA_HI20 .L1
- b4: R_LARCH_RELAX \*ABS\*
- b8: 02c00084 addi.d \$a0, \$a0, 0
- b8: R_LARCH_PCALA_LO12 .L1
- b8: R_LARCH_RELAX \*ABS\*
- bc: 1a000004 pcalau12i \$a0, 0
- bc: R_LARCH_PCALA_HI20 .L1
- bc: R_LARCH_RELAX \*ABS\*
- c0: 02c00084 addi.d \$a0, \$a0, 0
- c0: R_LARCH_PCALA_LO12 .L1
- c0: R_LARCH_RELAX \*ABS\*
- c4: 1a000004 pcalau12i \$a0, 0
- c4: R_LARCH_PCALA_HI20 .L1
- c4: R_LARCH_RELAX \*ABS\*
- c8: 02c00005 li.d \$a1, 0
- c8: R_LARCH_PCALA_LO12 .L1
- c8: R_LARCH_RELAX \*ABS\*
- cc: 16000005 lu32i.d \$a1, 0
- cc: R_LARCH_PCALA64_LO20 .L1
- d0: 030000a5 lu52i.d \$a1, \$a1, 0
- d0: R_LARCH_PCALA64_HI12 .L1
- d4: 00109484 add.d \$a0, \$a0, \$a1
- d8: 1a000004 pcalau12i \$a0, 0
- d8: R_LARCH_GOT_PC_HI20 .L1
- d8: R_LARCH_RELAX \*ABS\*
- dc: 28c00084 ld.d \$a0, \$a0, 0
- dc: R_LARCH_GOT_PC_LO12 .L1
- dc: R_LARCH_RELAX \*ABS\*
- e0: 1a000004 pcalau12i \$a0, 0
- e0: R_LARCH_GOT_PC_HI20 .L1
- e0: R_LARCH_RELAX \*ABS\*
- e4: 02c00005 li.d \$a1, 0
- e4: R_LARCH_GOT_PC_LO12 .L1
- e4: R_LARCH_RELAX \*ABS\*
- e8: 16000005 lu32i.d \$a1, 0
- e8: R_LARCH_GOT64_PC_LO20 .L1
- ec: 030000a5 lu52i.d \$a1, \$a1, 0
- ec: R_LARCH_GOT64_PC_HI12 .L1
- f0: 380c1484 ldx.d \$a0, \$a0, \$a1
- f4: 14000004 lu12i.w \$a0, 0
- f4: R_LARCH_TLS_LE_HI20 TLS1
- f8: 03800084 ori \$a0, \$a0, 0x0
- f8: R_LARCH_TLS_LE_LO12 TLS1
- fc: 1a000004 pcalau12i \$a0, 0
- fc: R_LARCH_TLS_IE_PC_HI20 TLS1
- 100: 28c00084 ld.d \$a0, \$a0, 0
- 100: R_LARCH_TLS_IE_PC_LO12 TLS1
- 104: 1a000004 pcalau12i \$a0, 0
- 104: R_LARCH_TLS_IE_PC_HI20 TLS1
- 108: 02c00005 li.d \$a1, 0
- 108: R_LARCH_TLS_IE_PC_LO12 TLS1
- 10c: 16000005 lu32i.d \$a1, 0
- 10c: R_LARCH_TLS_IE64_PC_LO20 TLS1
- 110: 030000a5 lu52i.d \$a1, \$a1, 0
- 110: R_LARCH_TLS_IE64_PC_HI12 TLS1
- 114: 380c1484 ldx.d \$a0, \$a0, \$a1
- 118: 1a000004 pcalau12i \$a0, 0
- 118: R_LARCH_TLS_LD_PC_HI20 TLS1
- 118: R_LARCH_RELAX \*ABS\*
- 11c: 02c00084 addi.d \$a0, \$a0, 0
- 11c: R_LARCH_GOT_PC_LO12 TLS1
- 11c: R_LARCH_RELAX \*ABS\*
- 120: 1a000004 pcalau12i \$a0, 0
- 120: R_LARCH_TLS_LD_PC_HI20 TLS1
- 120: R_LARCH_RELAX \*ABS\*
- 124: 02c00005 li.d \$a1, 0
- 124: R_LARCH_GOT_PC_LO12 TLS1
- 124: R_LARCH_RELAX \*ABS\*
- 128: 16000005 lu32i.d \$a1, 0
- 128: R_LARCH_GOT64_PC_LO20 TLS1
- 12c: 030000a5 lu52i.d \$a1, \$a1, 0
- 12c: R_LARCH_GOT64_PC_HI12 TLS1
- 130: 00109484 add.d \$a0, \$a0, \$a1
- 134: 1a000004 pcalau12i \$a0, 0
- 134: R_LARCH_TLS_GD_PC_HI20 TLS1
- 134: R_LARCH_RELAX \*ABS\*
- 138: 02c00084 addi.d \$a0, \$a0, 0
- 138: R_LARCH_GOT_PC_LO12 TLS1
- 138: R_LARCH_RELAX \*ABS\*
- 13c: 1a000004 pcalau12i \$a0, 0
- 13c: R_LARCH_TLS_GD_PC_HI20 TLS1
- 13c: R_LARCH_RELAX \*ABS\*
- 140: 02c00005 li.d \$a1, 0
- 140: R_LARCH_GOT_PC_LO12 TLS1
- 140: R_LARCH_RELAX \*ABS\*
- 144: 16000005 lu32i.d \$a1, 0
- 144: R_LARCH_GOT64_PC_LO20 TLS1
- 148: 030000a5 lu52i.d \$a1, \$a1, 0
- 148: R_LARCH_GOT64_PC_HI12 TLS1
- 14c: 00109484 add.d \$a0, \$a0, \$a1
+[ ]*0000000000000000 <.L1>:
+[ ]+0:[ ]+00150004[ ]+move[ ]+\$a0, \$zero
+[ ]+4:[ ]+02bffc04[ ]+li.w[ ]+\$a0, -1
+[ ]+8:[ ]+00150004[ ]+move[ ]+\$a0, \$zero
+[ ]+c:[ ]+02bffc04[ ]+li.w[ ]+\$a0, -1
+[ ]+10:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+10: R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+10: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+14:[ ]+28c00084[ ]+ld.d[ ]+\$a0, \$a0, 0
+[ ]+14: R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+14: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+18:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+18: R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+18: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+1c:[ ]+28c00084[ ]+ld.d[ ]+\$a0, \$a0, 0
+[ ]+1c: R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+1c: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+20:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+20: R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+24:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+24: R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+28:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+28: R_LARCH_GOT64_PC_LO20[ ]+.L1
+[ ]+2c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+2c: R_LARCH_GOT64_PC_HI12[ ]+.L1
+[ ]+30:[ ]+380c1484[ ]+ldx.d[ ]+\$a0, \$a0, \$a1
+[ ]+34:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+34: R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+34: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+38:[ ]+28c00084[ ]+ld.d[ ]+\$a0, \$a0, 0
+[ ]+38: R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+38: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+3c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+3c: R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+40:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+40: R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+44:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+44: R_LARCH_GOT64_PC_LO20[ ]+.L1
+[ ]+48:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+48: R_LARCH_GOT64_PC_HI12[ ]+.L1
+[ ]+4c:[ ]+380c1484[ ]+ldx.d[ ]+\$a0, \$a0, \$a1
+[ ]+50:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+50: R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+50: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+54:[ ]+28c00084[ ]+ld.d[ ]+\$a0, \$a0, 0
+[ ]+54: R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+54: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+58:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+58: R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+5c:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+5c: R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+60:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+60: R_LARCH_GOT64_PC_LO20[ ]+.L1
+[ ]+64:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+64: R_LARCH_GOT64_PC_HI12[ ]+.L1
+[ ]+68:[ ]+380c1484[ ]+ldx.d[ ]+\$a0, \$a0, \$a1
+[ ]+6c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+6c: R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+6c: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+70:[ ]+02c00084[ ]+addi.d[ ]+\$a0, \$a0, 0
+[ ]+70: R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+70: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+74:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+74: R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+78:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+78: R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+7c:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+7c: R_LARCH_PCALA64_LO20[ ]+.L1
+[ ]+80:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+80: R_LARCH_PCALA64_HI12[ ]+.L1
+[ ]+84:[ ]+00109484[ ]+add.d[ ]+\$a0, \$a0, \$a1
+[ ]+88:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+88: R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+88: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+8c:[ ]+02c00084[ ]+addi.d[ ]+\$a0, \$a0, 0
+[ ]+8c: R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+8c: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+90:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+90: R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+94:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+94: R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+98:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+98: R_LARCH_PCALA64_LO20[ ]+.L1
+[ ]+9c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+9c: R_LARCH_PCALA64_HI12[ ]+.L1
+[ ]+a0:[ ]+00109484[ ]+add.d[ ]+\$a0, \$a0, \$a1
+[ ]+a4:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+a4: R_LARCH_MARK_LA[ ]+\*ABS\*
+[ ]+a4: R_LARCH_ABS_HI20[ ]+.L1
+[ ]+a8:[ ]+03800084[ ]+ori[ ]+\$a0, \$a0, 0x0
+[ ]+a8: R_LARCH_ABS_LO12[ ]+.L1
+[ ]+ac:[ ]+16000004[ ]+lu32i.d[ ]+\$a0, 0
+[ ]+ac: R_LARCH_ABS64_LO20[ ]+.L1
+[ ]+b0:[ ]+03000084[ ]+lu52i.d[ ]+\$a0, \$a0, 0
+[ ]+b0: R_LARCH_ABS64_HI12[ ]+.L1
+[ ]+b4:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+b4: R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+b4: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+b8:[ ]+02c00084[ ]+addi.d[ ]+\$a0, \$a0, 0
+[ ]+b8: R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+b8: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+bc:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+bc: R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+bc: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+c0:[ ]+02c00084[ ]+addi.d[ ]+\$a0, \$a0, 0
+[ ]+c0: R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+c0: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+c4:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+c4: R_LARCH_PCALA_HI20[ ]+.L1
+[ ]+c8:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+c8: R_LARCH_PCALA_LO12[ ]+.L1
+[ ]+cc:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+cc: R_LARCH_PCALA64_LO20[ ]+.L1
+[ ]+d0:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+d0: R_LARCH_PCALA64_HI12[ ]+.L1
+[ ]+d4:[ ]+00109484[ ]+add.d[ ]+\$a0, \$a0, \$a1
+[ ]+d8:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+d8: R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+d8: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+dc:[ ]+28c00084[ ]+ld.d[ ]+\$a0, \$a0, 0
+[ ]+dc: R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+dc: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+e0:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+e0: R_LARCH_GOT_PC_HI20[ ]+.L1
+[ ]+e4:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+e4: R_LARCH_GOT_PC_LO12[ ]+.L1
+[ ]+e8:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+e8: R_LARCH_GOT64_PC_LO20[ ]+.L1
+[ ]+ec:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+ec: R_LARCH_GOT64_PC_HI12[ ]+.L1
+[ ]+f0:[ ]+380c1484[ ]+ldx.d[ ]+\$a0, \$a0, \$a1
+[ ]+f4:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+f4: R_LARCH_TLS_LE_HI20[ ]+TLS1
+[ ]+f8:[ ]+03800084[ ]+ori[ ]+\$a0, \$a0, 0x0
+[ ]+f8: R_LARCH_TLS_LE_LO12[ ]+TLS1
+[ ]+fc:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+fc: R_LARCH_TLS_IE_PC_HI20[ ]+TLS1
+[ ]+100:[ ]+28c00084[ ]+ld.d[ ]+\$a0, \$a0, 0
+[ ]+100: R_LARCH_TLS_IE_PC_LO12[ ]+TLS1
+[ ]+104:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+104: R_LARCH_TLS_IE_PC_HI20[ ]+TLS1
+[ ]+108:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+108: R_LARCH_TLS_IE_PC_LO12[ ]+TLS1
+[ ]+10c:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+10c: R_LARCH_TLS_IE64_PC_LO20[ ]+TLS1
+[ ]+110:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+110: R_LARCH_TLS_IE64_PC_HI12[ ]+TLS1
+[ ]+114:[ ]+380c1484[ ]+ldx.d[ ]+\$a0, \$a0, \$a1
+[ ]+118:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+118: R_LARCH_TLS_LD_PC_HI20[ ]+TLS1
+[ ]+118: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+11c:[ ]+02c00084[ ]+addi.d[ ]+\$a0, \$a0, 0
+[ ]+11c: R_LARCH_GOT_PC_LO12[ ]+TLS1
+[ ]+11c: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+120:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+120: R_LARCH_TLS_LD_PC_HI20[ ]+TLS1
+[ ]+124:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+124: R_LARCH_GOT_PC_LO12[ ]+TLS1
+[ ]+128:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+128: R_LARCH_GOT64_PC_LO20[ ]+TLS1
+[ ]+12c:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+12c: R_LARCH_GOT64_PC_HI12[ ]+TLS1
+[ ]+130:[ ]+00109484[ ]+add.d[ ]+\$a0, \$a0, \$a1
+[ ]+134:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+134: R_LARCH_TLS_GD_PC_HI20[ ]+TLS1
+[ ]+134: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+138:[ ]+02c00084[ ]+addi.d[ ]+\$a0, \$a0, 0
+[ ]+138: R_LARCH_GOT_PC_LO12[ ]+TLS1
+[ ]+138: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+13c:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
+[ ]+13c: R_LARCH_TLS_GD_PC_HI20[ ]+TLS1
+[ ]+140:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
+[ ]+140: R_LARCH_GOT_PC_LO12[ ]+TLS1
+[ ]+144:[ ]+16000005[ ]+lu32i.d[ ]+\$a1, 0
+[ ]+144: R_LARCH_GOT64_PC_LO20[ ]+TLS1
+[ ]+148:[ ]+030000a5[ ]+lu52i.d[ ]+\$a1, \$a1, 0
+[ ]+148: R_LARCH_GOT64_PC_HI12[ ]+TLS1
+[ ]+14c:[ ]+00109484[ ]+add.d[ ]+\$a0, \$a0, \$a1
--
2.33.0

View File

@ -0,0 +1,29 @@
From c4da692895d01cf281c22efc2c30a6d4fdfb3d21 Mon Sep 17 00:00:00 2001
From: Jinyang He <hejinyang@loongson.cn>
Date: Fri, 11 Aug 2023 16:10:40 +0800
Subject: [PATCH 009/123] LoongArch: Enable gas sort relocs
The md_pre_output_hook creating fixup is asynchronous, causing relocs
may be out of order in .eh_frame. Define GAS_SORT_RELOCS so that reorder
relocs when write_relocs.
Reported-by: Rui Ueyama <rui314@gmail.com>
---
gas/config/tc-loongarch.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h
index d353f18d..fd094356 100644
--- a/gas/config/tc-loongarch.h
+++ b/gas/config/tc-loongarch.h
@@ -123,6 +123,7 @@ extern void tc_loongarch_parse_to_dw2regnum (expressionS *);
extern void loongarch_pre_output_hook (void);
#define md_pre_output_hook loongarch_pre_output_hook ()
+#define GAS_SORT_RELOCS 1
#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
--
2.33.0

View File

@ -0,0 +1,74 @@
From 9a78ebba126036f6ebdd15ffbe50ffbd8ccd84dd Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Mon, 12 Aug 2024 18:23:47 +0800
Subject: [PATCH 108/123] LoongArch: Fix DT_RELR and relaxation interaction
Due to the way BFD implements DT_RELR as a part of relaxation, if in a
relax trip size_relative_relocs has changed the layout, when
relax_section runs only the vma of the section being relaxed is
guaranteed to be updated. Then bad thing can happen. For example, when
linking an auxilary program _freeze_module in the Python 3.12.4 building
system (with PGO + LTO), before sizing the .relr.dyn section, the vma of
.text is 30560 and the vma of .rodata is 2350944; in the final
executable the vma of .text is 36704 and the vma of .rodata is 2357024.
The vma increase is expected because .relr.dyn is squashed somewhere
before .text. But size_relative_relocs may see the state in which .text
is at 36704 but .rodata "is" still at 2350944. Thus the distance
between .text and .rodata can be under-estimated and overflowing
R_LARCH_PCREL20_S2 reloc can be created.
To avoid this issue, if size_relative_relocs is updating the size of
.relr.dyn, just supress the normal relaxation in this relax trip. In
this situation size_relative_relocs should have been demending the next
relax trip, so the normal relaxation can happen in the next trip.
I tried to make a reduced test case but failed.
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
bfd/elfnn-loongarch.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 73eea0f9..0c499c47 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -121,6 +121,12 @@ struct loongarch_elf_link_hash_table
/* Layout recomputation count. */
bfd_size_type relr_layout_iter;
+
+ /* In BFD DT_RELR is implemented as a "relaxation." If in a relax trip
+ size_relative_relocs is updating the layout, relax_section may see
+ a partially updated state (some sections have vma updated but the
+ others do not), and it's unsafe to do the normal relaxation. */
+ bool layout_mutating_for_relr;
};
struct loongarch_elf_section_data
@@ -2210,6 +2216,8 @@ loongarch_elf_size_relative_relocs (struct bfd_link_info *info,
*need_layout = false;
}
}
+
+ htab->layout_mutating_for_relr = *need_layout;
return true;
}
@@ -5256,6 +5264,13 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
return true;
struct loongarch_elf_link_hash_table *htab = loongarch_elf_hash_table (info);
+
+ /* It may happen that some sections have updated vma but the others do
+ not. Go to the next relax trip (size_relative_relocs should have
+ been demending another relax trip anyway). */
+ if (htab->layout_mutating_for_relr)
+ return true;
+
if (bfd_link_relocatable (info)
|| sec->sec_flg0
|| (sec->flags & SEC_RELOC) == 0
--
2.33.0

View File

@ -0,0 +1,27 @@
From 8b0f08599a65c649ce88b53b8042a13d1b307371 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Fri, 26 Jan 2024 11:16:49 +0800
Subject: [PATCH 054/123] LoongArch: Fix a bug of getting relocation type
The old code works because R_LARCH_RELAX has no symbol index. It causes
'(rel + 1)->r_info == R_LARCH_RELAX' is 1 and ELFNN_R_TYPE (1) is 1.
---
bfd/elfnn-loongarch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 858b95e1..2e72fe5c 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -4158,7 +4158,7 @@ loongarch_relax_tls_le (bfd *abfd, asection *sec,
static uint32_t insn_rj,insn_rd;
symval = symval - elf_hash_table (link_info)->tls_sec->vma;
/* Whether the symbol offset is in the interval (offset < 0x800). */
- if (ELFNN_R_TYPE ((rel + 1)->r_info == R_LARCH_RELAX) && (symval < 0x800))
+ if (ELFNN_R_TYPE ((rel + 1)->r_info) == R_LARCH_RELAX && (symval < 0x800))
{
switch (ELFNN_R_TYPE (rel->r_info))
{
--
2.33.0

View File

@ -0,0 +1,87 @@
From c49ea2f71e219ee85f2dd18ad18a928b135d45f9 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Mon, 12 Aug 2024 18:23:46 +0800
Subject: [PATCH 107/123] LoongArch: Fix assertion failure with DT_RELR
In the DT_RELR implementation I missed a code path emiting relative
reloc entries. Then the already packed relative reloc entries will be
(unnecessarily) pushed into .rela.dyn but we've not allocated the space
for them, triggering an assertion failure.
Unfortunately I failed to notice the issue until profiled bootstrapping
GCC with LTO and -Wl,-z,pack-relative-relocs. The failure can be easily
triggered by linking a "hello world" program with -fprofile-generate and
LTO:
$ PATH=$HOME/ld-test:$PATH gcc hw.c -fprofile-generate -Wl,-z,pack-relative-relocs -flto
/home/xry111/git-repos/binutils-build/TEST/ld: BFD (GNU Binutils) 2.43.50.20240802 assertion fail ../../binutils-gdb/bfd/elfnn-loongarch.c:2628
/home/xry111/git-repos/binutils-build/TEST/ld: BFD (GNU Binutils) 2.43.50.20240802 assertion fail ../../binutils-gdb/bfd/elfnn-loongarch.c:2628
collect2: error: ld returned 1 exit status
And the reduced test case is just incredibly simple (included in the
patch) so it seems I'm just stupid enough to fail to detect it before.
Let's fix it now anyway.
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
bfd/elfnn-loongarch.c | 3 ++-
ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp | 1 +
ld/testsuite/ld-loongarch-elf/relr-got-start.d | 7 +++++++
ld/testsuite/ld-loongarch-elf/relr-got-start.s | 5 +++++
4 files changed, 15 insertions(+), 1 deletion(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-got-start.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relr-got-start.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index adf16ddc..73eea0f9 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -4130,7 +4130,8 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bfd_link_pic (info),
h)
&& bfd_link_pic (info)
- && LARCH_REF_LOCAL (info, h))
+ && LARCH_REF_LOCAL (info, h)
+ && !info->enable_dt_relr)
{
Elf_Internal_Rela rela;
rela.r_offset = sec_addr (got) + got_off;
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 232e7c20..78726900 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -161,6 +161,7 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "relr-data-pie"
run_dump_test "relr-discard-pie"
run_dump_test "relr-got-pie"
+ run_dump_test "relr-got-start"
run_dump_test "relr-text-pie"
run_dump_test "abssym_pie"
}
diff --git a/ld/testsuite/ld-loongarch-elf/relr-got-start.d b/ld/testsuite/ld-loongarch-elf/relr-got-start.d
new file mode 100644
index 00000000..0b1a5b98
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-got-start.d
@@ -0,0 +1,7 @@
+#source: relr-got-start.s
+#ld: -pie -z pack-relative-relocs -T relr-relocs.ld
+#readelf: -rW
+
+Relocation section '\.relr\.dyn' at offset 0x[a-z0-f]+ contains 1 entry which relocates 1 location:
+Index: Entry Address Symbolic Address
+0000: 0000000000020008 0000000000020008 _GLOBAL_OFFSET_TABLE_ \+ 0x8
diff --git a/ld/testsuite/ld-loongarch-elf/relr-got-start.s b/ld/testsuite/ld-loongarch-elf/relr-got-start.s
new file mode 100644
index 00000000..c89fb425
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relr-got-start.s
@@ -0,0 +1,5 @@
+.globl _start
+_start:
+ pcalau12i $r5,%got_pc_hi20(_start)
+ ld.d $r5,$r5,%got_pc_lo12(_start)
+ ret
--
2.33.0

View File

@ -0,0 +1,269 @@
From 601d68c3a9866761ca19d1c27186f30de68a7af5 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Sun, 30 Jun 2024 15:18:22 +0800
Subject: [PATCH 096/123] LoongArch: Fix bad reloc with mixed visibility ifunc
symbols in shared libraries
With a simple test case:
.globl ifunc
.globl ifunc_hidden
.hidden ifunc_hidden
.type ifunc, %gnu_indirect_function
.type ifunc_hidden, %gnu_indirect_function
.text
.align 2
ifunc: ret
ifunc_hidden: ret
test:
bl ifunc
bl ifunc_hidden
"ld -shared" produces a shared object with one R_LARCH_NONE (instead of
R_LARCH_JUMP_SLOT as we expect) to relocate the GOT entry of "ifunc".
It's because the indices in .plt and .rela.plt mismatches for
STV_DEFAULT STT_IFUNC symbols when another PLT entry exists for a
STV_HIDDEN STT_IFUNC symbol, and such a mismatch breaks the logic of
loongarch_elf_finish_dynamic_symbol. Fix the issue by reordering .plt
so the indices no longer mismatch.
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
bfd/elfnn-loongarch.c | 77 ++++++++++++++++---
ld/testsuite/ld-loongarch-elf/ifunc-reloc.d | 19 +++++
ld/testsuite/ld-loongarch-elf/ifunc-reloc.s | 55 +++++++++++++
.../ld-loongarch-elf/ld-loongarch-elf.exp | 1 +
4 files changed, 140 insertions(+), 12 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/ifunc-reloc.d
create mode 100644 ld/testsuite/ld-loongarch-elf/ifunc-reloc.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index fa0a5e38..6b1a4ecc 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -1716,9 +1716,10 @@ local_allocate_ifunc_dyn_relocs (struct bfd_link_info *info,
ifunc dynamic relocs. */
static bool
-elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf)
+elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
+ struct bfd_link_info *info,
+ bool ref_local)
{
- struct bfd_link_info *info;
/* An example of a bfd_link_hash_indirect symbol is versioned
symbol. For example: __gxx_personality_v0(bfd_link_hash_indirect)
-> __gxx_personality_v0(bfd_link_hash_defined)
@@ -1734,20 +1735,18 @@ elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
- info = (struct bfd_link_info *) inf;
-
/* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
here if it is defined and referenced in a non-shared object. */
if (h->type == STT_GNU_IFUNC && h->def_regular)
{
- if (SYMBOL_REFERENCES_LOCAL (info, h))
+ if (ref_local && SYMBOL_REFERENCES_LOCAL (info, h))
return local_allocate_ifunc_dyn_relocs (info, h,
&h->dyn_relocs,
PLT_ENTRY_SIZE,
PLT_HEADER_SIZE,
GOT_ENTRY_SIZE,
false);
- else
+ else if (!ref_local && !SYMBOL_REFERENCES_LOCAL (info, h))
return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
&h->dyn_relocs,
PLT_ENTRY_SIZE,
@@ -1759,6 +1758,23 @@ elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h, void *inf)
return true;
}
+static bool
+elfNN_allocate_ifunc_dynrelocs_ref_local (struct elf_link_hash_entry *h,
+ void *info)
+{
+ return elfNN_allocate_ifunc_dynrelocs (h, (struct bfd_link_info *) info,
+ true);
+}
+
+static bool
+elfNN_allocate_ifunc_dynrelocs_ref_global (struct elf_link_hash_entry *h,
+ void *info)
+{
+ return elfNN_allocate_ifunc_dynrelocs (h, (struct bfd_link_info *) info,
+ false);
+}
+
+
/* Allocate space in .plt, .got and associated reloc sections for
ifunc dynamic relocs. */
@@ -1774,7 +1790,7 @@ elfNN_allocate_local_ifunc_dynrelocs (void **slot, void *inf)
|| h->root.type != bfd_link_hash_defined)
abort ();
- return elfNN_allocate_ifunc_dynrelocs (h, inf);
+ return elfNN_allocate_ifunc_dynrelocs_ref_local (h, inf);
}
/* Set DF_TEXTREL if we find any dynamic relocs that apply to
@@ -1933,11 +1949,48 @@ loongarch_elf_size_dynamic_sections (bfd *output_bfd,
sym dynamic relocs. */
elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
- /* Allocate global ifunc sym .plt and .got entries, and space for global
- ifunc sym dynamic relocs. */
- elf_link_hash_traverse (&htab->elf, elfNN_allocate_ifunc_dynrelocs, info);
-
- /* Allocate .plt and .got entries, and space for local ifunc symbols. */
+ /* Allocate global ifunc sym .plt and .got entries, and space for
+ *preemptible* ifunc sym dynamic relocs. Note that we must do it
+ for *all* preemptible ifunc (including local ifuncs and STV_HIDDEN
+ ifuncs) before doing it for any non-preemptible ifunc symbol:
+ assuming we are not so careful, when we link a shared library the
+ correlation of .plt and .rela.plt might look like:
+
+ idx in .plt idx in .rela.plt
+ ext_func1@plt 0 0
+ ext_func2@plt 1 1
+ ext_func3@plt 2 2
+ hidden_ifunc1@plt 3 None: it's in .rela.got
+ hidden_ifunc2@plt 4 None: it's in .rela.got
+ normal_ifunc1@plt 5 != 3
+ normal_ifunc2@plt 6 != 4
+ local_ifunc@plt 7 None: it's in .rela.got
+
+ Now oops the indices for normal_ifunc{1,2} in .rela.plt were different
+ from the indices in .plt :(. This would break finish_dynamic_symbol
+ which assumes the index in .rela.plt matches the index in .plt.
+
+ So let's be careful and make it correct:
+
+ idx in .plt idx in .rela.plt
+ ext_func1@plt 0 0
+ ext_func2@plt 1 1
+ ext_func3@plt 2 2
+ normal_ifunc1@plt 3 3
+ normal_ifunc2@plt 4 4
+ hidden_ifunc1@plt 5 None: it's in .rela.got
+ hidden_ifunc2@plt 6 None: it's in .rela.got
+ local_ifunc@plt 7 None: it's in .rela.got
+
+ Now normal_ifuncs first. */
+ elf_link_hash_traverse (&htab->elf,
+ elfNN_allocate_ifunc_dynrelocs_ref_global, info);
+
+ /* Next hidden_ifuncs follows. */
+ elf_link_hash_traverse (&htab->elf,
+ elfNN_allocate_ifunc_dynrelocs_ref_local, info);
+
+ /* Finally local_ifuncs. */
htab_traverse (htab->loc_hash_table,
elfNN_allocate_local_ifunc_dynrelocs, info);
diff --git a/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d b/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d
new file mode 100644
index 00000000..cb592874
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d
@@ -0,0 +1,19 @@
+#ld: -shared
+#readelf: -Wr
+
+#...
+.*'\.rela\.dyn'.*
+#...
+.* R_LARCH_RELATIVE .*
+.* R_LARCH_IRELATIVE .*
+.* R_LARCH_IRELATIVE .*
+.* R_LARCH_IRELATIVE .*
+#...
+.*'\.rela\.plt'.*
+#...
+.* R_LARCH_JUMP_SLOT .*
+.* R_LARCH_JUMP_SLOT .*
+.* R_LARCH_JUMP_SLOT .*
+.* R_LARCH_JUMP_SLOT .*
+.* R_LARCH_JUMP_SLOT .*
+.* R_LARCH_JUMP_SLOT .*
diff --git a/ld/testsuite/ld-loongarch-elf/ifunc-reloc.s b/ld/testsuite/ld-loongarch-elf/ifunc-reloc.s
new file mode 100644
index 00000000..e59f2b20
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/ifunc-reloc.s
@@ -0,0 +1,55 @@
+.globl foo
+.globl foo_hidden1
+.globl foo_hidden2
+.globl foo_protected
+
+.type foo, %gnu_indirect_function
+.type foo_hidden1, %gnu_indirect_function
+.type foo_hidden2, %gnu_indirect_function
+.type foo_protected, %gnu_indirect_function
+.type foo_internal, %gnu_indirect_function
+
+.hidden foo_hidden1
+.hidden foo_hidden2
+
+.protected foo_protected
+
+.globl ext_ifunc1
+.globl ext_ifunc2
+.type ext_ifunc1, %gnu_indirect_function
+.type ext_ifunc2, %gnu_indirect_function
+
+.text
+.align 2
+foo:
+ ret
+
+foo_hidden1:
+ ret
+
+foo_hidden2:
+ ret
+
+foo_protected:
+ ret
+
+foo_internal:
+ ret
+
+test:
+ la.got $a0, num
+ # The order is deliberately shuffled.
+ bl ext_ifunc1
+ bl foo
+ bl foo_hidden1
+ bl ext_func1
+ bl foo_protected
+ bl foo_internal
+ bl foo_hidden2
+ bl ext_func2
+ bl ext_ifunc2
+
+.data
+.align 3
+num:
+ .quad 114514
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 7ffabe2c..506dac3e 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -133,6 +133,7 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "reloc_ler_with_shared"
run_dump_test "reloc_abs_with_shared"
run_dump_test "r_larch_32_elf64"
+ run_dump_test "ifunc-reloc"
}
if [check_pie_support] {
--
2.33.0

View File

@ -0,0 +1,38 @@
From 30f91452b13e20976c0d470f1e097c083571459b Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Thu, 11 Jul 2024 19:00:43 +0800
Subject: [PATCH 102/123] LoongArch: Fix dwarf3 test cases from XPASS to PASS
In the past, the .align directive generated a label that did not match
the regular expression, and we set it to XFAIL.
But now it matches fine so it becomes XPASS. We fix it with PASS.
---
ld/testsuite/ld-elf/dwarf.exp | 5 -----
1 file changed, 5 deletions(-)
diff --git a/ld/testsuite/ld-elf/dwarf.exp b/ld/testsuite/ld-elf/dwarf.exp
index 5cb2aab9..3d1b99ac 100644
--- a/ld/testsuite/ld-elf/dwarf.exp
+++ b/ld/testsuite/ld-elf/dwarf.exp
@@ -52,9 +52,6 @@ set build_tests {
{"DWARF parse during linker error"
"" "-fno-toplevel-reorder"
{dwarf2a.c dwarf2b.c} {{error_output "dwarf2.err"}} "dwarf2.x"}
-}
-
-set build_tests_dwarf3 {
{"Handle no DWARF information"
"" "-g0"
{dwarf3.c} {{error_output "dwarf3.err"}} "dwarf3.x"}
@@ -75,8 +72,6 @@ set run_tests {
set old_CFLAGS "$CFLAGS_FOR_TARGET"
append CFLAGS_FOR_TARGET " $NOSANITIZE_CFLAGS"
run_cc_link_tests $build_tests
-setup_xfail loongarch*-*-*
-run_cc_link_tests $build_tests_dwarf3
run_ld_link_exec_tests $run_tests
set CFLAGS_FOR_TARGET "$old_CFLAGS"
--
2.33.0

View File

@ -0,0 +1,149 @@
From e361b5c22683557c2214f8bb9032d80bb7c3d4e0 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Thu, 7 Mar 2024 11:09:14 +0800
Subject: [PATCH 072/123] LoongArch: Fix gas and ld test cases
* After adding the old LE relax, all old LE relocations will have
an R_LARCH_RELAX relocation. Fix the gas test case failure caused
by the implementation of the old LE relax.
* loongarch64-elf does not support pie and -z norelro options,
removed in test files.
---
gas/testsuite/gas/loongarch/relocs_32.d | 2 ++
gas/testsuite/gas/loongarch/relocs_64.d | 4 ++++
ld/testsuite/ld-loongarch-elf/desc-le-norelax.d | 2 +-
ld/testsuite/ld-loongarch-elf/desc-le-relax.d | 2 +-
ld/testsuite/ld-loongarch-elf/ie-le-norelax.d | 2 +-
ld/testsuite/ld-loongarch-elf/ie-le-relax.d | 2 +-
ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp | 5 ++++-
ld/testsuite/ld-loongarch-elf/macro_op_32.d | 4 ++++
8 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/gas/testsuite/gas/loongarch/relocs_32.d b/gas/testsuite/gas/loongarch/relocs_32.d
index 3e1bb62e..96ef2800 100644
--- a/gas/testsuite/gas/loongarch/relocs_32.d
+++ b/gas/testsuite/gas/loongarch/relocs_32.d
@@ -30,8 +30,10 @@ Disassembly of section .text:
24: R_LARCH_GOT_LO12 .L1
28: 14000004 lu12i.w \$a0, 0
28: R_LARCH_TLS_LE_HI20 TLSL1
+ 28: R_LARCH_RELAX \*ABS\*
2c: 03800085 ori \$a1, \$a0, 0x0
2c: R_LARCH_TLS_LE_LO12 TLSL1
+ 2c: R_LARCH_RELAX \*ABS\*
30: 1a000004 pcalau12i \$a0, 0
30: R_LARCH_TLS_IE_PC_HI20 TLSL1
34: 02c00005 li.d \$a1, 0
diff --git a/gas/testsuite/gas/loongarch/relocs_64.d b/gas/testsuite/gas/loongarch/relocs_64.d
index 631137eb..35dde02f 100644
--- a/gas/testsuite/gas/loongarch/relocs_64.d
+++ b/gas/testsuite/gas/loongarch/relocs_64.d
@@ -48,12 +48,16 @@ Disassembly of section .text:
48: R_LARCH_GOT64_HI12 .L1
4c: 14000004 lu12i.w \$a0, 0
4c: R_LARCH_TLS_LE_HI20 TLSL1
+ 4c: R_LARCH_RELAX \*ABS\*
50: 03800085 ori \$a1, \$a0, 0x0
50: R_LARCH_TLS_LE_LO12 TLSL1
+ 50: R_LARCH_RELAX \*ABS\*
54: 16000004 lu32i.d \$a0, 0
54: R_LARCH_TLS_LE64_LO20 TLSL1
+ 54: R_LARCH_RELAX \*ABS\*
58: 03000085 lu52i.d \$a1, \$a0, 0
58: R_LARCH_TLS_LE64_HI12 TLSL1
+ 58: R_LARCH_RELAX \*ABS\*
5c: 1a000004 pcalau12i \$a0, 0
5c: R_LARCH_TLS_IE_PC_HI20 TLSL1
60: 02c00005 li.d \$a1, 0
diff --git a/ld/testsuite/ld-loongarch-elf/desc-le-norelax.d b/ld/testsuite/ld-loongarch-elf/desc-le-norelax.d
index 5a53245a..43749f1b 100644
--- a/ld/testsuite/ld-loongarch-elf/desc-le-norelax.d
+++ b/ld/testsuite/ld-loongarch-elf/desc-le-norelax.d
@@ -1,5 +1,5 @@
#as:
-#ld: -z norelro -e0 --no-relax
+#ld: -e0 --no-relax
#objdump: -dr
#skip: loongarch32-*-*
diff --git a/ld/testsuite/ld-loongarch-elf/desc-le-relax.d b/ld/testsuite/ld-loongarch-elf/desc-le-relax.d
index 03b5535e..71a540fd 100644
--- a/ld/testsuite/ld-loongarch-elf/desc-le-relax.d
+++ b/ld/testsuite/ld-loongarch-elf/desc-le-relax.d
@@ -1,5 +1,5 @@
#as:
-#ld: -z norelro -e0
+#ld: -e0
#objdump: -dr -M no-aliases
#skip: loongarch32-*-*
diff --git a/ld/testsuite/ld-loongarch-elf/ie-le-norelax.d b/ld/testsuite/ld-loongarch-elf/ie-le-norelax.d
index 81d78ca3..0221b495 100644
--- a/ld/testsuite/ld-loongarch-elf/ie-le-norelax.d
+++ b/ld/testsuite/ld-loongarch-elf/ie-le-norelax.d
@@ -1,5 +1,5 @@
#as:
-#ld: -z norelro -e0 --no-relax
+#ld: -e0 --no-relax
#objdump: -dr
#skip: loongarch32-*-*
diff --git a/ld/testsuite/ld-loongarch-elf/ie-le-relax.d b/ld/testsuite/ld-loongarch-elf/ie-le-relax.d
index 03b5535e..71a540fd 100644
--- a/ld/testsuite/ld-loongarch-elf/ie-le-relax.d
+++ b/ld/testsuite/ld-loongarch-elf/ie-le-relax.d
@@ -1,5 +1,5 @@
#as:
-#ld: -z norelro -e0
+#ld: -e0
#objdump: -dr -M no-aliases
#skip: loongarch32-*-*
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index ca428f5b..c839f525 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -133,6 +133,10 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "desc-relax"
}
+ if [check_pie_support] {
+ run_dump_test "pie_discard"
+ }
+
run_dump_test "max_imm_b16"
run_dump_test "max_imm_b21"
run_dump_test "max_imm_b26"
@@ -145,7 +149,6 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "underflow_b21"
run_dump_test "underflow_b26"
run_dump_test "underflow_pcrel20"
- run_dump_test "pie_discard"
run_dump_test "desc-le-norelax"
run_dump_test "desc-le-relax"
run_dump_test "ie-le-norelax"
diff --git a/ld/testsuite/ld-loongarch-elf/macro_op_32.d b/ld/testsuite/ld-loongarch-elf/macro_op_32.d
index a7349aa8..8fd69922 100644
--- a/ld/testsuite/ld-loongarch-elf/macro_op_32.d
+++ b/ld/testsuite/ld-loongarch-elf/macro_op_32.d
@@ -49,12 +49,16 @@ Disassembly of section .text:
3c: R_LARCH_RELAX \*ABS\*
40: 14000004 lu12i.w \$a0, 0
40: R_LARCH_TLS_LE_HI20 TLS1
+ 40: R_LARCH_RELAX \*ABS\*
44: 03800084 ori \$a0, \$a0, 0x0
44: R_LARCH_TLS_LE_LO12 TLS1
+ 44: R_LARCH_RELAX \*ABS\*
48: 1a000004 pcalau12i \$a0, 0
48: R_LARCH_TLS_IE_PC_HI20 TLS1
+ 48: R_LARCH_RELAX \*ABS\*
4c: 28800084 ld.w \$a0, \$a0, 0
4c: R_LARCH_TLS_IE_PC_LO12 TLS1
+ 4c: R_LARCH_RELAX \*ABS\*
50: 1a000004 pcalau12i \$a0, 0
50: R_LARCH_TLS_LD_PC_HI20 TLS1
50: R_LARCH_RELAX \*ABS\*
--
2.33.0

View File

@ -0,0 +1,42 @@
From 1dfd5f57202ef519e7ae21219be9c16e7a163072 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Sat, 15 Jul 2023 17:56:07 +0800
Subject: [PATCH 001/123] LoongArch: Fix immediate overflow check bug
For B16/B21/B26/PCREL20_S2 relocations, if immediate overflow check after
rightshift, and the mask need to include sign bit.
Now, the immediate overflow check before rightshift for easier understand.
bfd/ChangeLog:
* elfxx-loongarch.c (reloc_bits_pcrel20_s2): Delete.
(reloc_bits_b16): Delete.
(reloc_bits_b21): Delete.
(reloc_bits_b26): Delete.
(reloc_sign_bits): New.
---
bfd/elfxx-loongarch.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 35676ead..16a2b2fc 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -1708,10 +1708,12 @@ reloc_sign_bits (bfd *abfd, reloc_howto_type *howto, bfd_vma *fix_val)
{
case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
case R_LARCH_B26:
- /* Perform insn bits field. 25:16>>16, 15:0<<10. */
+ /* Perform insn bits field. 15:0<<10, 25:16>>16. */
val = ((val & 0xffff) << 10) | ((val >> 16) & 0x3ff);
break;
+ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
case R_LARCH_B21:
+ /* Perform insn bits field. 15:0<<10, 20:16>>16. */
val = ((val & 0xffff) << 10) | ((val >> 16) & 0x1f);
break;
default:
--
2.33.0

View File

@ -0,0 +1,91 @@
From 32434338ecb0d5547e2cb7986f98040bc726f43f Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Wed, 17 Jul 2024 10:54:46 +0800
Subject: [PATCH 104/123] LoongArch: Fix ld FAIL test cases
To avoid differences in C library paths on different systems
use gcc instead of ld to perform the test.
Problems caused by adding options to different distributions
will not be fixed.
---
ld/testsuite/ld-loongarch-elf/pic.exp | 41 ++++++++++++++++-----------
1 file changed, 24 insertions(+), 17 deletions(-)
diff --git a/ld/testsuite/ld-loongarch-elf/pic.exp b/ld/testsuite/ld-loongarch-elf/pic.exp
index 2ca5b3a0..241d198d 100644
--- a/ld/testsuite/ld-loongarch-elf/pic.exp
+++ b/ld/testsuite/ld-loongarch-elf/pic.exp
@@ -92,17 +92,6 @@ set link_tests [list \
] \
"nopic-global" \
] \
- [list \
- "$testname readelf -s/-r nopic-global-so" \
- "-L./tmpdir -lnopic-global -L/usr/lib -lc" "" \
- "" \
- {nopic-global.s} \
- [list \
- [list readelf -s nopic-global-so.sd] \
- [list readelf -r nopic-global-so.rd] \
- ] \
- "nopic-global-so" \
- ] \
[list \
"$testname readelf -s/-x nopic-weak-global" \
"-T pic.ld" "" \
@@ -114,19 +103,35 @@ set link_tests [list \
] \
"nopic-weak-global" \
] \
+]
+
+# Since the c library path may be different in different
+# Distributions, the test program can link to the c library
+# using the gcc instead of ld to avoid system impact.
+run_ld_link_tests $link_tests
+
+
+
+set link_tests_libc [list \
+ [list \
+ "$testname readelf -s/-r nopic-global-so" \
+ "-L./tmpdir -lnopic-global -L/usr/lib -lc" "" \
+ {nopic-global.s} \
+ {{readelf {-s} nopic-global-so.sd} \
+ {readelf {-r} nopic-global-so.rd}} \
+ "nopic-global-so" \
+ ] \
[list \
"$testname readelf -s/-x nopic-weak-global-so" \
"-L./tmpdir -lnopic-global -L/usr/lib -lc" "" \
- "" \
{nopic-weak-global.s} \
- [list \
- [list readelf -s nopic-weak-global-so.sd] \
- [list readelf -r nopic-weak-global-so.rd] \
- ] \
+ {{readelf {-s} nopic-weak-global-so.sd} \
+ {readelf {-r} nopic-weak-global-so.rd}} \
"nopic-weak-global-so" \
] \
]
+
# 0:name
# 1:ld/ar leading options, placed before object files
# 2:ld/ar trailing options, placed after object files
@@ -135,7 +140,9 @@ set link_tests [list \
# 5:list of actions, options and expected outputs.
# 6:name of output file
# 7:compiler flags (optional)
-run_ld_link_tests $link_tests
+run_cc_link_tests $link_tests_libc
+
+
set testname "nopic link exec test"
--
2.33.0

View File

@ -0,0 +1,29 @@
From 765057030817ea3083dd7a7ca607c89d21d4eed3 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Tue, 23 Apr 2024 15:49:09 +0800
Subject: [PATCH 085/123] LoongArch: Fix ld test failures caused by using
instruction aliases
Different versions of objdump may take different forms of output
for instructions. Use -M no-aliases to avoid the failure of ld
test cases caused by objdump using aliases.
---
ld/testsuite/ld-loongarch-elf/relax.exp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index bfd6d1c0..c1da9c10 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -37,7 +37,7 @@ proc run_partial_linking_align_test {} {
|| ![ld_link $ld tmpdir/$testname "tmpdir/$testname.os -e0 -Ttext 0x1000"] } {
fail $testname
} else {
- set objdump_output [run_host_cmd "objdump" "-d tmpdir/$testname"]
+ set objdump_output [run_host_cmd "objdump" "-d -M no-aliases tmpdir/$testname"]
if { [ regexp ".*1010:\\s*4c000020\\s*jirl.*" $objdump_output ] } {
pass $testname
} else {
--
2.33.0

View File

@ -0,0 +1,121 @@
From 9836fa5ff54d6543ab05e552579810ef150d8a77 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Thu, 1 Dec 2022 17:23:14 +0800
Subject: [PATCH 039/123] LoongArch: Fix linker generate PLT entry for data
symbol
With old "medium" code model, we call a function with a pair of PCALAU12I
and JIRL instructions. The assembler produces something like:
8: 1a00000c pcalau12i $t0, 0
8: R_LARCH_PCALA_HI20 g
c: 4c000181 jirl $ra, $t0, 0
c: R_LARCH_PCALA_LO12 g
The linker generates a "PLT entry" for data without any diagnostic.
If "g" is a data symbol and ld with -shared option, it may load two
instructions in the PLT.
Without -shared option, loongarch_elf_adjust_dynamic_symbol can delete PLT
entry.
For R_LARCH_PCALA_HI20 relocation, linker only generate PLT entry for STT_FUNC
and STT_GNU_IFUNC symbols.
---
bfd/elfnn-loongarch.c | 6 ++++-
ld/testsuite/ld-loongarch-elf/data-plt.s | 20 ++++++++++++++++
.../ld-loongarch-elf/ld-loongarch-elf.exp | 24 +++++++++++++++++++
ld/testsuite/ld-loongarch-elf/libjirl.s | 1 +
4 files changed, 50 insertions(+), 1 deletion(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/data-plt.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index f7eb66da..73e4b819 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -891,8 +891,12 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
h->non_got_ref = 1;
break;
+ /* For normal cmodel, pcalau12i + addi.d/w used to data.
+ For first version medium cmodel, pcalau12i + jirl are used to
+ function call, it need to creat PLT entry for STT_FUNC and
+ STT_GNU_IFUNC type symbol. */
case R_LARCH_PCALA_HI20:
- if (h != NULL)
+ if (h != NULL && (STT_FUNC == h->type || STT_GNU_IFUNC == h->type))
{
/* For pcalau12i + jirl. */
h->needs_plt = 1;
diff --git a/ld/testsuite/ld-loongarch-elf/data-plt.s b/ld/testsuite/ld-loongarch-elf/data-plt.s
new file mode 100644
index 00000000..faff052c
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/data-plt.s
@@ -0,0 +1,20 @@
+# The first version medium codel model function call is: pcalau12i + jirl.
+# R_LARCH_PCALA_HI20 only need to generate PLT entry for function symbols.
+ .text
+ .globl a
+
+ .data
+ .align 2
+ .type a, @object
+ .size a, 4
+a:
+ .word 1
+
+ .text
+ .align 2
+ .globl test
+ .type test, @function
+test:
+ pcalau12i $r12,%pc_hi20(a)
+ ld.w $r12,$r12,%pc_lo12(a)
+ .size test, .-test
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 8dc04fea..64e644d3 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -59,6 +59,30 @@ if [istarget "loongarch64-*-*"] {
]
}
+ # loongarch*-elf target do not support -shared option
+ if [check_shared_lib_support] {
+ run_ld_link_tests \
+ [list \
+ [list \
+ "data plt" \
+ "-shared" "" \
+ "" \
+ {data-plt.s} \
+ {} \
+ "data-plt.so" \
+ ] \
+ ]
+
+ if [file exist "tmpdir/data-plt.so"] {
+ set objdump_output [run_host_cmd "objdump" "-d tmpdir/data-plt.so"]
+ if { [ regexp "<a@plt>" $objdump_output] } {
+ fail "data plt"
+ } {
+ pass "data plt"
+ }
+ }
+ }
+
run_ld_link_tests \
[list \
[list \
diff --git a/ld/testsuite/ld-loongarch-elf/libjirl.s b/ld/testsuite/ld-loongarch-elf/libjirl.s
index 4d963870..de028c5a 100644
--- a/ld/testsuite/ld-loongarch-elf/libjirl.s
+++ b/ld/testsuite/ld-loongarch-elf/libjirl.s
@@ -1,2 +1,3 @@
+.type func @function
pcalau12i $r12, %pc_hi20(func)
jirl $r1,$r12, %pc_lo12(func)
--
2.33.0

View File

@ -0,0 +1,206 @@
From e86a0c83da7c0d80f02428d400538113f8294757 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Wed, 27 Dec 2023 17:10:41 +0800
Subject: [PATCH 038/123] LoongArch: Fix loongarch*-elf target ld testsuite
failure
The loongarch*-elf target does not support SHARED and PIE, so this
target is skipped for some tests that require these options.
---
.../ld-loongarch-elf/ld-loongarch-elf.exp | 30 +++---
.../ld-loongarch-elf/local-ifunc-reloc.d | 1 +
ld/testsuite/ld-loongarch-elf/relax.exp | 99 ++++++++++---------
3 files changed, 71 insertions(+), 59 deletions(-)
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 2a5709a5..8dc04fea 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -43,19 +43,21 @@ if [istarget "loongarch32-*-*"] {
}
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" \
- ] \
- ]
+ if [check_shared_lib_support] {
+ run_ld_link_tests \
+ [list \
+ [list \
+ "64_pcrel" \
+ "-e 0x0 -z relro" "" \
+ "" \
+ {64_pcrel.s} \
+ [list \
+ [list objdump -D 64_pcrel.d] \
+ ] \
+ "64_pcrel" \
+ ] \
+ ]
+ }
run_ld_link_tests \
[list \
@@ -71,10 +73,12 @@ if [istarget "loongarch64-*-*"] {
}
if [istarget "loongarch64-*-*"] {
+ if [check_shared_lib_support] {
run_dump_test "desc-ie"
run_dump_test "desc-le"
run_dump_test "ie-le"
run_dump_test "tlsdesc-dso"
run_dump_test "desc-norelax"
run_dump_test "desc-relax"
+ }
}
diff --git a/ld/testsuite/ld-loongarch-elf/local-ifunc-reloc.d b/ld/testsuite/ld-loongarch-elf/local-ifunc-reloc.d
index bf73d9f2..8e1d3f0d 100644
--- a/ld/testsuite/ld-loongarch-elf/local-ifunc-reloc.d
+++ b/ld/testsuite/ld-loongarch-elf/local-ifunc-reloc.d
@@ -1,6 +1,7 @@
#as:
#ld: -shared -z combreloc
#objdump: -R
+#skip: loongarch*-elf
.*: +file format .*
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index b697d015..6c65318a 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -150,17 +150,19 @@ if [istarget loongarch64-*-*] {
}
}
- run_ld_link_tests \
- [list \
- [list \
- "loongarch relax .so build" \
- "-shared -e 0x0" "" \
- "" \
- {relax-so.s} \
- {} \
- "relax-so" \
- ] \
- ]
+ if [check_shared_lib_support] {
+ 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"]
@@ -173,29 +175,31 @@ if [istarget loongarch64-*-*] {
# 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 0x120004000 -pie -z relro" "" \
- "" \
- {relax-segment-min.s} \
- {} \
- "relax-segment-min" \
- ] \
- ]
+ if [check_pie_support] {
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch relax segment alignment min" \
+ "-e0 -Ttext 0x120004000 -pie -z relro" "" \
+ "" \
+ {relax-segment-min.s} \
+ {} \
+ "relax-segment-min" \
+ ] \
+ ]
- run_ld_link_tests \
- [list \
- [list \
- "loongarch relax segment alignment max" \
- "-e0 -Ttext 0x120004000 -pie -z relro" "" \
- "" \
- {relax-segment-max.s} \
- {} \
- "relax-segment-max" \
- ] \
- ]
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch relax segment alignment max" \
+ "-e0 -Ttext 0x120004000 -pie -z relro" "" \
+ "" \
+ {relax-segment-max.s} \
+ {} \
+ "relax-segment-max" \
+ ] \
+ ]
+ }
if [file exist "tmpdir/relax-tls-le"] {
set objdump_output1 [run_host_cmd "objdump" "-d tmpdir/relax-tls-le"]
@@ -265,19 +269,22 @@ if [istarget loongarch64-*-*] {
}
}
- run_ld_link_tests \
- [list \
- [list \
- "loongarch relax-align" \
- "-e 0x0 -z relro" "" \
- "--no-warn" \
- {relax-align.s} \
- [list \
- [list objdump -d relax-align.dd] \
- ] \
- "relax-align" \
- ] \
- ]
+
+ if [check_shared_lib_support] {
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch relax-align" \
+ "-e 0x0 -z relro" "" \
+ "--no-warn" \
+ {relax-align.s} \
+ [list \
+ [list objdump -d relax-align.dd] \
+ ] \
+ "relax-align" \
+ ] \
+ ]
+ }
set objdump_flags "-s -j .data"
run_ld_link_tests \
--
2.33.0

View File

@ -0,0 +1,413 @@
From a86ce43d41f2b4453d1137939f25c7b2c68215ee Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Wed, 22 May 2024 14:27:08 +0800
Subject: [PATCH 088/123] LoongArch: Fix relaxation overflow caused by ld -z
separate-code
ld -z separate-code let .text and .rodata in two different but read only
segment. If the symbol and pc in two segment, the offset from pc to
symbol need to consider segment alignment.
Add a function 'loongarch_two_sections_in_same_segment' to determine
whether two sections are in the same segment.
---
bfd/elfnn-loongarch.c | 101 +++++++++++-------
.../ld-loongarch-elf/relax-medium-call-1.d | 51 ++++++---
.../ld-loongarch-elf/relax-medium-call-1.s | 6 +-
.../ld-loongarch-elf/relax-medium-call.d | 51 ++++++---
.../ld-loongarch-elf/relax-medium-call.s | 6 +-
.../relax-separate-code-overflow.s | 21 ++++
ld/testsuite/ld-loongarch-elf/relax.exp | 15 +++
7 files changed, 176 insertions(+), 75 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-separate-code-overflow.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 47fd08cd..eb572a77 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3948,6 +3948,12 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
info->callbacks->reloc_overflow
(info, h ? &h->root : NULL, name, howto->name, rel->r_addend,
input_bfd, input_section, rel->r_offset);
+ if (r_type == R_LARCH_PCREL20_S2
+ || r_type == R_LARCH_TLS_LD_PCREL20_S2
+ || r_type == R_LARCH_TLS_GD_PCREL20_S2
+ || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
+ _bfd_error_handler (_("recompile with 'gcc -mno-relax' or"
+ " 'as -mno-relax' or 'ld --no-relax'"));
break;
case bfd_reloc_outofrange:
@@ -4312,6 +4318,30 @@ loongarch_relax_tls_le (bfd *abfd, asection *sec,
return true;
}
+/* Whether two sections in the same segment. */
+static bool
+loongarch_two_sections_in_same_segment (bfd *abfd, asection *a, asection *b)
+{
+ struct elf_segment_map *m;
+ for (m = elf_seg_map (abfd); m != NULL; m = m->next)
+ {
+ int i;
+ int j = 0;
+ for (i = m->count - 1; i >= 0; i--)
+ {
+ if (m->sections[i] == a)
+ j++;
+ if (m->sections[i] == b)
+ j++;
+ }
+ if (1 == j)
+ return false;
+ if (2 == j)
+ return true;
+ }
+ return false;
+}
+
/* Relax pcalau12i,addi.d => pcaddi. */
static bool
loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
@@ -4332,23 +4362,17 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
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? How to determine if
- two sections are in the same segment. */
- if (!(sym_sec->flags & SEC_READONLY))
- {
- max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
- : max_alignment;
- if (symval > pc)
- pc -= max_alignment;
- else if (symval < pc)
- pc += max_alignment;
- }
- else
- if (symval > pc)
- pc -= max_alignment;
- else if (symval < pc)
- pc += max_alignment;
+ /* If pc and symbol not in the same segment, add/sub segment alignment. */
+ if (!loongarch_two_sections_in_same_segment (info->output_bfd,
+ sec->output_section,
+ sym_sec->output_section))
+ max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
+ : max_alignment;
+
+ if (symval > pc)
+ pc -= (max_alignment > 4 ? max_alignment : 0);
+ else if (symval < pc)
+ pc += (max_alignment > 4 ? max_alignment : 0);
const uint32_t addi_d = 0x02c00000;
const uint32_t pcaddi = 0x18000000;
@@ -4387,7 +4411,7 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
/* call36 f -> bl f
tail36 $t0, f -> b f. */
static bool
-loongarch_relax_call36 (bfd *abfd, asection *sec,
+loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec,
Elf_Internal_Rela *rel, bfd_vma symval,
struct bfd_link_info *info, bool *again,
bfd_vma max_alignment)
@@ -4403,9 +4427,13 @@ loongarch_relax_call36 (bfd *abfd, asection *sec,
sec->output_offset = sec->output_section->size;
bfd_vma pc = sec_addr (sec) + rel->r_offset;
- /* If pc and symbol not in the same segment, add/sub segment alignment.
- FIXME: if there are multiple readonly segments? How to determine if
- two sections are in the same segment. */
+ /* If pc and symbol not in the same segment, add/sub segment alignment. */
+ if (!loongarch_two_sections_in_same_segment (info->output_bfd,
+ sec->output_section,
+ sym_sec->output_section))
+ max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
+ : max_alignment;
+
if (symval > pc)
pc -= (max_alignment > 4 ? max_alignment : 0);
else if (symval < pc)
@@ -4559,22 +4587,17 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
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))
- {
- max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
- : max_alignment;
- if (symval > pc)
- pc -= max_alignment;
- else if (symval < pc)
- pc += max_alignment;
- }
- else
- if (symval > pc)
- pc -= max_alignment;
- else if (symval < pc)
- pc += max_alignment;
+ /* If pc and symbol not in the same segment, add/sub segment alignment. */
+ if (!loongarch_two_sections_in_same_segment (info->output_bfd,
+ sec->output_section,
+ sym_sec->output_section))
+ max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
+ : max_alignment;
+
+ if (symval > pc)
+ pc -= (max_alignment > 4 ? max_alignment : 0);
+ else if (symval < pc)
+ pc += (max_alignment > 4 ? max_alignment : 0);
const uint32_t addi_d = 0x02c00000;
const uint32_t pcaddi = 0x18000000;
@@ -4858,8 +4881,8 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
break;
case R_LARCH_CALL36:
if (0 == info->relax_pass && (i + 2) <= sec->reloc_count)
- loongarch_relax_call36 (abfd, sec, rel, symval, info, again,
- max_alignment);
+ loongarch_relax_call36 (abfd, sec, sym_sec, rel, symval,
+ info, again, max_alignment);
break;
case R_LARCH_TLS_LE_HI20_R:
diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d
index c8ee9333..96e7bb09 100644
--- a/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d
+++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.d
@@ -1,21 +1,42 @@
-#ld: -e0 -Ttext=0x120000000 --section-start=ta=0x118000000 --section-start=tb=0x127fffffc
-#objdump: -d -j .text
+#ld: -e0
+#objdump: -d
.*:[ ]+file format .*
Disassembly of section .text:
-[ ]*0000000120000000 <__bss_start-0x4030>:
-[ ]+120000000:[ ]+54000200[ ]+bl[ ]+-134217728[ ]+# 118000000 <a>
-[ ]+120000004:[ ]+1fffc001[ ]+pcaddu18i[ ]+\$ra, -512
-[ ]+120000008:[ ]+4ffffc21[ ]+jirl[ ]+\$ra, \$ra, -4
-[ ]+12000000c:[ ]+50000200[ ]+b[ ]+-134217728[ ]+# 11800000c <b>
-[ ]+120000010:[ ]+1fffc00c[ ]+pcaddu18i[ ]+\$t0, -512
-[ ]+120000014:[ ]+4ffffd80[ ]+jirl[ ]+\$zero, \$t0, -4
-[ ]+120000018:[ ]+1e004001[ ]+pcaddu18i[ ]+\$ra, 512
-[ ]+12000001c:[ ]+4c000421[ ]+jirl[ ]+\$ra, \$ra, 4
-[ ]+120000020:[ ]+57fffdff[ ]+bl[ ]+134217724[ ]+# 12800001c <c>
-[ ]+120000024:[ ]+1e00400c[ ]+pcaddu18i[ ]+\$t0, 512
-[ ]+120000028:[ ]+4c000580[ ]+jirl[ ]+\$zero, \$t0, 4
-[ ]+12000002c:[ ]+53fffdff[ ]+b[ ]+134217724[ ]+# 128000028 <d>
+[ ]*0000000120000078 <a>:
+[ ]+120000078:[ ]+4c000020[ ]+ret
+[ ]+12000007c:[ ]+4c000020[ ]+ret
+[ ]+120000080:[ ]+4c000020[ ]+ret
+[ ]*0000000120000084 <b>:
+[ ]+120000084:[ ]+4c000020[ ]+ret
+[ ]+...
+[ ]+128000078:[ ]+54000200[ ]+bl[ ]+-134217728[ ]+# 120000078 <a>
+[ ]+12800007c:[ ]+1fffc001[ ]+pcaddu18i[ ]+\$ra, -512
+[ ]+128000080:[ ]+4ffffc21[ ]+jirl[ ]+\$ra, \$ra, -4
+[ ]+128000084:[ ]+50000200[ ]+b[ ]+-134217728[ ]+# 120000084 <b>
+[ ]+128000088:[ ]+1fffc00c[ ]+pcaddu18i[ ]+\$t0, -512
+[ ]+12800008c:[ ]+4ffffd80[ ]+jirl[ ]+\$zero, \$t0, -4
+[ ]+128000090:[ ]+1e004001[ ]+pcaddu18i[ ]+\$ra, 512
+[ ]+128000094:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
+[ ]+128000098:[ ]+57fff9ff[ ]+bl[ ]+134217720[ ]+# 130000090 <c>
+[ ]+12800009c:[ ]+1e00400c[ ]+pcaddu18i[ ]+\$t0, 512
+[ ]+1280000a0:[ ]+4c000180[ ]+jr[ ]+\$t0
+[ ]+1280000a4:[ ]+53fff9ff[ ]+b[ ]+134217720[ ]+# 13000009c <d>
+[ ]+...
+[ ]+130000070:[ ]+4c000020[ ]+ret
+[ ]+130000074:[ ]+4c000020[ ]+ret
+[ ]+130000078:[ ]+4c000020[ ]+ret
+[ ]+13000007c:[ ]+4c000020[ ]+ret
+[ ]+130000080:[ ]+4c000020[ ]+ret
+[ ]+130000084:[ ]+4c000020[ ]+ret
+[ ]+130000088:[ ]+4c000020[ ]+ret
+[ ]+13000008c:[ ]+4c000020[ ]+ret
+[ ]*0000000130000090 <c>:
+[ ]+130000090:[ ]+4c000020[ ]+ret
+[ ]+130000094:[ ]+4c000020[ ]+ret
+[ ]+130000098:[ ]+4c000020[ ]+ret
+[ ]*000000013000009c <d>:
+[ ]+13000009c:[ ]+4c000020[ ]+ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s
index 5266fdab..1770ec9f 100644
--- a/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s
+++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call-1.s
@@ -1,12 +1,12 @@
-.section "ta", "ax"
+.text
a:
ret
ret
ret
b:
ret
+ .fill 0x7fffff0
-.text
pcaddu18i $ra, %call36(a) # min offset, can relax
jirl $ra, $ra, 0
pcaddu18i $ra, %call36(a) # overflow, not relax
@@ -25,7 +25,7 @@ b:
pcaddu18i $t0, %call36(d) # max offset, can relax
jirl $zero, $t0, 0
-.section "tb", "ax"
+ .fill 0x7ffffc8
ret
ret
ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call.d b/ld/testsuite/ld-loongarch-elf/relax-medium-call.d
index c8ee9333..96e7bb09 100644
--- a/ld/testsuite/ld-loongarch-elf/relax-medium-call.d
+++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call.d
@@ -1,21 +1,42 @@
-#ld: -e0 -Ttext=0x120000000 --section-start=ta=0x118000000 --section-start=tb=0x127fffffc
-#objdump: -d -j .text
+#ld: -e0
+#objdump: -d
.*:[ ]+file format .*
Disassembly of section .text:
-[ ]*0000000120000000 <__bss_start-0x4030>:
-[ ]+120000000:[ ]+54000200[ ]+bl[ ]+-134217728[ ]+# 118000000 <a>
-[ ]+120000004:[ ]+1fffc001[ ]+pcaddu18i[ ]+\$ra, -512
-[ ]+120000008:[ ]+4ffffc21[ ]+jirl[ ]+\$ra, \$ra, -4
-[ ]+12000000c:[ ]+50000200[ ]+b[ ]+-134217728[ ]+# 11800000c <b>
-[ ]+120000010:[ ]+1fffc00c[ ]+pcaddu18i[ ]+\$t0, -512
-[ ]+120000014:[ ]+4ffffd80[ ]+jirl[ ]+\$zero, \$t0, -4
-[ ]+120000018:[ ]+1e004001[ ]+pcaddu18i[ ]+\$ra, 512
-[ ]+12000001c:[ ]+4c000421[ ]+jirl[ ]+\$ra, \$ra, 4
-[ ]+120000020:[ ]+57fffdff[ ]+bl[ ]+134217724[ ]+# 12800001c <c>
-[ ]+120000024:[ ]+1e00400c[ ]+pcaddu18i[ ]+\$t0, 512
-[ ]+120000028:[ ]+4c000580[ ]+jirl[ ]+\$zero, \$t0, 4
-[ ]+12000002c:[ ]+53fffdff[ ]+b[ ]+134217724[ ]+# 128000028 <d>
+[ ]*0000000120000078 <a>:
+[ ]+120000078:[ ]+4c000020[ ]+ret
+[ ]+12000007c:[ ]+4c000020[ ]+ret
+[ ]+120000080:[ ]+4c000020[ ]+ret
+[ ]*0000000120000084 <b>:
+[ ]+120000084:[ ]+4c000020[ ]+ret
+[ ]+...
+[ ]+128000078:[ ]+54000200[ ]+bl[ ]+-134217728[ ]+# 120000078 <a>
+[ ]+12800007c:[ ]+1fffc001[ ]+pcaddu18i[ ]+\$ra, -512
+[ ]+128000080:[ ]+4ffffc21[ ]+jirl[ ]+\$ra, \$ra, -4
+[ ]+128000084:[ ]+50000200[ ]+b[ ]+-134217728[ ]+# 120000084 <b>
+[ ]+128000088:[ ]+1fffc00c[ ]+pcaddu18i[ ]+\$t0, -512
+[ ]+12800008c:[ ]+4ffffd80[ ]+jirl[ ]+\$zero, \$t0, -4
+[ ]+128000090:[ ]+1e004001[ ]+pcaddu18i[ ]+\$ra, 512
+[ ]+128000094:[ ]+4c000021[ ]+jirl[ ]+\$ra, \$ra, 0
+[ ]+128000098:[ ]+57fff9ff[ ]+bl[ ]+134217720[ ]+# 130000090 <c>
+[ ]+12800009c:[ ]+1e00400c[ ]+pcaddu18i[ ]+\$t0, 512
+[ ]+1280000a0:[ ]+4c000180[ ]+jr[ ]+\$t0
+[ ]+1280000a4:[ ]+53fff9ff[ ]+b[ ]+134217720[ ]+# 13000009c <d>
+[ ]+...
+[ ]+130000070:[ ]+4c000020[ ]+ret
+[ ]+130000074:[ ]+4c000020[ ]+ret
+[ ]+130000078:[ ]+4c000020[ ]+ret
+[ ]+13000007c:[ ]+4c000020[ ]+ret
+[ ]+130000080:[ ]+4c000020[ ]+ret
+[ ]+130000084:[ ]+4c000020[ ]+ret
+[ ]+130000088:[ ]+4c000020[ ]+ret
+[ ]+13000008c:[ ]+4c000020[ ]+ret
+[ ]*0000000130000090 <c>:
+[ ]+130000090:[ ]+4c000020[ ]+ret
+[ ]+130000094:[ ]+4c000020[ ]+ret
+[ ]+130000098:[ ]+4c000020[ ]+ret
+[ ]*000000013000009c <d>:
+[ ]+13000009c:[ ]+4c000020[ ]+ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax-medium-call.s b/ld/testsuite/ld-loongarch-elf/relax-medium-call.s
index c0521b65..7b149620 100644
--- a/ld/testsuite/ld-loongarch-elf/relax-medium-call.s
+++ b/ld/testsuite/ld-loongarch-elf/relax-medium-call.s
@@ -1,12 +1,12 @@
-.section "ta", "ax"
+.text
a:
ret
ret
ret
b:
ret
+ .fill 0x7fffff0
-.text
call36 a # min offset, can relax
call36 a # overflow, not relax
tail36 $t0, b # min offset, can relax
@@ -17,7 +17,7 @@ b:
tail36 $t0, d # overflow, no relax
tail36 $t0, d # max offset, can relax
-.section "tb", "ax"
+ .fill 0x7ffffc8
ret
ret
ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax-separate-code-overflow.s b/ld/testsuite/ld-loongarch-elf/relax-separate-code-overflow.s
new file mode 100644
index 00000000..df5dd5fe
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-separate-code-overflow.s
@@ -0,0 +1,21 @@
+# ld -z separate-code let .text and .rodata in two segment,
+# need to consider segment alignment
+.text
+ # first two la.local relax in the second trip, and result in the third
+ # la.local (relax to pcaddi) overflow
+ la.local $r12, a
+ la.local $r12, b
+ .fill 0x3ff8
+ # relax in the first trip
+ la.local $r12, c
+ .fill 0x1fbfec
+a:
+ .fill 8
+b:
+ .fill 0x1000
+d:
+ .fill 0x1
+
+.section .rodata
+c:
+ .8byte 0x1
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index c1da9c10..05c4ed0a 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -308,6 +308,21 @@ if [istarget loongarch64-*-*] {
"relax-section-align-overflow" \
] \
]
+
+ # # loongarch*-elf target do not support -z separate-code
+ if [check_shared_lib_support] {
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch relax separate code overflow" \
+ "-e0 -z separate-code" "" \
+ "" \
+ {relax-separate-code-overflow.s} \
+ {} \
+ "relax-separate-code-overflow" \
+ ] \
+ ]
+ }
}
if [check_shared_lib_support] {
--
2.33.0

View File

@ -0,0 +1,273 @@
From 9c12754717e9564ba5caa8220a87fa759f6e3f33 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Wed, 27 Dec 2023 11:12:30 +0800
Subject: [PATCH 043/123] LoongArch: Fix relaxation overflow caused by section
alignment
When deleting NOP instructions addend by .align at second pass, this may cause
the PC decrease but the symbol address to remain unchanged due to section
alignment.
To solve this question, we subtract a maximux alignment of all sections like
RISC-V.
---
bfd/elfnn-loongarch.c | 79 +++++++++++++------
.../relax-section-align-overflow.s | 25 ++++++
ld/testsuite/ld-loongarch-elf/relax.exp | 25 ++++--
3 files changed, 100 insertions(+), 29 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-section-align-overflow.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 3d858169..8b71e836 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -4188,8 +4188,9 @@ loongarch_relax_tls_le (bfd *abfd, asection *sec,
/* Relax pcalau12i,addi.d => pcaddi. */
static bool
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)
+ Elf_Internal_Rela *rel_hi, bfd_vma symval,
+ struct bfd_link_info *info, bool *again,
+ bfd_vma max_alignment)
{
bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
Elf_Internal_Rela *rel_lo = rel_hi + 2;
@@ -4205,14 +4206,22 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
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? */
+ FIXME: if there are multiple readonly segments? How to determine if
+ two sections are in the same segment. */
if (!(sym_sec->flags & SEC_READONLY))
{
+ max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
+ : max_alignment;
if (symval > pc)
- pc -= info->maxpagesize;
+ pc -= max_alignment;
else if (symval < pc)
- pc += info->maxpagesize;
+ pc += max_alignment;
}
+ else
+ if (symval > pc)
+ pc -= max_alignment;
+ else if (symval < pc)
+ pc += max_alignment;
const uint32_t addi_d = 0x02c00000;
const uint32_t pcaddi = 0x18000000;
@@ -4352,8 +4361,9 @@ loongarch_relax_align (bfd *abfd, asection *sec,
/* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi. */
static bool
loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
- Elf_Internal_Rela *rel_hi, bfd_vma symval,
- struct bfd_link_info *info, bool *again)
+ Elf_Internal_Rela *rel_hi, bfd_vma symval,
+ struct bfd_link_info *info, bool *again,
+ bfd_vma max_alignment)
{
bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
Elf_Internal_Rela *rel_lo = rel_hi + 2;
@@ -4372,11 +4382,18 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
FIXME: if there are multiple readonly segments? */
if (!(sym_sec->flags & SEC_READONLY))
{
+ max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
+ : max_alignment;
if (symval > pc)
- pc -= info->maxpagesize;
+ pc -= max_alignment;
else if (symval < pc)
- pc += info->maxpagesize;
+ pc += max_alignment;
}
+ else
+ if (symval > pc)
+ pc -= max_alignment;
+ else if (symval < pc)
+ pc += max_alignment;
const uint32_t addi_d = 0x02c00000;
const uint32_t pcaddi = 0x18000000;
@@ -4428,6 +4445,21 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
return true;
}
+/* Traverse all output sections and return the max alignment. */
+
+static bfd_vma
+loongarch_get_max_alignment (asection *sec)
+{
+ asection *o;
+ unsigned int max_alignment_power = 0;
+
+ for (o = sec->output_section->owner->sections; o != NULL; o = o->next)
+ if (o->alignment_power > max_alignment_power)
+ max_alignment_power = o->alignment_power;
+
+ return (bfd_vma) 1 << max_alignment_power;
+}
+
static bool
loongarch_elf_relax_section (bfd *abfd, asection *sec,
struct bfd_link_info *info,
@@ -4438,6 +4470,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
Elf_Internal_Rela *relocs;
*again = false;
+ bfd_vma max_alignment = 0;
if (bfd_link_relocatable (info)
|| sec->sec_flg0
@@ -4470,6 +4503,15 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
data->relocs = relocs;
+ /* Estimate the maximum alignment for all output sections once time
+ should be enough. */
+ max_alignment = htab->max_alignment;
+ if (max_alignment == (bfd_vma) -1)
+ {
+ max_alignment = loongarch_get_max_alignment (sec);
+ htab->max_alignment = max_alignment;
+ }
+
for (unsigned int i = 0; i < sec->reloc_count; i++)
{
char symtype;
@@ -4606,6 +4648,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
if (1 == info->relax_pass)
loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
break;
+
case R_LARCH_DELETE:
if (1 == info->relax_pass)
{
@@ -4613,6 +4656,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
}
break;
+
case R_LARCH_TLS_LE_HI20_R:
case R_LARCH_TLS_LE_LO12_R:
case R_LARCH_TLS_LE_ADD_R:
@@ -4623,34 +4667,25 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
case R_LARCH_PCALA_HI20:
if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
- info, again);
+ info, again, max_alignment);
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, sym_sec, rel, symval,
- info, again);
+ info, again, max_alignment);
}
break;
case R_LARCH_TLS_LD_PC_HI20:
- if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
- loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
- info, again);
- break;
-
case R_LARCH_TLS_GD_PC_HI20:
- if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
- loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
- info, again);
- break;
-
case R_LARCH_TLS_DESC_PC_HI20:
if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
- info, again);
+ info, again, max_alignment);
break;
default:
diff --git a/ld/testsuite/ld-loongarch-elf/relax-section-align-overflow.s b/ld/testsuite/ld-loongarch-elf/relax-section-align-overflow.s
new file mode 100644
index 00000000..c341a8bb
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-section-align-overflow.s
@@ -0,0 +1,25 @@
+# relocation overflow because .align
+.text
+ addi.d $t0, $t1, 0
+ addi.d $t0, $t1, 0
+ # Add one NOP instruction
+ .align 3
+ addi.d $t0, $t1, 0
+
+.section ".t.a", "ax"
+ addi.d $t0, $t1, 0
+ # In one try:
+ # first pass, la.local can be relaxed (0x120200010 - 0x120000014 = 0x1ffffc)
+ # second pass, the NOP addend by .align be deleted and pc decrease 4,
+ # but .L1 not decrease because section alignment.
+ # (0x120200010 - 0x120000010 = 0x200000)
+ la.local $t0, .L1
+ .fill 0x1ffff0
+
+.section ".t.b", "ax"
+.L1:
+ addi.d $t0, $t1, 0
+ # To make section address not change when first .align 3 delete NOP
+ .align 4
+ addi.d $t0, $t1, 0
+
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index aed8457d..107e5a56 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -82,14 +82,14 @@ if [istarget loongarch64-*-*] {
]
}
- 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 [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"
}
+ }
run_ld_link_tests \
[list \
@@ -268,6 +268,17 @@ if [istarget loongarch64-*-*] {
]
}
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch relax section align overflow" \
+ "-e0 -Ttext 0x120000000" "" \
+ "" \
+ {relax-section-align-overflow.s} \
+ {} \
+ "relax-section-align-overflow" \
+ ] \
+ ]
}
if [check_shared_lib_support] {
--
2.33.0

View File

@ -0,0 +1,390 @@
From 6ddd9c5a47335388ce3031313325b259a9f28773 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Wed, 27 Dec 2023 19:42:01 +0800
Subject: [PATCH 037/123] LoongArch: Fix some macro that cannot be expanded
properly
Suppose we want to use la.got to generate 32 pcrel and
32 abs instruction sequences respectively. According to
the existing conditions, to generate 32 pcrel sequences
use -mabi=ilp32*, and to generate 32 abs use -mabi=ilp32*
and -mla-global-with-abs.
Due to the fact that the conditions for generating 32 abs
also satisfy 32 pcrel, using -mabi=ilp32* and -mla-global-with-abs
will result in only generating instruction sequences of 32 pcrel.
By modifying the conditions for macro expansion and adjusting
the matching order of macro instructions, it is ensured that
the correct sequence of instructions can be generated.
---
.../gas/loongarch/macro_op_extreme_abs.d | 72 +++++++++++++++
.../gas/loongarch/macro_op_extreme_abs.s | 9 ++
...o_op_large_abs.d => macro_op_extreme_pc.d} | 13 ++-
.../gas/loongarch/macro_op_extreme_pc.s | 9 ++
.../gas/loongarch/macro_op_large_abs.s | 9 --
.../gas/loongarch/macro_op_large_pc.d | 89 -------------------
.../gas/loongarch/macro_op_large_pc.s | 9 --
opcodes/loongarch-opc.c | 24 ++---
8 files changed, 108 insertions(+), 126 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/macro_op_extreme_abs.d
create mode 100644 gas/testsuite/gas/loongarch/macro_op_extreme_abs.s
rename gas/testsuite/gas/loongarch/{macro_op_large_abs.d => macro_op_extreme_pc.d} (93%)
create mode 100644 gas/testsuite/gas/loongarch/macro_op_extreme_pc.s
delete mode 100644 gas/testsuite/gas/loongarch/macro_op_large_abs.s
delete mode 100644 gas/testsuite/gas/loongarch/macro_op_large_pc.d
delete mode 100644 gas/testsuite/gas/loongarch/macro_op_large_pc.s
diff --git a/gas/testsuite/gas/loongarch/macro_op_extreme_abs.d b/gas/testsuite/gas/loongarch/macro_op_extreme_abs.d
new file mode 100644
index 00000000..5c823ba0
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/macro_op_extreme_abs.d
@@ -0,0 +1,72 @@
+#as: -mla-global-with-abs -mla-local-with-abs
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+ <.L1>:
+ 0: 14000004 lu12i.w \$a0, 0
+ 0: R_LARCH_MARK_LA \*ABS\*
+ 0: R_LARCH_ABS_HI20 .L1
+ 4: 03800084 ori \$a0, \$a0, 0x0
+ 4: R_LARCH_ABS_LO12 .L1
+ 8: 16000004 lu32i.d \$a0, 0
+ 8: R_LARCH_ABS64_LO20 .L1
+ c: 03000084 lu52i.d \$a0, \$a0, 0
+ c: R_LARCH_ABS64_HI12 .L1
+ 10: 14000004 lu12i.w \$a0, 0
+ 10: R_LARCH_MARK_LA \*ABS\*
+ 10: R_LARCH_ABS_HI20 .L1
+ 14: 03800084 ori \$a0, \$a0, 0x0
+ 14: R_LARCH_ABS_LO12 .L1
+ 18: 16000004 lu32i.d \$a0, 0
+ 18: R_LARCH_ABS64_LO20 .L1
+ 1c: 03000084 lu52i.d \$a0, \$a0, 0
+ 1c: R_LARCH_ABS64_HI12 .L1
+ 20: 1a000004 pcalau12i \$a0, 0
+ 20: R_LARCH_PCALA_HI20 .L1
+ 20: R_LARCH_RELAX \*ABS\*
+ 24: 02c00084 addi.d \$a0, \$a0, 0
+ 24: R_LARCH_PCALA_LO12 .L1
+ 24: R_LARCH_RELAX \*ABS\*
+ 28: 14000004 lu12i.w \$a0, 0
+ 28: R_LARCH_GOT_HI20 .L1
+ 2c: 03800084 ori \$a0, \$a0, 0x0
+ 2c: R_LARCH_GOT_LO12 .L1
+ 30: 16000004 lu32i.d \$a0, 0
+ 30: R_LARCH_GOT64_LO20 .L1
+ 34: 03000084 lu52i.d \$a0, \$a0, 0
+ 34: R_LARCH_GOT64_HI12 .L1
+ 38: 28c00084 ld.d \$a0, \$a0, 0
+ 3c: 14000004 lu12i.w \$a0, 0
+ 3c: R_LARCH_TLS_LE_HI20 TLS1
+ 40: 03800084 ori \$a0, \$a0, 0x0
+ 40: R_LARCH_TLS_LE_LO12 TLS1
+ 44: 14000004 lu12i.w \$a0, 0
+ 44: R_LARCH_TLS_IE_HI20 TLS1
+ 48: 03800084 ori \$a0, \$a0, 0x0
+ 48: R_LARCH_TLS_IE_LO12 TLS1
+ 4c: 16000004 lu32i.d \$a0, 0
+ 4c: R_LARCH_TLS_IE64_LO20 TLS1
+ 50: 03000084 lu52i.d \$a0, \$a0, 0
+ 50: R_LARCH_TLS_IE64_HI12 TLS1
+ 54: 28c00084 ld.d \$a0, \$a0, 0
+ 58: 14000004 lu12i.w \$a0, 0
+ 58: R_LARCH_TLS_LD_HI20 TLS1
+ 5c: 03800084 ori \$a0, \$a0, 0x0
+ 5c: R_LARCH_GOT_LO12 TLS1
+ 60: 16000004 lu32i.d \$a0, 0
+ 60: R_LARCH_GOT64_LO20 TLS1
+ 64: 03000084 lu52i.d \$a0, \$a0, 0
+ 64: R_LARCH_GOT64_HI12 TLS1
+ 68: 14000004 lu12i.w \$a0, 0
+ 68: R_LARCH_TLS_GD_HI20 TLS1
+ 6c: 03800084 ori \$a0, \$a0, 0x0
+ 6c: R_LARCH_GOT_LO12 TLS1
+ 70: 16000004 lu32i.d \$a0, 0
+ 70: R_LARCH_GOT64_LO20 TLS1
+ 74: 03000084 lu52i.d \$a0, \$a0, 0
+ 74: R_LARCH_GOT64_HI12 TLS1
diff --git a/gas/testsuite/gas/loongarch/macro_op_extreme_abs.s b/gas/testsuite/gas/loongarch/macro_op_extreme_abs.s
new file mode 100644
index 00000000..eca07006
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/macro_op_extreme_abs.s
@@ -0,0 +1,9 @@
+.L1:
+la.local $r4, $r5, .L1
+la.global $r4, $r5, .L1
+la.pcrel $r4, .L1
+la.got $r4,.L1
+la.tls.le $r4, TLS1
+la.tls.ie $r4, TLS1
+la.tls.ld $r4, TLS1
+la.tls.gd $r4, TLS1
diff --git a/gas/testsuite/gas/loongarch/macro_op_large_abs.d b/gas/testsuite/gas/loongarch/macro_op_extreme_pc.d
similarity index 93%
rename from gas/testsuite/gas/loongarch/macro_op_large_abs.d
rename to gas/testsuite/gas/loongarch/macro_op_extreme_pc.d
index 729e878f..8e4b6e6c 100644
--- a/gas/testsuite/gas/loongarch/macro_op_large_abs.d
+++ b/gas/testsuite/gas/loongarch/macro_op_extreme_pc.d
@@ -1,10 +1,9 @@
-#as:
+#as: -mla-global-with-pcrel
#objdump: -dr
#skip: loongarch32-*-*
.*: file format .*
-
Disassembly of section .text:
0+ <.L1>:
@@ -20,16 +19,16 @@ Disassembly of section .text:
c: R_LARCH_PCALA64_HI12 .L1
10: 00109484 add.d \$a0, \$a0, \$a1
14: 1a000004 pcalau12i \$a0, 0
- 14: R_LARCH_GOT_PC_HI20 .L1
+ 14: R_LARCH_PCALA_HI20 .L1
14: R_LARCH_RELAX \*ABS\*
18: 02c00005 li.d \$a1, 0
- 18: R_LARCH_GOT_PC_LO12 .L1
+ 18: R_LARCH_PCALA_LO12 .L1
18: R_LARCH_RELAX \*ABS\*
1c: 16000005 lu32i.d \$a1, 0
- 1c: R_LARCH_GOT64_PC_LO20 .L1
+ 1c: R_LARCH_PCALA64_LO20 .L1
20: 030000a5 lu52i.d \$a1, \$a1, 0
- 20: R_LARCH_GOT64_PC_HI12 .L1
- 24: 380c1484 ldx.d \$a0, \$a0, \$a1
+ 20: R_LARCH_PCALA64_HI12 .L1
+ 24: 00109484 add.d \$a0, \$a0, \$a1
28: 1a000004 pcalau12i \$a0, 0
28: R_LARCH_PCALA_HI20 .L1
28: R_LARCH_RELAX \*ABS\*
diff --git a/gas/testsuite/gas/loongarch/macro_op_extreme_pc.s b/gas/testsuite/gas/loongarch/macro_op_extreme_pc.s
new file mode 100644
index 00000000..4c685b5b
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/macro_op_extreme_pc.s
@@ -0,0 +1,9 @@
+.L1:
+la.local $r4, $r5, .L1
+la.global $r4, $r5, .L1
+la.pcrel $r4, $r5, .L1
+la.got $r4, $r5, .L1
+la.tls.le $r4, TLS1
+la.tls.ie $r4, $r5, TLS1
+la.tls.ld $r4, $r5, TLS1
+la.tls.gd $r4, $r5, TLS1
diff --git a/gas/testsuite/gas/loongarch/macro_op_large_abs.s b/gas/testsuite/gas/loongarch/macro_op_large_abs.s
deleted file mode 100644
index fd76391d..00000000
--- a/gas/testsuite/gas/loongarch/macro_op_large_abs.s
+++ /dev/null
@@ -1,9 +0,0 @@
-.L1:
-la.local $r4, $r5, .L1
-la.global $r4, $r5, .L1
-la.pcrel $r4, $r5, .L1
-la.got $r4, $r5, .L1
-la.tls.le $r4, TLS1
-la.tls.ie $r4, $r5, TLS1
-la.tls.ld $r4, $r5, TLS1
-la.tls.gd $r4, $r5, TLS1
diff --git a/gas/testsuite/gas/loongarch/macro_op_large_pc.d b/gas/testsuite/gas/loongarch/macro_op_large_pc.d
deleted file mode 100644
index 729e878f..00000000
--- a/gas/testsuite/gas/loongarch/macro_op_large_pc.d
+++ /dev/null
@@ -1,89 +0,0 @@
-#as:
-#objdump: -dr
-#skip: loongarch32-*-*
-
-.*: file format .*
-
-
-Disassembly of section .text:
-
-0+ <.L1>:
- 0: 1a000004 pcalau12i \$a0, 0
- 0: R_LARCH_PCALA_HI20 .L1
- 0: R_LARCH_RELAX \*ABS\*
- 4: 02c00005 li.d \$a1, 0
- 4: R_LARCH_PCALA_LO12 .L1
- 4: R_LARCH_RELAX \*ABS\*
- 8: 16000005 lu32i.d \$a1, 0
- 8: R_LARCH_PCALA64_LO20 .L1
- c: 030000a5 lu52i.d \$a1, \$a1, 0
- c: R_LARCH_PCALA64_HI12 .L1
- 10: 00109484 add.d \$a0, \$a0, \$a1
- 14: 1a000004 pcalau12i \$a0, 0
- 14: R_LARCH_GOT_PC_HI20 .L1
- 14: R_LARCH_RELAX \*ABS\*
- 18: 02c00005 li.d \$a1, 0
- 18: R_LARCH_GOT_PC_LO12 .L1
- 18: R_LARCH_RELAX \*ABS\*
- 1c: 16000005 lu32i.d \$a1, 0
- 1c: R_LARCH_GOT64_PC_LO20 .L1
- 20: 030000a5 lu52i.d \$a1, \$a1, 0
- 20: R_LARCH_GOT64_PC_HI12 .L1
- 24: 380c1484 ldx.d \$a0, \$a0, \$a1
- 28: 1a000004 pcalau12i \$a0, 0
- 28: R_LARCH_PCALA_HI20 .L1
- 28: R_LARCH_RELAX \*ABS\*
- 2c: 02c00005 li.d \$a1, 0
- 2c: R_LARCH_PCALA_LO12 .L1
- 2c: R_LARCH_RELAX \*ABS\*
- 30: 16000005 lu32i.d \$a1, 0
- 30: R_LARCH_PCALA64_LO20 .L1
- 34: 030000a5 lu52i.d \$a1, \$a1, 0
- 34: R_LARCH_PCALA64_HI12 .L1
- 38: 00109484 add.d \$a0, \$a0, \$a1
- 3c: 1a000004 pcalau12i \$a0, 0
- 3c: R_LARCH_GOT_PC_HI20 .L1
- 3c: R_LARCH_RELAX \*ABS\*
- 40: 02c00005 li.d \$a1, 0
- 40: R_LARCH_GOT_PC_LO12 .L1
- 40: R_LARCH_RELAX \*ABS\*
- 44: 16000005 lu32i.d \$a1, 0
- 44: R_LARCH_GOT64_PC_LO20 .L1
- 48: 030000a5 lu52i.d \$a1, \$a1, 0
- 48: R_LARCH_GOT64_PC_HI12 .L1
- 4c: 380c1484 ldx.d \$a0, \$a0, \$a1
- 50: 14000004 lu12i.w \$a0, 0
- 50: R_LARCH_TLS_LE_HI20 TLS1
- 54: 03800084 ori \$a0, \$a0, 0x0
- 54: R_LARCH_TLS_LE_LO12 TLS1
- 58: 1a000004 pcalau12i \$a0, 0
- 58: R_LARCH_TLS_IE_PC_HI20 TLS1
- 5c: 02c00005 li.d \$a1, 0
- 5c: R_LARCH_TLS_IE_PC_LO12 TLS1
- 60: 16000005 lu32i.d \$a1, 0
- 60: R_LARCH_TLS_IE64_PC_LO20 TLS1
- 64: 030000a5 lu52i.d \$a1, \$a1, 0
- 64: R_LARCH_TLS_IE64_PC_HI12 TLS1
- 68: 380c1484 ldx.d \$a0, \$a0, \$a1
- 6c: 1a000004 pcalau12i \$a0, 0
- 6c: R_LARCH_TLS_LD_PC_HI20 TLS1
- 6c: R_LARCH_RELAX \*ABS\*
- 70: 02c00005 li.d \$a1, 0
- 70: R_LARCH_GOT_PC_LO12 TLS1
- 70: R_LARCH_RELAX \*ABS\*
- 74: 16000005 lu32i.d \$a1, 0
- 74: R_LARCH_GOT64_PC_LO20 TLS1
- 78: 030000a5 lu52i.d \$a1, \$a1, 0
- 78: R_LARCH_GOT64_PC_HI12 TLS1
- 7c: 00109484 add.d \$a0, \$a0, \$a1
- 80: 1a000004 pcalau12i \$a0, 0
- 80: R_LARCH_TLS_GD_PC_HI20 TLS1
- 80: R_LARCH_RELAX \*ABS\*
- 84: 02c00005 li.d \$a1, 0
- 84: R_LARCH_GOT_PC_LO12 TLS1
- 84: R_LARCH_RELAX \*ABS\*
- 88: 16000005 lu32i.d \$a1, 0
- 88: R_LARCH_GOT64_PC_LO20 TLS1
- 8c: 030000a5 lu52i.d \$a1, \$a1, 0
- 8c: R_LARCH_GOT64_PC_HI12 TLS1
- 90: 00109484 add.d \$a0, \$a0, \$a1
diff --git a/gas/testsuite/gas/loongarch/macro_op_large_pc.s b/gas/testsuite/gas/loongarch/macro_op_large_pc.s
deleted file mode 100644
index fd76391d..00000000
--- a/gas/testsuite/gas/loongarch/macro_op_large_pc.s
+++ /dev/null
@@ -1,9 +0,0 @@
-.L1:
-la.local $r4, $r5, .L1
-la.global $r4, $r5, .L1
-la.pcrel $r4, $r5, .L1
-la.got $r4, $r5, .L1
-la.tls.le $r4, TLS1
-la.tls.ie $r4, $r5, TLS1
-la.tls.ld $r4, $r5, TLS1
-la.tls.gd $r4, $r5, TLS1
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index 44b5f612..cc3d1986 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -171,7 +171,7 @@ const char *const loongarch_x_normal_name[32] =
"lu32i.d %1,%%got64_lo20(%2);" \
"lu52i.d %1,%1,%%got64_hi12(%2);" \
"ld.d %1,%1,0", \
- &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gabs, \
&LARCH_opts.ase_gpcr
/* got64 pic. */
#define INSN_LA_GOT64_LARGE_PCREL \
@@ -229,7 +229,7 @@ const char *const loongarch_x_normal_name[32] =
"lu32i.d %1,%%ie64_lo20(%2);" \
"lu52i.d %1,%1,%%ie64_hi12(%2);" \
"ld.d %1,%1,0", \
- &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gabs, \
&LARCH_opts.ase_gpcr
/* For LoongArch32/64 cmode=normal. */
@@ -260,7 +260,7 @@ const char *const loongarch_x_normal_name[32] =
"ori %1,%1,%%got_lo12(%2);" \
"lu32i.d %1,%%got64_lo20(%2);" \
"lu52i.d %1,%1,%%got64_hi12(%2);", \
- &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gabs, \
&LARCH_opts.ase_gpcr
#define INSN_LA_TLS_GD32 \
@@ -290,7 +290,7 @@ const char *const loongarch_x_normal_name[32] =
"ori %1,%1,%%got_lo12(%2);" \
"lu32i.d %1,%%got64_lo20(%2);" \
"lu52i.d %1,%1,%%got64_hi12(%2);", \
- &LARCH_opts.ase_lp64, \
+ &LARCH_opts.ase_gabs, \
&LARCH_opts.ase_gpcr
#define INSN_LA_CALL \
@@ -376,27 +376,27 @@ static struct loongarch_opcode loongarch_macro_opcodes[] =
{ 0, 0, "la.pcrel", "r,la", INSN_LA_PCREL32, 0 },
{ 0, 0, "la.pcrel", "r,la", INSN_LA_PCREL64, 0 },
{ 0, 0, "la.pcrel", "r,r,la", INSN_LA_PCREL64_LARGE, 0 },
- { 0, 0, "la.got", "r,la", INSN_LA_GOT32, 0 },
{ 0, 0, "la.got", "r,la", INSN_LA_GOT32_ABS, 0 },
- { 0, 0, "la.got", "r,la", INSN_LA_GOT64, 0 },
+ { 0, 0, "la.got", "r,la", INSN_LA_GOT32, 0 },
{ 0, 0, "la.got", "r,la", INSN_LA_GOT64_LARGE_ABS, 0 },
+ { 0, 0, "la.got", "r,la", INSN_LA_GOT64, 0 },
{ 0, 0, "la.got", "r,r,la", INSN_LA_GOT64_LARGE_PCREL, 0 },
{ 0, 0, "la.tls.le", "r,l", INSN_LA_TLS_LE, 0 },
{ 0, 0, "la.tls.le", "r,l", INSN_LA_TLS_LE64_LARGE, 0 },
- { 0, 0, "la.tls.ie", "r,l", INSN_LA_TLS_IE32, 0 },
{ 0, 0, "la.tls.ie", "r,l", INSN_LA_TLS_IE32_ABS, 0 },
- { 0, 0, "la.tls.ie", "r,l", INSN_LA_TLS_IE64, 0 },
+ { 0, 0, "la.tls.ie", "r,l", INSN_LA_TLS_IE32, 0 },
{ 0, 0, "la.tls.ie", "r,l", INSN_LA_TLS_IE64_LARGE_ABS, 0 },
+ { 0, 0, "la.tls.ie", "r,l", INSN_LA_TLS_IE64, 0 },
{ 0, 0, "la.tls.ie", "r,r,l", INSN_LA_TLS_IE64_LARGE_PCREL, 0 },
- { 0, 0, "la.tls.ld", "r,l", INSN_LA_TLS_LD32, 0 },
{ 0, 0, "la.tls.ld", "r,l", INSN_LA_TLS_LD32_ABS, 0 },
- { 0, 0, "la.tls.ld", "r,l", INSN_LA_TLS_LD64, 0 },
+ { 0, 0, "la.tls.ld", "r,l", INSN_LA_TLS_LD32, 0 },
{ 0, 0, "la.tls.ld", "r,l", INSN_LA_TLS_LD64_LARGE_ABS, 0 },
+ { 0, 0, "la.tls.ld", "r,l", INSN_LA_TLS_LD64, 0 },
{ 0, 0, "la.tls.ld", "r,r,l", INSN_LA_TLS_LD64_LARGE_PCREL, 0 },
- { 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD32, 0 },
{ 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD32_ABS, 0 },
- { 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD64, 0 },
+ { 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD32, 0 },
{ 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD64_LARGE_ABS, 0 },
+ { 0, 0, "la.tls.gd", "r,l", INSN_LA_TLS_GD64, 0 },
{ 0, 0, "la.tls.gd", "r,r,l", INSN_LA_TLS_GD64_LARGE_PCREL, 0 },
{ 0, 0, "call36", "la", INSN_LA_CALL, 0 },
{ 0, 0, "tail36", "r,la", INSN_LA_TAIL, 0 },
--
2.33.0

View File

@ -0,0 +1,997 @@
From 67ca2a7a3bd324aaef2d033de24384e64778d0d9 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Thu, 25 Jan 2024 19:20:00 +0800
Subject: [PATCH 071/123] LoongArch: Fix some test cases for TLS transition and
relax
---
gas/testsuite/gas/loongarch/macro_op.d | 4 +
gas/testsuite/gas/loongarch/macro_op_32.d | 4 +
.../gas/loongarch/macro_op_extreme_abs.d | 4 +-
.../gas/loongarch/macro_op_extreme_pc.d | 2 +
.../relax-cfi-fde-DW_CFA_advance_loc.d | 16 ++--
.../relax-cfi-fde-DW_CFA_advance_loc.s | 8 ++
gas/testsuite/gas/loongarch/reloc.d | 8 ++
gas/testsuite/gas/loongarch/tlsdesc_32.d | 27 ------
gas/testsuite/gas/loongarch/tlsdesc_32.s | 12 ---
gas/testsuite/gas/loongarch/tlsdesc_64.d | 2 +
ld/testsuite/ld-loongarch-elf/desc-ie.d | 14 ++-
ld/testsuite/ld-loongarch-elf/desc-ie.s | 13 +--
.../ld-loongarch-elf/desc-le-norelax.d | 15 ++++
.../ld-loongarch-elf/desc-le-norelax.s | 11 +++
ld/testsuite/ld-loongarch-elf/desc-le-relax.d | 13 +++
ld/testsuite/ld-loongarch-elf/desc-le-relax.s | 14 +++
ld/testsuite/ld-loongarch-elf/desc-le.d | 15 ----
ld/testsuite/ld-loongarch-elf/desc-le.s | 14 ---
ld/testsuite/ld-loongarch-elf/ie-le-norelax.d | 13 +++
.../{ie-le.s => ie-le-norelax.s} | 4 +-
ld/testsuite/ld-loongarch-elf/ie-le-relax.d | 13 +++
ld/testsuite/ld-loongarch-elf/ie-le-relax.s | 13 +++
ld/testsuite/ld-loongarch-elf/ie-le.d | 13 ---
.../ld-loongarch-elf/ld-loongarch-elf.exp | 11 ++-
ld/testsuite/ld-loongarch-elf/macro_op.d | 4 +
ld/testsuite/ld-loongarch-elf/relax.exp | 6 +-
.../ld-loongarch-elf/tls-le-norelax.d | 18 ++++
.../{tls-le.s => tls-le-norelax.s} | 4 +
ld/testsuite/ld-loongarch-elf/tls-le-relax.d | 13 +++
ld/testsuite/ld-loongarch-elf/tls-le-relax.s | 22 +++++
ld/testsuite/ld-loongarch-elf/tls-le.d | 14 ---
ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d | 86 ++++++++++---------
ld/testsuite/ld-loongarch-elf/tlsdesc-dso.s | 9 ++
ld/testsuite/ld-loongarch-elf/tlsdesc_abs.d | 23 +++++
ld/testsuite/ld-loongarch-elf/tlsdesc_abs.s | 7 ++
.../ld-loongarch-elf/tlsdesc_extreme.d | 25 ++++++
.../ld-loongarch-elf/tlsdesc_extreme.s | 7 ++
37 files changed, 333 insertions(+), 168 deletions(-)
delete mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32.d
delete mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32.s
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-le-norelax.d
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-le-norelax.s
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-le-relax.d
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-le-relax.s
delete mode 100644 ld/testsuite/ld-loongarch-elf/desc-le.d
delete mode 100644 ld/testsuite/ld-loongarch-elf/desc-le.s
create mode 100644 ld/testsuite/ld-loongarch-elf/ie-le-norelax.d
rename ld/testsuite/ld-loongarch-elf/{ie-le.s => ie-le-norelax.s} (63%)
create mode 100644 ld/testsuite/ld-loongarch-elf/ie-le-relax.d
create mode 100644 ld/testsuite/ld-loongarch-elf/ie-le-relax.s
delete mode 100644 ld/testsuite/ld-loongarch-elf/ie-le.d
create mode 100644 ld/testsuite/ld-loongarch-elf/tls-le-norelax.d
rename ld/testsuite/ld-loongarch-elf/{tls-le.s => tls-le-norelax.s} (70%)
create mode 100644 ld/testsuite/ld-loongarch-elf/tls-le-relax.d
create mode 100644 ld/testsuite/ld-loongarch-elf/tls-le-relax.s
delete mode 100644 ld/testsuite/ld-loongarch-elf/tls-le.d
create mode 100644 ld/testsuite/ld-loongarch-elf/tlsdesc_abs.d
create mode 100644 ld/testsuite/ld-loongarch-elf/tlsdesc_abs.s
create mode 100644 ld/testsuite/ld-loongarch-elf/tlsdesc_extreme.d
create mode 100644 ld/testsuite/ld-loongarch-elf/tlsdesc_extreme.s
diff --git a/gas/testsuite/gas/loongarch/macro_op.d b/gas/testsuite/gas/loongarch/macro_op.d
index 47f8f45c..106f619e 100644
--- a/gas/testsuite/gas/loongarch/macro_op.d
+++ b/gas/testsuite/gas/loongarch/macro_op.d
@@ -53,12 +53,16 @@ Disassembly of section .text:
44: R_LARCH_RELAX \*ABS\*
48: 14000004 lu12i.w \$a0, 0
48: R_LARCH_TLS_LE_HI20 TLS1
+ 48: R_LARCH_RELAX \*ABS\*
4c: 03800084 ori \$a0, \$a0, 0x0
4c: R_LARCH_TLS_LE_LO12 TLS1
+ 4c: R_LARCH_RELAX \*ABS\*
50: 1a000004 pcalau12i \$a0, 0
50: R_LARCH_TLS_IE_PC_HI20 TLS1
+ 50: R_LARCH_RELAX \*ABS\*
54: 28c00084 ld.d \$a0, \$a0, 0
54: R_LARCH_TLS_IE_PC_LO12 TLS1
+ 54: R_LARCH_RELAX \*ABS\*
58: 1a000004 pcalau12i \$a0, 0
58: R_LARCH_TLS_LD_PC_HI20 TLS1
58: R_LARCH_RELAX \*ABS\*
diff --git a/gas/testsuite/gas/loongarch/macro_op_32.d b/gas/testsuite/gas/loongarch/macro_op_32.d
index a7349aa8..8fd69922 100644
--- a/gas/testsuite/gas/loongarch/macro_op_32.d
+++ b/gas/testsuite/gas/loongarch/macro_op_32.d
@@ -49,12 +49,16 @@ Disassembly of section .text:
3c: R_LARCH_RELAX \*ABS\*
40: 14000004 lu12i.w \$a0, 0
40: R_LARCH_TLS_LE_HI20 TLS1
+ 40: R_LARCH_RELAX \*ABS\*
44: 03800084 ori \$a0, \$a0, 0x0
44: R_LARCH_TLS_LE_LO12 TLS1
+ 44: R_LARCH_RELAX \*ABS\*
48: 1a000004 pcalau12i \$a0, 0
48: R_LARCH_TLS_IE_PC_HI20 TLS1
+ 48: R_LARCH_RELAX \*ABS\*
4c: 28800084 ld.w \$a0, \$a0, 0
4c: R_LARCH_TLS_IE_PC_LO12 TLS1
+ 4c: R_LARCH_RELAX \*ABS\*
50: 1a000004 pcalau12i \$a0, 0
50: R_LARCH_TLS_LD_PC_HI20 TLS1
50: R_LARCH_RELAX \*ABS\*
diff --git a/gas/testsuite/gas/loongarch/macro_op_extreme_abs.d b/gas/testsuite/gas/loongarch/macro_op_extreme_abs.d
index 5c823ba0..8e3a2aa9 100644
--- a/gas/testsuite/gas/loongarch/macro_op_extreme_abs.d
+++ b/gas/testsuite/gas/loongarch/macro_op_extreme_abs.d
@@ -28,10 +28,8 @@ Disassembly of section .text:
1c: R_LARCH_ABS64_HI12 .L1
20: 1a000004 pcalau12i \$a0, 0
20: R_LARCH_PCALA_HI20 .L1
- 20: R_LARCH_RELAX \*ABS\*
24: 02c00084 addi.d \$a0, \$a0, 0
24: R_LARCH_PCALA_LO12 .L1
- 24: R_LARCH_RELAX \*ABS\*
28: 14000004 lu12i.w \$a0, 0
28: R_LARCH_GOT_HI20 .L1
2c: 03800084 ori \$a0, \$a0, 0x0
@@ -43,8 +41,10 @@ Disassembly of section .text:
38: 28c00084 ld.d \$a0, \$a0, 0
3c: 14000004 lu12i.w \$a0, 0
3c: R_LARCH_TLS_LE_HI20 TLS1
+ 3c: R_LARCH_RELAX \*ABS\*
40: 03800084 ori \$a0, \$a0, 0x0
40: R_LARCH_TLS_LE_LO12 TLS1
+ 40: R_LARCH_RELAX \*ABS\*
44: 14000004 lu12i.w \$a0, 0
44: R_LARCH_TLS_IE_HI20 TLS1
48: 03800084 ori \$a0, \$a0, 0x0
diff --git a/gas/testsuite/gas/loongarch/macro_op_extreme_pc.d b/gas/testsuite/gas/loongarch/macro_op_extreme_pc.d
index 68fbb338..21c5e5a0 100644
--- a/gas/testsuite/gas/loongarch/macro_op_extreme_pc.d
+++ b/gas/testsuite/gas/loongarch/macro_op_extreme_pc.d
@@ -46,8 +46,10 @@ Disassembly of section .text:
[ ]+4c:[ ]+380c1484[ ]+ldx.d[ ]+\$a0, \$a0, \$a1
[ ]+50:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
[ ]+50: R_LARCH_TLS_LE_HI20[ ]+TLS1
+[ ]+50: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+54:[ ]+03800084[ ]+ori[ ]+\$a0, \$a0, 0x0
[ ]+54: R_LARCH_TLS_LE_LO12[ ]+TLS1
+[ ]+54: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+58:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
[ ]+58: R_LARCH_TLS_IE_PC_HI20[ ]+TLS1
[ ]+5c:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
diff --git a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
index 367039e1..6b164cfb 100644
--- a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
+++ b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
@@ -14,7 +14,7 @@ Disassembly of section .eh_frame:
[ ]+c:[ ]+01017c01[ ]+fadd.d[ ]+\$fa1, \$fa0, \$fs7
[ ]+10:[ ]+0c030d1b[ ]+.word[ ]+[ ]+0x0c030d1b
[ ]+14:[ ]+00000016[ ]+.word[ ]+[ ]+0x00000016
-[ ]+18:[ ]+00000034[ ]+.word[ ]+[ ]+0x00000034
+[ ]+18:[ ]+0000003c[ ]+.word[ ]+[ ]+0x0000003c
[ ]+1c:[ ]+0000001c[ ]+.word[ ]+[ ]+0x0000001c
[ ]+...
[ ]+20: R_LARCH_32_PCREL[ ]+L0\^A
@@ -26,7 +26,7 @@ Disassembly of section .eh_frame:
[ ]+2c:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
[ ]+2e: R_LARCH_ADD6[ ]+L0\^A
[ ]+2e: R_LARCH_SUB6[ ]+L0\^A
-[ ]+30:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300044 <L0\^A\+0x30000c>
+[ ]+30:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300044 <L0\^A\+0x2ffffc>
[ ]+33: R_LARCH_ADD6[ ]+L0\^A
[ ]+33: R_LARCH_SUB6[ ]+L0\^A
[ ]+34:[ ]+00160cd6[ ]+orn[ ]+\$fp, \$a2, \$sp
@@ -39,8 +39,14 @@ Disassembly of section .eh_frame:
[ ]+40:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
[ ]+42: R_LARCH_ADD6[ ]+L0\^A
[ ]+42: R_LARCH_SUB6[ ]+L0\^A
-[ ]+44:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300058 <L0\^A\+0x300020>
+[ ]+44:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300058 <L0\^A\+0x300010>
[ ]+47: R_LARCH_ADD6[ ]+L0\^A
[ ]+47: R_LARCH_SUB6[ ]+L0\^A
-[ ]+48:[ ]+000000d6[ ]+.word[ ]+[ ]+0x000000d6
-[ ]+4c:[ ]+00000000[ ]+.word[ ]+[ ]+0x00000000
+[ ]+48:[ ]+00160cd6[ ]+orn[ ]+\$fp, \$a2, \$sp
+[ ]+4c:[ ]+160cd640[ ]+lu32i.d[ ]+\$zero, 26290
+[ ]+4c: R_LARCH_ADD6[ ]+L0\^A
+[ ]+4c: R_LARCH_SUB6[ ]+L0\^A
+[ ]+50:[ ]+00d64000[ ]+bstrpick.d[ ]+\$zero, \$zero, 0x16, 0x10
+[ ]+51: R_LARCH_ADD6[ ]+L0\^A
+[ ]+51: R_LARCH_SUB6[ ]+L0\^A
+[ ]+54:[ ]+00000000[ ]+.word[ ]+[ ]+0x00000000
diff --git a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
index 6e4c9b8b..2c67587b 100644
--- a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
+++ b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
@@ -30,4 +30,12 @@ pcalau12i $t0, %le_hi20_r(a)
add.d $t0, $tp, $t0, %le_add_r(a)
.cfi_restore 22
+.cfi_def_cfa 22, 0
+la.tls.ie $t0, a
+.cfi_restore 22
+
+.cfi_def_cfa 22, 0
+la.tls.le $t0, a
+.cfi_restore 22
+
.cfi_endproc
diff --git a/gas/testsuite/gas/loongarch/reloc.d b/gas/testsuite/gas/loongarch/reloc.d
index fa249c58..6a8f0e1f 100644
--- a/gas/testsuite/gas/loongarch/reloc.d
+++ b/gas/testsuite/gas/loongarch/reloc.d
@@ -81,12 +81,16 @@ Disassembly of section .text:
[ ]+8c:[ ]+R_LARCH_GOT64_HI12[ ]+.L1
[ ]+90:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0
[ ]+90:[ ]+R_LARCH_TLS_LE_HI20[ ]+TLSL1
+[ ]+90:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+94:[ ]+03800085[ ]+ori[ ]+\$a1,[ ]+\$a0,[ ]+0x0
[ ]+94:[ ]+R_LARCH_TLS_LE_LO12[ ]+TLSL1
+[ ]+94:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+98:[ ]+16000004[ ]+lu32i.d[ ]+\$a0,[ ]+0
[ ]+98:[ ]+R_LARCH_TLS_LE64_LO20[ ]+TLSL1
+[ ]+98:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+9c:[ ]+03000085[ ]+lu52i.d[ ]+\$a1,[ ]+\$a0,[ ]+0
[ ]+9c:[ ]+R_LARCH_TLS_LE64_HI12[ ]+TLSL1
+[ ]+9c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+a0:[ ]+58000085[ ]+beq[ ]+\$a0,[ ]+\$a1,[ ]+0[ ]+#[ ]+0xa0
[ ]+a0:[ ]+R_LARCH_B16[ ]+.L1\+0x8
[ ]+a4:[ ]+5c000085[ ]+bne[ ]+\$a0,[ ]+\$a1,[ ]+0[ ]+#[ ]+0xa4
@@ -159,12 +163,16 @@ Disassembly of section .text:
[ ]+128:[ ]+R_LARCH_GOT64_HI12[ ]+.L1\+0x8
[ ]+12c:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0
[ ]+12c:[ ]+R_LARCH_TLS_LE_HI20[ ]+TLSL1\+0x8
+[ ]+12c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+130:[ ]+03800085[ ]+ori[ ]+\$a1,[ ]+\$a0,[ ]+0x0
[ ]+130:[ ]+R_LARCH_TLS_LE_LO12[ ]+TLSL1\+0x8
+[ ]+130:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+134:[ ]+16000004[ ]+lu32i.d[ ]+\$a0,[ ]+0
[ ]+134:[ ]+R_LARCH_TLS_LE64_LO20[ ]+TLSL1\+0x8
+[ ]+134:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+138:[ ]+03000085[ ]+lu52i.d[ ]+\$a1,[ ]+\$a0,[ ]+0
[ ]+138:[ ]+R_LARCH_TLS_LE64_HI12[ ]+TLSL1\+0x8
+[ ]+138:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
[ ]+13c:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0
[ ]+13c:[ ]+R_LARCH_TLS_LE_HI20_R[ ]+TLSL1
[ ]+13c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_32.d b/gas/testsuite/gas/loongarch/tlsdesc_32.d
deleted file mode 100644
index eddcc5ed..00000000
--- a/gas/testsuite/gas/loongarch/tlsdesc_32.d
+++ /dev/null
@@ -1,27 +0,0 @@
-#as:
-#objdump: -dr
-#skip: loongarch64-*-*
-
-.*:[ ]+file format .*
-
-Disassembly of section .text:
-
-0+ <.*>:
- 0: 1a000004 pcalau12i \$a0, 0
- 0: R_LARCH_TLS_DESC_PC_HI20 var
- 4: 02800084 addi.w \$a0, \$a0, 0
- 4: R_LARCH_TLS_DESC_PC_LO12 var
- 8: 28800081 ld.w \$ra, \$a0, 0
- 8: R_LARCH_TLS_DESC_LD var
- c: 4c000021 jirl \$ra, \$ra, 0
- c: R_LARCH_TLS_DESC_CALL var
- 10: 1a000004 pcalau12i \$a0, 0
- 10: R_LARCH_TLS_DESC_PC_HI20 var
- 10: R_LARCH_RELAX \*ABS\*
- 14: 02800084 addi.w \$a0, \$a0, 0
- 14: R_LARCH_TLS_DESC_PC_LO12 var
- 14: R_LARCH_RELAX \*ABS\*
- 18: 28800081 ld.w \$ra, \$a0, 0
- 18: R_LARCH_TLS_DESC_LD var
- 1c: 4c000021 jirl \$ra, \$ra, 0
- 1c: R_LARCH_TLS_DESC_CALL var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_32.s b/gas/testsuite/gas/loongarch/tlsdesc_32.s
deleted file mode 100644
index 2a139c04..00000000
--- a/gas/testsuite/gas/loongarch/tlsdesc_32.s
+++ /dev/null
@@ -1,12 +0,0 @@
-.L1:
- # R_LARCH_TLS_DESC_PC_HI20 var
- pcalau12i $a0,%desc_pc_hi20(var)
- # R_LARCH_TLS_DESC_PC_LO12 var
- addi.w $a0,$a0,%desc_pc_lo12(var)
- # R_LARCH_TLS_DESC_LD var
- ld.w $ra,$a0,%desc_ld(var)
- # R_LARCH_TLS_DESC_CALL var
- jirl $ra,$ra,%desc_call(var)
-
- # test macro, pcalau12i + addi.w => pcaddi
- la.tls.desc $a0,var
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_64.d b/gas/testsuite/gas/loongarch/tlsdesc_64.d
index 2a2829c9..8fc9e883 100644
--- a/gas/testsuite/gas/loongarch/tlsdesc_64.d
+++ b/gas/testsuite/gas/loongarch/tlsdesc_64.d
@@ -24,5 +24,7 @@ Disassembly of section .text:
14: R_LARCH_RELAX \*ABS\*
18: 28c00081 ld.d \$ra, \$a0, 0
18: R_LARCH_TLS_DESC_LD var
+ 18: R_LARCH_RELAX \*ABS\*
1c: 4c000021 jirl \$ra, \$ra, 0
1c: R_LARCH_TLS_DESC_CALL var
+ 1c: R_LARCH_RELAX \*ABS\*
diff --git a/ld/testsuite/ld-loongarch-elf/desc-ie.d b/ld/testsuite/ld-loongarch-elf/desc-ie.d
index 32e35050..e1f49e2d 100644
--- a/ld/testsuite/ld-loongarch-elf/desc-ie.d
+++ b/ld/testsuite/ld-loongarch-elf/desc-ie.d
@@ -1,5 +1,5 @@
#as:
-#ld: -shared -z norelro -e 0x0 --hash-style=both
+#ld: -shared -z norelro --hash-style=both
#objdump: -dr
#skip: loongarch32-*-*
@@ -7,10 +7,8 @@
Disassembly of section .text:
-0+230 <fn1>:
- 230: 1a000084 pcalau12i \$a0, 4
- 234: 28cd6084 ld.d \$a0, \$a0, 856
- 238: 03400000 nop.*
- 23c: 03400000 nop.*
- 240: 1a000084 pcalau12i \$a0, 4
- 244: 28cd6081 ld.d \$ra, \$a0, 856
+[0-9a-f]+ <fn1>:
+ +[0-9a-f]+: 1a000084 pcalau12i \$a0, .*
+ +[0-9a-f]+: 28cca084 ld.d \$a0, \$a0, .*
+ +[0-9a-f]+: 1a000084 pcalau12i \$a0, .*
+ +[0-9a-f]+: 28cca084 ld.d \$a0, \$a0, .*
diff --git a/ld/testsuite/ld-loongarch-elf/desc-ie.s b/ld/testsuite/ld-loongarch-elf/desc-ie.s
index 7f5772bc..441080b6 100644
--- a/ld/testsuite/ld-loongarch-elf/desc-ie.s
+++ b/ld/testsuite/ld-loongarch-elf/desc-ie.s
@@ -1,6 +1,6 @@
- .global v1
+ .global var
.section .tdata,"awT",@progbits
-v1:
+var:
.word 1
.text
.global fn1
@@ -9,10 +9,5 @@ fn1:
# Use DESC and IE to access the same symbol,
# DESC will relax to IE.
- pcalau12i $a0,%desc_pc_hi20(var)
- addi.d $a0,$a0,%desc_pc_lo12(var)
- ld.d $ra,$a0,%desc_ld(var)
- jirl $ra,$ra,%desc_call(var)
-
- pcalau12i $a0,%ie_pc_hi20(var)
- ld.d $ra,$a0,%ie_pc_lo12(var)
+ la.tls.ie $a0,var
+ la.tls.desc $a0,var
diff --git a/ld/testsuite/ld-loongarch-elf/desc-le-norelax.d b/ld/testsuite/ld-loongarch-elf/desc-le-norelax.d
new file mode 100644
index 00000000..5a53245a
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-le-norelax.d
@@ -0,0 +1,15 @@
+#as:
+#ld: -z norelro -e0 --no-relax
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <fn1>:
+ +[0-9a-f]+: 14000004 lu12i.w \$a0, .*
+ +[0-9a-f]+: 03800084 ori \$a0, \$a0, .*
+ +[0-9a-f]+: 03400000 nop
+ +[0-9a-f]+: 03400000 nop
diff --git a/ld/testsuite/ld-loongarch-elf/desc-le-norelax.s b/ld/testsuite/ld-loongarch-elf/desc-le-norelax.s
new file mode 100644
index 00000000..c91f15de
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-le-norelax.s
@@ -0,0 +1,11 @@
+ .global var
+ .section .tdata,"awT",@progbits
+var:
+ .word 1
+ .text
+ .global fn1
+ .type fn1,@function
+fn1:
+
+ # DESC will relax to LE.
+ la.tls.desc $a0,var
diff --git a/ld/testsuite/ld-loongarch-elf/desc-le-relax.d b/ld/testsuite/ld-loongarch-elf/desc-le-relax.d
new file mode 100644
index 00000000..03b5535e
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-le-relax.d
@@ -0,0 +1,13 @@
+#as:
+#ld: -z norelro -e0
+#objdump: -dr -M no-aliases
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <fn1>:
+ +[0-9a-f]+: 03800004 ori \$a0, \$zero, 0x0
+ +[0-9a-f]+: 03801004 ori \$a0, \$zero, 0x4
diff --git a/ld/testsuite/ld-loongarch-elf/desc-le-relax.s b/ld/testsuite/ld-loongarch-elf/desc-le-relax.s
new file mode 100644
index 00000000..d590299d
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-le-relax.s
@@ -0,0 +1,14 @@
+ .global var
+ .section .tdata,"awT",@progbits
+var1:
+ .word 1
+var2:
+ .word 1
+ .text
+ .global fn1
+ .type fn1,@function
+fn1:
+
+ # DESC will relax to LE.
+ la.tls.desc $a0,var1
+ la.tls.desc $a0,var2
diff --git a/ld/testsuite/ld-loongarch-elf/desc-le.d b/ld/testsuite/ld-loongarch-elf/desc-le.d
deleted file mode 100644
index b4ca9f82..00000000
--- a/ld/testsuite/ld-loongarch-elf/desc-le.d
+++ /dev/null
@@ -1,15 +0,0 @@
-#as:
-#ld: -z norelro -e 0x0
-#objdump: -dr
-#skip: loongarch32-*-*
-
-.*: file format .*
-
-
-Disassembly of section .text:
-
-0+1200000e8 <fn1>:
- 1200000e8: 14000004 lu12i.w \$a0, 0
- 1200000ec: 03800084 ori \$a0, \$a0, 0x0
- 1200000f0: 03400000 nop.*
- 1200000f4: 03400000 nop.*
diff --git a/ld/testsuite/ld-loongarch-elf/desc-le.s b/ld/testsuite/ld-loongarch-elf/desc-le.s
deleted file mode 100644
index 9ffaa2d6..00000000
--- a/ld/testsuite/ld-loongarch-elf/desc-le.s
+++ /dev/null
@@ -1,14 +0,0 @@
- .global var
- .section .tdata,"awT",@progbits
-var:
- .word 1
- .text
- .global fn1
- .type fn1,@function
-fn1:
-
- # DESC will relax to LE.
- pcalau12i $a0,%desc_pc_hi20(var)
- addi.d $a0,$a0,%desc_pc_lo12(var)
- ld.d $ra,$a0,%desc_ld(var)
- jirl $ra,$ra,%desc_call(var)
diff --git a/ld/testsuite/ld-loongarch-elf/ie-le-norelax.d b/ld/testsuite/ld-loongarch-elf/ie-le-norelax.d
new file mode 100644
index 00000000..81d78ca3
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/ie-le-norelax.d
@@ -0,0 +1,13 @@
+#as:
+#ld: -z norelro -e0 --no-relax
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <.*>:
+ +[0-9a-f]+: 14000024 lu12i.w \$a0, .*
+ +[0-9a-f]+: 03800084 ori \$a0, \$a0, .*
diff --git a/ld/testsuite/ld-loongarch-elf/ie-le.s b/ld/testsuite/ld-loongarch-elf/ie-le-norelax.s
similarity index 63%
rename from ld/testsuite/ld-loongarch-elf/ie-le.s
rename to ld/testsuite/ld-loongarch-elf/ie-le-norelax.s
index 795c7ce4..db87a2d3 100644
--- a/ld/testsuite/ld-loongarch-elf/ie-le.s
+++ b/ld/testsuite/ld-loongarch-elf/ie-le-norelax.s
@@ -1,5 +1,6 @@
.data
.section .tdata,"awT",@progbits
+ .fill 0x1000,1,0
var:
.word 1
.text
@@ -7,5 +8,4 @@ var:
.type gn1,@function
fn1:
# expect IE to relax LE.
- pcalau12i $a0,%ie_pc_hi20(var)
- ld.d $a0,$a0,%ie_pc_lo12(var)
+ la.tls.ie $a0,var
diff --git a/ld/testsuite/ld-loongarch-elf/ie-le-relax.d b/ld/testsuite/ld-loongarch-elf/ie-le-relax.d
new file mode 100644
index 00000000..03b5535e
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/ie-le-relax.d
@@ -0,0 +1,13 @@
+#as:
+#ld: -z norelro -e0
+#objdump: -dr -M no-aliases
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <fn1>:
+ +[0-9a-f]+: 03800004 ori \$a0, \$zero, 0x0
+ +[0-9a-f]+: 03801004 ori \$a0, \$zero, 0x4
diff --git a/ld/testsuite/ld-loongarch-elf/ie-le-relax.s b/ld/testsuite/ld-loongarch-elf/ie-le-relax.s
new file mode 100644
index 00000000..08bc3987
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/ie-le-relax.s
@@ -0,0 +1,13 @@
+ .data
+ .section .tdata,"awT",@progbits
+var1:
+ .word 1
+var2:
+ .word 2
+ .text
+ .global fn1
+ .type gn1,@function
+fn1:
+ # expect IE to relax LE
+ la.tls.ie $a0,var1
+ la.tls.ie $a0,var2
diff --git a/ld/testsuite/ld-loongarch-elf/ie-le.d b/ld/testsuite/ld-loongarch-elf/ie-le.d
deleted file mode 100644
index 42694d7f..00000000
--- a/ld/testsuite/ld-loongarch-elf/ie-le.d
+++ /dev/null
@@ -1,13 +0,0 @@
-#as:
-#ld: -z norelro -e 0x0
-#objdump: -dr
-#skip: loongarch32-*-*
-
-.*: file format .*
-
-
-Disassembly of section .text:
-
-0+1200000e8 <fn1>:
- 1200000e8: 14000004 lu12i.w \$a0, 0
- 1200000ec: 03800084 ori \$a0, \$a0, 0x0
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 7dca8218..ca428f5b 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -34,7 +34,6 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "local-ifunc-reloc"
run_dump_test "anno-sym"
run_dump_test "pcala64"
- run_dump_test "tls-le"
run_dump_test "overflow_s_10_5"
run_dump_test "overflow_s_10_12"
run_dump_test "overflow_s_10_16"
@@ -51,6 +50,8 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "underflow_s_0_5_10_16_s2"
run_dump_test "underflow_s_0_10_10_16_s2"
run_dump_test "underflow_s_5_20"
+ run_dump_test "tls-le-norelax"
+ run_dump_test "tls-le-relax"
}
if [istarget "loongarch32-*-*"] {
@@ -127,8 +128,6 @@ if [istarget "loongarch64-*-*"] {
if [istarget "loongarch64-*-*"] {
if [check_shared_lib_support] {
run_dump_test "desc-ie"
- run_dump_test "desc-le"
- run_dump_test "ie-le"
run_dump_test "tlsdesc-dso"
run_dump_test "desc-norelax"
run_dump_test "desc-relax"
@@ -147,5 +146,11 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "underflow_b26"
run_dump_test "underflow_pcrel20"
run_dump_test "pie_discard"
+ run_dump_test "desc-le-norelax"
+ run_dump_test "desc-le-relax"
+ run_dump_test "ie-le-norelax"
+ run_dump_test "ie-le-relax"
+ run_dump_test "tlsdesc_abs"
+ run_dump_test "tlsdesc_extreme"
}
diff --git a/ld/testsuite/ld-loongarch-elf/macro_op.d b/ld/testsuite/ld-loongarch-elf/macro_op.d
index c9493918..6a886224 100644
--- a/ld/testsuite/ld-loongarch-elf/macro_op.d
+++ b/ld/testsuite/ld-loongarch-elf/macro_op.d
@@ -140,12 +140,16 @@ Disassembly of section .text:
[ ]+f0:[ ]+380c1484[ ]+ldx.d[ ]+\$a0, \$a0, \$a1
[ ]+f4:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
[ ]+f4: R_LARCH_TLS_LE_HI20[ ]+TLS1
+[ ]+f4: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+f8:[ ]+03800084[ ]+ori[ ]+\$a0, \$a0, 0x0
[ ]+f8: R_LARCH_TLS_LE_LO12[ ]+TLS1
+[ ]+f8: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+fc:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
[ ]+fc: R_LARCH_TLS_IE_PC_HI20[ ]+TLS1
+[ ]+fc: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+100:[ ]+28c00084[ ]+ld.d[ ]+\$a0, \$a0, 0
[ ]+100: R_LARCH_TLS_IE_PC_LO12[ ]+TLS1
+[ ]+100: R_LARCH_RELAX[ ]+\*ABS\*
[ ]+104:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
[ ]+104: R_LARCH_TLS_IE_PC_HI20[ ]+TLS1
[ ]+108:[ ]+02c00005[ ]+li.d[ ]+\$a1, 0
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index c537976a..bca3e1bd 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -137,7 +137,7 @@ if [istarget loongarch64-*-*] {
[list \
[list \
"loongarch old tls le .exe build" \
- "" "" \
+ "--no-relax" "" \
"" \
{old-tls-le.s} \
{} \
@@ -158,7 +158,7 @@ if [istarget loongarch64-*-*] {
[list \
[list \
"loongarch tls le realx compatible .exe build" \
- "" "" \
+ "--no-relax" "" \
"" \
{tls-relax-compatible-check-new.s tls-relax-compatible-check-old.s} \
{} \
@@ -201,7 +201,7 @@ if [istarget loongarch64-*-*] {
[list \
[list \
"loongarch tls le realx bound-check .exe build" \
- "" "" \
+ "--no-relax" "" \
"" \
{relax-bound-check-tls-le.s} \
{} \
diff --git a/ld/testsuite/ld-loongarch-elf/tls-le-norelax.d b/ld/testsuite/ld-loongarch-elf/tls-le-norelax.d
new file mode 100644
index 00000000..a53d8123
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-le-norelax.d
@@ -0,0 +1,18 @@
+#ld: --no-relax
+#objdump: -d -M no-aliases
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <_start>:
+ +[0-9a-f]+: 14000004 lu12i.w \$a0, 0
+ +[0-9a-f]+: 03802085 ori \$a1, \$a0, 0x8
+ +[0-9a-f]+: 14000004 lu12i.w \$a0, 0
+ +[0-9a-f]+: 02c02085 addi.d \$a1, \$a0, 8
+ +[0-9a-f]+: 14000004 lu12i.w \$a0, 0
+ +[0-9a-f]+: 03802084 ori \$a0, \$a0, 0x8
+ +[0-9a-f]+: 16000004 lu32i.d \$a0, 0
+ +[0-9a-f]+: 03000084 lu52i.d \$a0, \$a0, 0
+ +[0-9a-f]+: 4c000020 jirl \$zero, \$ra, 0
diff --git a/ld/testsuite/ld-loongarch-elf/tls-le.s b/ld/testsuite/ld-loongarch-elf/tls-le-norelax.s
similarity index 70%
rename from ld/testsuite/ld-loongarch-elf/tls-le.s
rename to ld/testsuite/ld-loongarch-elf/tls-le-norelax.s
index 2e6a9de4..80f87920 100644
--- a/ld/testsuite/ld-loongarch-elf/tls-le.s
+++ b/ld/testsuite/ld-loongarch-elf/tls-le-norelax.s
@@ -15,4 +15,8 @@ _start:
ori $r5,$r4,%le_lo12(a + 0x8)
lu12i.w $r4,%le_hi20_r(a + 0x8)
addi.d $r5,$r4,%le_lo12_r(a + 0x8)
+ lu12i.w $r4,%le_hi20(a + 0x8)
+ ori $r4,$r4,%le_lo12(a + 0x8)
+ lu32i.d $r4,%le64_lo20(a + 0x8)
+ lu52i.d $r4,$r4,%le64_hi12(a + 0x8)
jr $ra
diff --git a/ld/testsuite/ld-loongarch-elf/tls-le-relax.d b/ld/testsuite/ld-loongarch-elf/tls-le-relax.d
new file mode 100644
index 00000000..19e101c8
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-le-relax.d
@@ -0,0 +1,13 @@
+#ld:
+#objdump: -d -M no-aliases
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+[0-9a-f]+ <_start>:
+ +[0-9a-f]+: 03802005 ori \$a1, \$zero, 0x8
+ +[0-9a-f]+: 02c02045 addi.d \$a1, \$tp, 8
+ +[0-9a-f]+: 03802004 ori \$a0, \$zero, 0x8
+ +[0-9a-f]+: 4c000020 jirl \$zero, \$ra, 0
diff --git a/ld/testsuite/ld-loongarch-elf/tls-le-relax.s b/ld/testsuite/ld-loongarch-elf/tls-le-relax.s
new file mode 100644
index 00000000..80f87920
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-le-relax.s
@@ -0,0 +1,22 @@
+# Support for TLS LE symbols with addend
+ .text
+ .globl a
+ .section .tdata,"awT",@progbits
+ .align 2
+ .type a, @object
+ .size a, 4
+a:
+ .word 123
+
+ .text
+ .global _start
+_start:
+ lu12i.w $r4,%le_hi20(a + 0x8)
+ ori $r5,$r4,%le_lo12(a + 0x8)
+ lu12i.w $r4,%le_hi20_r(a + 0x8)
+ addi.d $r5,$r4,%le_lo12_r(a + 0x8)
+ lu12i.w $r4,%le_hi20(a + 0x8)
+ ori $r4,$r4,%le_lo12(a + 0x8)
+ lu32i.d $r4,%le64_lo20(a + 0x8)
+ lu52i.d $r4,$r4,%le64_hi12(a + 0x8)
+ jr $ra
diff --git a/ld/testsuite/ld-loongarch-elf/tls-le.d b/ld/testsuite/ld-loongarch-elf/tls-le.d
deleted file mode 100644
index cbd6adb8..00000000
--- a/ld/testsuite/ld-loongarch-elf/tls-le.d
+++ /dev/null
@@ -1,14 +0,0 @@
-#ld: --no-relax
-#objdump: -d
-
-.*:[ ]+file format .*
-
-
-Disassembly of section .text:
-
-[ ]*00000001200000e8 <_start>:
-[ ]+1200000e8:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
-[ ]+1200000ec:[ ]+03802085[ ]+ori[ ]+\$a1, \$a0, 0x8
-[ ]+1200000f0:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
-[ ]+1200000f4:[ ]+02c02085[ ]+addi.d[ ]+\$a1, \$a0, 8
-[ ]+1200000f8:[ ]+4c000020[ ]+ret
diff --git a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
index 453902d1..84ea97e0 100644
--- a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
+++ b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
@@ -8,49 +8,53 @@
Disassembly of section .text:
-0+418 <fun_gl1>:
- 418: 180214c4 pcaddi \$a0, 4262
- 41c: 1a000084 pcalau12i \$a0, 4
- 420: 28db0084 ld.d \$a0, \$a0, 1728
- 424: 180212a4 pcaddi \$a0, 4245
- 428: 18021304 pcaddi \$a0, 4248
- 42c: 28c00081 ld.d \$ra, \$a0, 0
- 430: 4c000021 jirl \$ra, \$ra, 0
- 434: 1a000084 pcalau12i \$a0, 4
- 438: 28d9c084 ld.d \$a0, \$a0, 1648
- 43c: 03400000 nop.*
- 440: 03400000 nop.*
- 444: 1a000084 pcalau12i \$a0, 4
- 448: 28d9c084 ld.d \$a0, \$a0, 1648
- 44c: 18021264 pcaddi \$a0, 4243
- 450: 18021244 pcaddi \$a0, 4242
- 454: 28c00081 ld.d \$ra, \$a0, 0
- 458: 4c000021 jirl \$ra, \$ra, 0
- 45c: 1a000084 pcalau12i \$a0, 4
- 460: 28daa084 ld.d \$a0, \$a0, 1704
-
-0+464 <fun_lo>:
+0+448 <fun_gl1>:
+ 448: 18021584 pcaddi \$a0, 4268
+ 44c: 1a000084 pcalau12i \$a0, 4
+ 450: 28dc2084 ld.d \$a0, \$a0, 1800
+ 454: 18021364 pcaddi \$a0, 4251
+ 458: 180213c4 pcaddi \$a0, 4254
+ 45c: 28c00081 ld.d \$ra, \$a0, 0
+ 460: 4c000021 jirl \$ra, \$ra, 0
464: 1a000084 pcalau12i \$a0, 4
- 468: 28d86084 ld.d \$a0, \$a0, 1560
- 46c: 18020ce4 pcaddi \$a0, 4199
- 470: 18020e04 pcaddi \$a0, 4208
- 474: 28c00081 ld.d \$ra, \$a0, 0
- 478: 4c000021 jirl \$ra, \$ra, 0
- 47c: 18020d24 pcaddi \$a0, 4201
- 480: 1a000084 pcalau12i \$a0, 4
- 484: 28d90084 ld.d \$a0, \$a0, 1600
- 488: 03400000 nop.*
- 48c: 03400000 nop.*
- 490: 1a000084 pcalau12i \$a0, 4
- 494: 28d90084 ld.d \$a0, \$a0, 1600
- 498: 18020d84 pcaddi \$a0, 4204
+ 468: 28dae084 ld.d \$a0, \$a0, 1720
+ 46c: 1a000084 pcalau12i \$a0, 4
+ 470: 28dae084 ld.d \$a0, \$a0, 1720
+ 474: 18021364 pcaddi \$a0, 4251
+ 478: 18021344 pcaddi \$a0, 4250
+ 47c: 28c00081 ld.d \$ra, \$a0, 0
+ 480: 4c000021 jirl \$ra, \$ra, 0
+ 484: 1a000084 pcalau12i \$a0, 4
+ 488: 28dbc084 ld.d \$a0, \$a0, 1776
+
+0+48c <fun_lo>:
+ 48c: 1a000084 pcalau12i \$a0, 4
+ 490: 28d98084 ld.d \$a0, \$a0, 1632
+ 494: 18020de4 pcaddi \$a0, 4207
+ 498: 18020f04 pcaddi \$a0, 4216
49c: 28c00081 ld.d \$ra, \$a0, 0
4a0: 4c000021 jirl \$ra, \$ra, 0
- 4a4: 18020d24 pcaddi \$a0, 4201
+ 4a4: 18020e24 pcaddi \$a0, 4209
4a8: 1a000084 pcalau12i \$a0, 4
- 4ac: 28d96084 ld.d \$a0, \$a0, 1624
+ 4ac: 28da2084 ld.d \$a0, \$a0, 1672
+ 4b0: 1a000084 pcalau12i \$a0, 4
+ 4b4: 28da2084 ld.d \$a0, \$a0, 1672
+ 4b8: 18020ec4 pcaddi \$a0, 4214
+ 4bc: 28c00081 ld.d \$ra, \$a0, 0
+ 4c0: 4c000021 jirl \$ra, \$ra, 0
+ 4c4: 18020e64 pcaddi \$a0, 4211
+ 4c8: 1a000084 pcalau12i \$a0, 4
+ 4cc: 28da8084 ld.d \$a0, \$a0, 1696
+
+0+4d0 <fun_external>:
+ 4d0: 18020ec4 pcaddi \$a0, 4214
+ 4d4: 28c00081 ld.d \$ra, \$a0, 0
+ 4d8: 4c000021 jirl \$ra, \$ra, 0
-0+4b0 <fun_external>:
- 4b0: 18020d84 pcaddi \$a0, 4204
- 4b4: 28c00081 ld.d \$ra, \$a0, 0
- 4b8: 4c000021 jirl \$ra, \$ra, 0
+0+4dc <fun_hidden>:
+ 4dc: 18021224 pcaddi \$a0, 4241
+ 4e0: 28c00081 ld.d \$ra, \$a0, 0
+ 4e4: 4c000021 jirl \$ra, \$ra, 0
+ 4e8: 18021144 pcaddi \$a0, 4234
+ 4ec: 28c00081 ld.d \$ra, \$a0, 0
+ 4f0: 4c000021 jirl \$ra, \$ra, 0
diff --git a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.s b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.s
index 936bbcea..faadca61 100644
--- a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.s
+++ b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.s
@@ -1,6 +1,8 @@
.data
.section .tdata,"awT",@progbits
.global gl1, gl2, gl3, gl4
+ .global hd1, hd2
+ .hidden hd1, hd2
gl1: .dword 1
gl2: .dword 2
gl3: .dword 3
@@ -9,6 +11,8 @@ lo1: .dword 10
lo2: .dword 20
lo3: .dword 30
lo4: .dword 40
+hd1: .dword 100
+hd2: .dword 200
.text
# Access global symbol
fun_gl1:
@@ -63,3 +67,8 @@ fun_lo:
# Access external undef symbol
fun_external:
la.tls.desc $a0, sH1
+
+# Access hidden symbol
+fun_hidden:
+ la.tls.desc $a0, hd1
+ la.tls.desc $a0, hd2
diff --git a/ld/testsuite/ld-loongarch-elf/tlsdesc_abs.d b/ld/testsuite/ld-loongarch-elf/tlsdesc_abs.d
new file mode 100644
index 00000000..62f5a2a0
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tlsdesc_abs.d
@@ -0,0 +1,23 @@
+#as: -mla-global-with-abs
+#ld: --no-relax -e0
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+120000100 <.*>:
+ 120000100: 14400084 lu12i.w \$a0, .*
+ 120000104: 03850084 ori \$a0, \$a0, .*
+ 120000108: 16000024 lu32i.d \$a0, .*
+ 12000010c: 03000084 lu52i.d \$a0, \$a0, 0
+ 120000110: 28c00081 ld.d \$ra, \$a0, 0
+ 120000114: 4c000021 jirl \$ra, \$ra, 0
+ 120000118: 14400084 lu12i.w \$a0, .*
+ 12000011c: 03850084 ori \$a0, \$a0, .*
+ 120000120: 16000024 lu32i.d \$a0, .*
+ 120000124: 03000084 lu52i.d \$a0, \$a0, 0
+ 120000128: 28c00081 ld.d \$ra, \$a0, 0
+ 12000012c: 4c000021 jirl \$ra, \$ra, 0
diff --git a/ld/testsuite/ld-loongarch-elf/tlsdesc_abs.s b/ld/testsuite/ld-loongarch-elf/tlsdesc_abs.s
new file mode 100644
index 00000000..61ac9a80
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tlsdesc_abs.s
@@ -0,0 +1,7 @@
+ .section ".tdata", "awT", @progbits
+ .global var
+var: .dword 1
+ .text
+ # No matter which register the user uses, the abs macro expansion uses $a0
+ la.tls.desc $a0,var
+ la.tls.desc $t0,var
diff --git a/ld/testsuite/ld-loongarch-elf/tlsdesc_extreme.d b/ld/testsuite/ld-loongarch-elf/tlsdesc_extreme.d
new file mode 100644
index 00000000..55179997
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tlsdesc_extreme.d
@@ -0,0 +1,25 @@
+#as: -mla-global-with-pcrel
+#ld: --no-relax -e0
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0+120000100 <.*>:
+ 120000100: 1a000084 pcalau12i \$a0, .*
+ 120000104: 02c52001 li.d \$ra, .*
+ 120000108: 16000001 lu32i.d \$ra, 0
+ 12000010c: 03000021 lu52i.d \$ra, \$ra, 0
+ 120000110: 00108484 add.d \$a0, \$a0, \$ra
+ 120000114: 28c00081 ld.d \$ra, \$a0, 0
+ 120000118: 4c000021 jirl \$ra, \$ra, 0
+ 12000011c: 1a000084 pcalau12i \$a0, .*
+ 120000120: 02c5200d li.d \$t1, .*
+ 120000124: 1600000d lu32i.d \$t1, 0
+ 120000128: 030001ad lu52i.d \$t1, \$t1, 0
+ 12000012c: 0010b484 add.d \$a0, \$a0, \$t1
+ 120000130: 28c00081 ld.d \$ra, \$a0, 0
+ 120000134: 4c000021 jirl \$ra, \$ra, 0
diff --git a/ld/testsuite/ld-loongarch-elf/tlsdesc_extreme.s b/ld/testsuite/ld-loongarch-elf/tlsdesc_extreme.s
new file mode 100644
index 00000000..3582692d
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tlsdesc_extreme.s
@@ -0,0 +1,7 @@
+ .section ".tdata", "awT", @progbits
+ .global var
+var: .dword 1
+ .text
+ # No matter which two registers are passed in, $a0 and $ra are always used
+ la.tls.desc $a0,$ra,var
+ la.tls.desc $t0,$t1,var
--
2.33.0

View File

@ -0,0 +1,146 @@
From ced17161d4aac5b19c9aca8e6183607a83fc1774 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Sat, 20 Jan 2024 00:38:24 +0800
Subject: [PATCH 048/123] LoongArch: Fix some test failures about TLS desc and
TLS relaxation
There are two issues causing 11 test failures:
1. The TLS desc tests are matching the entire disassemble of a linked
executable. But if ld is configured --enable-default-hash-style=gnu
(note that most modern distros use this option), the layout of the
linked executables will be different and the immediate operands in
the linked executables will also be different. So we add
"--hash-style=both" for these tests to cancel the effect of
--enable-default-hash-style=gnu, like [x86_64 mark-plt tests].
2. By default objdump disassemble uses [pseudo-instructions] so "addi.w"
is outputed as "li.w", causing mismatches in TLS relaxation tests.
We can turn off the pseudo-instruction usage in objdump using "-M
no-aliases" to fix them.
[x86_64 mark-plt tests]: 16666ccc91295d1568c5c2cb0e7600694840dfd9
[pseudo-instructions]: 17f9439038257b1de0c130a416a9a7645c653cb0
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
ld/testsuite/ld-loongarch-elf/desc-ie.d | 2 +-
ld/testsuite/ld-loongarch-elf/desc-norelax.d | 2 +-
ld/testsuite/ld-loongarch-elf/desc-relax.d | 2 +-
ld/testsuite/ld-loongarch-elf/relax.exp | 14 +++++++-------
ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d | 2 +-
5 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/ld/testsuite/ld-loongarch-elf/desc-ie.d b/ld/testsuite/ld-loongarch-elf/desc-ie.d
index d1acbfc6..32e35050 100644
--- a/ld/testsuite/ld-loongarch-elf/desc-ie.d
+++ b/ld/testsuite/ld-loongarch-elf/desc-ie.d
@@ -1,5 +1,5 @@
#as:
-#ld: -shared -z norelro -e 0x0
+#ld: -shared -z norelro -e 0x0 --hash-style=both
#objdump: -dr
#skip: loongarch32-*-*
diff --git a/ld/testsuite/ld-loongarch-elf/desc-norelax.d b/ld/testsuite/ld-loongarch-elf/desc-norelax.d
index 32ce3e5e..e4863dda 100644
--- a/ld/testsuite/ld-loongarch-elf/desc-norelax.d
+++ b/ld/testsuite/ld-loongarch-elf/desc-norelax.d
@@ -1,5 +1,5 @@
#as:
-#ld: -z norelro -shared --section-start=.got=0x1ff000
+#ld: -z norelro -shared --section-start=.got=0x1ff000 --hash-style=both
#objdump: -dr
#skip: loongarch32-*-*
diff --git a/ld/testsuite/ld-loongarch-elf/desc-relax.d b/ld/testsuite/ld-loongarch-elf/desc-relax.d
index ce53d317..c885953c 100644
--- a/ld/testsuite/ld-loongarch-elf/desc-relax.d
+++ b/ld/testsuite/ld-loongarch-elf/desc-relax.d
@@ -1,5 +1,5 @@
#as:
-#ld: -z norelro -shared
+#ld: -z norelro -shared --hash-style=both
#objdump: -dr
#skip: loongarch32-*-*
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index 107e5a56..c537976a 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -104,7 +104,7 @@ if [istarget loongarch64-*-*] {
]
if [file exist "tmpdir/relax-tls-le"] {
- set objdump_output1 [run_host_cmd "objdump" "-d tmpdir/relax-tls-le"]
+ set objdump_output1 [run_host_cmd "objdump" "-d tmpdir/relax-tls-le -M no-aliases"]
if { [ regexp ".addi.*st.*" $objdump_output1] } {
pass "loongarch relax success"
} {
@@ -125,7 +125,7 @@ if [istarget loongarch64-*-*] {
]
if [file exist "tmpdir/no-relax-tls-le"] {
- set objdump_output2 [run_host_cmd "objdump" "-d tmpdir/no-relax-tls-le"]
+ set objdump_output2 [run_host_cmd "objdump" "-d tmpdir/no-relax-tls-le -M no-aliases"]
if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output2] } {
pass "loongarch no-relax success"
} {
@@ -146,7 +146,7 @@ if [istarget loongarch64-*-*] {
]
if [file exist "tmpdir/old-tls-le"] {
- set objdump_output3 [run_host_cmd "objdump" "-d tmpdir/old-tls-le"]
+ set objdump_output3 [run_host_cmd "objdump" "-d tmpdir/old-tls-le -M no-aliases"]
if { [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output3] } {
pass "loongarch old tls le success"
} {
@@ -167,7 +167,7 @@ if [istarget loongarch64-*-*] {
]
if [file exist "tmpdir/realx-compatible"] {
- set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/realx-compatible"]
+ set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/realx-compatible -M no-aliases"]
if { [ regexp ".addi.*st.*" $objdump_output4] && \
[ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output4] } {
pass "loongarch tls le relax compatible check success"
@@ -188,7 +188,7 @@ if [istarget loongarch64-*-*] {
] \
]
if [file exist "tmpdir/no-realx-compatible"] {
- set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/no-realx-compatible"]
+ set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/no-realx-compatible -M no-aliases"]
if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output4] && \
[ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output4] } {
pass "loongarch tls le no-relax compatible check success"
@@ -210,7 +210,7 @@ if [istarget loongarch64-*-*] {
]
if [file exist "tmpdir/relax-bound-check-tls-le"] {
- set objdump_output5 [run_host_cmd "objdump" "-d tmpdir/relax-bound-check-tls-le"]
+ set objdump_output5 [run_host_cmd "objdump" "-d tmpdir/relax-bound-check-tls-le -M no-aliases"]
if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output5] && \
[ regexp ".addi.*st.*" $objdump_output5] } {
pass "loongarch no-relax success"
@@ -232,7 +232,7 @@ if [istarget loongarch64-*-*] {
]
if [file exist "tmpdir/no-relax-bound-check-tls-le"] {
- set objdump_output5 [run_host_cmd "objdump" "-d tmpdir/no-relax-bound-check-tls-le"]
+ set objdump_output5 [run_host_cmd "objdump" "-d tmpdir/no-relax-bound-check-tls-le -M no-aliases"]
if { [ regexp ".*addi.*st.*" $objdump_output5] } {
pass "loongarch no-relax success"
} {
diff --git a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
index 667ad746..453902d1 100644
--- a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
+++ b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
@@ -1,5 +1,5 @@
#as:
-#ld: -shared -z norelro
+#ld: -shared -z norelro --hash-style=both
#objdump: -dr
#skip: loongarch32-*-*
--
2.33.0

View File

@ -0,0 +1,437 @@
From e43c6e4abc81d9bbf66fb210d86682d9f647031d Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Thu, 21 Mar 2024 16:33:21 +0800
Subject: [PATCH 077/123] LoongArch: Fix the issue of excessive relocation
generated by GD and IE
Currently, whether GD and IE generate dynamic relocation is
determined by SYMBOL_REFERENCES_LOCAL and bfd_link_executable.
This results in dynamic relocations still being generated in some
situations where dynamic relocations are not necessary (such as
the undefined weak symbol in static links).
We use RLARCH_TLS_GD_IE_NEED_DYN_RELOC macros to determine whether
GD/IE needs dynamic relocation. If GD/IE requires dynamic relocation,
set need_reloc to true and indx to be a dynamic index.
At the same time, some test cases were modified to use regular
expression matching instead of complete disassembly matching.
---
bfd/elfnn-loongarch.c | 179 ++++++++++----------
ld/testsuite/ld-loongarch-elf/desc-ie.d | 4 +-
ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d | 94 +++++-----
3 files changed, 142 insertions(+), 135 deletions(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index f6975957..7f98dce1 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -159,6 +159,27 @@ struct loongarch_elf_link_hash_table
|| (R_TYPE) == R_LARCH_TLS_LE64_LO20 \
|| (R_TYPE) == R_LARCH_TLS_LE64_HI12)
+/* If TLS GD/IE need dynamic relocations, INDX will be the dynamic indx,
+ and set NEED_RELOC to true used in allocate_dynrelocs and
+ loongarch_elf_relocate_section for TLS GD/IE. */
+#define LARCH_TLS_GD_IE_NEED_DYN_RELOC(INFO, DYN, H, INDX, NEED_RELOC) \
+ do \
+ { \
+ if ((H) != NULL \
+ && (H)->dynindx != -1 \
+ && WILL_CALL_FINISH_DYNAMIC_SYMBOL ((DYN), \
+ bfd_link_pic (INFO), (H))) \
+ (INDX) = (H)->dynindx; \
+ if (((H) == NULL \
+ || ELF_ST_VISIBILITY ((H)->other) == STV_DEFAULT \
+ || (H)->root.type != bfd_link_hash_undefweak) \
+ && (!bfd_link_executable (INFO) \
+ || (INDX) != 0)) \
+ (NEED_RELOC) = true; \
+ } \
+ while (0)
+
+
/* Generate a PLT header. */
static bool
@@ -1276,40 +1297,24 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
h->got.offset = s->size;
if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
{
+ int indx = 0;
+ bool need_reloc = false;
+ LARCH_TLS_GD_IE_NEED_DYN_RELOC (info, dyn, h, indx,
+ need_reloc);
/* TLS_GD needs two dynamic relocs and two GOT slots. */
if (tls_type & GOT_TLS_GD)
{
s->size += 2 * GOT_ENTRY_SIZE;
- if (bfd_link_executable (info))
- {
- /* Link exe and not defined local. */
- if (!SYMBOL_REFERENCES_LOCAL (info, h))
- htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
- }
- else
- {
- if (SYMBOL_REFERENCES_LOCAL (info, h))
- htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
- else
- htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
- }
+ if (need_reloc)
+ htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
}
/* TLS_IE needs one dynamic reloc and one GOT slot. */
if (tls_type & GOT_TLS_IE)
{
s->size += GOT_ENTRY_SIZE;
-
- if (bfd_link_executable (info))
- {
- /* Link exe and not defined local. */
- if (!SYMBOL_REFERENCES_LOCAL (info, h))
- htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
- }
- else
- {
- htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
- }
+ if (need_reloc)
+ htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
}
/* TLS_DESC needs one dynamic reloc and two GOT slot. */
@@ -2550,13 +2555,18 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
})
+/* Compute the tp/dtp offset of a tls symbol.
+ It is dtp offset in dynamic tls model (gd/ld) and tp
+ offset in static tls model (ie/le). Both offsets are
+ calculated the same way on LoongArch, so the same
+ function is used. */
static bfd_vma
-tls_dtpoff_base (struct bfd_link_info *info)
+tlsoff (struct bfd_link_info *info, bfd_vma addr)
{
/* If tls_sec is NULL, we should have signalled an error already. */
if (elf_hash_table (info)->tls_sec == NULL)
return 0;
- return elf_hash_table (info)->tls_sec->vma;
+ return addr - elf_hash_table (info)->tls_sec->vma;
}
@@ -2890,7 +2900,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
is_undefweak, name, "TLS section not be created");
}
else
- relocation -= elf_hash_table (info)->tls_sec->vma;
+ relocation = tlsoff (info, relocation);
}
else
{
@@ -3416,7 +3426,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_LARCH_TLS_LE_HI20_R:
relocation += rel->r_addend;
- relocation -= elf_hash_table (info)->tls_sec->vma;
+ relocation = tlsoff (info, relocation);
RELOCATE_TLS_TP32_HI20 (relocation);
break;
@@ -3599,7 +3609,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
relocation += rel->r_addend;
- relocation -= elf_hash_table (info)->tls_sec->vma;
+ relocation = tlsoff (info, relocation);
break;
/* TLS IE LD/GD process separately is troublesome.
@@ -3654,71 +3664,72 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
/* If a tls variable is accessed in multiple ways, GD uses
the first two slots of GOT, desc follows with two slots,
and IE uses one slot at the end. */
- desc_off = 0;
- if (GOT_TLS_GD_BOTH_P (tls_type))
- desc_off = 2 * GOT_ENTRY_SIZE;
-
- ie_off = 0;
- if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
- ie_off = 4 * GOT_ENTRY_SIZE;
- else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
- ie_off = 2 * GOT_ENTRY_SIZE;
+ off = 0;
+ if (tls_type & GOT_TLS_GD)
+ off += 2 * GOT_ENTRY_SIZE;
+ desc_off = off;
+ if (tls_type & GOT_TLS_GDESC)
+ off += 2 * GOT_ENTRY_SIZE;
+ ie_off = off;
if ((got_off & 1) == 0)
{
Elf_Internal_Rela rela;
asection *relgot = htab->elf.srelgot;
- bfd_vma tls_block_off = 0;
- if (SYMBOL_REFERENCES_LOCAL (info, h))
- {
- BFD_ASSERT (elf_hash_table (info)->tls_sec);
- tls_block_off = relocation
- - elf_hash_table (info)->tls_sec->vma;
- }
+ int indx = 0;
+ bool need_reloc = false;
+ LARCH_TLS_GD_IE_NEED_DYN_RELOC (info, is_dyn, h, indx,
+ need_reloc);
if (tls_type & GOT_TLS_GD)
{
- rela.r_offset = sec_addr (got) + got_off;
- rela.r_addend = 0;
- if (SYMBOL_REFERENCES_LOCAL (info, h))
+ if (need_reloc)
{
- /* Local sym, used in exec, set module id 1. */
- if (bfd_link_executable (info))
- bfd_put_NN (output_bfd, 1, got->contents + got_off);
+ /* Dynamic resolved Module ID. */
+ rela.r_offset = sec_addr (got) + got_off;
+ rela.r_addend = 0;
+ rela.r_info = ELFNN_R_INFO (indx,R_LARCH_TLS_DTPMODNN);
+ bfd_put_NN (output_bfd, 0, got->contents + got_off);
+ loongarch_elf_append_rela (output_bfd, relgot, &rela);
+
+ if (indx == 0)
+ {
+ /* Local symbol, tp offset has been known. */
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_NN (output_bfd,
+ tlsoff (info, relocation),
+ (got->contents + got_off + GOT_ENTRY_SIZE));
+ }
else
{
- rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_DTPMODNN);
+ /* Dynamic resolved block offset. */
+ bfd_put_NN (output_bfd, 0,
+ got->contents + got_off + GOT_ENTRY_SIZE);
+ rela.r_info = ELFNN_R_INFO (indx,
+ R_LARCH_TLS_DTPRELNN);
+ rela.r_offset += GOT_ENTRY_SIZE;
loongarch_elf_append_rela (output_bfd, relgot, &rela);
}
-
- bfd_put_NN (output_bfd, tls_block_off,
- got->contents + got_off + GOT_ENTRY_SIZE);
}
- /* Dynamic resolved. */
else
{
- /* Dynamic relocate module id. */
- rela.r_info = ELFNN_R_INFO (h->dynindx,
- R_LARCH_TLS_DTPMODNN);
- loongarch_elf_append_rela (output_bfd, relgot, &rela);
-
- /* Dynamic relocate offset of block. */
- rela.r_offset += GOT_ENTRY_SIZE;
- rela.r_info = ELFNN_R_INFO (h->dynindx,
- R_LARCH_TLS_DTPRELNN);
- loongarch_elf_append_rela (output_bfd, relgot, &rela);
+ /* In a static link or an executable link with the symbol
+ binding locally. Mark it as belonging to module 1. */
+ bfd_put_NN (output_bfd, 1, got->contents + got_off);
+ bfd_put_NN (output_bfd, tlsoff (info, relocation),
+ got->contents + got_off + GOT_ENTRY_SIZE);
}
}
if (tls_type & GOT_TLS_GDESC)
{
/* Unless it is a static link, DESC always emits a
dynamic relocation. */
- int indx = h && h->dynindx != -1 ? h->dynindx : 0;
+ indx = h && h->dynindx != -1 ? h->dynindx : 0;
rela.r_offset = sec_addr (got) + got_off + desc_off;
rela.r_addend = 0;
if (indx == 0)
- rela.r_addend = relocation - tls_dtpoff_base (info);
+ rela.r_addend = tlsoff (info, relocation);
rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DESCNN);
loongarch_elf_append_rela (output_bfd, relgot, &rela);
@@ -3727,28 +3738,24 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
}
if (tls_type & GOT_TLS_IE)
{
- rela.r_offset = sec_addr (got) + got_off + ie_off;
- if (SYMBOL_REFERENCES_LOCAL (info, h))
+ if (need_reloc)
{
- /* Local sym, used in exec, set module id 1. */
- if (!bfd_link_executable (info))
- {
- rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
- rela.r_addend = tls_block_off;
- loongarch_elf_append_rela (output_bfd, relgot, &rela);
- }
+ bfd_put_NN (output_bfd, 0,
+ got->contents + got_off + ie_off);
+ rela.r_offset = sec_addr (got) + got_off + ie_off;
+ rela.r_addend = 0;
- bfd_put_NN (output_bfd, tls_block_off,
- got->contents + got_off + ie_off);
+ if (indx == 0)
+ rela.r_addend = tlsoff (info, relocation);
+ rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_TPRELNN);
+ loongarch_elf_append_rela (output_bfd, relgot, &rela);
}
- /* Dynamic resolved. */
else
{
- /* Dynamic relocate offset of block. */
- rela.r_info = ELFNN_R_INFO (h->dynindx,
- R_LARCH_TLS_TPRELNN);
- rela.r_addend = 0;
- loongarch_elf_append_rela (output_bfd, relgot, &rela);
+ /* In a static link or an executable link with the symbol
+ bindinglocally, compute offset directly. */
+ bfd_put_NN (output_bfd, tlsoff (info, relocation),
+ got->contents + got_off + ie_off);
}
}
}
@@ -3787,7 +3794,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
/* Use both TLS_GD and TLS_DESC. */
- if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
+ if (GOT_TLS_GD_BOTH_P (tls_type))
relocation += 2 * GOT_ENTRY_SIZE;
if (r_type == R_LARCH_TLS_DESC64_PC_LO20)
diff --git a/ld/testsuite/ld-loongarch-elf/desc-ie.d b/ld/testsuite/ld-loongarch-elf/desc-ie.d
index e1f49e2d..c833b233 100644
--- a/ld/testsuite/ld-loongarch-elf/desc-ie.d
+++ b/ld/testsuite/ld-loongarch-elf/desc-ie.d
@@ -9,6 +9,6 @@ Disassembly of section .text:
[0-9a-f]+ <fn1>:
+[0-9a-f]+: 1a000084 pcalau12i \$a0, .*
- +[0-9a-f]+: 28cca084 ld.d \$a0, \$a0, .*
+ +[0-9a-f]+: 28cd0084 ld.d \$a0, \$a0, .*
+[0-9a-f]+: 1a000084 pcalau12i \$a0, .*
- +[0-9a-f]+: 28cca084 ld.d \$a0, \$a0, .*
+ +[0-9a-f]+: 28cd0084 ld.d \$a0, \$a0, .*
diff --git a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
index 84ea97e0..8f66302f 100644
--- a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
+++ b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
@@ -8,53 +8,53 @@
Disassembly of section .text:
-0+448 <fun_gl1>:
- 448: 18021584 pcaddi \$a0, 4268
- 44c: 1a000084 pcalau12i \$a0, 4
- 450: 28dc2084 ld.d \$a0, \$a0, 1800
- 454: 18021364 pcaddi \$a0, 4251
- 458: 180213c4 pcaddi \$a0, 4254
- 45c: 28c00081 ld.d \$ra, \$a0, 0
- 460: 4c000021 jirl \$ra, \$ra, 0
- 464: 1a000084 pcalau12i \$a0, 4
- 468: 28dae084 ld.d \$a0, \$a0, 1720
- 46c: 1a000084 pcalau12i \$a0, 4
- 470: 28dae084 ld.d \$a0, \$a0, 1720
- 474: 18021364 pcaddi \$a0, 4251
- 478: 18021344 pcaddi \$a0, 4250
- 47c: 28c00081 ld.d \$ra, \$a0, 0
- 480: 4c000021 jirl \$ra, \$ra, 0
- 484: 1a000084 pcalau12i \$a0, 4
- 488: 28dbc084 ld.d \$a0, \$a0, 1776
+[0-9a-f]+ <fun_gl1>:
+ +[0-9a-f]+: 18021584 pcaddi \$a0, 4268
+ +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
+ +[0-9a-f]+: 28dd4084 ld.d \$a0, \$a0, 1872
+ +[0-9a-f]+: 18021364 pcaddi \$a0, 4251
+ +[0-9a-f]+: 180213c4 pcaddi \$a0, 4254
+ +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
+ +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
+ +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
+ +[0-9a-f]+: 28dc0084 ld.d \$a0, \$a0, 1792
+ +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
+ +[0-9a-f]+: 28dc0084 ld.d \$a0, \$a0, 1792
+ +[0-9a-f]+: 18021364 pcaddi \$a0, 4251
+ +[0-9a-f]+: 180213c4 pcaddi \$a0, 4254
+ +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
+ +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
+ +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
+ +[0-9a-f]+: 28dce084 ld.d \$a0, \$a0, 1848
-0+48c <fun_lo>:
- 48c: 1a000084 pcalau12i \$a0, 4
- 490: 28d98084 ld.d \$a0, \$a0, 1632
- 494: 18020de4 pcaddi \$a0, 4207
- 498: 18020f04 pcaddi \$a0, 4216
- 49c: 28c00081 ld.d \$ra, \$a0, 0
- 4a0: 4c000021 jirl \$ra, \$ra, 0
- 4a4: 18020e24 pcaddi \$a0, 4209
- 4a8: 1a000084 pcalau12i \$a0, 4
- 4ac: 28da2084 ld.d \$a0, \$a0, 1672
- 4b0: 1a000084 pcalau12i \$a0, 4
- 4b4: 28da2084 ld.d \$a0, \$a0, 1672
- 4b8: 18020ec4 pcaddi \$a0, 4214
- 4bc: 28c00081 ld.d \$ra, \$a0, 0
- 4c0: 4c000021 jirl \$ra, \$ra, 0
- 4c4: 18020e64 pcaddi \$a0, 4211
- 4c8: 1a000084 pcalau12i \$a0, 4
- 4cc: 28da8084 ld.d \$a0, \$a0, 1696
+[0-9a-f]+ <fun_lo>:
+ +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
+ +[0-9a-f]+: 28daa084 ld.d \$a0, \$a0, 1704
+ +[0-9a-f]+: 18020de4 pcaddi \$a0, 4207
+ +[0-9a-f]+: 18020f04 pcaddi \$a0, 4216
+ +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
+ +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
+ +[0-9a-f]+: 18020e24 pcaddi \$a0, 4209
+ +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
+ +[0-9a-f]+: 28db4084 ld.d \$a0, \$a0, 1744
+ +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
+ +[0-9a-f]+: 28db4084 ld.d \$a0, \$a0, 1744
+ +[0-9a-f]+: 18020f44 pcaddi \$a0, 4218
+ +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
+ +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
+ +[0-9a-f]+: 18020e64 pcaddi \$a0, 4211
+ +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
+ +[0-9a-f]+: 28dba084 ld.d \$a0, \$a0, 1768
-0+4d0 <fun_external>:
- 4d0: 18020ec4 pcaddi \$a0, 4214
- 4d4: 28c00081 ld.d \$ra, \$a0, 0
- 4d8: 4c000021 jirl \$ra, \$ra, 0
+[0-9a-f]+ <fun_external>:
+ +[0-9a-f]+: 18020ec4 pcaddi \$a0, 4214
+ +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
+ +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
-0+4dc <fun_hidden>:
- 4dc: 18021224 pcaddi \$a0, 4241
- 4e0: 28c00081 ld.d \$ra, \$a0, 0
- 4e4: 4c000021 jirl \$ra, \$ra, 0
- 4e8: 18021144 pcaddi \$a0, 4234
- 4ec: 28c00081 ld.d \$ra, \$a0, 0
- 4f0: 4c000021 jirl \$ra, \$ra, 0
+[0-9a-f]+ <fun_hidden>:
+ +[0-9a-f]+: 18021224 pcaddi \$a0, 4241
+ +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
+ +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
+ +[0-9a-f]+: 18021144 pcaddi \$a0, 4234
+ +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
+ +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
--
2.33.0

View File

@ -0,0 +1,126 @@
From a5d5353514c361b3fbc5be1e5d1b51c7b3de591b Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Fri, 9 Aug 2024 17:40:59 +0800
Subject: [PATCH 109/123] LoongArch: Fix wrong relocation handling of symbols
defined by PROVIDE
If the symbol defined by PROVIDE in the link script is not in SECTION,
the symbol is placed in the ABS section. The linker considers that
symbols in the ABS section do not need to calculate PC relative offsets.
Symbols in ABS sections should calculate PC relative offsets normally
based on relocations.
---
bfd/elfnn-loongarch.c | 2 +-
ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp | 3 +++
ld/testsuite/ld-loongarch-elf/provide_abs.d | 12 ++++++++++++
ld/testsuite/ld-loongarch-elf/provide_abs.ld | 1 +
ld/testsuite/ld-loongarch-elf/provide_noabs.d | 13 +++++++++++++
ld/testsuite/ld-loongarch-elf/provide_noabs.ld | 7 +++++++
ld/testsuite/ld-loongarch-elf/provide_sym.s | 7 +++++++
7 files changed, 44 insertions(+), 1 deletion(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/provide_abs.d
create mode 100644 ld/testsuite/ld-loongarch-elf/provide_abs.ld
create mode 100644 ld/testsuite/ld-loongarch-elf/provide_noabs.d
create mode 100644 ld/testsuite/ld-loongarch-elf/provide_noabs.ld
create mode 100644 ld/testsuite/ld-loongarch-elf/provide_sym.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 0c499c47..14ecd944 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3312,7 +3312,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
/* The r_symndx will be STN_UNDEF (zero) only for relocs against symbols
from removed linkonce sections, or sections discarded by a linker
script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
- if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
+ if (r_symndx == STN_UNDEF)
{
defined_local = false;
resolved_local = false;
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 78726900..cb6d2296 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -184,5 +184,8 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "ie-le-relax"
run_dump_test "tlsdesc_abs"
run_dump_test "tlsdesc_extreme"
+ run_dump_test "provide_abs"
+ run_dump_test "provide_noabs"
+
}
diff --git a/ld/testsuite/ld-loongarch-elf/provide_abs.d b/ld/testsuite/ld-loongarch-elf/provide_abs.d
new file mode 100644
index 00000000..1514fb18
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/provide_abs.d
@@ -0,0 +1,12 @@
+#source: provide_sym.s
+#as:
+#ld: -T provide_abs.ld
+#objdump: -d
+
+.*: +file format .*
+
+#...
+ 0: 58001085 beq \$a0, \$a1, 16 # 10 <fun1>
+ 4: 40000c80 beqz \$a0, 12 # 10 <fun1>
+ 8: 54000800 bl 8 # 10 <fun1>
+#pass
diff --git a/ld/testsuite/ld-loongarch-elf/provide_abs.ld b/ld/testsuite/ld-loongarch-elf/provide_abs.ld
new file mode 100644
index 00000000..473476cd
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/provide_abs.ld
@@ -0,0 +1 @@
+PROVIDE(fun1 = 0x10);
diff --git a/ld/testsuite/ld-loongarch-elf/provide_noabs.d b/ld/testsuite/ld-loongarch-elf/provide_noabs.d
new file mode 100644
index 00000000..7d6bc4d1
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/provide_noabs.d
@@ -0,0 +1,13 @@
+#source: provide_sym.s
+#as:
+#ld: -T provide_noabs.ld
+#objdump: -d
+
+.*: +file format .*
+
+
+#...
+ 0: 58001085 beq \$a0, \$a1, 16 # 10 <fun1>
+ 4: 40000c80 beqz \$a0, 12 # 10 <fun1>
+ 8: 54000800 bl 8 # 10 <fun1>
+#pass
diff --git a/ld/testsuite/ld-loongarch-elf/provide_noabs.ld b/ld/testsuite/ld-loongarch-elf/provide_noabs.ld
new file mode 100644
index 00000000..0154c6f3
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/provide_noabs.ld
@@ -0,0 +1,7 @@
+SECTIONS
+{
+ .text :
+ {
+ PROVIDE(fun1 = 0x10);
+ }
+}
diff --git a/ld/testsuite/ld-loongarch-elf/provide_sym.s b/ld/testsuite/ld-loongarch-elf/provide_sym.s
new file mode 100644
index 00000000..6610894e
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/provide_sym.s
@@ -0,0 +1,7 @@
+ .text
+ .globl main
+ .type main, @function
+main:
+ beq $a0,$a1,%b16(fun1)
+ beqz $a0,%b21(fun1)
+ bl %b26(fun1)
--
2.33.0

View File

@ -0,0 +1,152 @@
From aa37c01e929ddd41416ecdd6d8b57799cff4b001 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Thu, 5 Sep 2024 10:20:49 +0800
Subject: [PATCH 111/123] LoongArch: Fixed ABI v1.00 TLS dynamic relocation
generation bug
Commit "b67a17aa7c0c478a" modified the logic of allocating dynamic
relocation space for TLS GD/IE, but only modified the logic of
generation dynamic relocations for TLS GD/IE in ABI v2.00. When
linking an object file of ABI v1.00 with bfd ld of ABI v2.00, it
will cause an assertion failure.
Modified the dynamic relocation generation logic of TLS GD/IE
in ABI v1.00 to be consistent with ABI v2.00.
---
bfd/elfnn-loongarch.c | 92 +++++++++++++++++++++----------------------
1 file changed, 45 insertions(+), 47 deletions(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 14ecd944..30ac5555 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3541,7 +3541,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bfd_reloc_notsupported, is_undefweak, name,
"TLS section not be created"));
else
- relocation -= elf_hash_table (info)->tls_sec->vma;
+ relocation = tlsoff (info, relocation);
}
else
fatal = (loongarch_reloc_is_fatal
@@ -3890,73 +3890,71 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
{
Elf_Internal_Rela rela;
asection *srel = htab->elf.srelgot;
- bfd_vma tls_block_off = 0;
- if (LARCH_REF_LOCAL (info, h))
- {
- BFD_ASSERT (elf_hash_table (info)->tls_sec);
- tls_block_off = relocation
- - elf_hash_table (info)->tls_sec->vma;
- }
+ int indx = 0;
+ bool need_reloc = false;
+ LARCH_TLS_GD_IE_NEED_DYN_RELOC (info, is_dyn, h, indx,
+ need_reloc);
if (tls_type & GOT_TLS_GD)
{
- rela.r_offset = sec_addr (got) + got_off;
- rela.r_addend = 0;
- if (LARCH_REF_LOCAL (info, h))
+ if (need_reloc)
{
- /* Local sym, used in exec, set module id 1. */
- if (bfd_link_executable (info))
- bfd_put_NN (output_bfd, 1, got->contents + got_off);
+ /* Dynamic resolved Module ID. */
+ rela.r_offset = sec_addr (got) + got_off;
+ rela.r_addend = 0;
+ rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DTPMODNN);
+ bfd_put_NN (output_bfd, 0, got->contents + got_off);
+ loongarch_elf_append_rela (output_bfd, srel, &rela);
+
+ if (indx == 0)
+ {
+ /* Local symbol, tp offset has been known. */
+ BFD_ASSERT (! unresolved_reloc);
+ bfd_put_NN (output_bfd,
+ tlsoff (info, relocation),
+ (got->contents + got_off + GOT_ENTRY_SIZE));
+ }
else
{
- rela.r_info = ELFNN_R_INFO (0,
- R_LARCH_TLS_DTPMODNN);
+ /* Dynamic resolved block offset. */
+ bfd_put_NN (output_bfd, 0,
+ got->contents + got_off + GOT_ENTRY_SIZE);
+ rela.r_info = ELFNN_R_INFO (indx,
+ R_LARCH_TLS_DTPRELNN);
+ rela.r_offset += GOT_ENTRY_SIZE;
loongarch_elf_append_rela (output_bfd, srel, &rela);
}
-
- bfd_put_NN (output_bfd, tls_block_off,
- got->contents + got_off + GOT_ENTRY_SIZE);
}
- /* Dynamic resolved. */
else
{
- /* Dynamic relocate module id. */
- rela.r_info = ELFNN_R_INFO (h->dynindx,
- R_LARCH_TLS_DTPMODNN);
- loongarch_elf_append_rela (output_bfd, srel, &rela);
-
- /* Dynamic relocate offset of block. */
- rela.r_offset += GOT_ENTRY_SIZE;
- rela.r_info = ELFNN_R_INFO (h->dynindx,
- R_LARCH_TLS_DTPRELNN);
- loongarch_elf_append_rela (output_bfd, srel, &rela);
+ /* In a static link or an executable link with the symbol
+ binding locally. Mark it as belonging to module 1. */
+ bfd_put_NN (output_bfd, 1, got->contents + got_off);
+ bfd_put_NN (output_bfd, tlsoff (info, relocation),
+ got->contents + got_off + GOT_ENTRY_SIZE);
}
}
if (tls_type & GOT_TLS_IE)
{
- rela.r_offset = sec_addr (got) + got_off + ie_off;
- if (LARCH_REF_LOCAL (info, h))
+ if (need_reloc)
{
- /* Local sym, used in exec, set module id 1. */
- if (!bfd_link_executable (info))
- {
- rela.r_info = ELFNN_R_INFO (0, R_LARCH_TLS_TPRELNN);
- rela.r_addend = tls_block_off;
- loongarch_elf_append_rela (output_bfd, srel, &rela);
- }
+ bfd_put_NN (output_bfd, 0,
+ got->contents + got_off + ie_off);
+ rela.r_offset = sec_addr (got) + got_off + ie_off;
+ rela.r_addend = 0;
- bfd_put_NN (output_bfd, tls_block_off,
- got->contents + got_off + ie_off);
+ if (indx == 0)
+ rela.r_addend = tlsoff (info, relocation);
+ rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_TPRELNN);
+ loongarch_elf_append_rela (output_bfd, srel, &rela);
}
- /* Dynamic resolved. */
else
{
- /* Dynamic relocate offset of block. */
- rela.r_info = ELFNN_R_INFO (h->dynindx,
- R_LARCH_TLS_TPRELNN);
- rela.r_addend = 0;
- loongarch_elf_append_rela (output_bfd, srel, &rela);
+ /* In a static link or an executable link with the symbol
+ binding locally, compute offset directly. */
+ bfd_put_NN (output_bfd, tlsoff (info, relocation),
+ got->contents + got_off + ie_off);
}
}
}
--
2.33.0

View File

@ -0,0 +1,81 @@
From 75fa7292c935fc1306985b6959712d633edc9e36 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Sat, 21 Sep 2024 11:29:39 +0800
Subject: [PATCH 115/123] LoongArch: Fixed R_LARCH_[32/64]_PCREL generation bug
The enum BFD_RELOC_[32/64] was mistakenly used in the macro instead
of the relocation in fixp. This can cause the second relocation
of a pair to be deleted when -mthin-add-sub is enabled. Apply the
correct macro to fix this.
Also sets the initial value of -mthin-add-sub.
---
gas/config/tc-loongarch.h | 3 ++-
gas/testsuite/gas/loongarch/no_thin_add_sub_8_16.d | 12 ++++++++++++
gas/testsuite/gas/loongarch/no_thin_add_sub_8_16.s | 6 ++++++
opcodes/loongarch-opc.c | 3 ++-
4 files changed, 22 insertions(+), 2 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/no_thin_add_sub_8_16.d
create mode 100644 gas/testsuite/gas/loongarch/no_thin_add_sub_8_16.s
diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h
index 05c0af45..2f081edf 100644
--- a/gas/config/tc-loongarch.h
+++ b/gas/config/tc-loongarch.h
@@ -79,7 +79,8 @@ extern bool loongarch_frag_align_code (int, int);
SEC_CODE, we generate 32/64_PCREL. */
#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) \
(!(LARCH_opts.thin_add_sub \
- && (BFD_RELOC_32 || BFD_RELOC_64) \
+ && ((FIX)->fx_r_type == BFD_RELOC_32 \
+ ||(FIX)->fx_r_type == BFD_RELOC_64) \
&& (!LARCH_opts.relax \
|| S_GET_VALUE (FIX->fx_subsy) \
== FIX->fx_frag->fr_address + FIX->fx_where \
diff --git a/gas/testsuite/gas/loongarch/no_thin_add_sub_8_16.d b/gas/testsuite/gas/loongarch/no_thin_add_sub_8_16.d
new file mode 100644
index 00000000..334d1742
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/no_thin_add_sub_8_16.d
@@ -0,0 +1,12 @@
+#as: -mthin-add-sub
+#readelf: -rW
+#skip: loongarch32-*-*
+
+Relocation section '.rela.text' at offset 0x108 contains 6 entries:
+.*
+0+0 000000060000002f R_LARCH_ADD8 0+0 global_a \+ 0
+0+0 0000000400000034 R_LARCH_SUB8 0+0 L0\^A \+ 0
+0+1 0000000600000030 R_LARCH_ADD16 0+0 global_a \+ 0
+0+1 0000000500000035 R_LARCH_SUB16 0+1 L0\^A \+ 0
+0+3 0000000600000063 R_LARCH_32_PCREL 0+0 global_a \+ 0
+0+7 000000060000006d R_LARCH_64_PCREL 0+0 global_a \+ 0
diff --git a/gas/testsuite/gas/loongarch/no_thin_add_sub_8_16.s b/gas/testsuite/gas/loongarch/no_thin_add_sub_8_16.s
new file mode 100644
index 00000000..68f3655c
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/no_thin_add_sub_8_16.s
@@ -0,0 +1,6 @@
+ .text
+.L1:
+ .byte global_a - .
+ .2byte global_a - .
+ .4byte global_a - .
+ .8byte global_a - .
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index 6afc0e8a..f3794b6a 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -24,7 +24,8 @@
struct loongarch_ASEs_option LARCH_opts =
{
- .relax = 1
+ .relax = 1,
+ .thin_add_sub = 0
};
size_t
--
2.33.0

View File

@ -0,0 +1,86 @@
From 75fd1d4832ec228aa66be49e24ba686bfeb5507b Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Mon, 2 Sep 2024 12:05:54 +0800
Subject: [PATCH 119/123] LoongArch: Fixed precedence of expression operators
in instructions
The precedence of the operators "+" and "-" in the current loongarch
instruction expression is higher than "<<" and ">>", which is different
from the explanation in the user guide.
We modified the precedence of "<<" and ">>" to be higher than "+" and "-".
---
gas/config/loongarch-parse.y | 24 ++++++++++++------------
gas/testsuite/gas/loongarch/insn_expr.d | 10 ++++++++++
gas/testsuite/gas/loongarch/insn_expr.s | 1 +
3 files changed, 23 insertions(+), 12 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/insn_expr.d
create mode 100644 gas/testsuite/gas/loongarch/insn_expr.s
diff --git a/gas/config/loongarch-parse.y b/gas/config/loongarch-parse.y
index f786fdae..ec5a4166 100644
--- a/gas/config/loongarch-parse.y
+++ b/gas/config/loongarch-parse.y
@@ -368,24 +368,24 @@ multiplicative_expression
| multiplicative_expression '%' unary_expression {emit_bin ('%');}
;
-additive_expression
+shift_expression
: multiplicative_expression
- | additive_expression '+' multiplicative_expression {emit_bin ('+');}
- | additive_expression '-' multiplicative_expression {emit_bin ('-');}
+ | shift_expression LEFT_OP multiplicative_expression {emit_bin (LEFT_OP);}
+ | shift_expression RIGHT_OP multiplicative_expression {emit_bin (RIGHT_OP);}
;
-shift_expression
- : additive_expression
- | shift_expression LEFT_OP additive_expression {emit_bin (LEFT_OP);}
- | shift_expression RIGHT_OP additive_expression {emit_bin (RIGHT_OP);}
+additive_expression
+ : shift_expression
+ | additive_expression '+' shift_expression {emit_bin ('+');}
+ | additive_expression '-' shift_expression {emit_bin ('-');}
;
relational_expression
- : shift_expression
- | relational_expression '<' shift_expression {emit_bin ('<');}
- | relational_expression '>' shift_expression {emit_bin ('>');}
- | relational_expression LE_OP shift_expression {emit_bin (LE_OP);}
- | relational_expression GE_OP shift_expression {emit_bin (GE_OP);}
+ : additive_expression
+ | relational_expression '<' additive_expression {emit_bin ('<');}
+ | relational_expression '>' additive_expression {emit_bin ('>');}
+ | relational_expression LE_OP additive_expression {emit_bin (LE_OP);}
+ | relational_expression GE_OP additive_expression {emit_bin (GE_OP);}
;
equality_expression
diff --git a/gas/testsuite/gas/loongarch/insn_expr.d b/gas/testsuite/gas/loongarch/insn_expr.d
new file mode 100644
index 00000000..9abc711a
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_expr.d
@@ -0,0 +1,10 @@
+#as:
+#objdump: -d
+
+.*: file format .*
+
+
+Disassembly of section \.text:
+
+0+ <\.text>:
+ 0: 02c00ca4 addi.d \$a0, \$a1, 3
diff --git a/gas/testsuite/gas/loongarch/insn_expr.s b/gas/testsuite/gas/loongarch/insn_expr.s
new file mode 100644
index 00000000..3b9ef08a
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/insn_expr.s
@@ -0,0 +1 @@
+addi.d $a0,$a1,(8 >> 2 + 1)
--
2.33.0

View File

@ -0,0 +1,207 @@
From 6be26e106b7a240afce3fa1d8f214ef90ee53bd1 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Thu, 17 Oct 2024 15:08:47 +0800
Subject: [PATCH 118/123] LoongArch: Force relocation for every reference to
the global offset table
Local absolute symbols are resolved at assembly stage and the symbol
value is placed in the relocation addend. But non-zero addend will
cause an assertion failure during linking.
Forces emission of relocations to defer resolution of local abs symbols
until link time.
bfd/
* elfnn-loongarch.c (loongarch_elf_relax_section): Determine
absolute symbols in advance to avoid ld crash.
gas/
* config/tc-loongarch.c (loongarch_force_relocation): New
function to force relocation.
* config/tc-loongarch.h (TC_FORCE_RELOCATION): New macros
to force relocation.
(loongarch_force_relocation): Function declaration.
* testsuite/gas/loongarch/localpic.d: New test.
* testsuite/gas/loongarch/localpic.s: New test.
---
bfd/elfnn-loongarch.c | 16 ++++++++--------
gas/config/tc-loongarch.c | 24 ++++++++++++++++++++++++
gas/config/tc-loongarch.h | 3 +++
gas/testsuite/gas/loongarch/localpic.d | 22 ++++++++++++++++++++++
gas/testsuite/gas/loongarch/localpic.s | 26 ++++++++++++++++++++++++++
5 files changed, 83 insertions(+), 8 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/localpic.d
create mode 100644 gas/testsuite/gas/loongarch/localpic.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 890233d1..8b9628f7 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -5328,7 +5328,6 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
bfd_vma symval;
asection *sym_sec;
bool local_got = false;
- bool is_abs_symbol = false;
Elf_Internal_Rela *rel = relocs + i;
struct elf_link_hash_entry *h = NULL;
unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
@@ -5434,8 +5433,9 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
+ r_symndx;
- if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
- && r_type != R_LARCH_CALL36)
+ if ((ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC
+ && r_type != R_LARCH_CALL36)
+ || sym->st_shndx == SHN_ABS)
continue;
/* Only TLS instruction sequences that are accompanied by
@@ -5464,12 +5464,13 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
symval = sym->st_value;
}
symtype = ELF_ST_TYPE (sym->st_info);
- is_abs_symbol = sym->st_shndx == SHN_ABS;
}
else
{
- if (h != NULL && h->type == STT_GNU_IFUNC
- && r_type != R_LARCH_CALL36)
+ if (h != NULL
+ && ((h->type == STT_GNU_IFUNC
+ && r_type != R_LARCH_CALL36)
+ || bfd_is_abs_section (h->root.u.def.section)))
continue;
/* The GOT entry of tls symbols must in current execute file or
@@ -5511,7 +5512,6 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
else
continue;
- is_abs_symbol = bfd_is_abs_section (h->root.u.def.section);
if (h && LARCH_REF_LOCAL (info, h))
local_got = true;
symtype = h->type;
@@ -5544,7 +5544,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
symval += sec_addr (sym_sec);
- if (r_type == R_LARCH_GOT_PC_HI20 && (!local_got || is_abs_symbol))
+ if (r_type == R_LARCH_GOT_PC_HI20 && !local_got)
continue;
if (relax_func (abfd, sec, sym_sec, rel, symval,
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 046e198f..7fa7fa0f 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -1456,6 +1456,30 @@ md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
return 0;
}
+/* Return 1 if the relocation must be forced, and 0 if the relocation
+ should never be forced. */
+int
+loongarch_force_relocation (struct fix *fixp)
+{
+ /* Ensure we emit a relocation for every reference to the global
+ offset table. */
+ switch (fixp->fx_r_type)
+ {
+ case BFD_RELOC_LARCH_GOT_PC_HI20:
+ case BFD_RELOC_LARCH_GOT_PC_LO12:
+ case BFD_RELOC_LARCH_GOT64_PC_LO20:
+ case BFD_RELOC_LARCH_GOT64_PC_HI12:
+ case BFD_RELOC_LARCH_GOT_HI20:
+ case BFD_RELOC_LARCH_GOT_LO12:
+ case BFD_RELOC_LARCH_GOT64_LO20:
+ case BFD_RELOC_LARCH_GOT64_HI12:
+ return 1;
+ default:
+ break;
+ }
+ return generic_force_reloc (fixp);
+}
+
static void fix_reloc_insn (fixS *fixP, bfd_vma reloc_val, char *buf)
{
reloc_howto_type *howto;
diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h
index 2f081edf..da8b0547 100644
--- a/gas/config/tc-loongarch.h
+++ b/gas/config/tc-loongarch.h
@@ -74,6 +74,9 @@ extern bool loongarch_frag_align_code (int, int);
relaxation, so do not resolve such expressions in the assembler. */
#define md_allow_local_subtract(l,r,s) 0
+#define TC_FORCE_RELOCATION(FIX) loongarch_force_relocation (FIX)
+extern int loongarch_force_relocation (struct fix *);
+
/* If subsy of BFD_RELOC32/64 and PC in same segment, and without relax
or PC at start of subsy or with relax but sub_symbol_segment not in
SEC_CODE, we generate 32/64_PCREL. */
diff --git a/gas/testsuite/gas/loongarch/localpic.d b/gas/testsuite/gas/loongarch/localpic.d
new file mode 100644
index 00000000..bea19578
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/localpic.d
@@ -0,0 +1,22 @@
+#as:
+#readelf: -rWs
+#name: loongarch64 local PIC
+
+Relocation section '.rela.text' at offset 0x[0-9a-f]+ contains 12 entries:
+ Offset Info Type Symbol's Value Symbol's Name \+ Addend
+[0-9a-f]+ [0-9a-f]+ R_LARCH_GOT_PC_HI20 [0-9a-f]+ sym \+ 0
+[0-9a-f]+ [0-9a-f]+ R_LARCH_GOT_PC_LO12 [0-9a-f]+ sym \+ 0
+[0-9a-f]+ [0-9a-f]+ R_LARCH_GOT_PC_HI20 [0-9a-f]+ foo \+ 0
+[0-9a-f]+ [0-9a-f]+ R_LARCH_GOT_PC_LO12 [0-9a-f]+ foo \+ 0
+[0-9a-f]+ [0-9a-f]+ R_LARCH_GOT64_PC_LO20 [0-9a-f]+ foo \+ 0
+[0-9a-f]+ [0-9a-f]+ R_LARCH_GOT64_PC_HI12 [0-9a-f]+ foo \+ 0
+[0-9a-f]+ [0-9a-f]+ R_LARCH_GOT_HI20 [0-9a-f]+ foo \+ 0
+[0-9a-f]+ [0-9a-f]+ R_LARCH_GOT_LO12 [0-9a-f]+ foo \+ 0
+[0-9a-f]+ [0-9a-f]+ R_LARCH_GOT_HI20 [0-9a-f]+ sym \+ 0
+[0-9a-f]+ [0-9a-f]+ R_LARCH_GOT_LO12 [0-9a-f]+ sym \+ 0
+[0-9a-f]+ [0-9a-f]+ R_LARCH_GOT64_LO20 [0-9a-f]+ sym \+ 0
+[0-9a-f]+ [0-9a-f]+ R_LARCH_GOT64_HI12 [0-9a-f]+ sym \+ 0
+#...
+ +[0-9a-f]+: +[0-9a-f]+ 0 NOTYPE LOCAL DEFAULT +[0-9a-f]+ foo
+ +[0-9a-f]+: 0+abba 0 NOTYPE LOCAL DEFAULT ABS sym
+#pass
diff --git a/gas/testsuite/gas/loongarch/localpic.s b/gas/testsuite/gas/loongarch/localpic.s
new file mode 100644
index 00000000..55548e4b
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/localpic.s
@@ -0,0 +1,26 @@
+.text
+foo:
+ .quad 0
+ # 32-bit PC-relative
+ pcalau12i $a0,%got_pc_hi20(sym)
+ ld.d $a0,$a0,%got_pc_lo12(sym)
+ # 64-bit PC-relative
+ pcalau12i $a0,%got_pc_hi20(foo)
+ addi.d $a1,$zero,%got_pc_lo12(foo)
+ lu32i.d $a1,%got64_pc_lo20(foo)
+ lu52i.d $a1,$a1,%got64_pc_hi12(foo)
+ ldx.d $a0,$a0,$a1
+
+ # 32-bit absolute
+ lu12i.w $a0,%got_hi20(foo)
+ ori $a0,$a0,%got_lo12(foo)
+ ld.w $a0,$a0,0
+
+ #64-bit absolute
+ lu12i.w $a0,%got_hi20(sym)
+ ori $a0,$a0,%got_lo12(sym)
+ lu32i.d $a0,%got64_lo20(sym)
+ lu52i.d $a0,$a0,%got64_hi12(sym)
+ ld.d $a0,$a0,0
+
+.set sym,0xabba
--
2.33.0

View File

@ -0,0 +1,529 @@
From f9249a44e8e12e90cf5a49729107f69661ed07ec Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Sun, 24 Sep 2023 14:53:28 +0800
Subject: [PATCH 013/123] LoongArch/GAS: Add support for branch relaxation
For the instructions of R_LARCH_B16/B21, if the immediate overflow,
add a B instruction and R_LARCH_B26 relocation.
For example:
.L1
...
blt $t0, $t1, .L1
R_LARCH_B16
change to:
.L1
...
bge $t0, $t1, .L2
b .L1
R_LARCH_B26
.L2
---
gas/config/tc-loongarch.c | 236 +++++++++++++++---
.../gas/loongarch/la_branch_relax_1.d | 64 +++++
.../gas/loongarch/la_branch_relax_1.s | 33 +++
.../gas/loongarch/la_branch_relax_2.d | 40 +++
.../gas/loongarch/la_branch_relax_2.s | 23 ++
include/opcode/loongarch.h | 12 +
6 files changed, 367 insertions(+), 41 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/la_branch_relax_1.d
create mode 100644 gas/testsuite/gas/loongarch/la_branch_relax_1.s
create mode 100644 gas/testsuite/gas/loongarch/la_branch_relax_2.d
create mode 100644 gas/testsuite/gas/loongarch/la_branch_relax_2.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 4c48382c..059a1711 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -106,6 +106,16 @@ const char *md_shortopts = "O::g::G:";
static const char default_arch[] = DEFAULT_ARCH;
+/* The lowest 4-bit is the bytes of instructions. */
+#define RELAX_BRANCH_16 0xc0000014
+#define RELAX_BRANCH_21 0xc0000024
+#define RELAX_BRANCH_26 0xc0000048
+
+#define RELAX_BRANCH(x) \
+ (((x) & 0xf0000000) == 0xc0000000)
+#define RELAX_BRANCH_ENCODE(x) \
+ (BFD_RELOC_LARCH_B16 == (x) ? RELAX_BRANCH_16 : RELAX_BRANCH_21)
+
enum options
{
OPTION_IGNORE = OPTION_MD_BASE,
@@ -955,11 +965,22 @@ append_fixed_insn (struct loongarch_cl_insn *insn)
move_insn (insn, frag_now, f - frag_now->fr_literal);
}
+/* Add instructions based on the worst-case scenario firstly. */
+static void
+append_relaxed_branch_insn (struct loongarch_cl_insn *insn, int max_chars,
+ int var, relax_substateT subtype, symbolS *symbol, offsetT offset)
+{
+ frag_grow (max_chars);
+ move_insn (insn, frag_now, frag_more (0) - frag_now->fr_literal);
+ frag_var (rs_machine_dependent, max_chars, var,
+ subtype, symbol, offset, NULL);
+}
+
static void
append_fixp_and_insn (struct loongarch_cl_insn *ip)
{
reloc_howto_type *howto;
- bfd_reloc_code_real_type reloc_type;
+ bfd_reloc_code_real_type r_type;
struct reloc_info *reloc_info = ip->reloc_info;
size_t i;
@@ -967,14 +988,40 @@ append_fixp_and_insn (struct loongarch_cl_insn *ip)
for (i = 0; i < ip->reloc_num; i++)
{
- reloc_type = reloc_info[i].type;
- howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
- if (howto == NULL)
- as_fatal (_("no HOWTO loong relocation number %d"), reloc_type);
-
- ip->fixp[i] =
- fix_new_exp (ip->frag, ip->where, bfd_get_reloc_size (howto),
- &reloc_info[i].value, FALSE, reloc_type);
+ r_type = reloc_info[i].type;
+
+ if (r_type != BFD_RELOC_UNUSED)
+ {
+
+ gas_assert (&(reloc_info[i].value));
+ if (BFD_RELOC_LARCH_B16 == r_type || BFD_RELOC_LARCH_B21 == r_type)
+ {
+ int min_bytes = 4; /* One branch instruction. */
+ unsigned max_bytes = 8; /* Branch and jump instructions. */
+
+ if (now_seg == absolute_section)
+ {
+ as_bad (_("relaxable branches not supported in absolute section"));
+ return;
+ }
+
+ append_relaxed_branch_insn (ip, max_bytes, min_bytes,
+ RELAX_BRANCH_ENCODE (r_type),
+ reloc_info[i].value.X_add_symbol,
+ reloc_info[i].value.X_add_number);
+ return;
+ }
+ else
+ {
+ howto = bfd_reloc_type_lookup (stdoutput, r_type);
+ if (howto == NULL)
+ as_fatal (_("no HOWTO loong relocation number %d"), r_type);
+
+ ip->fixp[i] = fix_new_exp (ip->frag, ip->where,
+ bfd_get_reloc_size (howto),
+ &reloc_info[i].value, FALSE, r_type);
+ }
+ }
}
if (ip->insn_length < ip->relax_max_length)
@@ -1489,14 +1536,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
}
}
-int
-loongarch_relax_frag (asection *sec ATTRIBUTE_UNUSED,
- fragS *fragp ATTRIBUTE_UNUSED,
- long stretch ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
int
md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
asection *segtype ATTRIBUTE_UNUSED)
@@ -1528,30 +1567,6 @@ tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
return reloc;
}
-/* Convert a machine dependent frag. */
-void
-md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
- fragS *fragp)
-{
- expressionS exp;
- exp.X_op = O_symbol;
- exp.X_add_symbol = fragp->fr_symbol;
- exp.X_add_number = fragp->fr_offset;
- bfd_byte *buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix;
-
- fixS *fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
- 4, &exp, false, fragp->fr_subtype);
- buf += 4;
-
- fixp->fx_file = fragp->fr_file;
- fixp->fx_line = fragp->fr_line;
- fragp->fr_fix += fragp->fr_var;
-
- gas_assert (fragp->fr_next == NULL
- || (fragp->fr_next->fr_address - fragp->fr_address
- == fragp->fr_fix));
-}
-
/* Standard calling conventions leave the CFA at SP on entry. */
void
loongarch_cfi_frame_initial_instructions (void)
@@ -1777,3 +1792,142 @@ loongarch_elf_final_processing (void)
{
elf_elfheader (stdoutput)->e_flags = LARCH_opts.ase_abi;
}
+
+/* Compute the length of a branch sequence, and adjust the stored length
+ accordingly. If FRAGP is NULL, the worst-case length is returned. */
+static unsigned
+loongarch_relaxed_branch_length (fragS *fragp, asection *sec, int update)
+{
+ int length = 4;
+
+ if (!fragp)
+ return 8;
+
+ if (fragp->fr_symbol != NULL
+ && S_IS_DEFINED (fragp->fr_symbol)
+ && !S_IS_WEAK (fragp->fr_symbol)
+ && sec == S_GET_SEGMENT (fragp->fr_symbol))
+ {
+ offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset;
+
+ val -= fragp->fr_address + fragp->fr_fix;
+
+ if (RELAX_BRANCH_16 == fragp->fr_subtype
+ && OUT_OF_RANGE (val, 16, 2))
+ {
+ length = 8;
+ if (update)
+ fragp->fr_subtype = RELAX_BRANCH_26;
+ }
+
+ if (RELAX_BRANCH_21 == fragp->fr_subtype
+ && OUT_OF_RANGE (val, 21, 2))
+ {
+ length = 8;
+ if (update)
+ fragp->fr_subtype = RELAX_BRANCH_26;
+ }
+
+ if (RELAX_BRANCH_26 == fragp->fr_subtype)
+ length = 8;
+ }
+
+ return length;
+}
+
+int
+loongarch_relax_frag (asection *sec ATTRIBUTE_UNUSED,
+ fragS *fragp ATTRIBUTE_UNUSED,
+ long stretch ATTRIBUTE_UNUSED)
+{
+ if (RELAX_BRANCH (fragp->fr_subtype))
+ {
+ offsetT old_var = fragp->fr_var;
+ fragp->fr_var = loongarch_relaxed_branch_length (fragp, sec, true);
+ return fragp->fr_var - old_var;
+ }
+ return 0;
+}
+
+/* Expand far branches to multi-instruction sequences.
+ Branch instructions:
+ beq, bne, blt, bgt, bltz, bgtz, ble, bge, blez, bgez
+ bltu, bgtu, bleu, bgeu
+ beqz, bnez, bceqz, bcnez. */
+
+static void
+loongarch_convert_frag_branch (fragS *fragp)
+{
+ bfd_byte *buf;
+ expressionS exp;
+ fixS *fixp;
+ insn_t insn;
+
+ buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix;
+
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = fragp->fr_symbol;
+ exp.X_add_number = fragp->fr_offset;
+
+ gas_assert ((fragp->fr_subtype & 0xf) == fragp->fr_var);
+
+ /* blt $t0, $t1, .L1
+ nop
+ change to:
+ bge $t0, $t1, .L2
+ b .L1
+ .L2:
+ nop */
+ switch (fragp->fr_subtype)
+ {
+ case RELAX_BRANCH_26:
+ insn = bfd_getl32 (buf);
+ /* Invert the branch condition. */
+ if (LARCH_FLOAT_BRANCH == (insn & LARCH_BRANCH_OPCODE_MASK))
+ insn ^= LARCH_FLOAT_BRANCH_INVERT_BIT;
+ else
+ insn ^= LARCH_BRANCH_INVERT_BIT;
+ insn |= ENCODE_BRANCH16_IMM (8); /* Set target to PC + 8. */
+ bfd_putl32 (insn, buf);
+ buf += 4;
+
+ /* Add the B instruction and jump to the original target. */
+ bfd_putl32 (LARCH_B, buf);
+ fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
+ 4, &exp, false, BFD_RELOC_LARCH_B26);
+ buf += 4;
+ break;
+ case RELAX_BRANCH_21:
+ fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
+ 4, &exp, false, BFD_RELOC_LARCH_B21);
+ buf += 4;
+ break;
+ case RELAX_BRANCH_16:
+ fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
+ 4, &exp, false, BFD_RELOC_LARCH_B16);
+ buf += 4;
+ break;
+
+ default:
+ abort();
+ }
+
+ fixp->fx_file = fragp->fr_file;
+ fixp->fx_line = fragp->fr_line;
+
+ gas_assert (buf == (bfd_byte *)fragp->fr_literal
+ + fragp->fr_fix + fragp->fr_var);
+
+ fragp->fr_fix += fragp->fr_var;
+}
+
+/* Relax a machine dependent frag. This returns the amount by which
+ the current size of the frag should change. */
+
+void
+md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
+ fragS *fragp)
+{
+ gas_assert (RELAX_BRANCH (fragp->fr_subtype));
+ loongarch_convert_frag_branch (fragp);
+}
diff --git a/gas/testsuite/gas/loongarch/la_branch_relax_1.d b/gas/testsuite/gas/loongarch/la_branch_relax_1.d
new file mode 100644
index 00000000..7984b6df
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/la_branch_relax_1.d
@@ -0,0 +1,64 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0* <.L1>:
+[ ]+...
+[ ]+48d158:[ ]+5c00098d[ ]+bne[ ]+\$t0, \$t1, 8[ ]+# 48d160 <.L1\+0x48d160>
+[ ]+48d15c:[ ]+532ea7ed[ ]+b[ ]+-4772188[ ]+# 0 <.L1>
+[ ]+48d15c: R_LARCH_B26[ ]+.L1
+[ ]+48d160:[ ]+5800098d[ ]+beq[ ]+\$t0, \$t1, 8[ ]+# 48d168 <.L1\+0x48d168>
+[ ]+48d164:[ ]+532e9fed[ ]+b[ ]+-4772196[ ]+# 0 <.L1>
+[ ]+48d164: R_LARCH_B26[ ]+.L1
+[ ]+48d168:[ ]+6400098d[ ]+bge[ ]+\$t0, \$t1, 8[ ]+# 48d170 <.L1\+0x48d170>
+[ ]+48d16c:[ ]+532e97ed[ ]+b[ ]+-4772204[ ]+# 0 <.L1>
+[ ]+48d16c: R_LARCH_B26[ ]+.L1
+[ ]+48d170:[ ]+640009ac[ ]+bge[ ]+\$t1, \$t0, 8[ ]+# 48d178 <.L1\+0x48d178>
+[ ]+48d174:[ ]+532e8fed[ ]+b[ ]+-4772212[ ]+# 0 <.L1>
+[ ]+48d174: R_LARCH_B26[ ]+.L1
+[ ]+48d178:[ ]+64000980[ ]+bgez[ ]+\$t0, 8[ ]+# 48d180 <.L1\+0x48d180>
+[ ]+48d17c:[ ]+532e87ed[ ]+b[ ]+-4772220[ ]+# 0 <.L1>
+[ ]+48d17c: R_LARCH_B26[ ]+.L1
+[ ]+48d180:[ ]+6400080c[ ]+blez[ ]+\$t0, 8[ ]+# 48d188 <.L1\+0x48d188>
+[ ]+48d184:[ ]+532e7fed[ ]+b[ ]+-4772228[ ]+# 0 <.L1>
+[ ]+48d184: R_LARCH_B26[ ]+.L1
+[ ]+48d188:[ ]+600009ac[ ]+blt[ ]+\$t1, \$t0, 8[ ]+# 48d190 <.L1\+0x48d190>
+[ ]+48d18c:[ ]+532e77ed[ ]+b[ ]+-4772236[ ]+# 0 <.L1>
+[ ]+48d18c: R_LARCH_B26[ ]+.L1
+[ ]+48d190:[ ]+6000098d[ ]+blt[ ]+\$t0, \$t1, 8[ ]+# 48d198 <.L1\+0x48d198>
+[ ]+48d194:[ ]+532e6fed[ ]+b[ ]+-4772244[ ]+# 0 <.L1>
+[ ]+48d194: R_LARCH_B26[ ]+.L1
+[ ]+48d198:[ ]+6000080c[ ]+bgtz[ ]+\$t0, 8[ ]+# 48d1a0 <.L1\+0x48d1a0>
+[ ]+48d19c:[ ]+532e67ed[ ]+b[ ]+-4772252[ ]+# 0 <.L1>
+[ ]+48d19c: R_LARCH_B26[ ]+.L1
+[ ]+48d1a0:[ ]+60000980[ ]+bltz[ ]+\$t0, 8[ ]+# 48d1a8 <.L1\+0x48d1a8>
+[ ]+48d1a4:[ ]+532e5fed[ ]+b[ ]+-4772260[ ]+# 0 <.L1>
+[ ]+48d1a4: R_LARCH_B26[ ]+.L1
+[ ]+48d1a8:[ ]+6c00098d[ ]+bgeu[ ]+\$t0, \$t1, 8[ ]+# 48d1b0 <.L1\+0x48d1b0>
+[ ]+48d1ac:[ ]+532e57ed[ ]+b[ ]+-4772268[ ]+# 0 <.L1>
+[ ]+48d1ac: R_LARCH_B26[ ]+.L1
+[ ]+48d1b0:[ ]+6c0009ac[ ]+bgeu[ ]+\$t1, \$t0, 8[ ]+# 48d1b8 <.L1\+0x48d1b8>
+[ ]+48d1b4:[ ]+532e4fed[ ]+b[ ]+-4772276[ ]+# 0 <.L1>
+[ ]+48d1b4: R_LARCH_B26[ ]+.L1
+[ ]+48d1b8:[ ]+680009ac[ ]+bltu[ ]+\$t1, \$t0, 8[ ]+# 48d1c0 <.L1\+0x48d1c0>
+[ ]+48d1bc:[ ]+532e47ed[ ]+b[ ]+-4772284[ ]+# 0 <.L1>
+[ ]+48d1bc: R_LARCH_B26[ ]+.L1
+[ ]+48d1c0:[ ]+6800098d[ ]+bltu[ ]+\$t0, \$t1, 8[ ]+# 48d1c8 <.L1\+0x48d1c8>
+[ ]+48d1c4:[ ]+532e3fed[ ]+b[ ]+-4772292[ ]+# 0 <.L1>
+[ ]+48d1c4: R_LARCH_B26[ ]+.L1
+[ ]+48d1c8:[ ]+44000980[ ]+bnez[ ]+\$t0, 8[ ]+# 48d1d0 <.L1\+0x48d1d0>
+[ ]+48d1cc:[ ]+532e37ed[ ]+b[ ]+-4772300[ ]+# 0 <.L1>
+[ ]+48d1cc: R_LARCH_B26[ ]+.L1
+[ ]+48d1d0:[ ]+40000980[ ]+beqz[ ]+\$t0, 8[ ]+# 48d1d8 <.L1\+0x48d1d8>
+[ ]+48d1d4:[ ]+532e2fed[ ]+b[ ]+-4772308[ ]+# 0 <.L1>
+[ ]+48d1d4: R_LARCH_B26[ ]+.L1
+[ ]+48d1d8:[ ]+48000900[ ]+bcnez[ ]+\$fcc0, 8[ ]+# 48d1e0 <.L1\+0x48d1e0>
+[ ]+48d1dc:[ ]+532e27ed[ ]+b[ ]+-4772316[ ]+# 0 <.L1>
+[ ]+48d1dc: R_LARCH_B26[ ]+.L1
+[ ]+48d1e0:[ ]+48000800[ ]+bceqz[ ]+\$fcc0, 8[ ]+# 48d1e8 <.L1\+0x48d1e8>
+[ ]+48d1e4:[ ]+532e1fed[ ]+b[ ]+-4772324[ ]+# 0 <.L1>
+[ ]+48d1e4: R_LARCH_B26[ ]+.L1
diff --git a/gas/testsuite/gas/loongarch/la_branch_relax_1.s b/gas/testsuite/gas/loongarch/la_branch_relax_1.s
new file mode 100644
index 00000000..53288f25
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/la_branch_relax_1.s
@@ -0,0 +1,33 @@
+# Instruction and Relocation generating tests
+
+.L1:
+ .fill 0x123456, 4, 0x0
+
+# R_LARCH_B16
+ beq $r12, $r13, .L1
+ bne $r12, $r13, .L1
+
+ blt $r12, $r13, .L1
+ bgt $r12, $r13, .L1
+
+ bltz $r12, .L1
+ bgtz $r12, .L1
+
+ ble $r12, $r13, .L1
+ bge $r12, $r13, .L1
+
+ blez $r12, .L1
+ bgez $r12, .L1
+
+ bltu $r12, $r13, .L1
+ bgtu $r12, $r13, .L1
+
+ bleu $r12, $r13, .L1
+ bgeu $r12, $r13, .L1
+
+# R_LARCH_B21
+ beqz $r12, .L1
+ bnez $r12, .L1
+
+ bceqz $fcc0, .L1
+ bcnez $fcc0, .L1
diff --git a/gas/testsuite/gas/loongarch/la_branch_relax_2.d b/gas/testsuite/gas/loongarch/la_branch_relax_2.d
new file mode 100644
index 00000000..4a3c6384
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/la_branch_relax_2.d
@@ -0,0 +1,40 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0* <.L1>:
+[ ]+...
+[ ]+20000:[ ]+5a00018d[ ]+beq[ ]+\$t0, \$t1, -131072[ ]+# 0 <.L1>
+[ ]+20000: R_LARCH_B16[ ]+.L1
+[ ]+20004:[ ]+5c00098d[ ]+bne[ ]+\$t0, \$t1, 8[ ]+# 2000c <.L1\+0x2000c>
+[ ]+20008:[ ]+51fffbff[ ]+b[ ]+-131080[ ]+# 0 <.L1>
+[ ]+20008: R_LARCH_B26[ ]+.L1
+[ ]+2000c:[ ]+5c00098d[ ]+bne[ ]+\$t0, \$t1, 8[ ]+# 20014 <.L1\+0x20014>
+[ ]+20010:[ ]+52000000[ ]+b[ ]+131072[ ]+# 40010 <.L2>
+[ ]+20010: R_LARCH_B26[ ]+.L2
+[ ]+20014:[ ]+59fffd8d[ ]+beq[ ]+\$t0, \$t1, 131068[ ]+# 40010 <.L2>
+[ ]+20014: R_LARCH_B16[ ]+.L2
+[ ]+...
+0*40010 <.L2>:
+[ ]+...
+[ ]+440010:[ ]+40000190[ ]+beqz[ ]+\$t0, -4194304[ ]+# 40010 <.L2>
+[ ]+440010: R_LARCH_B21[ ]+.L2
+[ ]+440014:[ ]+44000980[ ]+bnez[ ]+\$t0, 8[ ]+# 44001c <.L2\+0x40000c>
+[ ]+440018:[ ]+53fffbef[ ]+b[ ]+-4194312[ ]+# 40010 <.L2>
+[ ]+440018: R_LARCH_B26[ ]+.L2
+[ ]+44001c:[ ]+44000980[ ]+bnez[ ]+\$t0, 8[ ]+# 440024 <.L2\+0x400014>
+[ ]+440020:[ ]+50000010[ ]+b[ ]+4194304[ ]+# 840020 <.L3>
+[ ]+440020: R_LARCH_B26[ ]+.L3
+[ ]+440024:[ ]+43fffd8f[ ]+beqz[ ]+\$t0, 4194300[ ]+# 840020 <.L3>
+[ ]+440024: R_LARCH_B21[ ]+.L3
+[ ]+...
+0*840020 <.L3>:
+[ ]+840020:[ ]+5800018d[ ]+beq[ ]+\$t0, \$t1, 0[ ]+# 840020 <.L3>
+[ ]+840020: R_LARCH_B16[ ]+.L4
+0*840024 <.L5>:
+[ ]+840024:[ ]+40000180[ ]+beqz[ ]+\$t0, 0[ ]+# 840024 <.L5>
+[ ]+840024: R_LARCH_B21[ ]+.L5
diff --git a/gas/testsuite/gas/loongarch/la_branch_relax_2.s b/gas/testsuite/gas/loongarch/la_branch_relax_2.s
new file mode 100644
index 00000000..3e6c5534
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/la_branch_relax_2.s
@@ -0,0 +1,23 @@
+# Immediate boundary value tests
+
+.L1:
+ .fill 0x8000, 4, 0
+ beq $r12, $r13, .L1 # min imm -0x20000
+ beq $r12, $r13, .L1 # out of range
+ beq $r12, $r13, .L2 # out of range
+ beq $r12, $r13, .L2 # max imm 0x1fffc
+ .fill 0x7ffe, 4, 0
+.L2:
+ .fill 0x100000, 4, 0
+ beqz $r12, .L2 # min imm -0x400000
+ beqz $r12, .L2 # out of range
+ beqz $r12, .L3 # out of range
+ beqz $r12, .L3 # max imm 0x3ffffc
+ .fill 0xffffe, 4, 0
+.L3:
+
+# 0 imm
+.L4:
+ beq $r12, $r13, .L4
+.L5:
+ beqz $r12, .L5
diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
index 2ed4082c..f358ff42 100644
--- a/include/opcode/loongarch.h
+++ b/include/opcode/loongarch.h
@@ -29,6 +29,18 @@ extern "C"
#endif
#define LARCH_NOP 0x03400000
+ #define LARCH_B 0x50000000
+ /* BCEQZ/BCNEZ. */
+ #define LARCH_FLOAT_BRANCH 0x48000000
+ #define LARCH_BRANCH_OPCODE_MASK 0xfc000000
+ #define LARCH_BRANCH_INVERT_BIT 0x04000000
+ #define LARCH_FLOAT_BRANCH_INVERT_BIT 0x00000100
+
+ #define ENCODE_BRANCH16_IMM(x) (((x) >> 2) << 10)
+
+ #define OUT_OF_RANGE(value, bits, align) \
+ ((value) < (-(1 << ((bits) - 1) << align)) \
+ || (value) > ((((1 << ((bits) - 1)) - 1) << align)))
typedef uint32_t insn_t;
--
2.33.0

View File

@ -0,0 +1,65 @@
From 87c63c08d6171b556f86c14fded00ab8b4aaa73b Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Wed, 7 Aug 2024 18:04:26 +0800
Subject: [PATCH 110/123] LoongArch: LoongArch64 allows relocations to use
64-bit addends
Relocations using 64-bit addends allow larger constant offset address
calculations to be fused.
---
gas/config/tc-loongarch.c | 3 +++
gas/testsuite/gas/loongarch/large_addend.d | 12 ++++++++++++
gas/testsuite/gas/loongarch/large_addend.s | 8 ++++++++
3 files changed, 23 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/large_addend.d
create mode 100644 gas/testsuite/gas/loongarch/large_addend.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 72815233..16355cac 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -1221,6 +1221,9 @@ append_fixp_and_insn (struct loongarch_cl_insn *ip)
bfd_get_reloc_size (howto),
&reloc_info[i].value, FALSE, r_type);
}
+ /* Allow LoongArch 64 to use 64-bit addends. */
+ if (LARCH_opts.ase_lp64)
+ ip->fixp[i]->fx_no_overflow = 1;
}
}
diff --git a/gas/testsuite/gas/loongarch/large_addend.d b/gas/testsuite/gas/loongarch/large_addend.d
new file mode 100644
index 00000000..18eb33a3
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/large_addend.d
@@ -0,0 +1,12 @@
+#as:
+#objdump: -r
+#skip: loongarch32-*-*
+
+.*: file format elf64-loongarch
+
+RELOCATION RECORDS FOR \[\.text\]:
+OFFSET TYPE VALUE
+0000000000000000 R_LARCH_PCALA_HI20 _start\+0x7fffabcd12345678
+0000000000000004 R_LARCH_PCALA_LO12 _start\+0x7fffabcd12345678
+0000000000000008 R_LARCH_PCALA64_LO20 _start\+0x7fffabcd12345678
+000000000000000c R_LARCH_PCALA64_HI12 _start\+0x7fffabcd12345678
diff --git a/gas/testsuite/gas/loongarch/large_addend.s b/gas/testsuite/gas/loongarch/large_addend.s
new file mode 100644
index 00000000..7db90525
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/large_addend.s
@@ -0,0 +1,8 @@
+ .text
+ .global _start
+_start:
+ pcalau12i $a0, %pc_hi20(_start+0x7fffabcd12345678)
+ addi.d $a1, $zero, %pc_lo12(_start+0x7fffabcd12345678)
+ lu32i.d $a1, %pc64_lo20(_start+0x7fffabcd12345678)
+ lu52i.d $a1, $a1, %pc64_hi12(_start+0x7fffabcd12345678)
+ add.d $a0, $a1, $a0
--
2.33.0

View File

@ -0,0 +1,303 @@
From ea14dbe723a67501b377bf6d4f390ca4b6a58938 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Wed, 29 May 2024 14:50:39 +0800
Subject: [PATCH 089/123] LoongArch: Make align symbol be in same section with
alignment directive
R_LARCH_ALIGN (psABI v2.30) requires a symbol index. The symbol is only
created at the first time to handle alignment directive. This means that
all other sections may use this symbol. If the section of this symbol is
discarded, there may be problems. Search it in its own section.
Remove elf_backend_data.is_rela_normal() function added at commit daeda14191c.
Co-authored-by: Jinyang He <hejinyang@loongson.cn>
Reported-by: WANG Xuerui <git@xen0n.name>
Link: https://lore.kernel.org/loongarch/2abbb633-a10e-71cc-a5e1-4d9e39074066@loongson.cn/T/#t
---
bfd/elf-bfd.h | 4 --
bfd/elflink.c | 5 +-
bfd/elfnn-loongarch.c | 16 ------
bfd/elfxx-target.h | 5 --
gas/config/tc-loongarch.c | 63 +++++++++++++++++++++-
gas/config/tc-loongarch.h | 3 ++
gas/testsuite/gas/loongarch/relax-align2.d | 24 +++++++++
gas/testsuite/gas/loongarch/relax-align2.s | 11 ++++
gas/testsuite/gas/loongarch/relax_align.d | 6 +--
9 files changed, 104 insertions(+), 33 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/relax-align2.d
create mode 100644 gas/testsuite/gas/loongarch/relax-align2.s
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 074120a5..ec856764 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1703,10 +1703,6 @@ struct elf_backend_data
backend relocate_section routine for relocatable linking. */
unsigned rela_normal : 1;
- /* Whether a relocation is rela_normal. Compared with rela_normal,
- is_rela_normal can set part of relocations to rela_normal. */
- bool (*is_rela_normal) (Elf_Internal_Rela *);
-
/* Set if DT_REL/DT_RELA/DT_RELSZ/DT_RELASZ should not include PLT
relocations. */
unsigned dtrel_excludes_plt : 1;
diff --git a/bfd/elflink.c b/bfd/elflink.c
index cbf87d70..7217c2f0 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11647,10 +11647,7 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
{
rel_hash = PTR_ADD (esdo->rela.hashes, esdo->rela.count);
rela_hash_list = rel_hash;
- if (bed->is_rela_normal != NULL)
- rela_normal = bed->is_rela_normal (irela);
- else
- rela_normal = bed->rela_normal;
+ rela_normal = bed->rela_normal;
}
irela->r_offset = _bfd_elf_section_offset (output_bfd,
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index eb572a77..9eaad7f4 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -5527,21 +5527,6 @@ elf_loongarch64_hash_symbol (struct elf_link_hash_entry *h)
return _bfd_elf_hash_symbol (h);
}
-/* If a relocation is rela_normal and the symbol associated with the
- relocation is STT_SECTION type, the addend of the relocation would add
- sec->output_offset when partial linking (ld -r).
- See elf_backend_data.rela_normal and elf_link_input_bfd().
- The addend of R_LARCH_ALIGN is used to represent the first and third
- expression of .align, it should be a constant when linking. */
-
-static bool
-loongarch_elf_is_rela_normal (Elf_Internal_Rela *rel)
-{
- if (R_LARCH_ALIGN == ELFNN_R_TYPE (rel->r_info))
- return false;
- return true;
-}
-
#define TARGET_LITTLE_SYM loongarch_elfNN_vec
#define TARGET_LITTLE_NAME "elfNN-loongarch"
#define ELF_ARCH bfd_arch_loongarch
@@ -5577,7 +5562,6 @@ loongarch_elf_is_rela_normal (Elf_Internal_Rela *rel)
#define elf_backend_grok_psinfo loongarch_elf_grok_psinfo
#define elf_backend_hash_symbol elf_loongarch64_hash_symbol
#define bfd_elfNN_bfd_relax_section loongarch_elf_relax_section
-#define elf_backend_is_rela_normal loongarch_elf_is_rela_normal
#define elf_backend_dtrel_excludes_plt 1
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index 385e40b7..f8553006 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -703,10 +703,6 @@
#define elf_backend_rela_normal 0
#endif
-#ifndef elf_backend_is_rela_normal
-#define elf_backend_is_rela_normal NULL
-#endif
-
#ifndef elf_backend_dtrel_excludes_plt
#define elf_backend_dtrel_excludes_plt 0
#endif
@@ -952,7 +948,6 @@ static const struct elf_backend_data elfNN_bed =
elf_backend_default_use_rela_p,
elf_backend_rela_plts_and_copies_p,
elf_backend_rela_normal,
- elf_backend_is_rela_normal,
elf_backend_dtrel_excludes_plt,
elf_backend_sign_extend_vma,
elf_backend_want_got_plt,
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index f030fd07..f039d027 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -419,6 +419,55 @@ loongarch_target_format ()
return LARCH_opts.ase_lp64 ? "elf64-loongarch" : "elf32-loongarch";
}
+typedef struct
+{
+ unsigned int sec_id;
+ symbolS *s;
+} align_sec_sym;
+
+static htab_t align_hash;
+
+static hashval_t
+align_sec_sym_hash (const void *entry)
+{
+ const align_sec_sym *e = entry;
+ return (hashval_t) (e->sec_id);
+}
+
+static int
+align_sec_sym_eq (const void *entry1, const void *entry2)
+{
+ const align_sec_sym *e1 = entry1, *e2 = entry2;
+ return e1->sec_id == e2->sec_id;
+}
+
+/* Make align symbol be in same section with alignment directive.
+ If the symbol is only created at the first time to handle alignment
+ directive. This means that all other sections may use this symbol.
+ If the section of this symbol is discarded, there may be problems. */
+
+static symbolS *get_align_symbol (segT sec)
+{
+ align_sec_sym search = { sec->id, NULL };
+ align_sec_sym *pentry = htab_find (align_hash, &search);
+ if (pentry)
+ return pentry->s;
+
+ /* If we not find the symbol in this section. Create and insert it. */
+ symbolS *s = (symbolS *)local_symbol_make (".Lla-relax-align", sec,
+ &zero_address_frag, 0);
+ align_sec_sym entry = { sec->id, s };
+ align_sec_sym **slot = (align_sec_sym **) htab_find_slot (align_hash,
+ &entry, INSERT);
+ if (slot == NULL)
+ return NULL;
+ *slot = (align_sec_sym *) xmalloc (sizeof (align_sec_sym));
+ if (*slot == NULL)
+ return NULL;
+ **slot = entry;
+ return entry.s;
+}
+
void
md_begin ()
{
@@ -440,11 +489,21 @@ md_begin ()
it->name, it->format, it->macro);
}
+ align_hash = htab_create (10, align_sec_sym_hash, align_sec_sym_eq, free);
+
/* FIXME: expressionS use 'offsetT' as constant,
* we want this is 64-bit type. */
assert (8 <= sizeof (offsetT));
}
+/* Called just before the assembler exits. */
+
+void
+loongarch_md_end (void)
+{
+ htab_delete (align_hash);
+}
+
unsigned long
loongarch_mach (void)
{
@@ -1826,7 +1885,9 @@ loongarch_frag_align_code (int n, int max)
if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype). */
if (align_max)
{
- s = symbol_find (now_seg->name);
+ s = get_align_symbol (now_seg);
+ if (!s)
+ as_fatal (_("internal error: cannot get align symbol"));
addend = ALIGN_MAX_ADDEND (n, max);
}
diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h
index 6963867e..05c0af45 100644
--- a/gas/config/tc-loongarch.h
+++ b/gas/config/tc-loongarch.h
@@ -32,6 +32,9 @@ extern unsigned long loongarch_mach (void);
#define WORKING_DOT_WORD 1
#define REPEAT_CONS_EXPRESSIONS
+#define md_end loongarch_md_end
+extern void loongarch_md_end (void);
+
/* Early than md_begin. */
#define md_after_parse_args loongarch_after_parse_args
extern void loongarch_after_parse_args (void);
diff --git a/gas/testsuite/gas/loongarch/relax-align2.d b/gas/testsuite/gas/loongarch/relax-align2.d
new file mode 100644
index 00000000..cbef84f8
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax-align2.d
@@ -0,0 +1,24 @@
+#as: --no-warn
+#readelf: -rsW
+#skip: loongarch32-*-*
+
+Relocation section '\.rela\.text' at offset .* contains 2 entries:
+.*
+0+04[ ]+0000000000000066[ ]+R_LARCH_ALIGN[ ]+c
+0+14[ ]+0000000500000066[ ]+R_LARCH_ALIGN[ ]+0+[ ]+\.Lla-relax-align \+ 404
+
+Relocation section '\.rela\.text2' at offset .* contains 2 entries:
+.*
+0+04[ ]+0000000000000066[ ]+R_LARCH_ALIGN[ ]+c
+0+14[ ]+0000000600000066[ ]+R_LARCH_ALIGN[ ]+0+[ ]+\.Lla-relax-align \+ 404
+
+Symbol table '\.symtab' contains .* entries:
+#...
+[ ]+.*:[ ]+0+[ ]+0[ ]+SECTION[ ]+LOCAL[ ]+DEFAULT[ ]+1[ ]+\.text
+#...
+[ ]+.*:[ ]+0+[ ]+0[ ]+SECTION[ ]+LOCAL[ ]+DEFAULT[ ]+5[ ]+\.text2
+#...
+[ ]+.*:[ ]+0+[ ]+0[ ]+NOTYPE[ ]+LOCAL[ ]+DEFAULT[ ]+1[ ]+\.Lla-relax-align
+#...
+[ ]+.*:[ ]+0+[ ]+0[ ]+NOTYPE[ ]+LOCAL[ ]+DEFAULT[ ]+5[ ]+\.Lla-relax-align
+#pass
diff --git a/gas/testsuite/gas/loongarch/relax-align2.s b/gas/testsuite/gas/loongarch/relax-align2.s
new file mode 100644
index 00000000..6cd6bd87
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax-align2.s
@@ -0,0 +1,11 @@
+.section ".text", "ax"
+nop
+.align 4
+nop
+.align 4, , 4
+
+.section ".text2", "ax"
+nop
+.align 4
+nop
+.align 4, , 4
diff --git a/gas/testsuite/gas/loongarch/relax_align.d b/gas/testsuite/gas/loongarch/relax_align.d
index acd215a4..fc1fd032 100644
--- a/gas/testsuite/gas/loongarch/relax_align.d
+++ b/gas/testsuite/gas/loongarch/relax_align.d
@@ -7,7 +7,7 @@
Disassembly of section .text:
-[ ]*0000000000000000 <.text>:
+[ ]*0000000000000000 <.Lla-relax-align>:
[ ]+0:[ ]+4c000020[ ]+ret
[ ]+4:[ ]+03400000[ ]+nop
[ ]+4: R_LARCH_ALIGN[ ]+\*ABS\*\+0xc
@@ -20,12 +20,12 @@ Disassembly of section .text:
[ ]+1c:[ ]+03400000[ ]+nop
[ ]+20:[ ]+4c000020[ ]+ret
[ ]+24:[ ]+03400000[ ]+nop
-[ ]+24: R_LARCH_ALIGN[ ]+.text\+0x104
+[ ]+24: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0x104
[ ]+28:[ ]+03400000[ ]+nop
[ ]+2c:[ ]+03400000[ ]+nop
[ ]+30:[ ]+4c000020[ ]+ret
[ ]+34:[ ]+03400000[ ]+nop
-[ ]+34: R_LARCH_ALIGN[ ]+.text\+0xb04
+[ ]+34: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0xb04
[ ]+38:[ ]+03400000[ ]+nop
[ ]+3c:[ ]+03400000[ ]+nop
[ ]+40:[ ]+4c000020[ ]+ret
--
2.33.0

View File

@ -0,0 +1,311 @@
From a95555b83c866216189dde969ab7b76ebd57c60c Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Sun, 30 Jun 2024 15:18:23 +0800
Subject: [PATCH 097/123] LoongArch: Make protected function symbols local for
-shared
On LoongArch there is no reason to treat STV_PROTECTED STT_FUNC symbols
as preemptible. See the comment above LARCH_REF_LOCAL for detailed
explanation.
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
bfd/elfnn-loongarch.c | 76 ++++++++++++++-----
ld/testsuite/ld-loongarch-elf/ifunc-reloc.d | 2 +-
.../ld-loongarch-elf/ld-loongarch-elf.exp | 1 +
.../ld-loongarch-elf/protected-func.d | 6 ++
.../ld-loongarch-elf/protected-func.s | 17 +++++
5 files changed, 81 insertions(+), 21 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/protected-func.d
create mode 100644 ld/testsuite/ld-loongarch-elf/protected-func.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 6b1a4ecc..2bdd7be2 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -181,6 +181,44 @@ struct loongarch_elf_link_hash_table
} \
while (0)
+/* TL;DR always use it in this file instead when you want to type
+ SYMBOL_REFERENCES_LOCAL.
+
+ It's like SYMBOL_REFERENCES_LOCAL, but it returns true for local
+ protected functions. It happens to be same as SYMBOL_CALLS_LOCAL but
+ let's not reuse SYMBOL_CALLS_LOCAL or "CALLS" may puzzle people.
+
+ We do generate a PLT entry when someone attempts to la.pcrel an external
+ function. But we never really implemented "R_LARCH_COPY", thus we've
+ never supported la.pcrel an external symbol unless the loaded address is
+ only used for locating a function to be called. Thus the PLT entry is
+ a normal PLT entry, not intended to be a so-called "canonical PLT entry"
+ on the ports supporting copy relocation. So attempting to la.pcrel an
+ external function will just break pointer equality, even it's a
+ STV_DEFAULT function:
+
+ $ cat t.c
+ #include <assert.h>
+ void check(void *p) {assert(p == check);}
+ $ cat main.c
+ extern void check(void *);
+ int main(void) { check(check); }
+ $ cc t.c -fPIC -shared -o t.so
+ $ cc main.c -mdirect-extern-access t.so -Wl,-rpath=. -fpie -pie
+ $ ./a.out
+ a.out: t.c:2: check: Assertion `p == check' failed.
+ Aborted
+
+ Thus handling STV_PROTECTED function specially just fixes nothing:
+ adding -fvisibility=protected compiling t.c will not magically fix
+ the inequality. The only possible and correct fix is not to use
+ -mdirect-extern-access.
+
+ So we should remove this special handling, because it's only an
+ unsuccessful workaround for invalid code and it's penalizing valid
+ code. */
+#define LARCH_REF_LOCAL(info, h) \
+ (_bfd_elf_symbol_refs_local_p ((h), (info), true))
/* Generate a PLT header. */
@@ -712,7 +750,7 @@ loongarch_tls_transition_without_check (struct bfd_link_info *info,
struct elf_link_hash_entry *h)
{
bool local_exec = bfd_link_executable (info)
- && SYMBOL_REFERENCES_LOCAL (info, h);
+ && LARCH_REF_LOCAL (info, h);
switch (r_type)
{
@@ -1221,7 +1259,7 @@ loongarch_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
{
if (h->plt.refcount <= 0
|| (h->type != STT_GNU_IFUNC
- && (SYMBOL_REFERENCES_LOCAL (info, h)
+ && (LARCH_REF_LOCAL (info, h)
|| (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
&& h->root.type == bfd_link_hash_undefweak))))
{
@@ -1739,14 +1777,14 @@ elfNN_allocate_ifunc_dynrelocs (struct elf_link_hash_entry *h,
here if it is defined and referenced in a non-shared object. */
if (h->type == STT_GNU_IFUNC && h->def_regular)
{
- if (ref_local && SYMBOL_REFERENCES_LOCAL (info, h))
+ if (ref_local && LARCH_REF_LOCAL (info, h))
return local_allocate_ifunc_dyn_relocs (info, h,
&h->dyn_relocs,
PLT_ENTRY_SIZE,
PLT_HEADER_SIZE,
GOT_ENTRY_SIZE,
false);
- else if (!ref_local && !SYMBOL_REFERENCES_LOCAL (info, h))
+ else if (!ref_local && !LARCH_REF_LOCAL (info, h))
return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
&h->dyn_relocs,
PLT_ENTRY_SIZE,
@@ -1774,7 +1812,6 @@ elfNN_allocate_ifunc_dynrelocs_ref_global (struct elf_link_hash_entry *h,
false);
}
-
/* Allocate space in .plt, .got and associated reloc sections for
ifunc dynamic relocs. */
@@ -2686,7 +2723,6 @@ tlsoff (struct bfd_link_info *info, bfd_vma addr)
return addr - elf_hash_table (info)->tls_sec->vma;
}
-
static int
loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bfd *input_bfd, asection *input_section,
@@ -2812,7 +2848,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
{
defined_local = !unresolved_reloc && !ignored;
resolved_local =
- defined_local && SYMBOL_REFERENCES_LOCAL (info, h);
+ defined_local && LARCH_REF_LOCAL (info, h);
resolved_dynly = !resolved_local;
resolved_to_const = !resolved_local && !resolved_dynly;
}
@@ -2901,7 +2937,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
outrel.r_addend = 0;
}
- if (SYMBOL_REFERENCES_LOCAL (info, h))
+ if (LARCH_REF_LOCAL (info, h))
{
if (htab->elf.splt != NULL)
@@ -3251,7 +3287,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
bfd_link_pic (info), h)
&& ((bfd_link_pic (info)
- && SYMBOL_REFERENCES_LOCAL (info, h))))
+ && LARCH_REF_LOCAL (info, h))))
{
/* This is actually a static link, or it is a
-Bsymbolic link and the symbol is defined
@@ -3396,7 +3432,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
asection *srel = htab->elf.srelgot;
bfd_vma tls_block_off = 0;
- if (SYMBOL_REFERENCES_LOCAL (info, h))
+ if (LARCH_REF_LOCAL (info, h))
{
BFD_ASSERT (elf_hash_table (info)->tls_sec);
tls_block_off = relocation
@@ -3407,7 +3443,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
{
rela.r_offset = sec_addr (got) + got_off;
rela.r_addend = 0;
- if (SYMBOL_REFERENCES_LOCAL (info, h))
+ if (LARCH_REF_LOCAL (info, h))
{
/* Local sym, used in exec, set module id 1. */
if (bfd_link_executable (info))
@@ -3440,7 +3476,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (tls_type & GOT_TLS_IE)
{
rela.r_offset = sec_addr (got) + got_off + ie_off;
- if (SYMBOL_REFERENCES_LOCAL (info, h))
+ if (LARCH_REF_LOCAL (info, h))
{
/* Local sym, used in exec, set module id 1. */
if (!bfd_link_executable (info))
@@ -3642,7 +3678,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bfd_link_pic (info),
h)
&& bfd_link_pic (info)
- && SYMBOL_REFERENCES_LOCAL (info, h))
+ && LARCH_REF_LOCAL (info, h))
{
Elf_Internal_Rela rela;
rela.r_offset = sec_addr (got) + got_off;
@@ -4183,7 +4219,7 @@ loongarch_tls_perform_trans (bfd *abfd, asection *sec,
{
unsigned long insn;
bool local_exec = bfd_link_executable (info)
- && SYMBOL_REFERENCES_LOCAL (info, h);
+ && LARCH_REF_LOCAL (info, h);
bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
@@ -4895,7 +4931,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
else
continue;
- if (h && SYMBOL_REFERENCES_LOCAL (info, h))
+ if (h && LARCH_REF_LOCAL (info, h))
local_got = true;
symtype = h->type;
}
@@ -5032,12 +5068,12 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
if (htab->elf.splt)
{
BFD_ASSERT ((h->type == STT_GNU_IFUNC
- && SYMBOL_REFERENCES_LOCAL (info, h))
+ && LARCH_REF_LOCAL (info, h))
|| h->dynindx != -1);
plt = htab->elf.splt;
gotplt = htab->elf.sgotplt;
- if (h->type == STT_GNU_IFUNC && SYMBOL_REFERENCES_LOCAL (info, h))
+ if (h->type == STT_GNU_IFUNC && LARCH_REF_LOCAL (info, h))
relplt = htab->elf.srelgot;
else
relplt = htab->elf.srelplt;
@@ -5048,7 +5084,7 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
else /* if (htab->elf.iplt) */
{
BFD_ASSERT (h->type == STT_GNU_IFUNC
- && SYMBOL_REFERENCES_LOCAL (info, h));
+ && LARCH_REF_LOCAL (info, h));
plt = htab->elf.iplt;
gotplt = htab->elf.igotplt;
@@ -5136,7 +5172,7 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
if (htab->elf.splt == NULL)
srela = htab->elf.irelplt;
- if (SYMBOL_REFERENCES_LOCAL (info, h))
+ if (LARCH_REF_LOCAL (info, h))
{
asection *sec = h->root.u.def.section;
rela.r_info = ELFNN_R_INFO (0, R_LARCH_IRELATIVE);
@@ -5173,7 +5209,7 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
return true;
}
}
- else if (bfd_link_pic (info) && SYMBOL_REFERENCES_LOCAL (info, h))
+ else if (bfd_link_pic (info) && LARCH_REF_LOCAL (info, h))
{
asection *sec = h->root.u.def.section;
rela.r_info = ELFNN_R_INFO (0, R_LARCH_RELATIVE);
diff --git a/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d b/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d
index cb592874..968e7564 100644
--- a/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d
+++ b/ld/testsuite/ld-loongarch-elf/ifunc-reloc.d
@@ -8,6 +8,7 @@
.* R_LARCH_IRELATIVE .*
.* R_LARCH_IRELATIVE .*
.* R_LARCH_IRELATIVE .*
+.* R_LARCH_IRELATIVE .*
#...
.*'\.rela\.plt'.*
#...
@@ -16,4 +17,3 @@
.* R_LARCH_JUMP_SLOT .*
.* R_LARCH_JUMP_SLOT .*
.* R_LARCH_JUMP_SLOT .*
-.* R_LARCH_JUMP_SLOT .*
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 506dac3e..30d7bc03 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -134,6 +134,7 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "reloc_abs_with_shared"
run_dump_test "r_larch_32_elf64"
run_dump_test "ifunc-reloc"
+ run_dump_test "protected-func"
}
if [check_pie_support] {
diff --git a/ld/testsuite/ld-loongarch-elf/protected-func.d b/ld/testsuite/ld-loongarch-elf/protected-func.d
new file mode 100644
index 00000000..501c7cb5
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/protected-func.d
@@ -0,0 +1,6 @@
+#ld: -shared
+#readelf: -Wr
+
+#...
+.* R_LARCH_RELATIVE .*
+.* R_LARCH_RELATIVE .*
diff --git a/ld/testsuite/ld-loongarch-elf/protected-func.s b/ld/testsuite/ld-loongarch-elf/protected-func.s
new file mode 100644
index 00000000..8f28f925
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/protected-func.s
@@ -0,0 +1,17 @@
+# protected function should be non-preemptible and relocated with
+# R_LARCH_RELATIVE in shared library, for both GOT and pointer data
+
+.globl x
+.protected x
+.type x, @function
+x:
+ ret
+
+.globl _start
+_start:
+ la.got $a0, x
+ ret
+
+.data
+p:
+ .quad x
--
2.33.0

View File

@ -0,0 +1,128 @@
From d7c082ef88547077b24d3b27144daf4ce4e442f4 Mon Sep 17 00:00:00 2001
From: Jinyang He <hejinyang@loongson.cn>
Date: Mon, 8 Jul 2024 11:27:52 +0800
Subject: [PATCH 101/123] LoongArch: Not alloc dynamic relocs if symbol is
absolute
The absolute symbol should be resolved to const when link to dso or exe.
Alloc dynamic relocs will cause extra space and R_LARCH_NONE finally.
---
bfd/elfnn-loongarch.c | 14 +++++++-------
ld/testsuite/ld-loongarch-elf/abssym.s | 3 +++
ld/testsuite/ld-loongarch-elf/abssym_pie.d | 6 ++++++
ld/testsuite/ld-loongarch-elf/abssym_shared.d | 6 ++++++
ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp | 2 ++
5 files changed, 24 insertions(+), 7 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/abssym.s
create mode 100644 ld/testsuite/ld-loongarch-elf/abssym_pie.d
create mode 100644 ld/testsuite/ld-loongarch-elf/abssym_shared.d
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index d11189b4..af4d8baa 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -899,6 +899,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
unsigned int r_type;
unsigned int r_symndx;
struct elf_link_hash_entry *h;
+ bool is_abs_symbol = false;
Elf_Internal_Sym *isym = NULL;
r_symndx = ELFNN_R_SYM (rel->r_info);
@@ -917,6 +918,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
if (isym == NULL)
return false;
+ is_abs_symbol = isym->st_shndx == SHN_ABS;
if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
{
h = elfNN_loongarch_get_local_sym_hash (htab, abfd, rel, true);
@@ -935,6 +937,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ is_abs_symbol = bfd_is_abs_symbol (&h->root);
}
/* It is referenced by a non-shared object. */
@@ -1142,13 +1145,6 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
&& bfd_link_pic (info)
&& (sec->flags & SEC_ALLOC) != 0)
{
- bool is_abs_symbol = false;
-
- if (r_symndx < symtab_hdr->sh_info)
- is_abs_symbol = isym->st_shndx == SHN_ABS;
- else
- is_abs_symbol = bfd_is_abs_symbol (&h->root);
-
if (!is_abs_symbol)
{
_bfd_error_handler
@@ -1165,6 +1161,10 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_LARCH_JUMP_SLOT:
case R_LARCH_64:
+ /* Resolved to const. */
+ if (is_abs_symbol)
+ break;
+
need_dynreloc = 1;
/* If resolved symbol is defined in this object,
diff --git a/ld/testsuite/ld-loongarch-elf/abssym.s b/ld/testsuite/ld-loongarch-elf/abssym.s
new file mode 100644
index 00000000..3eacc766
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/abssym.s
@@ -0,0 +1,3 @@
+.section .data,"aw"
+.quad _size8
+.word _size4
diff --git a/ld/testsuite/ld-loongarch-elf/abssym_pie.d b/ld/testsuite/ld-loongarch-elf/abssym_pie.d
new file mode 100644
index 00000000..dfc3e35b
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/abssym_pie.d
@@ -0,0 +1,6 @@
+#source: abssym.s
+#ld: -pie -e 0 --defsym _size8=0 --defsym _size4=0
+#readelf: -r
+#...
+There are no relocations in this file.
+#...
diff --git a/ld/testsuite/ld-loongarch-elf/abssym_shared.d b/ld/testsuite/ld-loongarch-elf/abssym_shared.d
new file mode 100644
index 00000000..2db7e890
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/abssym_shared.d
@@ -0,0 +1,6 @@
+#source: abssym.s
+#ld: -shared --defsym _size8=0 --defsym _size4=0
+#readelf: -r
+#...
+There are no relocations in this file.
+#...
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 2be67651..032b9bad 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -141,6 +141,7 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "relr-discard-shared"
run_dump_test "relr-got-shared"
run_dump_test "relr-text-shared"
+ run_dump_test "abssym_shared"
}
if [check_pie_support] {
@@ -149,6 +150,7 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "relr-discard-pie"
run_dump_test "relr-got-pie"
run_dump_test "relr-text-pie"
+ run_dump_test "abssym_pie"
}
run_dump_test "max_imm_b16"
--
2.33.0

View File

@ -0,0 +1,482 @@
From 4c19c0fd7815a9acabdca9954028f772da1d985e Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Thu, 10 Oct 2024 16:20:52 +0800
Subject: [PATCH 116/123] LoongArch: Optimize the relaxation process
The symbol value is only calculated when the relocation can be relaxed.
---
bfd/elfnn-loongarch.c | 281 +++++++++++++++++++++---------------------
1 file changed, 139 insertions(+), 142 deletions(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index b6d7d1e8..70522fae 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -4072,7 +4072,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
/* For 2G jump, generate pcalau12i, jirl. */
/* If use jirl, turns to R_LARCH_B16. */
uint32_t insn = bfd_get (32, input_bfd, contents + rel->r_offset);
- if (LARCH_INSN_JIRL(insn))
+ if (LARCH_INSN_JIRL (insn))
{
relocation &= 0xfff;
/* Signed extend. */
@@ -4852,9 +4852,11 @@ loongarch_tls_perform_trans (bfd *abfd, asection *sec,
*/
static bool
loongarch_relax_tls_le (bfd *abfd, asection *sec,
- Elf_Internal_Rela *rel,
+ asection *sym_sec ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela *rel, bfd_vma symval,
struct bfd_link_info *link_info,
- bfd_vma symval)
+ bool *agin ATTRIBUTE_UNUSED,
+ bfd_vma max_alignment ATTRIBUTE_UNUSED)
{
bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
uint32_t insn = bfd_get (32, abfd, contents + rel->r_offset);
@@ -4862,7 +4864,7 @@ loongarch_relax_tls_le (bfd *abfd, asection *sec,
symval = symval - elf_hash_table (link_info)->tls_sec->vma;
/* The old LE instruction sequence can be relaxed when the symbol offset
is smaller than the 12-bit range. */
- if (ELFNN_R_TYPE ((rel + 1)->r_info) == R_LARCH_RELAX && (symval <= 0xfff))
+ if (symval <= 0xfff)
{
switch (ELFNN_R_TYPE (rel->r_info))
{
@@ -4975,9 +4977,6 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
/* Is pcalau12i + addi.d insns? */
if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_PCALA_LO12)
- || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
- || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
- || (rel_hi->r_offset + 4 != rel_lo->r_offset)
|| !LARCH_INSN_ADDI_D(add)
/* Is pcalau12i $rd + addi.d $rd,$rd? */
|| (LARCH_GET_RD(add) != rd)
@@ -5035,10 +5034,8 @@ loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec,
else if (symval < pc)
pc += (max_alignment > 4 ? max_alignment : 0);
-
/* Is pcalau12i + addi.d insns? */
- if ((ELFNN_R_TYPE ((rel + 1)->r_info) != R_LARCH_RELAX)
- || !LARCH_INSN_JIRL(jirl)
+ if (!LARCH_INSN_JIRL (jirl)
|| ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xf8000000)
|| ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x7fffffc))
return false;
@@ -5064,7 +5061,12 @@ loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec,
/* Relax pcalau12i,ld.d => pcalau12i,addi.d. */
static bool
loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
- Elf_Internal_Rela *rel_hi)
+ asection *sym_sec ATTRIBUTE_UNUSED,
+ Elf_Internal_Rela *rel_hi,
+ bfd_vma symval ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ bool *again ATTRIBUTE_UNUSED,
+ bfd_vma max_alignment ATTRIBUTE_UNUSED)
{
bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
Elf_Internal_Rela *rel_lo = rel_hi + 2;
@@ -5074,9 +5076,6 @@ loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
uint32_t addi_d = LARCH_OP_ADDI_D;
if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
- || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
- || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
- || (rel_hi->r_offset + 4 != rel_lo->r_offset)
|| (LARCH_GET_RD(ld) != rd)
|| (LARCH_GET_RJ(ld) != rd)
|| !LARCH_INSN_LD_D(ld))
@@ -5106,11 +5105,12 @@ bfd_elfNN_loongarch_set_data_segment_info (struct bfd_link_info *info,
/* Implement R_LARCH_ALIGN by deleting excess alignment NOPs.
Once we've handled an R_LARCH_ALIGN, we can't relax anything else. */
static bool
-loongarch_relax_align (bfd *abfd, asection *sec,
- asection *sym_sec,
- struct bfd_link_info *link_info,
+loongarch_relax_align (bfd *abfd, asection *sec, asection *sym_sec,
Elf_Internal_Rela *rel,
- bfd_vma symval)
+ bfd_vma symval ATTRIBUTE_UNUSED,
+ struct bfd_link_info *link_info,
+ bool *again ATTRIBUTE_UNUSED,
+ bfd_vma max_alignment ATTRIBUTE_UNUSED)
{
bfd_vma addend, max = 0, alignment = 1;
@@ -5198,9 +5198,6 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
/* Is pcalau12i + addi.d insns? */
if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12
&& ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_TLS_DESC_PC_LO12)
- || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
- || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
- || (rel_hi->r_offset + 4 != rel_lo->r_offset)
|| !LARCH_INSN_ADDI_D(add)
/* Is pcalau12i $rd + addi.d $rd,$rd? */
|| (LARCH_GET_RD(add) != rd)
@@ -5257,12 +5254,18 @@ loongarch_get_max_alignment (asection *sec)
return (bfd_vma) 1 << max_alignment_power;
}
+typedef bool (*relax_func_t) (bfd *, asection *, asection *,
+ Elf_Internal_Rela *, bfd_vma,
+ struct bfd_link_info *, bool *,
+ bfd_vma);
+
static bool
loongarch_elf_relax_section (bfd *abfd, asection *sec,
struct bfd_link_info *info,
bool *again)
{
*again = false;
+
if (!is_elf_hash_table (info->hash)
|| elf_hash_table_id (elf_hash_table (info)) != LARCH_ELF_DATA)
return true;
@@ -5277,13 +5280,13 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
if (bfd_link_relocatable (info)
|| sec->sec_flg0
- || (sec->flags & SEC_RELOC) == 0
|| sec->reloc_count == 0
+ || (sec->flags & SEC_RELOC) == 0
+ || (sec->flags & SEC_HAS_CONTENTS) == 0
+ /* The exp_seg_relro_adjust is enum phase_enum (0x4). */
+ || *(htab->data_segment_phase) == 4
|| (info->disable_target_specific_optimizations
- && info->relax_pass == 0)
- /* The exp_seg_relro_adjust is enum phase_enum (0x4),
- and defined in ld/ldexp.h. */
- || *(htab->data_segment_phase) == 4)
+ && info->relax_pass == 0))
return true;
struct bfd_elf_section_data *data = elf_section_data (sec);
@@ -5293,11 +5296,14 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
info->keep_memory)))
return true;
+ data->relocs = relocs;
+ /* Read this BFD's contents if we haven't done so already. */
if (!data->this_hdr.contents
&& !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents))
return true;
+ /* Read this BFD's symbols if we haven't done so already. */
Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
if (symtab_hdr->sh_info != 0
&& !symtab_hdr->contents
@@ -5307,8 +5313,6 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
0, NULL, NULL, NULL)))
return true;
- data->relocs = relocs;
-
/* Estimate the maximum alignment for all output sections once time
should be enough. */
bfd_vma max_alignment = htab->max_alignment;
@@ -5330,6 +5334,93 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
+ if (r_symndx >= symtab_hdr->sh_info)
+ {
+ h = elf_sym_hashes (abfd)[r_symndx - symtab_hdr->sh_info];
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+ }
+
+ /* If the conditions for tls type transition are met, type
+ transition is performed instead of relax.
+ During the transition from DESC->IE/LE, there are 2 situations
+ depending on the different configurations of the relax/norelax
+ option.
+ If the -relax option is used, the extra nops will be removed,
+ and this transition is performed in pass 0.
+ If the --no-relax option is used, nop will be retained, and
+ this transition is performed in pass 1. */
+ if (IS_LOONGARCH_TLS_TRANS_RELOC (r_type)
+ && (i + 1 != sec->reloc_count)
+ && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX
+ && rel->r_offset == rel[1].r_offset
+ && loongarch_can_trans_tls (abfd, info, h, r_symndx, r_type))
+ {
+ loongarch_tls_perform_trans (abfd, sec, rel, h, info);
+ r_type = ELFNN_R_TYPE (rel->r_info);
+ }
+
+ relax_func_t relax_func = NULL;
+ if (info->relax_pass == 0)
+ {
+ switch (r_type)
+ {
+ case R_LARCH_PCALA_HI20:
+ relax_func = loongarch_relax_pcala_addi;
+ break;
+ case R_LARCH_GOT_PC_HI20:
+ relax_func = loongarch_relax_pcala_ld;
+ break;
+ case R_LARCH_CALL36:
+ relax_func = loongarch_relax_call36;
+ break;
+ case R_LARCH_TLS_LE_HI20_R:
+ case R_LARCH_TLS_LE_LO12_R:
+ case R_LARCH_TLS_LE_ADD_R:
+ case R_LARCH_TLS_LE_HI20:
+ case R_LARCH_TLS_LE_LO12:
+ case R_LARCH_TLS_LE64_LO20:
+ case R_LARCH_TLS_LE64_HI12:
+ relax_func = loongarch_relax_tls_le;
+ break;
+ case R_LARCH_TLS_LD_PC_HI20:
+ case R_LARCH_TLS_GD_PC_HI20:
+ case R_LARCH_TLS_DESC_PC_HI20:
+ relax_func = loongarch_relax_tls_ld_gd_desc;
+ break;
+ default:
+ continue;
+ }
+
+ /* Only relax this reloc if it is paired with R_RISCV_RELAX. */
+ if (r_type == R_LARCH_TLS_LD_PC_HI20
+ || r_type == R_LARCH_TLS_GD_PC_HI20
+ || r_type == R_LARCH_TLS_DESC_PC_HI20
+ || r_type == R_LARCH_PCALA_HI20
+ || r_type == R_LARCH_GOT_PC_HI20)
+ {
+ if ((i + 2) == sec->reloc_count - 1
+ || ELFNN_R_TYPE ((rel + 1)->r_info) != R_LARCH_RELAX
+ || ELFNN_R_TYPE ((rel + 3)->r_info) != R_LARCH_RELAX
+ || rel->r_offset != (rel + 1)->r_offset
+ || (rel + 2)->r_offset != (rel + 3)->r_offset
+ || rel->r_offset + 4 != (rel + 2)->r_offset)
+ continue;
+ }
+ else
+ {
+ if (i == sec->reloc_count - 1
+ || ELFNN_R_TYPE ((rel + 1)->r_info) != R_LARCH_RELAX
+ || rel->r_offset != (rel + 1)->r_offset)
+ continue;
+ }
+ }
+ else if (info->relax_pass == 1 && r_type == R_LARCH_ALIGN)
+ relax_func = loongarch_relax_align;
+ else
+ continue;
+
/* Four kind of relocations:
Normal: symval is the symbol address.
R_LARCH_ALIGN: symval is the address of the last NOP instruction
@@ -5342,29 +5433,26 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
{
Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
+ r_symndx;
+
if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
continue;
/* Only TLS instruction sequences that are accompanied by
R_LARCH_RELAX and cannot perform type transition can be
relaxed. */
- if (R_LARCH_TLS_LD_PC_HI20 == r_type
- || R_LARCH_TLS_GD_PC_HI20 == r_type
- || (R_LARCH_TLS_DESC_PC_HI20 == r_type
- && (i + 1 != sec->reloc_count)
- && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX
- && ! loongarch_can_trans_tls (abfd, info, h,
- r_symndx, r_type)))
+ if (r_type == R_LARCH_TLS_LD_PC_HI20
+ || r_type == R_LARCH_TLS_GD_PC_HI20
+ || r_type == R_LARCH_TLS_DESC_PC_HI20)
{
sym_sec = htab->elf.sgot;
symval = elf_local_got_offsets (abfd)[r_symndx];
char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
r_symndx);
- if (R_LARCH_TLS_DESC_PC_HI20 == r_type
+ if (r_type == R_LARCH_TLS_DESC_PC_HI20
&& GOT_TLS_GD_BOTH_P (tls_type))
symval += 2 * GOT_ENTRY_SIZE;
}
- else if (sym->st_shndx == SHN_UNDEF || R_LARCH_ALIGN == r_type)
+ else if (sym->st_shndx == SHN_UNDEF || r_type == R_LARCH_ALIGN)
{
sym_sec = sec;
symval = rel->r_offset;
@@ -5375,35 +5463,25 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
symval = sym->st_value;
}
symtype = ELF_ST_TYPE (sym->st_info);
+ is_abs_symbol = sym->st_shndx == SHN_ABS;
}
else
{
- r_symndx = ELFNN_R_SYM (rel->r_info) - symtab_hdr->sh_info;
- h = elf_sym_hashes (abfd)[r_symndx];
-
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
/* Disable the relaxation for ifunc. */
if (h != NULL && h->type == STT_GNU_IFUNC)
continue;
/* The GOT entry of tls symbols must in current execute file or
shared object. */
- if (R_LARCH_TLS_LD_PC_HI20 == r_type
- || R_LARCH_TLS_GD_PC_HI20 == r_type
- || (R_LARCH_TLS_DESC_PC_HI20 == r_type
- && (i + 1 != sec->reloc_count)
- && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX
- && !loongarch_can_trans_tls (abfd, info, h,
- r_symndx, r_type)))
+ if (r_type == R_LARCH_TLS_LD_PC_HI20
+ || r_type == R_LARCH_TLS_GD_PC_HI20
+ || r_type == R_LARCH_TLS_DESC_PC_HI20)
{
sym_sec = htab->elf.sgot;
symval = h->got.offset;
char tls_type = _bfd_loongarch_elf_tls_type (abfd, h,
r_symndx);
- if (R_LARCH_TLS_DESC_PC_HI20 == r_type
+ if (r_type == R_LARCH_TLS_DESC_PC_HI20
&& GOT_TLS_GD_BOTH_P (tls_type))
symval += 2 * GOT_ENTRY_SIZE;
}
@@ -5412,12 +5490,13 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
&& h->root.u.def.section != NULL
&& h->root.u.def.section->output_section != NULL)
{
- symval = h->root.u.def.value;
sym_sec = h->root.u.def.section;
+ symval = h->root.u.def.value;
}
else
continue;
+ is_abs_symbol = bfd_is_abs_section (h->root.u.def.section);
if (h && LARCH_REF_LOCAL (info, h))
local_got = true;
symtype = h->type;
@@ -5440,7 +5519,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
+ (alingmeng - 4).
If r_symndx is 0, alignmeng-4 is r_addend.
If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */
- else if (R_LARCH_ALIGN == r_type)
+ else if (r_type == R_LARCH_ALIGN)
if (r_symndx > 0)
symval += ((1 << (rel->r_addend & 0xff)) - 4);
else
@@ -5450,96 +5529,14 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
symval += sec_addr (sym_sec);
- /* If the conditions for tls type transition are met, type
- transition is performed instead of relax.
- During the transition from DESC->IE/LE, there are 2 situations
- depending on the different configurations of the relax/norelax
- option.
- If the -relax option is used, the extra nops will be removed,
- and this transition is performed in pass 0.
- If the --no-relax option is used, nop will be retained, and
- this transition is performed in pass 1. */
- if (IS_LOONGARCH_TLS_TRANS_RELOC (r_type)
- && (i + 1 != sec->reloc_count)
- && ELFNN_R_TYPE (rel[1].r_info) == R_LARCH_RELAX
- && loongarch_can_trans_tls (abfd, info, h, r_symndx, r_type))
- {
- loongarch_tls_perform_trans (abfd, sec, rel, h, info);
- r_type = ELFNN_R_TYPE (rel->r_info);
- }
-
- switch (r_type)
- {
- case R_LARCH_ALIGN:
- if (1 == info->relax_pass)
- loongarch_relax_align (abfd, sec, sym_sec, info, rel, symval);
- break;
+ if (r_type == R_LARCH_GOT_PC_HI20 && (!local_got || is_abs_symbol))
+ continue;
- case R_LARCH_DELETE:
- 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_CALL36:
- if (0 == info->relax_pass && (i + 2) <= sec->reloc_count)
- loongarch_relax_call36 (abfd, sec, sym_sec, rel, symval,
+ if (relax_func (abfd, sec, sym_sec, rel, symval,
+ info, again, max_alignment)
+ && relax_func == loongarch_relax_pcala_ld)
+ loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
info, again, max_alignment);
- break;
-
- case R_LARCH_TLS_LE_HI20_R:
- case R_LARCH_TLS_LE_LO12_R:
- case R_LARCH_TLS_LE_ADD_R:
- case R_LARCH_TLS_LE_HI20:
- case R_LARCH_TLS_LE_LO12:
- case R_LARCH_TLS_LE64_LO20:
- case R_LARCH_TLS_LE64_HI12:
- if (0 == info->relax_pass && (i + 2) <= sec->reloc_count)
- loongarch_relax_tls_le (abfd, sec, rel, info, symval);
- break;
-
- case R_LARCH_PCALA_HI20:
- if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
- loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
- info, again, max_alignment);
- break;
-
- case R_LARCH_GOT_PC_HI20:
- if (h)
- is_abs_symbol = bfd_is_abs_section(h->root.u.def.section);
- else
- {
- Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
- + ELFNN_R_SYM (rel->r_info);
- is_abs_symbol = sym->st_shndx == SHN_ABS;
- }
- /* If symval is in the range [-2^31, 2^31), we can relax the
- pair of instructions from pcalau12i/ld.d to lu12i.w/ori for
- abosulte symbol. This is not implemented yet, so we just
- remain the r_type which will be needed when relocate for
- absolute symbol. */
- if (local_got && 0 == info->relax_pass
- && !is_abs_symbol
- && (i + 4) <= sec->reloc_count)
- {
- if (loongarch_relax_pcala_ld (abfd, sec, rel))
- loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
- info, again, max_alignment);
- }
- break;
-
- case R_LARCH_TLS_LD_PC_HI20:
- case R_LARCH_TLS_GD_PC_HI20:
- case R_LARCH_TLS_DESC_PC_HI20:
- if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
- loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
- info, again, max_alignment);
- break;
-
- default:
- break;
- }
}
return true;
--
2.33.0

View File

@ -0,0 +1,132 @@
From b1375201b1643fee97a240ba17523a529b286e12 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Sun, 30 Jun 2024 15:18:21 +0800
Subject: [PATCH 095/123] LoongArch: Reject R_LARCH_32 from becoming a runtime
reloc in ELFCLASS64
We were converting R_LARCH_32 to R_LARCH_RELATIVE for ELFCLASS64:
$ cat t.s
.data
x:
.4byte x
.4byte 0xdeadbeef
$ as/as-new t.s -o t.o
$ ld/ld-new -shared t.o
$ objdump -R
a.out: file format elf64-loongarch
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
00000000000001a8 R_LARCH_RELATIVE *ABS*+0x00000000000001a8
But this is just wrong: at runtime the dynamic linker will run
*(uintptr *)&x += load_address, clobbering the next 4 bytes of data
("0xdeadbeef" in the example).
If we keep the R_LARCH_32 reloc as-is in ELFCLASS64, it'll be rejected
by the Glibc dynamic linker anyway. And it does not make too much sense
to modify Glibc to support it. So we can just reject it like x86_64:
relocation R_X86_64_32 against `.data' can not be used when making a
shared object; recompile with -fPIC
or RISC-V:
relocation R_RISCV_32 against non-absolute symbol `a local symbol'
can not be used in RV64 when making a shared object
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
bfd/elfnn-loongarch.c | 30 +++++++++++++++++--
.../ld-loongarch-elf/ld-loongarch-elf.exp | 1 +
.../ld-loongarch-elf/r_larch_32_elf64.d | 4 +++
.../ld-loongarch-elf/r_larch_32_elf64.s | 3 ++
4 files changed, 36 insertions(+), 2 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d
create mode 100644 ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 840cdd35..fa0a5e38 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -1036,8 +1036,32 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
only_need_pcrel = 1;
break;
- case R_LARCH_JUMP_SLOT:
case R_LARCH_32:
+ if (ARCH_SIZE > 32
+ && bfd_link_pic (info)
+ && (sec->flags & SEC_ALLOC) != 0)
+ {
+ bool is_abs_symbol = false;
+
+ if (r_symndx < symtab_hdr->sh_info)
+ is_abs_symbol = isym->st_shndx == SHN_ABS;
+ else
+ is_abs_symbol = bfd_is_abs_symbol (&h->root);
+
+ if (!is_abs_symbol)
+ {
+ _bfd_error_handler
+ (_("%pB: relocation R_LARCH_32 against non-absolute "
+ "symbol `%s' cannot be used in ELFCLASS64 when "
+ "making a shared object or PIE"),
+ abfd, h ? h->root.root.string : "a local symbol");
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+ }
+
+ /* Fall through. */
+ case R_LARCH_JUMP_SLOT:
case R_LARCH_64:
need_dynreloc = 1;
@@ -2858,8 +2882,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
outrel.r_addend = relocation + rel->r_addend;
}
- /* No alloc space of func allocate_dynrelocs. */
+ /* No alloc space of func allocate_dynrelocs.
+ No alloc space of invalid R_LARCH_32 in ELFCLASS64. */
if (unresolved_reloc
+ && (ARCH_SIZE == 32 || r_type != R_LARCH_32)
&& !(h && (h->is_weakalias || !h->dyn_relocs)))
loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
}
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 89552a11..7ffabe2c 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -132,6 +132,7 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "reloc_le_with_shared"
run_dump_test "reloc_ler_with_shared"
run_dump_test "reloc_abs_with_shared"
+ run_dump_test "r_larch_32_elf64"
}
if [check_pie_support] {
diff --git a/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d
new file mode 100644
index 00000000..34313295
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d
@@ -0,0 +1,4 @@
+#name: R_LARCH_32 in ELFCLASS64
+#source: r_larch_32_elf64.s
+#ld: -shared -melf64loongarch
+#error: R_LARCH_32 .* cannot be used in ELFCLASS64
diff --git a/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s
new file mode 100644
index 00000000..6649f2bc
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s
@@ -0,0 +1,3 @@
+.data
+x:
+ .4byte x
--
2.33.0

View File

@ -0,0 +1,45 @@
From a88594951ad3b0657d8e6139c3fde63e7a771b12 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Sat, 22 Jun 2024 18:06:47 +0800
Subject: [PATCH 094/123] LoongArch: Remove unused code in ld test suite
These seems some left over from MIPS code and they do not make any
sense for LoongArch.
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
ld/testsuite/ld-loongarch-elf/anno-sym.d | 2 --
ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp | 7 -------
2 files changed, 9 deletions(-)
diff --git a/ld/testsuite/ld-loongarch-elf/anno-sym.d b/ld/testsuite/ld-loongarch-elf/anno-sym.d
index a58f4a6c..6d2149f0 100644
--- a/ld/testsuite/ld-loongarch-elf/anno-sym.d
+++ b/ld/testsuite/ld-loongarch-elf/anno-sym.d
@@ -3,5 +3,3 @@
#as: -mno-relax
#ld: -e _start
#error_output: anno-sym.l
-# The mips-irix6 target fails this test because it does not find any function symbols. Not sure why.
-#skip: *-*-irix*
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 5d109a4d..89552a11 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -19,13 +19,6 @@
# MA 02110-1301, USA.
#
-proc loongarch_choose_lp64_emul {} {
- if { [istarget "loongarch64be-*"] } {
- return "elf64bloongarch"
- }
- return "elf64lloongarch"
-}
-
if [istarget "loongarch64-*-*"] {
run_dump_test "jmp_op"
run_dump_test "macro_op"
--
2.33.0

View File

@ -0,0 +1,50 @@
From 070b9a5e5d1a0864a8e9971cefd4b0e73637e783 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Tue, 27 Feb 2024 15:12:14 +0800
Subject: [PATCH 061/123] LoongArch: Run overflow testcases only on LoongArch
target
---
.../ld-loongarch-elf/ld-loongarch-elf.exp | 27 ++++++++++---------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index b3029e53..7dca8218 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -133,18 +133,19 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "desc-norelax"
run_dump_test "desc-relax"
}
+
+ run_dump_test "max_imm_b16"
+ run_dump_test "max_imm_b21"
+ run_dump_test "max_imm_b26"
+ run_dump_test "max_imm_pcrel20"
+ run_dump_test "overflow_b16"
+ run_dump_test "overflow_b21"
+ run_dump_test "overflow_b26"
+ run_dump_test "overflow_pcrel20"
+ run_dump_test "underflow_b16"
+ run_dump_test "underflow_b21"
+ run_dump_test "underflow_b26"
+ run_dump_test "underflow_pcrel20"
+ run_dump_test "pie_discard"
}
-run_dump_test "max_imm_b16"
-run_dump_test "max_imm_b21"
-run_dump_test "max_imm_b26"
-run_dump_test "max_imm_pcrel20"
-run_dump_test "overflow_b16"
-run_dump_test "overflow_b21"
-run_dump_test "overflow_b26"
-run_dump_test "overflow_pcrel20"
-run_dump_test "underflow_b16"
-run_dump_test "underflow_b21"
-run_dump_test "underflow_b26"
-run_dump_test "underflow_pcrel20"
-run_dump_test "pie_discard"
--
2.33.0

View File

@ -0,0 +1,381 @@
From e3cee667f81d7f7982f4a9f75370415b00e9cff6 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Sat, 2 Mar 2024 10:47:42 +0800
Subject: [PATCH 073/123] LoongArch: Scan all illegal operand instructions
without interruption
Currently, gas will exit immediately and report an error when
it sees illegal operands, and will not process the remaining
instructions. Replace as_fatal with as_bad to check for all
illegal operands.
Add test cases for illegal operands of some instructions.
---
gas/config/tc-loongarch.c | 11 +-
.../gas/loongarch/check_bstrins-pick.d | 18 +++
.../gas/loongarch/check_bstrins-pick.s | 9 ++
gas/testsuite/gas/loongarch/illegal-operand.l | 113 +++++++++++++++++
gas/testsuite/gas/loongarch/illegal-operand.s | 117 ++++++++++++++++++
gas/testsuite/gas/loongarch/loongarch.exp | 4 +
gas/testsuite/gas/loongarch/lvz-lbt.d | 2 +-
gas/testsuite/gas/loongarch/lvz-lbt.s | 2 +-
8 files changed, 269 insertions(+), 7 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/check_bstrins-pick.d
create mode 100644 gas/testsuite/gas/loongarch/check_bstrins-pick.s
create mode 100644 gas/testsuite/gas/loongarch/illegal-operand.l
create mode 100644 gas/testsuite/gas/loongarch/illegal-operand.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index b510d228..ff126d56 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -958,8 +958,8 @@ check_this_insn_before_appending (struct loongarch_cl_insn *ip)
/* For AMO insn amswap.[wd], amadd.[wd], etc. */
if (ip->args[0] != 0
&& (ip->args[0] == ip->args[1] || ip->args[0] == ip->args[2]))
- as_fatal (_("AMO insns require rd != base && rd != rt"
- " when rd isn't $r0"));
+ as_bad (_("automic memory operations insns require rd != rj"
+ " && rd != rk when rd isn't r0"));
}
else if ((ip->insn->mask == 0xffe08000
/* bstrins.w rd, rj, msbw, lsbw */
@@ -970,12 +970,13 @@ check_this_insn_before_appending (struct loongarch_cl_insn *ip)
{
/* For bstr(ins|pick).[wd]. */
if (ip->args[2] < ip->args[3])
- as_fatal (_("bstr(ins|pick).[wd] require msbd >= lsbd"));
+ as_bad (_("bstr(ins|pick).[wd] require msbd >= lsbd"));
}
else if (ip->insn->mask != 0 && (ip->insn_bin & 0xfe0003c0) == 0x04000000
/* csrxchg rd, rj, csr_num */
- && (strcmp ("csrxchg", ip->name) == 0))
- as_fatal (_("csrxchg require rj != $r0 && rj != $r1"));
+ && (strcmp ("csrxchg", ip->name) == 0
+ || strcmp ("gcsrxchg", ip->name) == 0))
+ as_bad (_("g?csrxchg require rj != r0 && rj != r1"));
return ret;
}
diff --git a/gas/testsuite/gas/loongarch/check_bstrins-pick.d b/gas/testsuite/gas/loongarch/check_bstrins-pick.d
new file mode 100644
index 00000000..7575be19
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/check_bstrins-pick.d
@@ -0,0 +1,18 @@
+#as:
+#objdump: -d
+#skip: loongarch32-*-*
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+0+ <.*>:
+ 0: 00682041 bstrins\.w \$ra, \$tp, 0x8, 0x8
+ 4: 00882041 bstrins\.d \$ra, \$tp, 0x8, 0x8
+ 8: 0068a041 bstrpick\.w \$ra, \$tp, 0x8, 0x8
+ c: 00c82041 bstrpick\.d \$ra, \$tp, 0x8, 0x8
+ 10: 00680041 bstrins\.w \$ra, \$tp, 0x8, 0x0
+ 14: 00880041 bstrins\.d \$ra, \$tp, 0x8, 0x0
+ 18: 00688041 bstrpick\.w \$ra, \$tp, 0x8, 0x0
+ 1c: 00c80041 bstrpick\.d \$ra, \$tp, 0x8, 0x0
diff --git a/gas/testsuite/gas/loongarch/check_bstrins-pick.s b/gas/testsuite/gas/loongarch/check_bstrins-pick.s
new file mode 100644
index 00000000..0decaf98
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/check_bstrins-pick.s
@@ -0,0 +1,9 @@
+bstrins.w $r1,$r2,8,8
+bstrins.d $r1,$r2,8,8
+bstrpick.w $r1,$r2,8,8
+bstrpick.d $r1,$r2,8,8
+
+bstrins.w $r1,$r2,8,0
+bstrins.d $r1,$r2,8,0
+bstrpick.w $r1,$r2,8,0
+bstrpick.d $r1,$r2,8,0
diff --git a/gas/testsuite/gas/loongarch/illegal-operand.l b/gas/testsuite/gas/loongarch/illegal-operand.l
new file mode 100644
index 00000000..dddc6d6f
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/illegal-operand.l
@@ -0,0 +1,113 @@
+.*: Assembler messages:
+.*:2: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:3: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:4: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:5: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:6: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:7: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:8: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:9: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:10: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:11: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:12: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:13: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:14: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:15: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:16: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:17: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:18: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:19: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:20: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:21: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:22: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:23: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:24: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:25: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:26: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:27: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:28: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:29: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:30: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:31: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:32: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:33: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:34: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:35: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:36: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:37: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:38: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:39: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:40: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:41: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:42: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:43: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:44: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:45: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:46: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:47: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:48: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:49: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:50: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:51: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:52: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:53: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:54: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:55: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:56: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:57: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:58: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:59: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:60: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:61: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:62: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:63: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:64: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:65: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:66: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:67: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:68: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:69: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:70: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:71: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:72: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:73: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:74: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:75: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:76: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:77: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:78: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:79: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:80: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:81: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:82: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:83: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:84: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:85: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:86: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:87: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:88: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:89: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:90: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:91: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:92: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:93: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:94: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:95: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:96: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:97: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:98: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:99: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:100: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:101: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:102: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:103: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:104: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:105: Error: automic memory operations insns require rd != rj && rd != rk when rd isn't r0
+.*:108: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
+.*:109: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
+.*:110: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
+.*:111: Error: bstr\(ins\|pick\)\.\[wd\] require msbd >= lsbd
+.*:114: Error: g\?csrxchg require rj != r0 && rj != r1
+.*:115: Error: g\?csrxchg require rj != r0 && rj != r1
+.*:116: Error: g\?csrxchg require rj != r0 && rj != r1
+.*:117: Error: g\?csrxchg require rj != r0 && rj != r1
diff --git a/gas/testsuite/gas/loongarch/illegal-operand.s b/gas/testsuite/gas/loongarch/illegal-operand.s
new file mode 100644
index 00000000..3860539d
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/illegal-operand.s
@@ -0,0 +1,117 @@
+# Illegal operand of atomic memory access instruction.
+amcas.b $r1,$r1,$r2
+amcas.b $r1,$r2,$r1
+amcas.h $r1,$r1,$r2
+amcas.h $r1,$r2,$r1
+amcas.w $r1,$r1,$r2
+amcas.w $r1,$r2,$r1
+amcas.d $r1,$r1,$r2
+amcas.d $r1,$r2,$r1
+amcas_db.b $r1,$r1,$r2
+amcas_db.b $r1,$r2,$r1
+amcas_db.h $r1,$r1,$r2
+amcas_db.h $r1,$r2,$r1
+amcas_db.w $r1,$r1,$r2
+amcas_db.w $r1,$r2,$r1
+amcas_db.d $r1,$r1,$r2
+amcas_db.d $r1,$r2,$r1
+amswap.b $r1,$r1,$r2
+amswap.b $r1,$r2,$r1
+amswap.h $r1,$r1,$r2
+amswap.h $r1,$r2,$r1
+amadd.b $r1,$r1,$r2
+amadd.b $r1,$r2,$r1
+amadd.h $r1,$r1,$r2
+amadd.h $r1,$r2,$r1
+amswap_db.b $r1,$r1,$r2
+amswap_db.b $r1,$r2,$r1
+amswap_db.h $r1,$r1,$r2
+amswap_db.h $r1,$r2,$r1
+amadd_db.b $r1,$r1,$r2
+amadd_db.b $r1,$r2,$r1
+amadd_db.h $r1,$r1,$r2
+amadd_db.h $r1,$r2,$r1
+amswap.w $r1,$r1,$r2
+amswap.w $r1,$r2,$r1
+amswap.d $r1,$r1,$r2
+amswap.d $r1,$r2,$r1
+amadd.w $r1,$r1,$r2
+amadd.w $r1,$r2,$r1
+amadd.d $r1,$r1,$r2
+amadd.d $r1,$r2,$r1
+amand.w $r1,$r1,$r2
+amand.w $r1,$r2,$r1
+amand.d $r1,$r1,$r2
+amand.d $r1,$r2,$r1
+amor.w $r1,$r1,$r2
+amor.w $r1,$r2,$r1
+amor.d $r1,$r1,$r2
+amor.d $r1,$r2,$r1
+amxor.w $r1,$r1,$r2
+amxor.w $r1,$r2,$r1
+amxor.d $r1,$r1,$r2
+amxor.d $r1,$r2,$r1
+ammax.w $r1,$r1,$r2
+ammax.w $r1,$r2,$r1
+ammax.d $r1,$r1,$r2
+ammax.d $r1,$r2,$r1
+ammin.w $r1,$r1,$r2
+ammin.w $r1,$r2,$r1
+ammin.d $r1,$r1,$r2
+ammin.d $r1,$r2,$r1
+ammax.wu $r1,$r1,$r2
+ammax.wu $r1,$r2,$r1
+ammax.du $r1,$r1,$r2
+ammax.du $r1,$r2,$r1
+ammin.wu $r1,$r1,$r2
+ammin.wu $r1,$r2,$r1
+ammin.du $r1,$r1,$r2
+ammin.du $r1,$r2,$r1
+amswap_db.w $r1,$r1,$r2
+amswap_db.w $r1,$r2,$r1
+amswap_db.d $r1,$r1,$r2
+amswap_db.d $r1,$r2,$r1
+amadd_db.w $r1,$r1,$r2
+amadd_db.w $r1,$r2,$r1
+amadd_db.d $r1,$r1,$r2
+amadd_db.d $r1,$r2,$r1
+amand_db.w $r1,$r1,$r2
+amand_db.w $r1,$r2,$r1
+amand_db.d $r1,$r1,$r2
+amand_db.d $r1,$r2,$r1
+amor_db.w $r1,$r1,$r2
+amor_db.w $r1,$r2,$r1
+amor_db.d $r1,$r1,$r2
+amor_db.d $r1,$r2,$r1
+amxor_db.w $r1,$r1,$r2
+amxor_db.w $r1,$r2,$r1
+amxor_db.d $r1,$r1,$r2
+amxor_db.d $r1,$r2,$r1
+ammax_db.w $r1,$r1,$r2
+ammax_db.w $r1,$r2,$r1
+ammax_db.d $r1,$r1,$r2
+ammax_db.d $r1,$r2,$r1
+ammin_db.w $r1,$r1,$r2
+ammin_db.w $r1,$r2,$r1
+ammin_db.d $r1,$r1,$r2
+ammin_db.d $r1,$r2,$r1
+ammax_db.wu $r1,$r1,$r2
+ammax_db.wu $r1,$r2,$r1
+ammax_db.du $r1,$r1,$r2
+ammax_db.du $r1,$r2,$r1
+ammin_db.wu $r1,$r1,$r2
+ammin_db.wu $r1,$r2,$r1
+ammin_db.du $r1,$r1,$r2
+ammin_db.du $r1,$r2,$r1
+
+# Illegal operand of bstr(ins|pick).[wd]
+bstrins.w $r1,$r2,0,8
+bstrins.d $r1,$r2,0,8
+bstrpick.w $r1,$r2,0,8
+bstrpick.d $r1,$r2,0,8
+
+# Illegal operand of csrxchg/gcsrxchg
+csrxchg $r0,$r0,1
+csrxchg $r0,$r1,1
+gcsrxchg $r0,$r0,1
+gcsrxchg $r0,$r1,1
diff --git a/gas/testsuite/gas/loongarch/loongarch.exp b/gas/testsuite/gas/loongarch/loongarch.exp
index 1051a541..a2ccfb13 100644
--- a/gas/testsuite/gas/loongarch/loongarch.exp
+++ b/gas/testsuite/gas/loongarch/loongarch.exp
@@ -32,4 +32,8 @@ if [istarget loongarch*-*-*] {
run_list_test "align"
run_list_test "reg-s9"
+
+ if [istarget loongarch64-*-*] {
+ run_list_test "illegal-operand"
+ }
}
diff --git a/gas/testsuite/gas/loongarch/lvz-lbt.d b/gas/testsuite/gas/loongarch/lvz-lbt.d
index f8970776..760066a0 100644
--- a/gas/testsuite/gas/loongarch/lvz-lbt.d
+++ b/gas/testsuite/gas/loongarch/lvz-lbt.d
@@ -10,7 +10,7 @@ Disassembly of section .text:
00000000.* <.text>:
[ ]*0:[ ]*05000400[ ]*gcsrrd[ ]*\$zero,[ ]*0x1[ ]*
[ ]*4:[ ]*05000420[ ]*gcsrwr[ ]*\$zero,[ ]*0x1[ ]*
-[ ]*8:[ ]*05000420[ ]*gcsrwr[ ]*\$zero,[ ]*0x1[ ]*
+[ ]*8:[ ]*05000440[ ]*gcsrxchg[ ]*\$zero,[ ]*\$tp,[ ]*0x1[ ]*
[ ]*c:[ ]*06482401[ ]*gtlbflush[ ]*
[ ]*10:[ ]*002b8001[ ]*hvcl[ ]*0x1[ ]*
[ ]*14:[ ]*00000820[ ]*movgr2scr[ ]*\$scr0,[ ]*\$ra[ ]*
diff --git a/gas/testsuite/gas/loongarch/lvz-lbt.s b/gas/testsuite/gas/loongarch/lvz-lbt.s
index 64469a43..2e5089e4 100644
--- a/gas/testsuite/gas/loongarch/lvz-lbt.s
+++ b/gas/testsuite/gas/loongarch/lvz-lbt.s
@@ -1,6 +1,6 @@
gcsrrd $r0, 1
gcsrwr $r0, 1
-gcsrxchg $r0, $r1, 1
+gcsrxchg $r0, $r2, 1
gtlbflush
hvcl 1
movgr2scr $scr0, $r1
--
2.33.0

View File

@ -0,0 +1,201 @@
From 35938863d51f469f5bc715b3a7aa6f2a0eb150a6 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Wed, 19 Jun 2024 14:04:18 +0800
Subject: [PATCH 092/123] LoongArch: TLS IE needs only one dynamic reloc
As the comment in the code says, TLS_IE needs only one dynamic reloc.
But commit b67a17aa7c0c ("LoongArch: Fix the issue of excessive
relocation generated by GD and IE") has incorrectly allocated the space
for two dynamic relocs, causing libc.so to contain 8 R_LARCH_NONE.
Adjust tlsdesc-dso.d for the offset changes and add two tests to ensure
there are no R_LARCH_NONE with TLS.
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
bfd/elfnn-loongarch.c | 2 +-
ld/testsuite/ld-loongarch-elf/desc-ie-reloc.d | 9 ++
ld/testsuite/ld-loongarch-elf/desc-ie.d | 8 +-
.../ld-loongarch-elf/ld-loongarch-elf.exp | 2 +
.../ld-loongarch-elf/tlsdesc-dso-reloc.d | 9 ++
ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d | 86 +++++++++----------
6 files changed, 68 insertions(+), 48 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/desc-ie-reloc.d
create mode 100644 ld/testsuite/ld-loongarch-elf/tlsdesc-dso-reloc.d
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 9eaad7f4..51e3d311 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -1353,7 +1353,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{
s->size += GOT_ENTRY_SIZE;
if (need_reloc)
- htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
+ htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
}
/* TLS_DESC needs one dynamic reloc and two GOT slot. */
diff --git a/ld/testsuite/ld-loongarch-elf/desc-ie-reloc.d b/ld/testsuite/ld-loongarch-elf/desc-ie-reloc.d
new file mode 100644
index 00000000..c7a2f8ed
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/desc-ie-reloc.d
@@ -0,0 +1,9 @@
+#source: desc-ie.s
+#as:
+#ld: -shared -z norelro --hash-style=both
+#readelf: -Wr
+
+#failif
+#...
+.* +R_LARCH_NONE +.*
+#...
diff --git a/ld/testsuite/ld-loongarch-elf/desc-ie.d b/ld/testsuite/ld-loongarch-elf/desc-ie.d
index c833b233..0759404b 100644
--- a/ld/testsuite/ld-loongarch-elf/desc-ie.d
+++ b/ld/testsuite/ld-loongarch-elf/desc-ie.d
@@ -8,7 +8,7 @@
Disassembly of section .text:
[0-9a-f]+ <fn1>:
- +[0-9a-f]+: 1a000084 pcalau12i \$a0, .*
- +[0-9a-f]+: 28cd0084 ld.d \$a0, \$a0, .*
- +[0-9a-f]+: 1a000084 pcalau12i \$a0, .*
- +[0-9a-f]+: 28cd0084 ld.d \$a0, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcalau12i \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$a0, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcalau12i \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$a0, \$a0, .*
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 3c8e9195..5d109a4d 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -130,7 +130,9 @@ if [istarget "loongarch64-*-*"] {
if [istarget "loongarch64-*-*"] {
if [check_shared_lib_support] {
run_dump_test "desc-ie"
+ run_dump_test "desc-ie-reloc"
run_dump_test "tlsdesc-dso"
+ run_dump_test "tlsdesc-dso-reloc"
run_dump_test "desc-norelax"
run_dump_test "desc-relax"
run_dump_test "data-got"
diff --git a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso-reloc.d b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso-reloc.d
new file mode 100644
index 00000000..d5afa7c3
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso-reloc.d
@@ -0,0 +1,9 @@
+#source: tlsdesc-dso.s
+#as:
+#ld: -shared -z norelro --hash-style=both
+#readelf: -Wr
+
+#failif
+#...
+.* +R_LARCH_NONE +.*
+#...
diff --git a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
index 8f66302f..d6997ec9 100644
--- a/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
+++ b/ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
@@ -9,52 +9,52 @@
Disassembly of section .text:
[0-9a-f]+ <fun_gl1>:
- +[0-9a-f]+: 18021584 pcaddi \$a0, 4268
- +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
- +[0-9a-f]+: 28dd4084 ld.d \$a0, \$a0, 1872
- +[0-9a-f]+: 18021364 pcaddi \$a0, 4251
- +[0-9a-f]+: 180213c4 pcaddi \$a0, 4254
- +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
- +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
- +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
- +[0-9a-f]+: 28dc0084 ld.d \$a0, \$a0, 1792
- +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
- +[0-9a-f]+: 28dc0084 ld.d \$a0, \$a0, 1792
- +[0-9a-f]+: 18021364 pcaddi \$a0, 4251
- +[0-9a-f]+: 180213c4 pcaddi \$a0, 4254
- +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
- +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
- +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
- +[0-9a-f]+: 28dce084 ld.d \$a0, \$a0, 1848
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcalau12i \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$a0, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$ra, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ jirl \$ra, \$ra, .*
+ +[0-9a-f]+: [0-9a-f]+ pcalau12i \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$a0, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcalau12i \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$a0, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$ra, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ jirl \$ra, \$ra, .*
+ +[0-9a-f]+: [0-9a-f]+ pcalau12i \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$a0, \$a0, .*
[0-9a-f]+ <fun_lo>:
- +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
- +[0-9a-f]+: 28daa084 ld.d \$a0, \$a0, 1704
- +[0-9a-f]+: 18020de4 pcaddi \$a0, 4207
- +[0-9a-f]+: 18020f04 pcaddi \$a0, 4216
- +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
- +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
- +[0-9a-f]+: 18020e24 pcaddi \$a0, 4209
- +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
- +[0-9a-f]+: 28db4084 ld.d \$a0, \$a0, 1744
- +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
- +[0-9a-f]+: 28db4084 ld.d \$a0, \$a0, 1744
- +[0-9a-f]+: 18020f44 pcaddi \$a0, 4218
- +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
- +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
- +[0-9a-f]+: 18020e64 pcaddi \$a0, 4211
- +[0-9a-f]+: 1a000084 pcalau12i \$a0, 4
- +[0-9a-f]+: 28dba084 ld.d \$a0, \$a0, 1768
+ +[0-9a-f]+: [0-9a-f]+ pcalau12i \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$a0, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$ra, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ jirl \$ra, \$ra, .*
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcalau12i \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$a0, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcalau12i \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$a0, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$ra, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ jirl \$ra, \$ra, .*
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ pcalau12i \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$a0, \$a0, .*
[0-9a-f]+ <fun_external>:
- +[0-9a-f]+: 18020ec4 pcaddi \$a0, 4214
- +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
- +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$ra, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ jirl \$ra, \$ra, .*
[0-9a-f]+ <fun_hidden>:
- +[0-9a-f]+: 18021224 pcaddi \$a0, 4241
- +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
- +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
- +[0-9a-f]+: 18021144 pcaddi \$a0, 4234
- +[0-9a-f]+: 28c00081 ld.d \$ra, \$a0, 0
- +[0-9a-f]+: 4c000021 jirl \$ra, \$ra, 0
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$ra, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ jirl \$ra, \$ra, .*
+ +[0-9a-f]+: [0-9a-f]+ pcaddi \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ ld.d \$ra, \$a0, .*
+ +[0-9a-f]+: [0-9a-f]+ jirl \$ra, \$ra, .*
--
2.33.0

View File

@ -0,0 +1,37 @@
From 6f250e80b7445f58291c273adf8fa03c65939b43 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Fri, 19 Apr 2024 10:24:52 +0800
Subject: [PATCH 081/123] LoongArch: The symbol got type can only be obtained
after initialization
When scanning relocations and determining whether TLS type transition is
possible, it will try to obtain the symbol got type. If the symbol got
type record has not yet been allocated space and initialized, it will
cause ld to crash. So when uninitialized, the symbol is set to GOT_UNKNOWN.
---
bfd/elfnn-loongarch.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 70ef28f3..0a7caa2a 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -683,7 +683,14 @@ loongarch_can_trans_tls (bfd *input_bfd,
if (! IS_LOONGARCH_TLS_TRANS_RELOC (r_type))
return false;
- symbol_tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
+ /* Obtaining tls got type here may occur before
+ loongarch_elf_record_tls_and_got_reference, so it is necessary
+ to ensure that tls got type has been initialized, otherwise it
+ is set to GOT_UNKNOWN. */
+ symbol_tls_type = GOT_UNKNOWN;
+ if (_bfd_loongarch_elf_local_got_tls_type (input_bfd) || h)
+ symbol_tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
+
reloc_got_type = loongarch_reloc_got_type (r_type);
if (symbol_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
--
2.33.0

View File

@ -0,0 +1,43 @@
From 6f1158c052786ad574d6fdb34db4e1e5ddf90309 Mon Sep 17 00:00:00 2001
From: Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
Date: Thu, 28 Dec 2023 23:58:01 +0900
Subject: [PATCH 046/123] LoongArch: Use tab to indent assembly in TLSDESC test
suite
The usual convention is to use tabs. Not all test are following this,
but at least when using tabs, let's use it consistently throughout the
file.
---
gas/testsuite/gas/loongarch/tlsdesc_32.s | 2 +-
gas/testsuite/gas/loongarch/tlsdesc_64.s | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_32.s b/gas/testsuite/gas/loongarch/tlsdesc_32.s
index ef6aee94..2a139c04 100644
--- a/gas/testsuite/gas/loongarch/tlsdesc_32.s
+++ b/gas/testsuite/gas/loongarch/tlsdesc_32.s
@@ -4,7 +4,7 @@
# R_LARCH_TLS_DESC_PC_LO12 var
addi.w $a0,$a0,%desc_pc_lo12(var)
# R_LARCH_TLS_DESC_LD var
- ld.w $ra,$a0,%desc_ld(var)
+ ld.w $ra,$a0,%desc_ld(var)
# R_LARCH_TLS_DESC_CALL var
jirl $ra,$ra,%desc_call(var)
diff --git a/gas/testsuite/gas/loongarch/tlsdesc_64.s b/gas/testsuite/gas/loongarch/tlsdesc_64.s
index 9d0ccb17..9850940e 100644
--- a/gas/testsuite/gas/loongarch/tlsdesc_64.s
+++ b/gas/testsuite/gas/loongarch/tlsdesc_64.s
@@ -4,7 +4,7 @@
# R_LARCH_TLS_DESC_PC_LO12 var
addi.d $a0,$a0,%desc_pc_lo12(var)
# R_LARCH_TLS_DESC_LD var
- ld.d $ra,$a0,%desc_ld(var)
+ ld.d $ra,$a0,%desc_ld(var)
# R_LARCH_TLS_DESC_CALL var
jirl $ra,$ra,%desc_call(var)
--
2.33.0

View File

@ -0,0 +1,207 @@
From fdb688f870f5d9078de4fe77a7d3fbed57df5b07 Mon Sep 17 00:00:00 2001
From: Lulu Cai <cailulu@loongson.cn>
Date: Tue, 21 May 2024 10:14:27 +0800
Subject: [PATCH 091/123] LoongArch: add .option directive
In some cases we may want to use different options only for certain
assembly, so the .option directive is added to control the assembler
options.
.option can accept 4 parameters:
push
pop
Pushes or pops the current option stack. They limit the scope of
option changes so that they do not affect other parts of the assembly
file.
relax
norelax
Enables or disables relaxation.
---
gas/config/tc-loongarch.c | 59 +++++++++++++++++++
gas/testsuite/gas/loongarch/loongarch.exp | 1 +
.../gas/loongarch/pseudo_op_option.d | 36 +++++++++++
.../gas/loongarch/pseudo_op_option.s | 19 ++++++
.../gas/loongarch/pseudo_op_option_fail.l | 2 +
.../gas/loongarch/pseudo_op_option_fail.s | 2 +
6 files changed, 119 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/pseudo_op_option.d
create mode 100644 gas/testsuite/gas/loongarch/pseudo_op_option.s
create mode 100644 gas/testsuite/gas/loongarch/pseudo_op_option_fail.l
create mode 100644 gas/testsuite/gas/loongarch/pseudo_op_option_fail.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index f039d027..72815233 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -541,6 +541,64 @@ s_dtprel (int bytes)
demand_empty_rest_of_line ();
}
+struct LARCH_option_stack
+{
+ struct LARCH_option_stack *next;
+ struct loongarch_ASEs_option options;
+};
+
+static struct LARCH_option_stack *LARCH_opts_stack = NULL;
+
+/* Handle the .option pseudo-op.
+ The alignment of .align is done by R_LARCH_ALIGN at link time.
+ If the .align directive is within the range controlled by
+ .option norelax, that is, relax is turned off, R_LARCH_ALIGN
+ cannot be generated, which may cause ld to be unable to handle
+ the alignment. */
+static void
+s_loongarch_option (int x ATTRIBUTE_UNUSED)
+{
+ char *name = input_line_pointer, ch;
+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
+ ++input_line_pointer;
+ ch = *input_line_pointer;
+ *input_line_pointer = '\0';
+
+ if (strcmp (name, "relax") == 0)
+ LARCH_opts.relax = 1;
+ else if (strcmp (name, "norelax") == 0)
+ LARCH_opts.relax = 0;
+ else if (strcmp (name, "push") == 0)
+ {
+ struct LARCH_option_stack *s;
+
+ s = XNEW (struct LARCH_option_stack);
+ s->next = LARCH_opts_stack;
+ s->options = LARCH_opts;
+ LARCH_opts_stack = s;
+ }
+ else if (strcmp (name, "pop") == 0)
+ {
+ struct LARCH_option_stack *s;
+
+ s = LARCH_opts_stack;
+ if (s == NULL)
+ as_bad (_(".option pop with no .option push"));
+ else
+ {
+ LARCH_opts_stack = s->next;
+ LARCH_opts = s->options;
+ free (s);
+ }
+ }
+ else
+ {
+ as_warn (_("unrecognized .option directive: %s"), name);
+ }
+ *input_line_pointer = ch;
+ demand_empty_rest_of_line ();
+}
+
static const pseudo_typeS loongarch_pseudo_table[] =
{
{ "dword", cons, 8 },
@@ -548,6 +606,7 @@ static const pseudo_typeS loongarch_pseudo_table[] =
{ "half", cons, 2 },
{ "dtprelword", s_dtprel, 4 },
{ "dtpreldword", s_dtprel, 8 },
+ { "option", s_loongarch_option, 0},
{ NULL, NULL, 0 },
};
diff --git a/gas/testsuite/gas/loongarch/loongarch.exp b/gas/testsuite/gas/loongarch/loongarch.exp
index a2ccfb13..157797c5 100644
--- a/gas/testsuite/gas/loongarch/loongarch.exp
+++ b/gas/testsuite/gas/loongarch/loongarch.exp
@@ -35,5 +35,6 @@ if [istarget loongarch*-*-*] {
if [istarget loongarch64-*-*] {
run_list_test "illegal-operand"
+ run_list_test "pseudo_op_option_fail"
}
}
diff --git a/gas/testsuite/gas/loongarch/pseudo_op_option.d b/gas/testsuite/gas/loongarch/pseudo_op_option.d
new file mode 100644
index 00000000..53921a1e
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/pseudo_op_option.d
@@ -0,0 +1,36 @@
+#as: -mrelax
+#objdump: -dr
+#skip: loongarch32-*-*
+
+.*: file format .*
+
+
+Disassembly of section .text:
+
+0.* <.text>:
+ 0: 1a000004 pcalau12i \$a0, 0
+ 0: R_LARCH_PCALA_HI20 x
+ 0: R_LARCH_RELAX \*ABS\*
+ 4: 02c00084 addi.d \$a0, \$a0, 0
+ 4: R_LARCH_PCALA_LO12 x
+ 4: R_LARCH_RELAX \*ABS\*
+ 8: 1a000004 pcalau12i \$a0, 0
+ 8: R_LARCH_PCALA_HI20 x
+ c: 02c00084 addi.d \$a0, \$a0, 0
+ c: R_LARCH_PCALA_LO12 x
+ 10: 1a000004 pcalau12i \$a0, 0
+ 10: R_LARCH_PCALA_HI20 x
+ 10: R_LARCH_RELAX \*ABS\*
+ 14: 02c00084 addi.d \$a0, \$a0, 0
+ 14: R_LARCH_PCALA_LO12 x
+ 14: R_LARCH_RELAX \*ABS\*
+ 18: 1a000004 pcalau12i \$a0, 0
+ 18: R_LARCH_PCALA_HI20 x
+ 1c: 02c00084 addi.d \$a0, \$a0, 0
+ 1c: R_LARCH_PCALA_LO12 x
+ 20: 1a000004 pcalau12i \$a0, 0
+ 20: R_LARCH_PCALA_HI20 x
+ 20: R_LARCH_RELAX \*ABS\*
+ 24: 02c00084 addi.d \$a0, \$a0, 0
+ 24: R_LARCH_PCALA_LO12 x
+ 24: R_LARCH_RELAX \*ABS\*
diff --git a/gas/testsuite/gas/loongarch/pseudo_op_option.s b/gas/testsuite/gas/loongarch/pseudo_op_option.s
new file mode 100644
index 00000000..f21b7263
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/pseudo_op_option.s
@@ -0,0 +1,19 @@
+# Gas enables relax by default.
+# Push and pop can be nested, and each pop restores the options before
+# the most recent push.
+ .text
+.L1:
+ la.pcrel $a0,x
+
+ .option push
+ .option norelax
+ la.pcrel $a0,x
+
+ .option push
+ .option relax
+ la.pcrel $a0,x
+ .option pop
+
+ la.pcrel $a0,x
+ .option pop
+ la.pcrel $a0,x
diff --git a/gas/testsuite/gas/loongarch/pseudo_op_option_fail.l b/gas/testsuite/gas/loongarch/pseudo_op_option_fail.l
new file mode 100644
index 00000000..ffb9a72e
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/pseudo_op_option_fail.l
@@ -0,0 +1,2 @@
+.*: Assembler messages:
+.*: Error: \.option pop with no \.option push
diff --git a/gas/testsuite/gas/loongarch/pseudo_op_option_fail.s b/gas/testsuite/gas/loongarch/pseudo_op_option_fail.s
new file mode 100644
index 00000000..e368cdba
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/pseudo_op_option_fail.s
@@ -0,0 +1,2 @@
+ .text
+ .option pop
--
2.33.0

View File

@ -0,0 +1,345 @@
From 7bba42c3fe6dd98cf8f08fc13fcc246f4c7aee90 Mon Sep 17 00:00:00 2001
From: changjiachen <changjiachen@stu.xupt.edu.cn>
Date: Thu, 28 Dec 2023 20:07:54 +0800
Subject: [PATCH 031/123] LoongArch: bfd: Add support for tls le relax.
Add tls le relax support and related relocs in bfd.
New relocation related explanation can refer to the following url:
https://github.com/loongson/la-abi-specs/blob/release/laelf.adoc
This support does two main things:
1. Implement support for three new relocation items in bfd.
The three new relocation items are shown below:
R_LARCH_TLS_LE_ADD_R
R_LARCH_TLS_LE_HI20_R
R_LARCH_TLS_LE_LO12_R
2. ADD a new macro RELOCATE_TLS_TP32_HI20
Handle problems caused by symbol extensions in TLS LE, The processing
is similar to the macro RELOCATE_CALC_PC32_HI20 method.
3. Implement the tls le relax function.
bfd/ChangeLog:
* bfd-in2.h: Add relocs related to tls le relax.
* elfnn-loongarch.c:
(loongarch_relax_tls_le): New function.
(RELOCATE_TLS_TP32_HI20): New macro.
(loongarch_elf_check_relocs): Add new reloc support.
(perform_relocation): Likewise.
(loongarch_elf_relocate_section): Handle new relocs related to relax.
(loongarch_elf_relax_section): Likewise.
* elfxx-loongarch.c:
(LOONGARCH_HOWTO (R_LARCH_TLS_LE_ADD_R)): New reloc how to type.
(LOONGARCH_HOWTO (R_LARCH_TLS_LE_HI20_R)): Likewise.
(LOONGARCH_HOWTO (R_LARCH_TLS_LE_LO12_R)): Likewise.
* libbfd.h: Add relocs related to tls le relax.
* reloc.c: Likewise.
---
bfd/bfd-in2.h | 4 ++
bfd/elfnn-loongarch.c | 105 ++++++++++++++++++++++++++++++++++++++++++
bfd/elfxx-loongarch.c | 55 ++++++++++++++++++++--
bfd/libbfd.h | 3 ++
bfd/reloc.c | 7 +++
5 files changed, 169 insertions(+), 5 deletions(-)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index d7b762d4..4e7ad048 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7356,11 +7356,15 @@ assembler and not (currently) written to any object files. */
BFD_RELOC_LARCH_TLS_DESC64_HI12,
BFD_RELOC_LARCH_TLS_DESC_LD,
BFD_RELOC_LARCH_TLS_DESC_CALL,
+ BFD_RELOC_LARCH_TLS_LE_HI20_R,
+ BFD_RELOC_LARCH_TLS_LE_ADD_R,
+ BFD_RELOC_LARCH_TLS_LE_LO12_R,
BFD_RELOC_LARCH_TLS_LD_PCREL20_S2,
BFD_RELOC_LARCH_TLS_GD_PCREL20_S2,
BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2,
BFD_RELOC_UNUSED
};
+
typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
reloc_howto_type *bfd_reloc_type_lookup
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index d46bcd77..f7eb66da 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -858,6 +858,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
break;
case R_LARCH_TLS_LE_HI20:
+ case R_LARCH_TLS_LE_HI20_R:
case R_LARCH_SOP_PUSH_TLS_TPREL:
if (!bfd_link_executable (info))
return false;
@@ -2261,6 +2262,8 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
case R_LARCH_GOT64_HI12:
case R_LARCH_TLS_LE_HI20:
case R_LARCH_TLS_LE_LO12:
+ case R_LARCH_TLS_LE_HI20_R:
+ case R_LARCH_TLS_LE_LO12_R:
case R_LARCH_TLS_LE64_LO20:
case R_LARCH_TLS_LE64_HI12:
case R_LARCH_TLS_IE_PC_HI20:
@@ -2303,6 +2306,7 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
break;
case R_LARCH_RELAX:
+ case R_LARCH_TLS_LE_ADD_R:
break;
default:
@@ -2483,6 +2487,16 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
relocation += 0x1000; \
})
+/* Handle problems caused by symbol extensions in TLS LE, The processing
+ is similar to the macro RELOCATE_CALC_PC32_HI20 method. */
+#define RELOCATE_TLS_TP32_HI20(relocation) \
+ ({ \
+ bfd_vma __lo = (relocation) & ((bfd_vma)0xfff); \
+ if (__lo > 0x7ff) \
+ relocation += 0x800; \
+ relocation = relocation & ~(bfd_vma)0xfff; \
+ })
+
/* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
= 0x712347ffff000
@@ -3474,6 +3488,13 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
break;
+ case R_LARCH_TLS_LE_HI20_R:
+ relocation -= elf_hash_table (info)->tls_sec->vma;
+
+ RELOCATE_TLS_TP32_HI20 (relocation);
+
+ break;
+
case R_LARCH_PCALA_LO12:
/* Not support if sym_addr in 2k page edge.
pcalau12i pc_hi20 (sym_addr)
@@ -3644,6 +3665,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_LARCH_TLS_LE_HI20:
case R_LARCH_TLS_LE_LO12:
+ case R_LARCH_TLS_LE_LO12_R:
case R_LARCH_TLS_LE64_LO20:
case R_LARCH_TLS_LE64_HI12:
BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
@@ -4082,6 +4104,82 @@ loongarch_relax_delete_bytes (bfd *abfd,
return true;
}
+/* Relax tls le, mainly relax the process of getting TLS le symbolic addresses.
+ there are three situations in which an assembly instruction sequence needs to
+ be relaxed:
+ symbol address = tp + offset (symbol),offset (symbol) = le_hi20_r + le_lo12_r
+
+ Case 1:
+ in this case, the rd register in the st.{w/d} instruction does not store the
+ full tls symbolic address, but tp + le_hi20_r, which is a part of the tls
+ symbolic address, and then obtains the rd + le_lo12_r address through the
+ st.w instruction feature.
+ this is the full tls symbolic address (tp + le_hi20_r + le_lo12_r).
+
+ before relax: after relax:
+
+ lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
+ add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
+ st.{w/d} $rs,$rd,%le_lo12_r (sym) ==> st.{w/d} $rs,$tp,%le_lo12_r (sym)
+
+ Case 2:
+ in this case, ld.{w/d} is similar to st.{w/d} in case1.
+
+ before relax: after relax:
+
+ lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
+ add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
+ ld.{w/d} $rs,$rd,%le_lo12_r (sym) ==> ld.{w/d} $rs,$tp,%le_lo12_r (sym)
+
+ Case 3:
+ in this case,the rs register in addi.{w/d} stores the full address of the tls
+ symbol (tp + le_hi20_r + le_lo12_r).
+
+ before relax: after relax:
+
+ lu12i.w $rd,%le_hi20_r (sym) ==> (instruction deleted)
+ add.{w/d} $rd,$rd,$tp,%le_add_r (sym) ==> (instruction deleted)
+ addi.{w/d} $rs,$rd,%le_lo12_r (sym) ==> addi.{w/d} $rs,$tp,%le_lo12_r (sym)
+*/
+static bool
+loongarch_relax_tls_le (bfd *abfd, asection *sec,
+ Elf_Internal_Rela *rel,
+ struct bfd_link_info *link_info,
+ bfd_vma symval)
+{
+ bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
+ uint32_t insn = bfd_get (32, abfd, contents + rel->r_offset);
+ static uint32_t insn_rj,insn_rd;
+ symval = symval - elf_hash_table (link_info)->tls_sec->vma;
+ /* Whether the symbol offset is in the interval (offset < 0x800). */
+ if (ELFNN_R_TYPE ((rel + 1)->r_info == R_LARCH_RELAX) && (symval < 0x800))
+ {
+ switch (ELFNN_R_TYPE (rel->r_info))
+ {
+ case R_LARCH_TLS_LE_HI20_R:
+ case R_LARCH_TLS_LE_ADD_R:
+ /* delete insn. */
+ rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
+ loongarch_relax_delete_bytes (abfd, sec, rel->r_offset, 4, link_info);
+ break;
+ case R_LARCH_TLS_LE_LO12_R:
+ /* Change rj to $tp. */
+ insn_rj = 0x2 << 5;
+ /* Get rd register. */
+ insn_rd = insn & 0x1f;
+ /* Write symbol offset. */
+ symval <<= 10;
+ /* Writes the modified instruction. */
+ insn = insn & 0xffc00000;
+ insn = insn | symval | insn_rj | insn_rd;
+ bfd_put (32, abfd, insn, contents + rel->r_offset);
+ break;
+ default:
+ break;
+ }
+ }
+ return true;
+}
/* Relax pcalau12i,addi.d => pcaddi. */
static bool
@@ -4511,6 +4609,13 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
rel->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
}
break;
+ case R_LARCH_TLS_LE_HI20_R:
+ case R_LARCH_TLS_LE_LO12_R:
+ case R_LARCH_TLS_LE_ADD_R:
+ if (0 == info->relax_pass && (i + 2) <= sec->reloc_count)
+ loongarch_relax_tls_le (abfd, sec, rel, info, symval);
+ break;
+
case R_LARCH_PCALA_HI20:
if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
loongarch_relax_pcala_addi (abfd, sec, sym_sec, rel, symval,
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 4fe8cbff..2c40fb02 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -1776,9 +1776,56 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
NULL, /* adjust_reloc_bits. */
"desc_call"), /* larch_reloc_type_name. */
- LOONGARCH_EMPTY_HOWTO (121),
- LOONGARCH_EMPTY_HOWTO (122),
- LOONGARCH_EMPTY_HOWTO (123),
+ LOONGARCH_HOWTO (R_LARCH_TLS_LE_HI20_R, /* type (121). */
+ 12, /* rightshift. */
+ 4, /* size. */
+ 20, /* bitsize. */
+ false, /* pc_relative. */
+ 5, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_LE_HI20_R", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x1ffffe0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_LE_HI20_R, /* bfd_reloc_code_real_type. */
+ reloc_bits, /* adjust_reloc_bits. */
+ "le_hi20_r"), /* larch_reloc_type_name. */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_LE_ADD_R, /* type (122). */
+ 0, /* rightshift. */
+ 0, /* size. */
+ 0, /* bitsize. */
+ false, /* pc_relative. */
+ 0, /* bitpos. */
+ complain_overflow_dont, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_LE_ADD_R", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_LE_ADD_R, /* bfd_reloc_code_real_type. */
+ NULL, /* adjust_reloc_bits. */
+ "le_add_r"), /* larch_reloc_type_name. */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_LE_LO12_R, /* type (123). */
+ 0, /* rightshift. */
+ 4, /* size. */
+ 12, /* bitsize. */
+ false, /* pc_relative. */
+ 10, /* bitpos. */
+ complain_overflow_signed, /* complain_on_overflow. */
+ bfd_elf_generic_reloc, /* special_function. */
+ "R_LARCH_TLS_LE_LO12_R", /* name. */
+ false, /* partial_inplace. */
+ 0, /* src_mask. */
+ 0x3ffc00, /* dst_mask. */
+ false, /* pcrel_offset. */
+ BFD_RELOC_LARCH_TLS_LE_LO12_R, /* bfd_reloc_code_real_type. */
+ reloc_bits, /* adjust_reloc_bits. */
+ "le_lo12_r"), /* larch_reloc_type_name. */
/* For pcaddi, ld_pc_hi20 + ld_pc_lo12 can relax to ld_pcrel20_s2. */
LOONGARCH_HOWTO (R_LARCH_TLS_LD_PCREL20_S2, /* type (124). */
@@ -1870,9 +1917,7 @@ reloc_howto_type *
loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
bfd_reloc_code_real_type code)
{
- /*
BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count);
- */
/* Fast search for new reloc types. */
if (BFD_RELOC_LARCH_B16 <= code && code < BFD_RELOC_LARCH_RELAX)
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index b5af327f..617d5239 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3538,6 +3538,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_LARCH_TLS_DESC64_HI12",
"BFD_RELOC_LARCH_TLS_DESC_LD",
"BFD_RELOC_LARCH_TLS_DESC_CALL",
+ "BFD_RELOC_LARCH_TLS_LE_HI20_R",
+ "BFD_RELOC_LARCH_TLS_LE_ADD_R",
+ "BFD_RELOC_LARCH_TLS_LE_LO12_R",
"BFD_RELOC_LARCH_TLS_LD_PCREL20_S2",
"BFD_RELOC_LARCH_TLS_GD_PCREL20_S2",
"BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 4782f0f6..bb45027c 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -8188,6 +8188,13 @@ ENUMX
ENUMX
BFD_RELOC_LARCH_TLS_DESC_CALL
+ENUMX
+ BFD_RELOC_LARCH_TLS_LE_HI20_R
+ENUMX
+ BFD_RELOC_LARCH_TLS_LE_ADD_R
+ENUMX
+ BFD_RELOC_LARCH_TLS_LE_LO12_R
+
ENUMX
BFD_RELOC_LARCH_TLS_LD_PCREL20_S2
ENUMX
--
2.33.0

View File

@ -0,0 +1,26 @@
From af43295f92b7f2c85f9613481eb92efcd348f5be Mon Sep 17 00:00:00 2001
From: Jinyang He <hejinyang@loongson.cn>
Date: Tue, 5 Sep 2023 10:31:27 +0800
Subject: [PATCH 057/123] LoongArch: bfd: Correct the name of
R_LARCH_SOP_POP_32_U in howto_table
---
bfd/elfxx-loongarch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 2c40fb02..fe38f369 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -548,7 +548,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
0, /* bitpos. */
complain_overflow_unsigned, /* complain_on_overflow. */
bfd_elf_generic_reloc, /* special_function. */
- "R_LARCH_SOP_POP_32_S_U", /* name. */
+ "R_LARCH_SOP_POP_32_U", /* name. */
false, /* partial_inplace. */
0xffffffff00000000, /* src_mask */
0x00000000ffffffff, /* dst_mask */
--
2.33.0

View File

@ -0,0 +1,52 @@
From 4945a32e162be2a7001ed8e8066e983d0ae41bf4 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Thu, 22 Feb 2024 20:18:25 +0800
Subject: [PATCH 058/123] LoongArch: bfd: Fix some bugs of howto table
R_LARCH_IRELATIVE: For dynamic relocation that does not distinguish between
32/64 bits, size and bitsize set to 8 and 64.
R_LARCH_TLS_DESC64: Change size to 8.
R_LARCH_SOP_POP_32_S_0_5_10_16_S2: Change src_mask to 0, dst_mask to
0x03fffc1f.
---
bfd/elfxx-loongarch.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index fe38f369..127f3548 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -278,8 +278,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
LOONGARCH_HOWTO (R_LARCH_IRELATIVE, /* type (12). */
0, /* rightshift */
- 4, /* size */
- 32, /* bitsize */
+ 8, /* size */
+ 64, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
complain_overflow_dont, /* complain_on_overflow */
@@ -312,7 +312,7 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
LOONGARCH_HOWTO (R_LARCH_TLS_DESC64, /* type (14). */
0, /* rightshift. */
- 4, /* size. */
+ 8, /* size. */
64, /* bitsize. */
false, /* pc_relative. */
0, /* bitpos. */
@@ -514,8 +514,8 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
bfd_elf_generic_reloc, /* special_function. */
"R_LARCH_SOP_POP_32_S_0_5_10_16_S2", /* name. */
false, /* partial_inplace. */
- 0xfc0003e0, /* src_mask */
- 0xfc0003e0, /* dst_mask */
+ 0x0, /* src_mask */
+ 0x03fffc1f, /* dst_mask */
false, /* pcrel_offset */
BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2,
/* bfd_reloc_code_real_type */
--
2.33.0

View File

@ -0,0 +1,98 @@
From 0f44b5db22c6059f8b8742e08eca9ae282973c7a Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Thu, 25 Jan 2024 14:44:12 +0800
Subject: [PATCH 053/123] LoongArch: gas: Add support for s9 register
In LoongArch ABI, r22 register can be used as frame pointer or
static register(s9).
Link: https://github.com/loongson/la-abi-specs/blob/release/lapcs.adoc#general-purpose-registers
---
gas/config/tc-loongarch.c | 7 +++++--
gas/testsuite/gas/loongarch/loongarch.exp | 1 +
gas/testsuite/gas/loongarch/reg-s9.l | 1 +
gas/testsuite/gas/loongarch/reg-s9.s | 2 ++
include/opcode/loongarch.h | 1 +
opcodes/loongarch-opc.c | 9 +++++++++
6 files changed, 19 insertions(+), 2 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/reg-s9.l
create mode 100644 gas/testsuite/gas/loongarch/reg-s9.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 5b7f5137..0495f63a 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -316,8 +316,11 @@ loongarch_after_parse_args ()
/* Init ilp32/lp64 registers alias. */
r_abi_names = loongarch_r_alias;
for (i = 0; i < ARRAY_SIZE (loongarch_r_alias); i++)
- str_hash_insert (r_htab, loongarch_r_alias[i], (void *) (i + 1),
- 0);
+ str_hash_insert (r_htab, loongarch_r_alias[i], (void *) (i + 1), 0);
+
+ for (i = 0; i < ARRAY_SIZE (loongarch_r_alias_1); i++)
+ str_hash_insert (r_htab, loongarch_r_alias_1[i], (void *) (i + 1), 0);
+
for (i = 0; i < ARRAY_SIZE (loongarch_r_alias_deprecated); i++)
str_hash_insert (r_deprecated_htab, loongarch_r_alias_deprecated[i],
(void *) (i + 1), 0);
diff --git a/gas/testsuite/gas/loongarch/loongarch.exp b/gas/testsuite/gas/loongarch/loongarch.exp
index fedeeecb..1051a541 100644
--- a/gas/testsuite/gas/loongarch/loongarch.exp
+++ b/gas/testsuite/gas/loongarch/loongarch.exp
@@ -31,4 +31,5 @@ if [istarget loongarch*-*-*] {
}
run_list_test "align"
+ run_list_test "reg-s9"
}
diff --git a/gas/testsuite/gas/loongarch/reg-s9.l b/gas/testsuite/gas/loongarch/reg-s9.l
new file mode 100644
index 00000000..8ea739b7
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/reg-s9.l
@@ -0,0 +1 @@
+# No warning or error expected.
diff --git a/gas/testsuite/gas/loongarch/reg-s9.s b/gas/testsuite/gas/loongarch/reg-s9.s
new file mode 100644
index 00000000..74f40481
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/reg-s9.s
@@ -0,0 +1,2 @@
+# Add support for $s9 register
+addi.d $t0, $s9, 0
diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
index 32ff4d8a..5fc6e190 100644
--- a/include/opcode/loongarch.h
+++ b/include/opcode/loongarch.h
@@ -196,6 +196,7 @@ dec2 : [1-9][0-9]?
extern const char *const loongarch_r_normal_name[32];
extern const char *const loongarch_r_alias[32];
+ extern const char *const loongarch_r_alias_1[32];
extern const char *const loongarch_r_alias_deprecated[32];
extern const char *const loongarch_f_normal_name[32];
extern const char *const loongarch_f_alias[32];
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index cc3d1986..6afc0e8a 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -49,6 +49,15 @@ const char *const loongarch_r_alias[32] =
"$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7", "$s8",
};
+/* Add support for $s9. */
+const char *const loongarch_r_alias_1[32] =
+{
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "", "",
+ "", "", "", "", "", "", "$s9", "",
+ "", "", "", "", "", "", "", "",
+};
+
const char *const loongarch_r_alias_deprecated[32] =
{
"", "", "", "", "$v0", "$v1", "", "", "", "", "", "", "", "", "", "",
--
2.33.0

View File

@ -0,0 +1,166 @@
From d839b6eeb36c9d033038854e08cc8e10b34968ba Mon Sep 17 00:00:00 2001
From: changjiachen <changjiachen@stu.xupt.edu.cn>
Date: Thu, 28 Dec 2023 19:59:39 +0800
Subject: [PATCH 034/123] LoongArch: gas: Add support for tls le relax.
Add tls le relax related relocs support and testsuites in gas.
The main test is three new relocation items,
R_LARCH_TLS_LE_ADD_R, R_LARCH_TLS_LE_HI20_R,
R_LARCH_TLS_LE_LO12_R can be generated properly
and tls le insn format check.
gas/ChangeLog:
* config/tc-loongarch.c:
(loongarch_args_parser_can_match_arg_helper): Add support for relax.
* gas/testsuite/gas/loongarch/reloc.d: Likewise.
* gas/testsuite/gas/loongarch/reloc.s: Likewise.
* gas/testsuite/gas/loongarch/loongarch.exp: Likewise.
* gas/testsuite/gas/loongarch/tls_le_insn_format_check.s: New test.
---
gas/config/tc-loongarch.c | 32 +++++++++++++++++++
gas/testsuite/gas/loongarch/loongarch.exp | 9 ++++++
gas/testsuite/gas/loongarch/reloc.d | 18 +++++++++++
gas/testsuite/gas/loongarch/reloc.s | 11 +++++++
.../gas/loongarch/tls_le_insn_format_check.s | 15 +++++++++
5 files changed, 85 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/tls_le_insn_format_check.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index def26daf..fad18fcd 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -636,6 +636,30 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
break;
}
break;
+ /* This is used for TLS, where the fourth operand is %le_add_r,
+ to get a relocation applied to an add instruction, for relaxation to use.
+ Two conditions, ip->match_now and reloc_num, are used to check tls insn
+ to prevent cases like add.d $a0,$a0,$a0,8. */
+ case 't':
+ ip->match_now = loongarch_parse_expr (arg, ip->reloc_info + ip->reloc_num,
+ reloc_num_we_have, &reloc_num, &imm) == 0;
+
+ if (!ip->match_now)
+ break;
+
+ bfd_reloc_code_real_type tls_reloc_type = BFD_RELOC_LARCH_TLS_LE_ADD_R;
+
+ if (reloc_num
+ && (ip->reloc_info[ip->reloc_num].type == tls_reloc_type))
+ {
+ ip->reloc_num += reloc_num;
+ ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
+ ip->reloc_info[ip->reloc_num].value = const_0;
+ ip->reloc_num++;
+ }
+ else
+ ip->match_now = 0;
+ break;
case 's':
case 'u':
ip->match_now =
@@ -690,6 +714,14 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
ip->reloc_num += reloc_num;
reloc_type = ip->reloc_info[0].type;
+ if (LARCH_opts.relax
+ && (BFD_RELOC_LARCH_TLS_LE_HI20_R == reloc_type
+ || BFD_RELOC_LARCH_TLS_LE_LO12_R == reloc_type))
+ {
+ ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
+ ip->reloc_info[ip->reloc_num].value = const_0;
+ ip->reloc_num++;
+ }
if (LARCH_opts.relax && ip->macro_id
&& (BFD_RELOC_LARCH_PCALA_HI20 == reloc_type
|| BFD_RELOC_LARCH_PCALA_LO12 == reloc_type
diff --git a/gas/testsuite/gas/loongarch/loongarch.exp b/gas/testsuite/gas/loongarch/loongarch.exp
index 6d126fd4..c0aa593d 100644
--- a/gas/testsuite/gas/loongarch/loongarch.exp
+++ b/gas/testsuite/gas/loongarch/loongarch.exp
@@ -21,4 +21,13 @@
if [istarget loongarch*-*-*] {
run_dump_tests [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
gas_test_old bfd_reloc_8.s "" "bfd_reloc_8"
+ if [file exist "tls_le_insn_format_check.s "] {
+ set format [run_host_cmd "as" "tls_le_insn_format_check.s"]
+ if { [ regexp ".*no match insn.*" $format] } {
+ pass "loongarch tls le insn format pass"
+ } {
+ pass "loongarch tls le insn format fail"
+ }
+ }
+
}
diff --git a/gas/testsuite/gas/loongarch/reloc.d b/gas/testsuite/gas/loongarch/reloc.d
index c3820c55..0458830f 100644
--- a/gas/testsuite/gas/loongarch/reloc.d
+++ b/gas/testsuite/gas/loongarch/reloc.d
@@ -165,3 +165,21 @@ Disassembly of section .text:
[ ]+134:[ ]+R_LARCH_TLS_LE64_LO20[ ]+TLSL1\+0x8
[ ]+138:[ ]+03000085[ ]+lu52i.d[ ]+\$a1,[ ]+\$a0,[ ]+0
[ ]+138:[ ]+R_LARCH_TLS_LE64_HI12[ ]+TLSL1\+0x8
+[ ]+13c:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0
+[ ]+13c:[ ]+R_LARCH_TLS_LE_HI20_R[ ]+TLSL1
+[ ]+13c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+140:[ ]+001090a5[ ]+add.d[ ]+\$a1,[ ]+\$a1,[ ]+\$a0
+[ ]+140:[ ]+R_LARCH_TLS_LE_ADD_R[ ]+TLSL1
+[ ]+140:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+144:[ ]+29800085[ ]+st.w[ ]+\$a1,[ ]+\$a0,[ ]+0
+[ ]+144:[ ]+R_LARCH_TLS_LE_LO12_R[ ]+TLSL1
+[ ]+144:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+148:[ ]+14000004[ ]+lu12i.w[ ]+\$a0,[ ]+0
+[ ]+148:[ ]+R_LARCH_TLS_LE_HI20_R[ ]+TLSL1\+0x8
+[ ]+148:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+14c:[ ]+001090a5[ ]+add.d[ ]+\$a1,[ ]+\$a1,[ ]+\$a0
+[ ]+14c:[ ]+R_LARCH_TLS_LE_ADD_R[ ]+TLSL1\+0x8
+[ ]+14c:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+150:[ ]+29800085[ ]+st.w[ ]+\$a1,[ ]+\$a0,[ ]+0
+[ ]+150:[ ]+R_LARCH_TLS_LE_LO12_R[ ]+TLSL1\+0x8
+[ ]+150:[ ]+R_LARCH_RELAX[ ]+\*ABS\*
diff --git a/gas/testsuite/gas/loongarch/reloc.s b/gas/testsuite/gas/loongarch/reloc.s
index a67fecd9..0a343c11 100644
--- a/gas/testsuite/gas/loongarch/reloc.s
+++ b/gas/testsuite/gas/loongarch/reloc.s
@@ -142,3 +142,14 @@ lu12i.w $r4,%le_hi20(TLSL1 + 0x8)
ori $r5,$r4,%le_lo12(TLSL1 + 0x8)
lu32i.d $r4,%le64_lo20(TLSL1 + 0x8)
lu52i.d $r5,$r4,%le64_hi12(TLSL1 + 0x8)
+
+
+/* New TLS Insn. */
+lu12i.w $r4,%le_hi20_r(TLSL1)
+add.d $r5,$r5,$r4,%le_add_r(TLSL1)
+st.w $r5,$r4,%le_lo12_r(TLSL1)
+
+/* New TLS Insn with addend. */
+lu12i.w $r4,%le_hi20_r(TLSL1 + 0x8)
+add.d $r5,$r5,$r4,%le_add_r(TLSL1 + 0x8)
+st.w $r5,$r4,%le_lo12_r(TLSL1 + 0x8)
diff --git a/gas/testsuite/gas/loongarch/tls_le_insn_format_check.s b/gas/testsuite/gas/loongarch/tls_le_insn_format_check.s
new file mode 100644
index 00000000..1b3c9d18
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tls_le_insn_format_check.s
@@ -0,0 +1,15 @@
+/* Assemble the following assembly statements using as.
+
+ The test case is mainly to check the format of tls le type
+ symbolic address fetch instruction.Because in tls le symbolic
+ address acquisition, there will be a special add.d instruction,
+ which has four operands (add.d op1,op2,op3,op4),the first three
+ operands are registers, and the last operand is a relocation,
+ we need to format check the fourth operand.If it is not a correct
+ relocation type operand, we need to throw the relevant exception
+ message.
+
+ if a "no match insn" exception is thrown, the test passes;
+ otherwise, the test fails. */
+
+add.d $a0,$a0,$a0,8
--
2.33.0

View File

@ -0,0 +1,49 @@
From 3b3e724f35e119acdbac2c8c6682a11e9cae64e2 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Mon, 29 Apr 2024 15:11:31 +0800
Subject: [PATCH 086/123] LoongArch: gas: Adjust DWARF CIE alignment factors
Set DWARF2_CIE_DATA_ALIGNMENT (data alignment factors) to -8.
It helps to save space.
Data Alignment Factor
A signed LEB128 encoded value that is factored out of all offset
instructions that are associated with this CIE or its FDEs. This value
shall be multiplied by the register offset argument of an offset
instruction to obtain the new offset value.
---
gas/config/tc-loongarch.h | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h
index 0b5cdfe6..6963867e 100644
--- a/gas/config/tc-loongarch.h
+++ b/gas/config/tc-loongarch.h
@@ -99,15 +99,19 @@ extern bool loongarch_frag_align_code (int, int);
#define TC_FORCE_RELOCATION_LOCAL(FIX) 1
-/* Adjust debug_line after relaxation. */
-#define DWARF2_USE_FIXED_ADVANCE_PC 1
-
/* Values passed to md_apply_fix don't include symbol values. */
#define MD_APPLY_SYM_VALUE(FIX) 0
#define TARGET_USE_CFIPOP 1
-#define DWARF2_DEFAULT_RETURN_COLUMN 1 /* $ra. */
-#define DWARF2_CIE_DATA_ALIGNMENT -4
+/* Adjust debug_line after relaxation. */
+#define DWARF2_USE_FIXED_ADVANCE_PC 1
+
+/* FDE Data Alignment Factor.
+ FDE Code Alignment Factor (DWARF2_LINE_MIN_INSN_LENGTH) should be 1
+ because DW_CFA_advance_loc need to be relocated in bytes
+ when linker relaxation. */
+#define DWARF2_CIE_DATA_ALIGNMENT (-8)
+#define DWARF2_DEFAULT_RETURN_COLUMN 1 /* FDE Return Address Register. */
#define tc_cfi_frame_initial_instructions \
loongarch_cfi_frame_initial_instructions
--
2.33.0

View File

@ -0,0 +1,82 @@
From f30bb80d462445ac5557bc65abd4672ce915b9e9 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Sun, 1 Oct 2023 15:29:44 +0800
Subject: [PATCH 050/123] LoongArch: gas: Don't define LoongArch .align
Gcc may generate "\t.align\t%d,54525952,4\n" before commit
b20c7ee066cb7d952fa193972e8bc6362c6e4063. To write 54525952 (NOP) to object
file, we call s_align_ptwo (-4). It result in alignment padding must be a
multiple of 4 if .align has second parameter.
Use default s_align_ptwo for .align.
---
gas/config/tc-loongarch.c | 13 -------------
gas/testsuite/gas/loongarch/align.l | 1 +
gas/testsuite/gas/loongarch/align.s | 5 +++++
gas/testsuite/gas/loongarch/loongarch.exp | 1 +
4 files changed, 7 insertions(+), 13 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/align.l
create mode 100644 gas/testsuite/gas/loongarch/align.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 1ae57b45..49470073 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -436,18 +436,6 @@ loongarch_mach (void)
static const expressionS const_0 = { .X_op = O_constant, .X_add_number = 0 };
-static void
-s_loongarch_align (int arg)
-{
- const char *t = input_line_pointer;
- while (!is_end_of_line[(unsigned char) *t] && *t != ',')
- ++t;
- if (*t == ',')
- s_align_ptwo (arg);
- else
- s_align_ptwo (0);
-}
-
/* Handle the .dtprelword and .dtpreldword pseudo-ops. They generate
a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
use in DWARF debug information. */
@@ -479,7 +467,6 @@ s_dtprel (int bytes)
static const pseudo_typeS loongarch_pseudo_table[] =
{
- { "align", s_loongarch_align, -4 },
{ "dword", cons, 8 },
{ "word", cons, 4 },
{ "half", cons, 2 },
diff --git a/gas/testsuite/gas/loongarch/align.l b/gas/testsuite/gas/loongarch/align.l
new file mode 100644
index 00000000..8ea739b7
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/align.l
@@ -0,0 +1 @@
+# No warning or error expected.
diff --git a/gas/testsuite/gas/loongarch/align.s b/gas/testsuite/gas/loongarch/align.s
new file mode 100644
index 00000000..93f25289
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/align.s
@@ -0,0 +1,5 @@
+# Fix bug: alignment padding must a multiple of 4 if .align has second parameter
+.data
+ .byte 1
+ .align 3, 2
+ .4byte 3
diff --git a/gas/testsuite/gas/loongarch/loongarch.exp b/gas/testsuite/gas/loongarch/loongarch.exp
index c0aa593d..fedeeecb 100644
--- a/gas/testsuite/gas/loongarch/loongarch.exp
+++ b/gas/testsuite/gas/loongarch/loongarch.exp
@@ -30,4 +30,5 @@ if [istarget loongarch*-*-*] {
}
}
+ run_list_test "align"
}
--
2.33.0

View File

@ -0,0 +1,26 @@
From e80e6624e3b5aafd683706f6567e4b748c4c441f Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Fri, 18 Aug 2023 17:02:20 +0800
Subject: [PATCH 005/123] LoongArch: gas: Fix make check-gas crash
---
gas/testsuite/lib/gas-defs.exp | 3 ---
1 file changed, 3 deletions(-)
diff --git a/gas/testsuite/lib/gas-defs.exp b/gas/testsuite/lib/gas-defs.exp
index 3e134ca8..da0c24ea 100644
--- a/gas/testsuite/lib/gas-defs.exp
+++ b/gas/testsuite/lib/gas-defs.exp
@@ -361,9 +361,6 @@ proc verbose_eval { expr { level 1 } } {
# that version gets released, and has been out in the world for a few
# months at least, it may be safe to delete this copy.
-if { [istarget loongarch*-*-*] } {
- rename prune_warnings prune_warnings_other
-}
if ![string length [info proc prune_warnings]] {
#
# prune_warnings -- delete various system verbosities from TEXT.
--
2.33.0

View File

@ -0,0 +1,84 @@
From f0efc301a550708ea07b8dad127d5cb149661d24 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Fri, 2 Feb 2024 21:00:58 +0800
Subject: [PATCH 055/123] LoongArch: gas: Fix the types of symbols referred
with %le_*_r in the symtab
When a symbol is referred with %le_{hi20,lo12,add}_r, it's definitely a
TLS symbol and we should set its type to TLS in the symtab. Otherwise
when building Perl with gcc-14 -flto, we get:
/usr/bin/ld: PL_current_context: TLS definition in
./miniperl.ltrans0.ltrans.o section .tbss mismatches non-TLS reference
in ./miniperl.ltrans1.ltrans.o
A minimal reproducer:
$ cat t1.s
.section .tbss
.globl x
x: .word 0
$ cat t2.s
f:
lu12i.w $a0, %le_hi20_r(x)
add.d $a0, $a0, $tp, %le_add_r(x)
li.w $a1, 1
st.w $a1, $a0, %le_lo12_r(x)
$ gas/as-new t1.s -o t1.o
$ gas/as-new t2.s -o t2.o
$ ld/ld-new t1.o t2.o
ld/ld-new: x: TLS definition in t1.o section .tbss mismatches
non-TLS reference in t2.o
Unfortunately this was undetected before Binutils-2.42 release because
GCC < 14 does not use %le_*_r, and without LTO it's very rare to have a
TLS LE definition and its reference in two different translation units.
So this fix should be backported to Binutils-2.42 branch too.
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
---
gas/config/tc-loongarch.c | 3 +++
gas/testsuite/gas/loongarch/tls_le_r_sym_type.d | 3 +++
gas/testsuite/gas/loongarch/tls_le_r_sym_type.s | 6 ++++++
3 files changed, 12 insertions(+)
create mode 100644 gas/testsuite/gas/loongarch/tls_le_r_sym_type.d
create mode 100644 gas/testsuite/gas/loongarch/tls_le_r_sym_type.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 0495f63a..5e96f624 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -1340,6 +1340,9 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
case BFD_RELOC_LARCH_TLS_DESC_LO12:
case BFD_RELOC_LARCH_TLS_DESC64_LO20:
case BFD_RELOC_LARCH_TLS_DESC64_HI12:
+ case BFD_RELOC_LARCH_TLS_LE_ADD_R:
+ case BFD_RELOC_LARCH_TLS_LE_HI20_R:
+ case BFD_RELOC_LARCH_TLS_LE_LO12_R:
/* Add tls lo (got_lo reloc type). */
if (fixP->fx_addsy == NULL)
as_bad_where (fixP->fx_file, fixP->fx_line,
diff --git a/gas/testsuite/gas/loongarch/tls_le_r_sym_type.d b/gas/testsuite/gas/loongarch/tls_le_r_sym_type.d
new file mode 100644
index 00000000..43bcd789
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tls_le_r_sym_type.d
@@ -0,0 +1,3 @@
+#readelf: -s
+#...
+.*TLS[ \t]+GLOBAL[ \t]+DEFAULT[ \t]+UND[ \t]+x
diff --git a/gas/testsuite/gas/loongarch/tls_le_r_sym_type.s b/gas/testsuite/gas/loongarch/tls_le_r_sym_type.s
new file mode 100644
index 00000000..3ccedae9
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/tls_le_r_sym_type.s
@@ -0,0 +1,6 @@
+f:
+ lu12i.w $a0, %le_hi20_r(x)
+ add.d $a0, $a0, $tp, %le_add_r(x)
+ li.w $a1, 1
+ st.w $a1, $a0, %le_lo12_r(x)
+ ret
--
2.33.0

View File

@ -0,0 +1,308 @@
From adb3d28328bbf2d17c3a44778497827d7d35124a Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Tue, 19 Mar 2024 21:09:12 +0800
Subject: [PATCH 076/123] LoongArch: gas: Ignore .align if it is at the start
of a section
Ignore .align if it is at the start of a section and the alignment
can be divided by the section alignment, the section alignment
can ensure this .align has a correct alignment.
---
gas/config/tc-loongarch.c | 134 ++++++++++++++----
.../gas/loongarch/relax-align-first.d | 12 ++
.../gas/loongarch/relax-align-first.s | 7 +
.../ld-loongarch-elf/relax-align-first.d | 15 ++
.../ld-loongarch-elf/relax-align-first.s | 13 ++
ld/testsuite/ld-loongarch-elf/relax.exp | 1 +
6 files changed, 157 insertions(+), 25 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/relax-align-first.d
create mode 100644 gas/testsuite/gas/loongarch/relax-align-first.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align-first.d
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align-first.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 1e835f51..110b92e4 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -128,6 +128,11 @@ static bool call36 = 0;
#define RELAX_BRANCH_ENCODE(x) \
(BFD_RELOC_LARCH_B16 == (x) ? RELAX_BRANCH_16 : RELAX_BRANCH_21)
+#define ALIGN_MAX_ADDEND(n, max) ((max << 8) | n)
+#define ALIGN_MAX_NOP_BYTES(addend) ((1 << (addend & 0xff)) - 4)
+#define FRAG_AT_START_OF_SECTION(frag) \
+ (0 == frag->fr_address && 0 == frag->fr_fix)
+
enum options
{
OPTION_IGNORE = OPTION_MD_BASE,
@@ -1647,10 +1652,32 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
}
}
+/* Estimate the size of a frag before relaxing. */
+
int
-md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
- asection *segtype ATTRIBUTE_UNUSED)
+md_estimate_size_before_relax (fragS *fragp, asection *sec)
{
+ /* align pseudo instunctions. */
+ if (rs_align_code == fragp->fr_subtype)
+ {
+ offsetT nop_bytes;
+ if (NULL == fragp->fr_symbol)
+ nop_bytes = fragp->fr_offset;
+ else
+ nop_bytes = ALIGN_MAX_NOP_BYTES (fragp->fr_offset);
+
+ /* Normally, nop_bytes should be >= 4. */
+ gas_assert (nop_bytes > 0);
+
+ if (FRAG_AT_START_OF_SECTION (fragp)
+ && 0 == ((1 << sec->alignment_power) % (nop_bytes + 4)))
+ return (fragp->fr_var = 0);
+ else
+ return (fragp->fr_var = nop_bytes);
+ }
+
+ /* branch instructions and other instructions.
+ branch instructions may become 8 bytes after relaxing. */
return (fragp->fr_var = 4);
}
@@ -1767,8 +1794,7 @@ bool
loongarch_frag_align_code (int n, int max)
{
char *nops;
- symbolS *s;
- expressionS ex;
+ symbolS *s = NULL;
bfd_vma insn_alignment = 4;
bfd_vma bytes = (bfd_vma) 1 << n;
@@ -1783,8 +1809,6 @@ loongarch_frag_align_code (int n, int max)
if (!LARCH_opts.relax)
return false;
- nops = frag_more (worst_case_bytes);
-
/* If max <= 0, ignore max.
If max >= worst_case_bytes, max has no effect.
Similar to gas/write.c relax_segment function rs_align_code case:
@@ -1792,20 +1816,20 @@ loongarch_frag_align_code (int n, int max)
if (max > 0 && (bfd_vma) max < worst_case_bytes)
{
s = symbol_find (now_seg->name);
- ex.X_add_symbol = s;
- ex.X_op = O_symbol;
- ex.X_add_number = (max << 8) | n;
- }
- else
- {
- ex.X_op = O_constant;
- ex.X_add_number = worst_case_bytes;
+ worst_case_bytes = ALIGN_MAX_ADDEND (n, max);
}
- loongarch_make_nops (nops, worst_case_bytes);
+ frag_grow (worst_case_bytes);
+ /* Use relaxable frag for .align.
+ If .align at the start of section, do nothing. Section alignment can
+ ensure correct alignment.
+ If .align is not at the start of a section, reserve NOP instructions
+ and R_LARCH_ALIGN relocation. */
+ nops = frag_var (rs_machine_dependent, worst_case_bytes, worst_case_bytes,
+ rs_align_code, s, worst_case_bytes, NULL);
- fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
- &ex, false, BFD_RELOC_LARCH_ALIGN);
+ /* Default write NOP for aligned bytes. */
+ loongarch_make_nops (nops, worst_case_bytes);
/* We need to start a new frag after the alignment which may be removed by
the linker, to prevent the assembler from computing static offsets.
@@ -1963,8 +1987,7 @@ loongarch_relaxed_branch_length (fragS *fragp, asection *sec, int update)
}
int
-loongarch_relax_frag (asection *sec ATTRIBUTE_UNUSED,
- fragS *fragp ATTRIBUTE_UNUSED,
+loongarch_relax_frag (asection *sec, fragS *fragp,
long stretch ATTRIBUTE_UNUSED)
{
if (RELAX_BRANCH (fragp->fr_subtype))
@@ -1973,6 +1996,27 @@ loongarch_relax_frag (asection *sec ATTRIBUTE_UNUSED,
fragp->fr_var = loongarch_relaxed_branch_length (fragp, sec, true);
return fragp->fr_var - old_var;
}
+ else if (rs_align_code == fragp->fr_subtype)
+ {
+ offsetT nop_bytes;
+ if (NULL == fragp->fr_symbol)
+ nop_bytes = fragp->fr_offset;
+ else
+ nop_bytes = ALIGN_MAX_NOP_BYTES (fragp->fr_offset);
+
+ /* Normally, nop_bytes should be >= 4. */
+ gas_assert (nop_bytes > 0);
+
+ offsetT old_var = fragp->fr_var;
+ /* If .align at the start of a section, do nothing. Section alignment
+ * can ensure correct alignment. */
+ if (FRAG_AT_START_OF_SECTION (fragp)
+ && 0 == ((1 << sec->alignment_power) % (nop_bytes + 4)))
+ fragp->fr_var = 0;
+ else
+ fragp->fr_var = nop_bytes;
+ return fragp->fr_var - old_var;
+ }
return 0;
}
@@ -2048,13 +2092,53 @@ loongarch_convert_frag_branch (fragS *fragp)
fragp->fr_fix += fragp->fr_var;
}
-/* Relax a machine dependent frag. This returns the amount by which
- the current size of the frag should change. */
+/* Relax .align frag. */
+
+static void
+loongarch_convert_frag_align (fragS *fragp, asection *sec)
+{
+ bfd_byte *buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix;
+
+ offsetT nop_bytes;
+ if (NULL == fragp->fr_symbol)
+ nop_bytes = fragp->fr_offset;
+ else
+ nop_bytes = ALIGN_MAX_NOP_BYTES (fragp->fr_offset);
+
+ /* Normally, nop_bytes should be >= 4. */
+ gas_assert (nop_bytes > 0);
+
+ if (!(FRAG_AT_START_OF_SECTION (fragp)
+ && 0 == ((1 << sec->alignment_power) % (nop_bytes + 4))))
+ {
+ expressionS exp;
+ exp.X_op = O_symbol;
+ exp.X_add_symbol = fragp->fr_symbol;
+ exp.X_add_number = fragp->fr_offset;
+
+ fixS *fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
+ nop_bytes, &exp, false, BFD_RELOC_LARCH_ALIGN);
+ fixp->fx_file = fragp->fr_file;
+ fixp->fx_line = fragp->fr_line;
+
+ buf += nop_bytes;
+ }
+
+ gas_assert (buf == (bfd_byte *)fragp->fr_literal
+ + fragp->fr_fix + fragp->fr_var);
+
+ fragp->fr_fix += fragp->fr_var;
+}
+
+/* Relax a machine dependent frag. */
void
-md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
- fragS *fragp)
+md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
{
- gas_assert (RELAX_BRANCH (fragp->fr_subtype));
- loongarch_convert_frag_branch (fragp);
+ gas_assert (RELAX_BRANCH (fragp->fr_subtype)
+ || rs_align_code == fragp->fr_subtype);
+ if (RELAX_BRANCH (fragp->fr_subtype))
+ loongarch_convert_frag_branch (fragp);
+ else if (rs_align_code == fragp->fr_subtype)
+ loongarch_convert_frag_align (fragp, asec);
}
diff --git a/gas/testsuite/gas/loongarch/relax-align-first.d b/gas/testsuite/gas/loongarch/relax-align-first.d
new file mode 100644
index 00000000..ec0698b6
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax-align-first.d
@@ -0,0 +1,12 @@
+#as:
+#objdump: -dr
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+0* <.text>:
+[ ]+0:[ ]+4c000020[ ]+ret
+Disassembly of section abc:
+0* <abc>:
+[ ]+0:[ ]+4c000020[ ]+ret
diff --git a/gas/testsuite/gas/loongarch/relax-align-first.s b/gas/testsuite/gas/loongarch/relax-align-first.s
new file mode 100644
index 00000000..a4c3d68f
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax-align-first.s
@@ -0,0 +1,7 @@
+.text
+.align 3
+ret
+
+.section "abc", "ax"
+.align 4, ,4
+ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-first.d b/ld/testsuite/ld-loongarch-elf/relax-align-first.d
new file mode 100644
index 00000000..9a4fad8e
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-align-first.d
@@ -0,0 +1,15 @@
+#ld: -e0
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section aaa:
+0000000120000078 <aaa>:
+[ ]+120000078:[ ]+4c000020[ ]+ret
+Disassembly of section bbb:
+0000000120000080 <bbb>:
+[ ]+120000080:[ ]+4c000020[ ]+ret
+Disassembly of section ccc:
+0000000120000090 <__bss_start-0x4004>:
+[ ]+120000090:[ ]+4c000020[ ]+ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-first.s b/ld/testsuite/ld-loongarch-elf/relax-align-first.s
new file mode 100644
index 00000000..0a9115b5
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-align-first.s
@@ -0,0 +1,13 @@
+# If .align at the start of a section, do not add NOP instructions
+# and do not emit R_LARCH_ALIGN relocations.
+# Section alignment can ensure correct alignment.
+.section "aaa", "ax"
+ret
+
+.section "bbb", "ax"
+.align 3
+ret
+
+.section "ccc", "ax"
+.align 4, ,4
+ret
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index f378b93b..7274218f 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -20,6 +20,7 @@
#
if [istarget loongarch64-*-*] {
+ run_dump_test "relax-align-first"
if [isbuild loongarch64-*-*] {
set testname "loongarch relax .exe build"
--
2.33.0

View File

@ -0,0 +1,68 @@
From 47494a014c00dfa3832441171255018be62ac756 Mon Sep 17 00:00:00 2001
From: Jinyang He <hejinyang@loongson.cn>
Date: Mon, 22 Apr 2024 17:49:50 +0800
Subject: [PATCH 083/123] LoongArch: gas: Simplify relocations in sections
without code flag
Gas should not emit ADD/SUB relocation pairs for label differences
if they are in the same section without code flag even relax enabled.
Because the real value is not be affected by relaxation and it can be
compute out in assembly stage. Thus, correct the `TC_FORCE_RELOCATION
_SUB_SAME` and the label differences in same section without code
flag can be resolved in fixup_segment().
---
gas/config/tc-loongarch.h | 4 +---
gas/testsuite/gas/loongarch/relax_debug_line.d | 12 ++++++++++++
gas/testsuite/gas/loongarch/relax_debug_line.s | 6 ++++++
3 files changed, 19 insertions(+), 3 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/relax_debug_line.d
create mode 100644 gas/testsuite/gas/loongarch/relax_debug_line.s
diff --git a/gas/config/tc-loongarch.h b/gas/config/tc-loongarch.h
index 194ee107..0b5cdfe6 100644
--- a/gas/config/tc-loongarch.h
+++ b/gas/config/tc-loongarch.h
@@ -91,9 +91,7 @@ extern bool loongarch_frag_align_code (int, int);
#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEC) \
(LARCH_opts.relax ? \
(GENERIC_FORCE_RELOCATION_SUB_SAME (FIX, SEC) \
- || ((SEC)->flags & SEC_CODE) != 0 \
- || ((SEC)->flags & SEC_DEBUGGING) != 0 \
- || TC_FORCE_RELOCATION (FIX)) \
+ || ((SEC)->flags & SEC_CODE) != 0) \
: (GENERIC_FORCE_RELOCATION_SUB_SAME (FIX, SEC))) \
#define TC_LINKRELAX_FIXUP(seg) ((seg->flags & SEC_CODE) \
diff --git a/gas/testsuite/gas/loongarch/relax_debug_line.d b/gas/testsuite/gas/loongarch/relax_debug_line.d
new file mode 100644
index 00000000..c17813c2
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax_debug_line.d
@@ -0,0 +1,12 @@
+#as: --gdwarf-5
+#readelf: -r --wide
+#skip: loongarch32-*-*
+
+Relocation section '\.rela\.debug_line' at offset .* contains 5 entries:
+#...
+0+22.*R_LARCH_32[ \t]+[0-9]+.*
+0+2c.*R_LARCH_32[ \t]+[0-9]+.*
+0+36.*R_LARCH_64[ \t]+[0-9]+.*
+0+42.*R_LARCH_ADD16[ \t]+[0-9]+.*
+0+42.*R_LARCH_SUB16[ \t]+[0-9]+.*
+#pass
diff --git a/gas/testsuite/gas/loongarch/relax_debug_line.s b/gas/testsuite/gas/loongarch/relax_debug_line.s
new file mode 100644
index 00000000..d2852bb9
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax_debug_line.s
@@ -0,0 +1,6 @@
+ .file 0 "test"
+ .text
+ .loc 0 10 0
+ nop
+
+.section .debug_line, "", @progbits
--
2.33.0

View File

@ -0,0 +1,143 @@
From 04b665b402affb89a5b077516bc306da11af1e84 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Thu, 18 Jan 2024 19:03:11 +0800
Subject: [PATCH 051/123] LoongArch: gas: Start a new frag after instructions
that can be relaxed
For R_LARCH_TLS_{LE_HI20_R,LE_ADD_R,LD_PC_HI20,GD_PC_HI20, DESC_PC_HI20}
relocations, start a new frag to get correct eh_frame Call Frame Information
FDE DW_CFA_advance_loc info.
---
gas/config/tc-loongarch.c | 19 ++++++--
.../relax-cfi-fde-DW_CFA_advance_loc.d | 46 +++++++++++++++++++
.../relax-cfi-fde-DW_CFA_advance_loc.s | 33 +++++++++++++
3 files changed, 93 insertions(+), 5 deletions(-)
create mode 100644 gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
create mode 100644 gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 49470073..5b7f5137 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -1070,13 +1070,22 @@ append_fixp_and_insn (struct loongarch_cl_insn *ip)
optimized away or compressed by the linker during relaxation, to prevent
the assembler from computing static offsets across such an instruction.
- This is necessary to get correct .eh_frame cfa info. If one cfa's two
- symbol is not in the same frag, it will generate relocs to calculate
- symbol subtraction. (gas/dw2gencfi.c:output_cfi_insn:
- if (symbol_get_frag (to) == symbol_get_frag (from))) */
+ This is necessary to get correct .eh_frame FDE DW_CFA_advance_loc info.
+ If one cfi_insn_data's two symbols are not in the same frag, it will
+ generate ADD and SUB relocations pairs to calculate DW_CFA_advance_loc.
+ (gas/dw2gencfi.c: output_cfi_insn:
+ if (symbol_get_frag (to) == symbol_get_frag (from)))
+
+ For macro instructions, only the first instruction expanded from macro
+ need to start a new frag. */
if (LARCH_opts.relax
&& (BFD_RELOC_LARCH_PCALA_HI20 == reloc_info[0].type
- || BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_info[0].type))
+ || BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_info[0].type
+ || BFD_RELOC_LARCH_TLS_LE_HI20_R == reloc_info[0].type
+ || BFD_RELOC_LARCH_TLS_LE_ADD_R == reloc_info[0].type
+ || BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_info[0].type
+ || BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_info[0].type
+ || BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_info[0].type))
{
frag_wane (frag_now);
frag_new (0);
diff --git a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
new file mode 100644
index 00000000..367039e1
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.d
@@ -0,0 +1,46 @@
+#as: -mrelax
+#objdump: -Dr -j .eh_frame
+#skip: loongarch32-*-*
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .eh_frame:
+
+[ ]*0000000000000000 <.eh_frame>:
+[ ]+0:[ ]+00000014[ ]+.word[ ]+[ ]+0x00000014
+[ ]+4:[ ]+00000000[ ]+.word[ ]+[ ]+0x00000000
+[ ]+8:[ ]+00527a01[ ]+.word[ ]+[ ]+0x00527a01
+[ ]+c:[ ]+01017c01[ ]+fadd.d[ ]+\$fa1, \$fa0, \$fs7
+[ ]+10:[ ]+0c030d1b[ ]+.word[ ]+[ ]+0x0c030d1b
+[ ]+14:[ ]+00000016[ ]+.word[ ]+[ ]+0x00000016
+[ ]+18:[ ]+00000034[ ]+.word[ ]+[ ]+0x00000034
+[ ]+1c:[ ]+0000001c[ ]+.word[ ]+[ ]+0x0000001c
+[ ]+...
+[ ]+20: R_LARCH_32_PCREL[ ]+L0\^A
+[ ]+24: R_LARCH_ADD32[ ]+L0\^A
+[ ]+24: R_LARCH_SUB32[ ]+L0\^A
+[ ]+28:[ ]+0cd64000[ ]+.word[ ]+[ ]+0x0cd64000
+[ ]+29: R_LARCH_ADD6[ ]+L0\^A
+[ ]+29: R_LARCH_SUB6[ ]+L0\^A
+[ ]+2c:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
+[ ]+2e: R_LARCH_ADD6[ ]+L0\^A
+[ ]+2e: R_LARCH_SUB6[ ]+L0\^A
+[ ]+30:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300044 <L0\^A\+0x30000c>
+[ ]+33: R_LARCH_ADD6[ ]+L0\^A
+[ ]+33: R_LARCH_SUB6[ ]+L0\^A
+[ ]+34:[ ]+00160cd6[ ]+orn[ ]+\$fp, \$a2, \$sp
+[ ]+38:[ ]+160cd640[ ]+lu32i.d[ ]+\$zero, 26290
+[ ]+38: R_LARCH_ADD6[ ]+L0\^A
+[ ]+38: R_LARCH_SUB6[ ]+L0\^A
+[ ]+3c:[ ]+0cd64000[ ]+.word[ ]+[ ]+0x0cd64000
+[ ]+3d: R_LARCH_ADD6[ ]+L0\^A
+[ ]+3d: R_LARCH_SUB6[ ]+L0\^A
+[ ]+40:[ ]+d6400016[ ]+.word[ ]+[ ]+0xd6400016
+[ ]+42: R_LARCH_ADD6[ ]+L0\^A
+[ ]+42: R_LARCH_SUB6[ ]+L0\^A
+[ ]+44:[ ]+4000160c[ ]+beqz[ ]+\$t4, 3145748[ ]+# 300058 <L0\^A\+0x300020>
+[ ]+47: R_LARCH_ADD6[ ]+L0\^A
+[ ]+47: R_LARCH_SUB6[ ]+L0\^A
+[ ]+48:[ ]+000000d6[ ]+.word[ ]+[ ]+0x000000d6
+[ ]+4c:[ ]+00000000[ ]+.word[ ]+[ ]+0x00000000
diff --git a/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
new file mode 100644
index 00000000..6e4c9b8b
--- /dev/null
+++ b/gas/testsuite/gas/loongarch/relax-cfi-fde-DW_CFA_advance_loc.s
@@ -0,0 +1,33 @@
+# Emits ADD/SUB relocations for CFA FDE DW_CFA_advance_loc with -mrelax option.
+.text
+.cfi_startproc
+
+.cfi_def_cfa 22, 0
+la.local $t0, a
+.cfi_restore 22
+
+.cfi_def_cfa 22, 0
+la.got $t0, a
+.cfi_restore 22
+
+.cfi_def_cfa 22, 0
+la.tls.ld $t0, a
+.cfi_restore 22
+
+.cfi_def_cfa 22, 0
+la.tls.gd $t0, a
+.cfi_restore 22
+
+.cfi_def_cfa 22, 0
+la.tls.desc $t0, a
+.cfi_restore 22
+
+.cfi_def_cfa 22, 0
+pcalau12i $t0, %le_hi20_r(a)
+.cfi_restore 22
+
+.cfi_def_cfa 22, 0
+add.d $t0, $tp, $t0, %le_add_r(a)
+.cfi_restore 22
+
+.cfi_endproc
--
2.33.0

View File

@ -0,0 +1,166 @@
From 7b212e5db865a826dc15aaf5e0562133c88eb769 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Mon, 5 Feb 2024 16:16:52 +0800
Subject: [PATCH 056/123] LoongArch: gas: Try to avoid R_LARCH_ALIGN associate
with a symbol
The R_LARCH_ALIGN need to associated with a symbol if .align has the first
and third expressions. If R_LARCH_ALIGN associate with a symbol, the addend can
represent the first and third expression of .align.
For '.align 3', the addend of R_LARCH_ALIGN only need to represent the alignment
and R_LARCH_ALIGN not need to associate with a symbol.
For '.align x, , y', R_LARCH_ALIGN need to associate with a symbol if 0 < y <
2^x - 4.
---
gas/config/tc-loongarch.c | 27 +++++++---
gas/testsuite/gas/loongarch/relax_align.d | 64 +++++++++++++----------
gas/testsuite/gas/loongarch/relax_align.s | 20 +++++--
3 files changed, 72 insertions(+), 39 deletions(-)
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 5e96f624..e6da4e1e 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -1746,14 +1746,25 @@ loongarch_frag_align_code (int n, int max)
nops = frag_more (worst_case_bytes);
- s = symbol_find (".Lla-relax-align");
- if (s == NULL)
- s = (symbolS *)local_symbol_make (".Lla-relax-align", now_seg,
- &zero_address_frag, 0);
-
- ex.X_add_symbol = s;
- ex.X_op = O_symbol;
- ex.X_add_number = (max << 8) | n;
+ /* If max <= 0, ignore max.
+ If max >= worst_case_bytes, max has no effect.
+ Similar to gas/write.c relax_segment function rs_align_code case:
+ if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype). */
+ if (max > 0 && (bfd_vma) max < worst_case_bytes)
+ {
+ s = symbol_find (".Lla-relax-align");
+ if (s == NULL)
+ s = (symbolS *)local_symbol_make (".Lla-relax-align", now_seg,
+ &zero_address_frag, 0);
+ ex.X_add_symbol = s;
+ ex.X_op = O_symbol;
+ ex.X_add_number = (max << 8) | n;
+ }
+ else
+ {
+ ex.X_op = O_constant;
+ ex.X_add_number = worst_case_bytes;
+ }
loongarch_make_nops (nops, worst_case_bytes);
diff --git a/gas/testsuite/gas/loongarch/relax_align.d b/gas/testsuite/gas/loongarch/relax_align.d
index 2cc6c86d..fc1fd032 100644
--- a/gas/testsuite/gas/loongarch/relax_align.d
+++ b/gas/testsuite/gas/loongarch/relax_align.d
@@ -1,4 +1,4 @@
-#as: --no-warn
+#as:
#objdump: -dr
#skip: loongarch32-*-*
@@ -8,29 +8,39 @@
Disassembly of section .text:
[ ]*0000000000000000 <.Lla-relax-align>:
-[ ]+0:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
-[ ]+0: R_LARCH_PCALA_HI20[ ]+L1
-[ ]+0: R_LARCH_RELAX[ ]+\*ABS\*
-[ ]+4:[ ]+02c00084[ ]+addi.d[ ]+\$a0, \$a0, 0
-[ ]+4: R_LARCH_PCALA_LO12[ ]+L1
-[ ]+4: R_LARCH_RELAX[ ]+\*ABS\*
-[ ]+8:[ ]+03400000[ ]+nop.*
-[ ]+8: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0x4
-[ ]+c:[ ]+03400000[ ]+nop.*
-[ ]+10:[ ]+03400000[ ]+nop.*
-[ ]+14:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
-[ ]+14: R_LARCH_PCALA_HI20[ ]+L1
-[ ]+14: R_LARCH_RELAX[ ]+\*ABS\*
-[ ]+18:[ ]+02c00084[ ]+addi.d[ ]+\$a0, \$a0, 0
-[ ]+18: R_LARCH_PCALA_LO12[ ]+L1
-[ ]+18: R_LARCH_RELAX[ ]+\*ABS\*
-[ ]+1c:[ ]+03400000[ ]+nop.*
-[ ]+1c: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0x404
-[ ]+20:[ ]+03400000[ ]+nop.*
-[ ]+24:[ ]+03400000[ ]+nop.*
-[ ]+28:[ ]+1a000004[ ]+pcalau12i[ ]+\$a0, 0
-[ ]+28: R_LARCH_PCALA_HI20[ ]+L1
-[ ]+28: R_LARCH_RELAX[ ]+\*ABS\*
-[ ]+2c:[ ]+02c00084[ ]+addi.d[ ]+\$a0, \$a0, 0
-[ ]+2c: R_LARCH_PCALA_LO12[ ]+L1
-[ ]+2c: R_LARCH_RELAX[ ]+\*ABS\*
+[ ]+0:[ ]+4c000020[ ]+ret
+[ ]+4:[ ]+03400000[ ]+nop
+[ ]+4: R_LARCH_ALIGN[ ]+\*ABS\*\+0xc
+[ ]+8:[ ]+03400000[ ]+nop
+[ ]+c:[ ]+03400000[ ]+nop
+[ ]+10:[ ]+4c000020[ ]+ret
+[ ]+14:[ ]+03400000[ ]+nop
+[ ]+14: R_LARCH_ALIGN[ ]+\*ABS\*\+0xc
+[ ]+18:[ ]+03400000[ ]+nop
+[ ]+1c:[ ]+03400000[ ]+nop
+[ ]+20:[ ]+4c000020[ ]+ret
+[ ]+24:[ ]+03400000[ ]+nop
+[ ]+24: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0x104
+[ ]+28:[ ]+03400000[ ]+nop
+[ ]+2c:[ ]+03400000[ ]+nop
+[ ]+30:[ ]+4c000020[ ]+ret
+[ ]+34:[ ]+03400000[ ]+nop
+[ ]+34: R_LARCH_ALIGN[ ]+.Lla-relax-align\+0xb04
+[ ]+38:[ ]+03400000[ ]+nop
+[ ]+3c:[ ]+03400000[ ]+nop
+[ ]+40:[ ]+4c000020[ ]+ret
+[ ]+44:[ ]+03400000[ ]+nop
+[ ]+44: R_LARCH_ALIGN[ ]+\*ABS\*\+0xc
+[ ]+48:[ ]+03400000[ ]+nop
+[ ]+4c:[ ]+03400000[ ]+nop
+[ ]+50:[ ]+4c000020[ ]+ret
+[ ]+54:[ ]+03400000[ ]+nop
+[ ]+54: R_LARCH_ALIGN[ ]+\*ABS\*\+0xc
+[ ]+58:[ ]+03400000[ ]+nop
+[ ]+5c:[ ]+03400000[ ]+nop
+[ ]+60:[ ]+4c000020[ ]+ret
+[ ]+64:[ ]+03400000[ ]+nop
+[ ]+64: R_LARCH_ALIGN[ ]+\*ABS\*\+0xc
+[ ]+68:[ ]+03400000[ ]+nop
+[ ]+6c:[ ]+03400000[ ]+nop
+[ ]+70:[ ]+4c000020[ ]+ret
diff --git a/gas/testsuite/gas/loongarch/relax_align.s b/gas/testsuite/gas/loongarch/relax_align.s
index c0177c88..4f4867fb 100644
--- a/gas/testsuite/gas/loongarch/relax_align.s
+++ b/gas/testsuite/gas/loongarch/relax_align.s
@@ -1,7 +1,19 @@
+# If max < -0x80000000, max becomes a positive number because type conversion
+# (bfd_signed_vma -> unsigned int).
.text
.L1:
- la.local $a0, L1
+ ret
.align 4
- la.local $a0, L1
- .align 4, , 4
- la.local $a0, L1
+ ret
+ .align 4, , 0
+ ret
+ .align 4, , 1
+ ret
+ .align 4, , 11
+ ret
+ .align 4, , 12
+ ret
+ .align 4, , -1
+ ret
+ .align 4, , -0x80000000
+ ret
--
2.33.0

View File

@ -0,0 +1,46 @@
From 92fd8ea969cddf3434830ea3f3cfa48cd3e23f30 Mon Sep 17 00:00:00 2001
From: Xi Ruoyao <xry111@xry111.site>
Date: Mon, 7 Aug 2023 13:07:08 +0200
Subject: [PATCH 004/123] LoongArch: implement count_{leading,trailing}_zeros
LoongArch always support clz and ctz instructions, so we can always use
__builtin_{clz,ctz} for count_{leading,trailing}_zeros. This improves
the code of libgcc, and also benefits Glibc once we merge longlong.h
there.
Bootstrapped and regtested on loongarch64-linux-gnu.
include/
* longlong.h [__loongarch__] (count_leading_zeros): Define.
[__loongarch__] (count_trailing_zeros): Likewise.
[__loongarch__] (COUNT_LEADING_ZEROS_0): Likewise.
---
include/longlong.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/include/longlong.h b/include/longlong.h
index 9948a587..32d2048d 100644
--- a/include/longlong.h
+++ b/include/longlong.h
@@ -593,6 +593,18 @@ extern UDItype __umulsidi3 (USItype, USItype);
#define UMUL_TIME 14
#endif
+#ifdef __loongarch__
+# if W_TYPE_SIZE == 32
+# define count_leading_zeros(count, x) ((count) = __builtin_clz (x))
+# define count_trailing_zeros(count, x) ((count) = __builtin_ctz (x))
+# define COUNT_LEADING_ZEROS_0 32
+# elif W_TYPE_SIZE == 64
+# define count_leading_zeros(count, x) ((count) = __builtin_clzll (x))
+# define count_trailing_zeros(count, x) ((count) = __builtin_ctzll (x))
+# define COUNT_LEADING_ZEROS_0 64
+# endif
+#endif
+
#if defined (__M32R__) && W_TYPE_SIZE == 32
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
/* The cmp clears the condition bit. */ \
--
2.33.0

View File

@ -0,0 +1,43 @@
From fd100b34ac667ad62f57800762c76ac5272ceb16 Mon Sep 17 00:00:00 2001
From: changjiachen <changjiachen@stu.xupt.edu.cn>
Date: Thu, 28 Dec 2023 19:57:30 +0800
Subject: [PATCH 032/123] LoongArch: include: Add support for tls le relax.
Add new relocs number for tls le relax.
include/ChangeLog:
* elf/loongarch.h:
(RELOC_NUMBER (R_LARCH_TLS_LE_HI20_R, 121)): New relocs number.
(RELOC_NUMBER (R_LARCH_TLS_LE_ADD_R, 122)): Likewise.
(RELOC_NUMBER (R_LARCH_TLS_LE_LO12_R, 123)): Likewise.
---
include/elf/loongarch.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
index 6cfee164..1deb6ba1 100644
--- a/include/elf/loongarch.h
+++ b/include/elf/loongarch.h
@@ -273,6 +273,18 @@ RELOC_NUMBER (R_LARCH_TLS_DESC64_HI12, 118)
RELOC_NUMBER (R_LARCH_TLS_DESC_LD, 119)
RELOC_NUMBER (R_LARCH_TLS_DESC_CALL, 120)
+/* TLS-LE-LUI
+ lu12i.w rd,%le_hi20_r (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LE_HI20_R, 121)
+
+/* TLS-LE-ADD
+ add.d rd,rj,rk,%le_add_r (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LE_ADD_R, 122)
+
+/* TLS-LE-ST
+ st.w/addi.w/ld.w rd,rj,%le_lo12_r (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LE_LO12_R, 123)
+
RELOC_NUMBER (R_LARCH_TLS_LD_PCREL20_S2, 124)
RELOC_NUMBER (R_LARCH_TLS_GD_PCREL20_S2, 125)
RELOC_NUMBER (R_LARCH_TLS_DESC_PCREL20_S2, 126)
--
2.33.0

View File

@ -0,0 +1,105 @@
From 7460efab086ff238d2b4de990a6d4f89efaafc23 Mon Sep 17 00:00:00 2001
From: mengqinggang <mengqinggang@loongson.cn>
Date: Thu, 25 Jan 2024 09:32:14 +0800
Subject: [PATCH 052/123] LoongArch: ld: Add support for TLS LE symbol with
addend
Add support for TLS LE symbol with addend, such as:
lu12i.w $t0, %le_hi20(a + 0x8)
ori $t0, $t0, %le_lo12(a + 0x8)
---
bfd/elfnn-loongarch.c | 5 ++---
.../ld-loongarch-elf/ld-loongarch-elf.exp | 1 +
ld/testsuite/ld-loongarch-elf/tls-le.d | 14 ++++++++++++++
ld/testsuite/ld-loongarch-elf/tls-le.s | 18 ++++++++++++++++++
4 files changed, 35 insertions(+), 3 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/tls-le.d
create mode 100644 ld/testsuite/ld-loongarch-elf/tls-le.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index f57b6152..858b95e1 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3487,14 +3487,12 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
relocation += rel->r_addend;
RELOCATE_CALC_PC32_HI20 (relocation, pc);
-
break;
case R_LARCH_TLS_LE_HI20_R:
+ relocation += rel->r_addend;
relocation -= elf_hash_table (info)->tls_sec->vma;
-
RELOCATE_TLS_TP32_HI20 (relocation);
-
break;
case R_LARCH_PCALA_LO12:
@@ -3675,6 +3673,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_LARCH_TLS_LE64_HI12:
BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
+ relocation += rel->r_addend;
relocation -= elf_hash_table (info)->tls_sec->vma;
break;
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index c81f20af..46b53536 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -34,6 +34,7 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "local-ifunc-reloc"
run_dump_test "anno-sym"
run_dump_test "pcala64"
+ run_dump_test "tls-le"
}
if [istarget "loongarch32-*-*"] {
diff --git a/ld/testsuite/ld-loongarch-elf/tls-le.d b/ld/testsuite/ld-loongarch-elf/tls-le.d
new file mode 100644
index 00000000..cbd6adb8
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-le.d
@@ -0,0 +1,14 @@
+#ld: --no-relax
+#objdump: -d
+
+.*:[ ]+file format .*
+
+
+Disassembly of section .text:
+
+[ ]*00000001200000e8 <_start>:
+[ ]+1200000e8:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+1200000ec:[ ]+03802085[ ]+ori[ ]+\$a1, \$a0, 0x8
+[ ]+1200000f0:[ ]+14000004[ ]+lu12i.w[ ]+\$a0, 0
+[ ]+1200000f4:[ ]+02c02085[ ]+addi.d[ ]+\$a1, \$a0, 8
+[ ]+1200000f8:[ ]+4c000020[ ]+ret
diff --git a/ld/testsuite/ld-loongarch-elf/tls-le.s b/ld/testsuite/ld-loongarch-elf/tls-le.s
new file mode 100644
index 00000000..2e6a9de4
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-le.s
@@ -0,0 +1,18 @@
+# Support for TLS LE symbols with addend
+ .text
+ .globl a
+ .section .tdata,"awT",@progbits
+ .align 2
+ .type a, @object
+ .size a, 4
+a:
+ .word 123
+
+ .text
+ .global _start
+_start:
+ lu12i.w $r4,%le_hi20(a + 0x8)
+ ori $r5,$r4,%le_lo12(a + 0x8)
+ lu12i.w $r4,%le_hi20_r(a + 0x8)
+ addi.d $r5,$r4,%le_lo12_r(a + 0x8)
+ jr $ra
--
2.33.0

View File

@ -0,0 +1,410 @@
From 752d56ec3ba19235fd3d75fd30adaa4bec10dded Mon Sep 17 00:00:00 2001
From: changjiachen <changjiachen@stu.xupt.edu.cn>
Date: Thu, 28 Dec 2023 20:01:15 +0800
Subject: [PATCH 035/123] LoongArch: ld: Add support for tls le relax.
Add tls le relax related testsuites in ld.
The new test cases are mainly tested in three aspects:
1. tls le relax function correctness test.
2. tls le relax boundary check test.
3. tls le relax function compatibility test.
ld/testsuite/ChangeLog:
* ld/testsuite/ld-loongarch-elf/relax.exp: Modify test.
* ld/testsuite/ld-loongarch-elf/old-tls-le.s: New test.
* ld/testsuite/ld-loongarch-elf/relax-bound-check-tls-le.s: Likewise.
* ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-new.s: Likewise.
* ld/testsuite/ld-loongarch-elf/relax-tls-le.s: Likewise.
* ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-old.s: Likewise.
---
ld/testsuite/ld-loongarch-elf/old-tls-le.s | 23 +++
.../relax-bound-check-tls-le.s | 53 ++++++
ld/testsuite/ld-loongarch-elf/relax-tls-le.s | 26 +++
ld/testsuite/ld-loongarch-elf/relax.exp | 151 +++++++++++++++++-
.../tls-relax-compatible-check-new.s | 35 ++++
.../tls-relax-compatible-check-old.s | 33 ++++
6 files changed, 320 insertions(+), 1 deletion(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/old-tls-le.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-bound-check-tls-le.s
create mode 100644 ld/testsuite/ld-loongarch-elf/relax-tls-le.s
create mode 100644 ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-new.s
create mode 100644 ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-old.s
diff --git a/ld/testsuite/ld-loongarch-elf/old-tls-le.s b/ld/testsuite/ld-loongarch-elf/old-tls-le.s
new file mode 100644
index 00000000..be3d2b9c
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/old-tls-le.s
@@ -0,0 +1,23 @@
+/* This test case mainly tests whether the original
+ tls le assembly instruction can be linked normally
+ after tls le relax is added to the current ld. */
+
+ .text
+ .globl aa
+ .section .tbss,"awT",@nobits
+ .align 2
+ .type aa, @object
+ .size aa, 4
+aa:
+ .space 4
+ .text
+ .align 2
+ .globl main
+ .type main, @function
+main:
+ lu12i.w $r12,%le_hi20(aa)
+ ori $r12,$r12,%le_lo12(aa)
+ add.d $r12,$r12,$r2
+ addi.w $r13,$r0,2 # 0x2
+ stptr.w $r13,$r12,0
+
diff --git a/ld/testsuite/ld-loongarch-elf/relax-bound-check-tls-le.s b/ld/testsuite/ld-loongarch-elf/relax-bound-check-tls-le.s
new file mode 100644
index 00000000..b2a64b5d
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-bound-check-tls-le.s
@@ -0,0 +1,53 @@
+/* This test case mainly tests whether the address of the
+ tls le symbol can be resolved normally when the offset
+ of the symbol is greater than 0x800. (When the symbol
+ offset is greater than 0x800, relax is not performed). */
+
+ .text
+ .globl count1
+ .section .tbss,"awT",@nobits
+ .align 2
+ .type count1, @object
+ .size count1, 4
+count1:
+ .space 0x400
+ .globl count2
+ .align 2
+ .type count2, @object
+ .size count2, 4
+count2:
+ .space 0x400
+ .globl count3
+ .align 2
+ .type count3, @object
+ .size count3, 4
+count3:
+ .space 0x400
+ .globl count4
+ .align 2
+ .type count4, @object
+ .size count4, 4
+count4:
+ .space 4
+ .text
+ .align 2
+ .globl main
+ .type main, @function
+main:
+ lu12i.w $r12,%le_hi20_r(count1)
+ add.d $r12,$r12,$r2,%le_add_r(count1)
+ addi.w $r13,$r0,1
+ st.w $r13,$r12,%le_lo12_r(count1)
+ lu12i.w $r12,%le_hi20_r(count2)
+ add.d $r12,$r12,$r2,%le_add_r(count2)
+ addi.w $r13,$r0,2
+ st.w $r13,$r12,%le_lo12_r(count2)
+ lu12i.w $r12,%le_hi20(count3)
+ add.d $r12,$r12,$r2,%le_add_r(count3)
+ addi.w $r13,$r0,3
+ st.w $r13,$r12,%le_lo12_r(count3)
+ lu12i.w $r12,%le_hi20(count4)
+ add.d $r12,$r12,$r2,%le_add_r(count4)
+ addi.w $r13,$r0,4
+ st.w $r13,$r12,%le_lo12_r(count4)
+
diff --git a/ld/testsuite/ld-loongarch-elf/relax-tls-le.s b/ld/testsuite/ld-loongarch-elf/relax-tls-le.s
new file mode 100644
index 00000000..1ea53baf
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-tls-le.s
@@ -0,0 +1,26 @@
+/* This test case mainly tests whether the tls le variable
+ address acquisition can be relax normally.
+
+ before relax: after relax:
+
+ lu12i.w $r12,%le_hi20_r(sym) ====> (instruction deleted).
+ add.d $r12,$r12,$r2,%le_add_r(sym) ====> (instruction deleted).
+ st.w $r13,$r12,%le_lo12_r(sym) ====> st.w $r13,$r2,%le_lo12_r(sym). */
+
+ .text
+ .globl a
+ .section .tbss,"awT",@nobits
+ .align 2
+ .type a, @object
+ .size a, 4
+a:
+ .space 4
+ .text
+ .align 2
+ .globl main
+ .type main, @function
+main:
+ lu12i.w $r12,%le_hi20_r(a)
+ add.d $r12,$r12,$r2,%le_add_r(a)
+ addi.w $r13,$r0,1 # 0x1
+ st.w $r13,$r12,%le_lo12_r(a)
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index 77323d8d..b697d015 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -33,8 +33,90 @@ if [istarget loongarch64-*-*] {
"relax" \
] \
]
+ set tls_relax_builds [list \
+ [list \
+ "tls_relax_builds" \
+ "" \
+ "" \
+ {relax-tls-le.s} \
+ {} \
+ "relax-tls-le" \
+ ] \
+ ]
+ set tls_no_relax_builds [list \
+ [list \
+ "tls_no_relax_builds" \
+ "-Wl,--no-relax" \
+ "" \
+ {relax-tls-le.s} \
+ {} \
+ "no-relax-tls-le" \
+ ] \
+ ]
+
+ set relax_bound_check [list \
+ [list \
+ "relax_bound_check" \
+ "" \
+ "" \
+ {relax-bound-check-tls-le.s} \
+ {} \
+ "relax-bound-check-tls-le" \
+ ] \
+ ]
+ set no_relax_bound_check [list \
+ [list \
+ "no_relax_bound_check" \
+ "-Wl,--no-relax" \
+ "" \
+ {relax-bound-check-tls-le.s} \
+ {} \
+ "no-relax-bound-check-tls-le" \
+ ] \
+ ]
+
+ set old_tls_le [list \
+ [list \
+ "old_tls_le" \
+ "" \
+ "" \
+ {old-tls-le.s} \
+ {} \
+ "old-tls-le" \
+ ] \
+ ]
+
+ set relax_compatible [list \
+ [list \
+ "relax_compatible" \
+ "" \
+ "" \
+ {tls-relax-compatible-check-new.s tls-relax-compatible-check-old.s} \
+ {} \
+ "realx-compatible" \
+ ] \
+ ]
+
+ set no_relax_compatible [list \
+ [list \
+ "no_relax_compatible" \
+ "-Wl,--no-relax" \
+ "" \
+ {tls-relax-compatible-check-new.s tls-relax-compatible-check-old.s} \
+ {} \
+ "no-realx-compatible" \
+ ] \
+ ]
+
run_cc_link_tests $pre_builds
+ run_cc_link_tests $tls_relax_builds
+ run_cc_link_tests $tls_no_relax_builds
+ run_cc_link_tests $relax_bound_check
+ run_cc_link_tests $no_relax_bound_check
+ run_cc_link_tests $old_tls_le
+ run_cc_link_tests $relax_compatible
+ run_cc_link_tests $no_relax_compatible
if [file exist "tmpdir/relax"] {
set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax"]
@@ -114,8 +196,75 @@ if [istarget loongarch64-*-*] {
"relax-segment-max" \
] \
]
- }
+ if [file exist "tmpdir/relax-tls-le"] {
+ set objdump_output1 [run_host_cmd "objdump" "-d tmpdir/relax-tls-le"]
+ if { [ regexp ".addi.*st.*" $objdump_output1] } {
+ pass "loongarch relax success"
+ } {
+ fail "loongarch relax fail"
+ }
+ }
+ if [file exist "tmpdir/no-relax-tls-le"] {
+ set objdump_output2 [run_host_cmd "objdump" "-d tmpdir/no-relax-tls-le"]
+ if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output2] } {
+ pass "loongarch no-relax success"
+ } {
+ fail "loongarch no-relax fail"
+ }
+
+ }
+ if [file exist "tmpdir/old-tls-le"] {
+ set objdump_output3 [run_host_cmd "objdump" "-d tmpdir/old-tls-le"]
+ if { [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output3] } {
+ pass "loongarch old tls le success"
+ } {
+ fail "loongarch old tls le fail"
+ }
+
+ }
+
+ if [file exist "tmpdir/realx-compatible"] {
+ set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/realx-compatible"]
+ if { [ regexp ".addi.*st.*" $objdump_output4] && \
+ [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output4] } {
+ pass "loongarch tls le relax compatible check success"
+ } {
+ fail "loongarch tls le relax compatible check fail"
+ }
+ }
+
+ if [file exist "tmpdir/no-realx-compatible"] {
+ set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/realx-compatible"]
+ if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output4] && \
+ [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output4] } {
+ pass "loongarch tls le no-relax compatible check success"
+ } {
+ fail "loongarch tls le no-relax compatible check fail"
+ }
+ }
+
+
+ if [file exist "tmpdir/relax-bound-check-tls-le"] {
+ set objdump_output5 [run_host_cmd "objdump" "-d tmpdir/relax-bound-check-tls-le"]
+ if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output5] && \
+ [ regexp ".addi.*st.*" $objdump_output5] } {
+ pass "loongarch no-relax success"
+ } {
+ fail "loongarch no-relax fail"
+ }
+
+ }
+ if [file exist "tmpdir/no-relax-bound-check-tls-le"] {
+ set objdump_output5 [run_host_cmd "objdump" "-d tmpdir/no-relax-bound-check-tls-le"]
+ if { [ regexp ".*addi.*st.*" $objdump_output5] } {
+ pass "loongarch no-relax success"
+ } {
+ fail "loongarch no-relax fail"
+ }
+ }
+
+ }
run_ld_link_tests \
[list \
[list \
diff --git a/ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-new.s b/ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-new.s
new file mode 100644
index 00000000..059ca0b9
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-new.s
@@ -0,0 +1,35 @@
+/* This test case mainly carries out ld compatibility test.
+ This test case is the new tls le instruction sequence,
+ which will be linked with tls-relax-compatible-check-old.s.
+ If the link is normal, it indicates that there is no
+ compatibility problem. */
+
+ .text
+ .globl new
+ .section .tbss,"awT",@nobits
+ .align 2
+ .type new, @object
+ .size new, 4
+new:
+ .space 4
+ .text
+ .align 2
+ .globl main
+ .type main, @function
+main:
+.LFB0 = .
+ addi.d $r3,$r3,-16
+ st.d $r1,$r3,8
+ stptr.d $r22,$r3,0
+ addi.d $r22,$r3,16
+ bl %plt(old)
+ lu12i.w $r12,%le_hi20_r(new)
+ add.d $r12,$r12,$r2,%le_add_r(new)
+ addi.w $r13,$r0,2 # 0x2
+ st.w $r13,$r12,%le_lo12_r(new)
+ or $r12,$r0,$r0
+ or $r4,$r12,$r0
+ ld.d $r1,$r3,8
+ ldptr.d $r22,$r3,0
+ addi.d $r3,$r3,16
+ jr $r1
diff --git a/ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-old.s b/ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-old.s
new file mode 100644
index 00000000..083a2688
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-old.s
@@ -0,0 +1,33 @@
+/* This test case mainly carries out ld compatibility test.
+ This test case is the old tls le instruction sequence,
+ which will be linked with tls-relax-compatible-check-new.s.
+ If the link is normal, it indicates that there is no
+ compatibility problem. */
+
+ .text
+ .globl older
+ .section .tbss,"awT",@nobits
+ .align 2
+ .type older, @object
+ .size older, 4
+older:
+ .space 4
+ .text
+ .align 2
+ .globl old
+ .type old, @function
+old:
+.LFB0 = .
+ addi.d $r3,$r3,-16
+ st.d $r22,$r3,8
+ addi.d $r22,$r3,16
+ lu12i.w $r12,%le_hi20(older)
+ ori $r12,$r12,%le_lo12(older)
+ add.d $r12,$r12,$r2
+ addi.w $r13,$r0,1 # 0x1
+ stptr.w $r13,$r12,0
+ nop
+ or $r4,$r12,$r0
+ ld.d $r22,$r3,8
+ addi.d $r3,$r3,16
+ jr $r1
--
2.33.0

View File

@ -0,0 +1,340 @@
From 075962ddaa562d7d9b9bd9de8a5204e3913ea36a Mon Sep 17 00:00:00 2001
From: changjiachen <changjiachen@stu.xupt.edu.cn>
Date: Thu, 4 Jan 2024 14:06:09 +0800
Subject: [PATCH 042/123] LoongArch: ld: Adjusted some code order in relax.exp.
ld/testsuite/ChangeLog:
* ld/testsuite/ld-loongarch-elf/relax.exp: Modify test.
---
ld/testsuite/ld-loongarch-elf/relax.exp | 298 ++++++++++++------------
1 file changed, 149 insertions(+), 149 deletions(-)
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index 6c65318a..aed8457d 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -33,90 +33,8 @@ if [istarget loongarch64-*-*] {
"relax" \
] \
]
- set tls_relax_builds [list \
- [list \
- "tls_relax_builds" \
- "" \
- "" \
- {relax-tls-le.s} \
- {} \
- "relax-tls-le" \
- ] \
- ]
- set tls_no_relax_builds [list \
- [list \
- "tls_no_relax_builds" \
- "-Wl,--no-relax" \
- "" \
- {relax-tls-le.s} \
- {} \
- "no-relax-tls-le" \
- ] \
- ]
-
- set relax_bound_check [list \
- [list \
- "relax_bound_check" \
- "" \
- "" \
- {relax-bound-check-tls-le.s} \
- {} \
- "relax-bound-check-tls-le" \
- ] \
- ]
- set no_relax_bound_check [list \
- [list \
- "no_relax_bound_check" \
- "-Wl,--no-relax" \
- "" \
- {relax-bound-check-tls-le.s} \
- {} \
- "no-relax-bound-check-tls-le" \
- ] \
- ]
-
- set old_tls_le [list \
- [list \
- "old_tls_le" \
- "" \
- "" \
- {old-tls-le.s} \
- {} \
- "old-tls-le" \
- ] \
- ]
-
- set relax_compatible [list \
- [list \
- "relax_compatible" \
- "" \
- "" \
- {tls-relax-compatible-check-new.s tls-relax-compatible-check-old.s} \
- {} \
- "realx-compatible" \
- ] \
- ]
-
- set no_relax_compatible [list \
- [list \
- "no_relax_compatible" \
- "-Wl,--no-relax" \
- "" \
- {tls-relax-compatible-check-new.s tls-relax-compatible-check-old.s} \
- {} \
- "no-realx-compatible" \
- ] \
- ]
-
run_cc_link_tests $pre_builds
- run_cc_link_tests $tls_relax_builds
- run_cc_link_tests $tls_no_relax_builds
- run_cc_link_tests $relax_bound_check
- run_cc_link_tests $no_relax_bound_check
- run_cc_link_tests $old_tls_le
- run_cc_link_tests $relax_compatible
- run_cc_link_tests $no_relax_compatible
if [file exist "tmpdir/relax"] {
set objdump_output [run_host_cmd "objdump" "-d tmpdir/relax"]
@@ -173,6 +91,155 @@ if [istarget loongarch64-*-*] {
}
}
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch tls le relax .exe build" \
+ "" "" \
+ "" \
+ {relax-tls-le.s} \
+ {} \
+ "relax-tls-le" \
+ ] \
+ ]
+
+ if [file exist "tmpdir/relax-tls-le"] {
+ set objdump_output1 [run_host_cmd "objdump" "-d tmpdir/relax-tls-le"]
+ if { [ regexp ".addi.*st.*" $objdump_output1] } {
+ pass "loongarch relax success"
+ } {
+ fail "loongarch relax fail"
+ }
+ }
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch tls le no relax .exe build" \
+ "--no-relax" "" \
+ "" \
+ {relax-tls-le.s} \
+ {} \
+ "no-relax-tls-le" \
+ ] \
+ ]
+
+ if [file exist "tmpdir/no-relax-tls-le"] {
+ set objdump_output2 [run_host_cmd "objdump" "-d tmpdir/no-relax-tls-le"]
+ if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output2] } {
+ pass "loongarch no-relax success"
+ } {
+ fail "loongarch no-relax fail"
+ }
+ }
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch old tls le .exe build" \
+ "" "" \
+ "" \
+ {old-tls-le.s} \
+ {} \
+ "old-tls-le" \
+ ] \
+ ]
+
+ if [file exist "tmpdir/old-tls-le"] {
+ set objdump_output3 [run_host_cmd "objdump" "-d tmpdir/old-tls-le"]
+ if { [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output3] } {
+ pass "loongarch old tls le success"
+ } {
+ fail "loongarch old tls le fail"
+ }
+ }
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch tls le realx compatible .exe build" \
+ "" "" \
+ "" \
+ {tls-relax-compatible-check-new.s tls-relax-compatible-check-old.s} \
+ {} \
+ "realx-compatible" \
+ ] \
+ ]
+
+ if [file exist "tmpdir/realx-compatible"] {
+ set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/realx-compatible"]
+ if { [ regexp ".addi.*st.*" $objdump_output4] && \
+ [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output4] } {
+ pass "loongarch tls le relax compatible check success"
+ } {
+ fail "loongarch tls le relax compatible check fail"
+ }
+ }
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch tls le no realx compatible .exe build" \
+ "--no-relax" "" \
+ "" \
+ {tls-relax-compatible-check-new.s tls-relax-compatible-check-old.s} \
+ {} \
+ "no-realx-compatible" \
+ ] \
+ ]
+ if [file exist "tmpdir/no-realx-compatible"] {
+ set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/no-realx-compatible"]
+ if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output4] && \
+ [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output4] } {
+ pass "loongarch tls le no-relax compatible check success"
+ } {
+ fail "loongarch tls le no-relax compatible check fail"
+ }
+ }
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch tls le realx bound-check .exe build" \
+ "" "" \
+ "" \
+ {relax-bound-check-tls-le.s} \
+ {} \
+ "relax-bound-check-tls-le" \
+ ] \
+ ]
+
+ if [file exist "tmpdir/relax-bound-check-tls-le"] {
+ set objdump_output5 [run_host_cmd "objdump" "-d tmpdir/relax-bound-check-tls-le"]
+ if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output5] && \
+ [ regexp ".addi.*st.*" $objdump_output5] } {
+ pass "loongarch no-relax success"
+ } {
+ fail "loongarch no-relax fail"
+ }
+ }
+
+ run_ld_link_tests \
+ [list \
+ [list \
+ "loongarch tls le no realx bound-check .exe build" \
+ "--no-relax" "" \
+ "" \
+ {relax-bound-check-tls-le.s} \
+ {} \
+ "no-relax-bound-check-tls-le" \
+ ] \
+ ]
+
+ if [file exist "tmpdir/no-relax-bound-check-tls-le"] {
+ set objdump_output5 [run_host_cmd "objdump" "-d tmpdir/no-relax-bound-check-tls-le"]
+ if { [ regexp ".*addi.*st.*" $objdump_output5] } {
+ pass "loongarch no-relax success"
+ } {
+ fail "loongarch no-relax fail"
+ }
+ }
+
# If symbol in data segment, offset need to sub segment align to prevent
# overflow.
if [check_pie_support] {
@@ -201,73 +268,6 @@ if [istarget loongarch64-*-*] {
]
}
- if [file exist "tmpdir/relax-tls-le"] {
- set objdump_output1 [run_host_cmd "objdump" "-d tmpdir/relax-tls-le"]
- if { [ regexp ".addi.*st.*" $objdump_output1] } {
- pass "loongarch relax success"
- } {
- fail "loongarch relax fail"
- }
- }
- if [file exist "tmpdir/no-relax-tls-le"] {
- set objdump_output2 [run_host_cmd "objdump" "-d tmpdir/no-relax-tls-le"]
- if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output2] } {
- pass "loongarch no-relax success"
- } {
- fail "loongarch no-relax fail"
- }
-
- }
- if [file exist "tmpdir/old-tls-le"] {
- set objdump_output3 [run_host_cmd "objdump" "-d tmpdir/old-tls-le"]
- if { [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output3] } {
- pass "loongarch old tls le success"
- } {
- fail "loongarch old tls le fail"
- }
-
- }
-
- if [file exist "tmpdir/realx-compatible"] {
- set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/realx-compatible"]
- if { [ regexp ".addi.*st.*" $objdump_output4] && \
- [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output4] } {
- pass "loongarch tls le relax compatible check success"
- } {
- fail "loongarch tls le relax compatible check fail"
- }
- }
-
- if [file exist "tmpdir/no-realx-compatible"] {
- set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/realx-compatible"]
- if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output4] && \
- [ regexp ".*lu12i.*ori.*add.*addi.*stptr.*" $objdump_output4] } {
- pass "loongarch tls le no-relax compatible check success"
- } {
- fail "loongarch tls le no-relax compatible check fail"
- }
- }
-
-
- if [file exist "tmpdir/relax-bound-check-tls-le"] {
- set objdump_output5 [run_host_cmd "objdump" "-d tmpdir/relax-bound-check-tls-le"]
- if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output5] && \
- [ regexp ".addi.*st.*" $objdump_output5] } {
- pass "loongarch no-relax success"
- } {
- fail "loongarch no-relax fail"
- }
-
- }
- if [file exist "tmpdir/no-relax-bound-check-tls-le"] {
- set objdump_output5 [run_host_cmd "objdump" "-d tmpdir/no-relax-bound-check-tls-le"]
- if { [ regexp ".*addi.*st.*" $objdump_output5] } {
- pass "loongarch no-relax success"
- } {
- fail "loongarch no-relax fail"
- }
- }
-
}
if [check_shared_lib_support] {
--
2.33.0

Some files were not shown because too many files have changed in this diff Show More