* [PATCH v1 1/5] LoongArch: bfd: Add support for tls le relax.
2023-12-01 9:07 [PATCH v1 0/5] LoongArch tls le model linker relaxation support changjiachen
@ 2023-12-01 9:07 ` changjiachen
2023-12-01 9:07 ` [PATCH v1 2/5] LoongArch: include: " changjiachen
` (5 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: changjiachen @ 2023-12-01 9:07 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
cailulu, luweining, wanglei, hejinyang, Lazy_Linux, changjiachen
Add tls le relax support and related relocs in bfd.
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 | 74 +++++++++++++++++++++++++++++++++++++++++++
bfd/elfxx-loongarch.c | 50 +++++++++++++++++++++++++++++
bfd/libbfd.h | 3 ++
bfd/reloc.c | 6 ++++
5 files changed, 137 insertions(+)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 79f7f24436c..3972b9b1a9a 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7457,8 +7457,12 @@ enum bfd_reloc_code_real
BFD_RELOC_LARCH_ADD_ULEB128,
BFD_RELOC_LARCH_SUB_ULEB128,
BFD_RELOC_LARCH_64_PCREL,
+ BFD_RELOC_LARCH_TLS_LE_HI20_R,
+ BFD_RELOC_LARCH_TLS_LE_ADD_R,
+ BFD_RELOC_LARCH_TLS_LE_LO12_R,
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 18ad3cc91ca..b8a3199d27a 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -738,6 +738,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;
@@ -2105,6 +2106,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:
@@ -2130,6 +2133,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:
@@ -2310,6 +2314,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 += 0xfff; \
+ relocation = relocation & ~(bfd_vma)0xfff; \
+ })
+
/* For example: pc is 0x11000010000100, symbol is 0x1812348ffff812
offset = (0x1812348ffff812 & ~0xfff) - (0x11000010000100 & ~0xfff)
= 0x712347ffff000
@@ -3205,6 +3219,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)
@@ -3375,6 +3396,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);
@@ -3735,6 +3757,47 @@ loongarch_relax_delete_bytes (bfd *abfd,
return true;
}
+/* Relax tls le. */
+static bool
+loongarch_relax_tls_le (bfd *abfd, asection *sec,
+ Elf_Internal_Rela *rel_hi,
+ 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_hi->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_hi + 1)->r_info)
+ == R_LARCH_RELAX && symval < 0x800)
+ {
+ switch (ELFNN_R_TYPE (rel_hi->r_info))
+ {
+ case R_LARCH_TLS_LE_HI20_R:
+ case R_LARCH_TLS_LE_ADD_R:
+ /* delete insn. */
+ rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
+ R_LARCH_DELETE);
+ 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_hi->r_offset);
+ break;
+ default:
+ break;
+ }
+ }
+ return true;
+}
/* Relax pcalau12i,addi.d => pcaddi. */
static bool
@@ -4002,6 +4065,17 @@ 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 (info->relax_pass == 0)
+ {
+ if (i + 2 > sec->reloc_count)
+ break;
+ loongarch_relax_tls_le (abfd, sec, rel, info, symval);
+ }
+ break;
+
case R_LARCH_PCALA_HI20:
if (info->relax_pass == 0)
{
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index a970a257aa9..a24333e6838 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -1547,6 +1547,56 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
NULL, /* adjust_reloc_bits */
NULL), /* larch_reloc_type_name */
+ LOONGARCH_HOWTO (R_LARCH_TLS_LE_HI20_R, /* type (110). */
+ 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 (111). */
+ 0, /* rightshift. */
+ 1, /* 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. */
+ "tls_le_add_r"), /* larch_reloc_type_name. */
+
+ LOONGARCH_HOWTO (R_LARCH_TLS_LE_LO12_R, /* type (112). */
+ 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. */
};
reloc_howto_type *
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index cc432677a81..4b0e9405e76 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3599,6 +3599,9 @@ 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_TLS_LE_HI20_R",
+ "BFD_RELOC_LARCH_TLS_LE_ADD_R",
+ "BFD_RELOC_LARCH_TLS_LE_LO12_R",
"@@overflow: BFD_RELOC_UNUSED@@",
};
#endif
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 93ebad879e0..f6312ff9b77 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -8291,6 +8291,12 @@ ENUMX
ENUMX
BFD_RELOC_LARCH_64_PCREL
+ENUMX
+ BFD_RELOC_LARCH_TLS_LE_HI20_R
+ENUMX
+ BFD_RELOC_LARCH_TLS_LE_ADD_R
+ENUMX
+ BFD_RELOC_LARCH_TLS_LE_LO12_R
ENUMDOC
LARCH relocations.
--
2.40.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v1 2/5] LoongArch: include: Add support for tls le relax.
2023-12-01 9:07 [PATCH v1 0/5] LoongArch tls le model linker relaxation support changjiachen
2023-12-01 9:07 ` [PATCH v1 1/5] LoongArch: bfd: Add support for tls le relax changjiachen
@ 2023-12-01 9:07 ` changjiachen
2023-12-01 9:07 ` [PATCH v1 3/5] LoongArch: opcodes: " changjiachen
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: changjiachen @ 2023-12-01 9:07 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
cailulu, luweining, wanglei, hejinyang, Lazy_Linux, changjiachen
Add new relocs number for tls le relax.
include/ChangeLog:
* elf/loongarch.h:
(RELOC_NUMBER (R_LARCH_TLS_LE_HI20_R, 110)): New relocs number.
(RELOC_NUMBER (R_LARCH_TLS_LE_ADD_R, 111)): Likewise.
(RELOC_NUMBER (R_LARCH_TLS_LE_LO12_R, 112)): Likewise.
---
include/elf/loongarch.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
index e31395e13d5..e04ee99bcf2 100644
--- a/include/elf/loongarch.h
+++ b/include/elf/loongarch.h
@@ -250,6 +250,19 @@ RELOC_NUMBER (R_LARCH_ADD_ULEB128, 107)
RELOC_NUMBER (R_LARCH_SUB_ULEB128, 108)
RELOC_NUMBER (R_LARCH_64_PCREL, 109)
+/* TLS-LE-LUI
+ lu12i.w $r12,%le_hi20_r (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LE_HI20_R, 110)
+
+/* TLS-LE-ADD
+ add.d $r12,$r12,$r2,
+ %tls_le_add_r (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LE_ADD_R, 111)
+
+/* TLS-LE-ST
+ st.w $r12,%le_lo12_r (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LE_LO12_R, 112)
+
END_RELOC_NUMBERS (R_LARCH_count)
--
2.40.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v1 3/5] LoongArch: opcodes: Add support for tls le relax.
2023-12-01 9:07 [PATCH v1 0/5] LoongArch tls le model linker relaxation support changjiachen
2023-12-01 9:07 ` [PATCH v1 1/5] LoongArch: bfd: Add support for tls le relax changjiachen
2023-12-01 9:07 ` [PATCH v1 2/5] LoongArch: include: " changjiachen
@ 2023-12-01 9:07 ` changjiachen
2023-12-01 9:47 ` Xi Ruoyao
2023-12-01 9:07 ` [PATCH v1 4/5] LoongArch: gas: " changjiachen
` (3 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: changjiachen @ 2023-12-01 9:07 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
cailulu, luweining, wanglei, hejinyang, Lazy_Linux, changjiachen
Add new opcode for tls le relax.
opcode/ChangeLog:
* loongarch-opc.c: Add new loongarch opcode.
---
opcodes/loongarch-opc.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index 82b88bdad2a..e9ced5383e5 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -399,6 +399,7 @@ static struct loongarch_opcode loongarch_fix_opcodes[] =
{ 0x000c0000, 0xfffc0000, "bytepick.d", "r0:5,r5:5,r10:5,u15:3", 0, 0, 0, 0 },
{ 0x00100000, 0xffff8000, "add.w", "r0:5,r5:5,r10:5", 0, 0, 0, 0 },
{ 0x00108000, 0xffff8000, "add.d", "r0:5,r5:5,r10:5", 0, 0, 0, 0 },
+ { 0x00108000, 0xffff8000, "add.d", "r0:5,r5:5,r10:5,s10:5", 0, 0, 0, 0 },
{ 0x00110000, 0xffff8000, "sub.w", "r0:5,r5:5,r10:5", 0, 0, 0, 0 },
{ 0x00118000, 0xffff8000, "sub.d", "r0:5,r5:5,r10:5", 0, 0, 0, 0 },
{ 0x00120000, 0xffff8000, "slt", "r0:5,r5:5,r10:5", 0, 0, 0, 0 },
--
2.40.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v1 3/5] LoongArch: opcodes: Add support for tls le relax.
2023-12-01 9:07 ` [PATCH v1 3/5] LoongArch: opcodes: " changjiachen
@ 2023-12-01 9:47 ` Xi Ruoyao
0 siblings, 0 replies; 11+ messages in thread
From: Xi Ruoyao @ 2023-12-01 9:47 UTC (permalink / raw)
To: changjiachen, binutils
Cc: xuchenghua, chenglulu, liuzhensong, i.swmail, maskray, cailulu,
luweining, wanglei, hejinyang, Lazy_Linux
On Fri, 2023-12-01 at 17:07 +0800, changjiachen wrote:
> + { 0x00108000, 0xffff8000, "add.d", "r0:5,r5:5,r10:5,s10:5", 0, 0, 0, 0 },
Let's not do this. This allows wrongly written assembly code like
"add.d $r12,$r12,$r12,114" undetected.
If you just want a relocation you can always emit it with a .reloc
directive.
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v1 4/5] LoongArch: gas: Add support for tls le relax.
2023-12-01 9:07 [PATCH v1 0/5] LoongArch tls le model linker relaxation support changjiachen
` (2 preceding siblings ...)
2023-12-01 9:07 ` [PATCH v1 3/5] LoongArch: opcodes: " changjiachen
@ 2023-12-01 9:07 ` changjiachen
2023-12-01 9:07 ` [PATCH v1 5/5] LoongArch: ld: " changjiachen
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: changjiachen @ 2023-12-01 9:07 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
cailulu, luweining, wanglei, hejinyang, Lazy_Linux, changjiachen
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.
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/config/tc-loongarch.c | 12 ++++++++++--
gas/testsuite/gas/loongarch/reloc.d | 18 ++++++++++++++++++
gas/testsuite/gas/loongarch/reloc.s | 11 +++++++++++
3 files changed, 39 insertions(+), 2 deletions(-)
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index d1ce111c186..71bce1b85dc 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -680,9 +680,8 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
as_fatal (
_("not support reloc bit-field\nfmt: %c%c %s\nargs: %s"),
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.
@@ -690,6 +689,15 @@ 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
+ || BFD_RELOC_LARCH_TLS_LE_ADD_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/reloc.d b/gas/testsuite/gas/loongarch/reloc.d
index c3820c55f98..0458830f30b 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 a67fecd9429..182d7f81c71 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,%tls_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,%tls_le_add_r(TLSL1 + 0x8)
+st.w $r5,$r4,%le_lo12_r(TLSL1 + 0x8)
--
2.40.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v1 5/5] LoongArch: ld: Add support for tls le relax.
2023-12-01 9:07 [PATCH v1 0/5] LoongArch tls le model linker relaxation support changjiachen
` (3 preceding siblings ...)
2023-12-01 9:07 ` [PATCH v1 4/5] LoongArch: gas: " changjiachen
@ 2023-12-01 9:07 ` changjiachen
2023-12-01 9:56 ` [PATCH v1 0/5] LoongArch tls le model linker relaxation support Xi Ruoyao
2023-12-02 1:55 ` Jinyang He
6 siblings, 0 replies; 11+ messages in thread
From: changjiachen @ 2023-12-01 9:07 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
cailulu, luweining, wanglei, hejinyang, Lazy_Linux, changjiachen
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/relax-check-tls-le.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 | 19 +++
.../relax-bound-check-tls-le.s | 48 ++++++
.../ld-loongarch-elf/relax-check-tls-le.s | 43 ++++++
ld/testsuite/ld-loongarch-elf/relax-tls-le.s | 17 ++
ld/testsuite/ld-loongarch-elf/relax.exp | 146 +++++++++++++++++-
.../tls-relax-compatible-check-old.s | 39 +++++
6 files changed, 311 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-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-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 00000000000..290c4c61c18
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/old-tls-le.s
@@ -0,0 +1,19 @@
+ .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 00000000000..55e05fe12c2
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-bound-check-tls-le.s
@@ -0,0 +1,48 @@
+ .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,%tls_le_hi20(count1)
+ add.d $r12,$r12,$r2,%tprel_add(count1)
+ addi.w $r13,$r0,1 # 0x1
+ st.w $r13,$r12,%tls_le_lo12(count1)
+ lu12i.w $r12,%tls_le_hi20(count2)
+ add.d $r12,$r12,$r2,%tprel_add(count2)
+ addi.w $r13,$r0,2 # 0x2
+ st.w $r13,$r12,%tls_le_lo12(count2)
+ lu12i.w $r12,%tls_le_hi20(count3)
+ add.d $r12,$r12,$r2,%tprel_add(count3)
+ addi.w $r13,$r0,3 # 0x3
+ st.w $r13,$r12,%tls_le_lo12(count3)
+ lu12i.w $r12,%tls_le_hi20(count4)
+ add.d $r12,$r12,$r2,%tprel_add(count4)
+ addi.w $r13,$r0,4 # 0x4
+ st.w $r13,$r12,%tls_le_lo12(count4)
+
diff --git a/ld/testsuite/ld-loongarch-elf/relax-check-tls-le.s b/ld/testsuite/ld-loongarch-elf/relax-check-tls-le.s
new file mode 100644
index 00000000000..fe564dd49e0
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-check-tls-le.s
@@ -0,0 +1,43 @@
+ .file "tls_relax_compatible_check_new.c"
+ .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 = .
+ .cfi_startproc
+ addi.d $r3,$r3,-16
+ .cfi_def_cfa_offset 16
+ st.d $r1,$r3,8
+ stptr.d $r22,$r3,0
+ .cfi_offset 1, -8
+ .cfi_offset 22, -16
+ addi.d $r22,$r3,16
+ .cfi_def_cfa 22, 0
+ bl %plt(old)
+ lu12i.w $r12,%tls_le_hi20(new)
+ add.d $r12,$r12,$r2,%tprel_add(new)
+ addi.w $r13,$r0,2 # 0x2
+ st.w $r13,$r12,%tls_le_lo12(new)
+ or $r12,$r0,$r0
+ or $r4,$r12,$r0
+ ld.d $r1,$r3,8
+ .cfi_restore 1
+ ldptr.d $r22,$r3,0
+ .cfi_restore 22
+ addi.d $r3,$r3,16
+ .cfi_def_cfa_register 3
+ jr $r1
+ .cfi_endproc
+.LFE0:
+ .size main, .-main
+ .ident "GCC: (GNU) 14.0.0 20230526 (experimental)"
+ .section .note.GNU-stack,"",@progbits
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 00000000000..1f8dcc3edda
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-tls-le.s
@@ -0,0 +1,17 @@
+ .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,%tls_le_hi20(a)
+ add.d $r12,$r12,$r2,%tprel_add(a)
+ addi.w $r13,$r0,1 # 0x1
+ st.w $r13,$r12,%tls_le_lo12(a)
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index 7ff876d7914..1520cfc0dba 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" \
+ "" \
+ "" \
+ {relax-check-tls-le.s tls-relax-compatible-check-old.s} \
+ {} \
+ "realx-compatible" \
+ ] \
+ ]
+
+ set no_relax_compatible [list \
+ [list \
+ "no_relax_compatible" \
+ "-Wl,--no-relax" \
+ "" \
+ {relax-check-tls-le.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"]
@@ -44,8 +126,70 @@ if [istarget loongarch64-*-*] {
fail "loongarch relax"
}
}
- }
+ 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"] {
+ if { [catch {exec tmpdir/realx-compatible} number]} {
+ fail "loongarch tls le relax compatible check fail"
+ } {
+ pass "loongarch tls le relax compatible check success"
+ }
+ }
+
+ if [file exist "tmpdir/no-realx-compatible"] {
+ if { [catch {exec tmpdir/no-realx-compatible} number] } {
+ fail "loongarch tls le no-relax compatible check fail"
+ } {
+ pass "loongarch tls le no-relax compatible check success"
+ }
+ }
+
+
+ if [file exist "tmpdir/relax-bound-check-tls-le"] {
+ set objdump_output4 [run_host_cmd "objdump" "-d tmpdir/relax-bound-check-tls-le"]
+ if { [ regexp ".*lu12i.*add.*addi.*st.*" $objdump_output4] && \
+ [ regexp ".addi.*st.*" $objdump_output4] } {
+ 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_output4] } {
+ 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-old.s b/ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-old.s
new file mode 100644
index 00000000000..9adb657a87d
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-old.s
@@ -0,0 +1,39 @@
+ .file "tls_relax_compatible_check_old.c"
+ .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 = .
+ .cfi_startproc
+ addi.d $r3,$r3,-16
+ .cfi_def_cfa_offset 16
+ st.d $r22,$r3,8
+ .cfi_offset 22, -8
+ addi.d $r22,$r3,16
+ .cfi_def_cfa 22, 0
+ 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
+ .cfi_restore 22
+ addi.d $r3,$r3,16
+ .cfi_def_cfa_register 3
+ jr $r1
+ .cfi_endproc
+.LFE0:
+ .size old, .-old
+ .ident "GCC: (GNU) 13.0.1 20230316 (experimental)"
+ .section .note.GNU-stack,"",@progbits
--
2.40.0
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v1 0/5] LoongArch tls le model linker relaxation support.
2023-12-01 9:07 [PATCH v1 0/5] LoongArch tls le model linker relaxation support changjiachen
` (4 preceding siblings ...)
2023-12-01 9:07 ` [PATCH v1 5/5] LoongArch: ld: " changjiachen
@ 2023-12-01 9:56 ` Xi Ruoyao
2023-12-02 1:55 ` Jinyang He
6 siblings, 0 replies; 11+ messages in thread
From: Xi Ruoyao @ 2023-12-01 9:56 UTC (permalink / raw)
To: changjiachen, binutils
Cc: xuchenghua, chenglulu, liuzhensong, i.swmail, maskray, cailulu,
luweining, wanglei, hejinyang, Lazy_Linux
On Fri, 2023-12-01 at 17:07 +0800, changjiachen wrote:
> R_LARCH_TLS_LE_HI20_R
> R_LARCH_TLS_LE_LO12_R
> R_LARCH_TLS_LE_ADD_R
Why do we need them? Why not just use a combination of R_LARCH_RELAX
and R_LARCH_TLS_LE_HI20/LO12?
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v1 0/5] LoongArch tls le model linker relaxation support.
2023-12-01 9:07 [PATCH v1 0/5] LoongArch tls le model linker relaxation support changjiachen
` (5 preceding siblings ...)
2023-12-01 9:56 ` [PATCH v1 0/5] LoongArch tls le model linker relaxation support Xi Ruoyao
@ 2023-12-02 1:55 ` Jinyang He
2023-12-02 2:49 ` chenglulu
2023-12-04 4:37 ` 常佳琛
6 siblings, 2 replies; 11+ messages in thread
From: Jinyang He @ 2023-12-02 1:55 UTC (permalink / raw)
To: changjiachen, binutils
Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
cailulu, luweining, wanglei, Lazy_Linux
On 2023-12-01 17:07, changjiachen wrote:
> This is the v1 version of patches to support loongarch linker tls le model relax.
>
> This support does three main things:
>
> 1. Modify LoongArch tls le model assembly instruction sequence.
>
> This change is mainly implemented in gcc. Due to the characteristics
> of st.w instruction in Loongarch and the unique addressing mode of
> tls le model, in order to implement tls le model linker relax, it is
> decided to change the tls le model instruction sequence.
>
> The specific changes are as follows:
>
> example: __thread int a = 1;
>
> old insn sequence:
>
> lu12i.w $r12,%le_hi20_r(a)
> ori $r12,$r12,%le_lo12_r(a)
> add.d $r12,$r12,$r2,%le_add_r(a)
> li.w $r13,$r0,1
> stptr.w $r13,$r12,0
Hi,
It's more complex than I thought as you said it is mainly implemented
in gcc. Now I compile it, in archlinux, by gcc 13.2.1, and insn sequence
like follows,
lu12i.w $r12,%le_hi20(a)
ori $r12,$r12,%le_lo12(a)
addi.w $r13,$r0,1
stx.w $r13,$r12,$r2
It use `stx.w` rather than `st.w` or `stptr.w`. Will the gcc implementation
change this sequence?
>
> new insn sequence:
>
> lu12i.w $r12,%le_hi20_r(a)
> add.d $r12,$r12,$r2,%le_add_r(a)
> li.w $r13,$r0,1
> st.w $r13,$r12,%le_lo12_r(a)
In old sequence, $r12 is the real address of "a". In new sequence, $r12 is
not the real address of "a". How about we use $r12 after this sequence?
> 2. Added LoongArch three relocations related to tls le model relax.
>
> In order to ensure forward compatibility of binutils versions and
> implement tls le model relax, it was decided to add three relocation items.
>
> The relocation items are as follows:
>
> R_LARCH_TLS_LE_HI20_R
> R_LARCH_TLS_LE_LO12_R
> R_LARCH_TLS_LE_ADD_R
>
> 3. Implement Loongarch tls le model relax in ld.
>
> This change will add a loongarch_relax_tls_le function to relax tls le model.
>
> The instructions before and after relax change as follows:
>
> example: __thread int a = 1;
>
> before relax insn:
>
> lu12i.w $t0, 0
> add.d $t0, $t0, $tp
> li.w $t1, 1
> st.w $t1, $t0, 0
>
> after relax insn:
>
> li.w $t1, 1
> st.w $t1, $tp, 0
>
> changjiachen (5):
> LoongArch: bfd: Add support for tls le relax.
> LoongArch: include: Add support for tls le relax.
> LoongArch: opcodes: Add support for tls le relax.
> LoongArch: gas: Add support for tls le relax.
> LoongArch: ld: Add support for tls le relax.
>
> bfd/bfd-in2.h | 4 +
> bfd/elfnn-loongarch.c | 74 +++++++++
> bfd/elfxx-loongarch.c | 50 ++++++
> bfd/libbfd.h | 3 +
> bfd/reloc.c | 6 +
> gas/config/tc-loongarch.c | 12 +-
> gas/testsuite/gas/loongarch/reloc.d | 18 +++
> gas/testsuite/gas/loongarch/reloc.s | 11 ++
> include/elf/loongarch.h | 13 ++
> ld/testsuite/ld-loongarch-elf/old-tls-le.s | 19 +++
> .../relax-bound-check-tls-le.s | 48 ++++++
> .../ld-loongarch-elf/relax-check-tls-le.s | 43 ++++++
> ld/testsuite/ld-loongarch-elf/relax-tls-le.s | 17 ++
> ld/testsuite/ld-loongarch-elf/relax.exp | 146 +++++++++++++++++-
> .../tls-relax-compatible-check-old.s | 39 +++++
> opcodes/loongarch-opc.c | 1 +
> 16 files changed, 501 insertions(+), 3 deletions(-)
> 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-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-old.s
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH v1 0/5] LoongArch tls le model linker relaxation support.
2023-12-02 1:55 ` Jinyang He
@ 2023-12-02 2:49 ` chenglulu
2023-12-04 4:37 ` 常佳琛
1 sibling, 0 replies; 11+ messages in thread
From: chenglulu @ 2023-12-02 2:49 UTC (permalink / raw)
To: Jinyang He, changjiachen, binutils
Cc: xuchenghua, liuzhensong, xry111, i.swmail, maskray, cailulu,
luweining, wanglei, Lazy_Linux
在 2023/12/2 上午9:55, Jinyang He 写道:
> On 2023-12-01 17:07, changjiachen wrote:
>
>> This is the v1 version of patches to support loongarch linker tls le
>> model relax.
>>
>> This support does three main things:
>>
>> 1. Modify LoongArch tls le model assembly instruction sequence.
>>
>> This change is mainly implemented in gcc. Due to the characteristics
>> of st.w instruction in Loongarch and the unique addressing mode of
>> tls le model, in order to implement tls le model linker relax, it is
>> decided to change the tls le model instruction sequence.
>>
>> The specific changes are as follows:
>>
>> example: __thread int a = 1;
>>
>> old insn sequence:
>>
>> lu12i.w $r12,%le_hi20_r(a)
>> ori $r12,$r12,%le_lo12_r(a)
>> add.d $r12,$r12,$r2,%le_add_r(a)
>> li.w $r13,$r0,1
>> stptr.w $r13,$r12,0
>
> Hi,
>
>
> It's more complex than I thought as you said it is mainly implemented
> in gcc. Now I compile it, in archlinux, by gcc 13.2.1, and insn sequence
> like follows,
>
> lu12i.w $r12,%le_hi20(a)
> ori $r12,$r12,%le_lo12(a)
> addi.w $r13,$r0,1
> stx.w $r13,$r12,$r2
>
> It use `stx.w` rather than `st.w` or `stptr.w`. Will the gcc
> implementation
> change this sequence?
>
First, the compilation generated in this scenario should be as follows
(at the O0 optimization level):
lu12i.w $r12,%le_hi20(a)
ori $r12,$r12,%le_lo12(a)
add.d $r12,$r12,$r2
addi.w $r13,$r0,1 # 0x1
stptr.w $r13,$r12,0
After adding optimizations, this sequence may be optimized,
e.g. O2 will generate the following:
lu12i.w $r12,%le_hi20(.LANCHOR0)
addi.w $r13,$r0,1 # 0x1
ori $r12,$r12,%le_lo12(.LANCHOR0)
stx.w $r13,$r12,$r2
At the same time, the instruction sequence may also change.
Lulu
>
>>
>> new insn sequence:
>>
>> lu12i.w $r12,%le_hi20_r(a)
>> add.d $r12,$r12,$r2,%le_add_r(a)
>> li.w $r13,$r0,1
>> st.w $r13,$r12,%le_lo12_r(a)
>
> In old sequence, $r12 is the real address of "a". In new sequence,
> $r12 is
> not the real address of "a". How about we use $r12 after this sequence?
>
>
>> 2. Added LoongArch three relocations related to tls le model relax.
>>
>> In order to ensure forward compatibility of binutils versions and
>> implement tls le model relax, it was decided to add three relocation
>> items.
>>
>> The relocation items are as follows:
>>
>> R_LARCH_TLS_LE_HI20_R
>> R_LARCH_TLS_LE_LO12_R
>> R_LARCH_TLS_LE_ADD_R
>>
>> 3. Implement Loongarch tls le model relax in ld.
>>
>> This change will add a loongarch_relax_tls_le function to relax tls
>> le model.
>>
>> The instructions before and after relax change as follows:
>>
>> example: __thread int a = 1;
>>
>> before relax insn:
>>
>> lu12i.w $t0, 0
>> add.d $t0, $t0, $tp
>> li.w $t1, 1
>> st.w $t1, $t0, 0
>>
>> after relax insn:
>>
>> li.w $t1, 1
>> st.w $t1, $tp, 0
>>
>> changjiachen (5):
>> LoongArch: bfd: Add support for tls le relax.
>> LoongArch: include: Add support for tls le relax.
>> LoongArch: opcodes: Add support for tls le relax.
>> LoongArch: gas: Add support for tls le relax.
>> LoongArch: ld: Add support for tls le relax.
>>
>> bfd/bfd-in2.h | 4 +
>> bfd/elfnn-loongarch.c | 74 +++++++++
>> bfd/elfxx-loongarch.c | 50 ++++++
>> bfd/libbfd.h | 3 +
>> bfd/reloc.c | 6 +
>> gas/config/tc-loongarch.c | 12 +-
>> gas/testsuite/gas/loongarch/reloc.d | 18 +++
>> gas/testsuite/gas/loongarch/reloc.s | 11 ++
>> include/elf/loongarch.h | 13 ++
>> ld/testsuite/ld-loongarch-elf/old-tls-le.s | 19 +++
>> .../relax-bound-check-tls-le.s | 48 ++++++
>> .../ld-loongarch-elf/relax-check-tls-le.s | 43 ++++++
>> ld/testsuite/ld-loongarch-elf/relax-tls-le.s | 17 ++
>> ld/testsuite/ld-loongarch-elf/relax.exp | 146 +++++++++++++++++-
>> .../tls-relax-compatible-check-old.s | 39 +++++
>> opcodes/loongarch-opc.c | 1 +
>> 16 files changed, 501 insertions(+), 3 deletions(-)
>> 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-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-old.s
>>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re:Re: [PATCH v1 0/5] LoongArch tls le model linker relaxation support.
2023-12-02 1:55 ` Jinyang He
2023-12-02 2:49 ` chenglulu
@ 2023-12-04 4:37 ` 常佳琛
1 sibling, 0 replies; 11+ messages in thread
From: 常佳琛 @ 2023-12-04 4:37 UTC (permalink / raw)
To: Jinyang He, binutils
Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
cailulu, luweining, wanglei, Lazy_Linux
[-- Attachment #1: Type: text/plain, Size: 5453 bytes --]
From: Jinyang He <hejinyang@loongson.cn>
Date: 2023-12-02 09:55:14
To: changjiachen <changjiachen@stu.xupt.edu.cn>,binutils@sourceware.org
Cc: xuchenghua@loongson.cn,chenglulu@loongson.cn,liuzhensong@loongson.cn,xry111@xry111.site,i.swmail@xen0n.name,maskray@google.com,cailulu@loongson.cn,luweining@loongson.cn,wanglei@loongson.cn,Lazy_Linux@126.com
Subject: Re: [PATCH v1 0/5] LoongArch tls le model linker relaxation support.>On 2023-12-01 17:07, changjiachen wrote:
>
>> This is the v1 version of patches to support loongarch linker tls le model relax.
>>
>> This support does three main things:
>>
>> 1. Modify LoongArch tls le model assembly instruction sequence.
>>
>> This change is mainly implemented in gcc. Due to the characteristics
>> of st.w instruction in Loongarch and the unique addressing mode of
>> tls le model, in order to implement tls le model linker relax, it is
>> decided to change the tls le model instruction sequence.
>>
>> The specific changes are as follows:
>>
>> example: __thread int a = 1;
>>
>> old insn sequence:
>>
>> lu12i.w $r12,%le_hi20_r(a)
>> ori $r12,$r12,%le_lo12_r(a)
>> add.d $r12,$r12,$r2,%le_add_r(a)
>> li.w $r13,$r0,1
>> stptr.w $r13,$r12,0
>
>Hi,
>
>
>It's more complex than I thought as you said it is mainly implemented
>in gcc. Now I compile it, in archlinux, by gcc 13.2.1, and insn sequence
>like follows,
>
>lu12i.w $r12,%le_hi20(a)
>ori $r12,$r12,%le_lo12(a)
>addi.w $r13,$r0,1
>stx.w $r13,$r12,$r2
>
>It use `stx.w` rather than `st.w` or `stptr.w`. Will the gcc implementation
>change this sequence?
>
>>
>> new insn sequence:
>>
>> lu12i.w $r12,%le_hi20_r(a)
>> add.d $r12,$r12,$r2,%le_add_r(a)
>> li.w $r13,$r0,1
>> st.w $r13,$r12,%le_lo12_r(a)
>
>In old sequence, $r12 is the real address of "a". In new sequence, $r12 is
>not the real address of "a". How about we use $r12 after this sequence?
>
>To solve this problem, I will give you the following explanation
> In the new and old sequences, the final r12 value is different,
> and there are some small changes in the address calculation of the tls variable.
>
> The address calculation of the tls variable is of the form tp+offset.
>
> In the old sequence:
> In the old sequence, the hi20 and lo12 parts of the offset of the tls variable
> were computed first, then the entire offet and tp were added together, and
> the result was stored in r12.
>
> In the new sequence:
> In the new sequence, the hi20 part of the offset of the tls variable is computed,
> the hi20 part and tp are added together, and the result is stored in r12. The immediate
> portion of the st.w instruction stores the lo12 portion of the tls variable, and finally the st.w
> instruction stores the value in the address r12+offset(lo12).
>
> To sum up, in the old sequence, r12 stores the real address of tls variable (tp+offset(hi20)+offset(lo12)),
> while in the new sequence r12 does not store the real address of tls variable (tp+offset(hi20)),
> but takes advantage of the instruction characteristics of st.w. So the new sequence and the old
> sequence actually point to the same address.
>
> Note: st.w rd, rj, s12
> The memory address of this instruction is the sum of the value in the universal register rj
> and the 12-bit immediate number si12 after the symbol extension.
> >> 2. Added LoongArch three relocations related to tls le model relax. >> >> In order to ensure forward compatibility of binutils versions and >> implement tls le model relax, it was decided to add three relocation items. >> >> The relocation items are as follows: >> >> R_LARCH_TLS_LE_HI20_R >> R_LARCH_TLS_LE_LO12_R >> R_LARCH_TLS_LE_ADD_R >> >> 3. Implement Loongarch tls le model relax in ld. >> >> This change will add a loongarch_relax_tls_le function to relax tls le model. >> >> The instructions before and after relax change as follows: >> >> example: __thread int a = 1; >> >> before relax insn: >> >> lu12i.w $t0, 0 >> add.d $t0, $t0, $tp >> li.w $t1, 1 >> st.w $t1, $t0, 0 >> >> after relax insn: >> >> li.w $t1, 1 >> st.w $t1, $tp, 0 >> >> changjiachen (5): >> LoongArch: bfd: Add support for tls le relax. >> LoongArch: include: Add support for tls le relax. >> LoongArch: opcodes: Add support for tls le relax. >> LoongArch: gas: Add support for tls le relax. >> LoongArch: ld: Add support for tls le relax. >> >> bfd/bfd-in2.h | 4 + >> bfd/elfnn-loongarch.c | 74 +++++++++ >> bfd/elfxx-loongarch.c | 50 ++++++ >> bfd/libbfd.h | 3 + >> bfd/reloc.c | 6 + >> gas/config/tc-loongarch.c | 12 +- >> gas/testsuite/gas/loongarch/reloc.d | 18 +++ >> gas/testsuite/gas/loongarch/reloc.s | 11 ++ >> include/elf/loongarch.h | 13 ++ >> ld/testsuite/ld-loongarch-elf/old-tls-le.s | 19 +++ >> .../relax-bound-check-tls-le.s | 48 ++++++ >> .../ld-loongarch-elf/relax-check-tls-le.s | 43 ++++++ >> ld/testsuite/ld-loongarch-elf/relax-tls-le.s | 17 ++ >> ld/testsuite/ld-loongarch-elf/relax.exp | 146 +++++++++++++++++- >> .../tls-relax-compatible-check-old.s | 39 +++++ >> opcodes/loongarch-opc.c | 1 + >> 16 files changed, 501 insertions(+), 3 deletions(-) >> 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-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-old.s >> >
^ permalink raw reply [flat|nested] 11+ messages in thread