* [PATCH v3 1/5] LoongArch: bfd: Add support for tls le relax.
2023-12-15 10:06 [PATCH v3 0/5] LoongArch tls le model linker relaxation support changjiachen
@ 2023-12-15 10:06 ` changjiachen
2023-12-15 10:06 ` [PATCH v3 2/5] LoongArch: include: " changjiachen
` (4 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: changjiachen @ 2023-12-15 10:06 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
cailulu, luweining, wanglei, hejinyang, Lazy_Linux, mengqinggang,
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 | 76 +++++++++++++++++++++++++++++++++++++++++++
bfd/elfxx-loongarch.c | 50 ++++++++++++++++++++++++++++
bfd/libbfd.h | 3 ++
bfd/reloc.c | 6 ++++
5 files changed, 139 insertions(+)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 040d5560cdf..6b3303d99e9 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7460,8 +7460,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 024c5d4cd96..9f578af6ae3 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 += 0x800; \
+ 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,49 @@ loongarch_relax_delete_bytes (bfd *abfd,
return true;
}
+/* Relax tls le.
+ lu12i.w,add.d,addi.w,st.w/addi.w/ld.w
+ ====> addi.w,st.w/addi.w/ld.w. */
+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
@@ -4023,6 +4088,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 (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 7f298c08fd3..9f24307fffd 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. */
+ 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 (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] 9+ messages in thread
* [PATCH v3 2/5] LoongArch: include: Add support for tls le relax.
2023-12-15 10:06 [PATCH v3 0/5] LoongArch tls le model linker relaxation support changjiachen
2023-12-15 10:06 ` [PATCH v3 1/5] LoongArch: bfd: Add support for tls le relax changjiachen
@ 2023-12-15 10:06 ` changjiachen
2023-12-15 10:06 ` [PATCH v3 3/5] LoongArch: opcodes: " changjiachen
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: changjiachen @ 2023-12-15 10:06 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
cailulu, luweining, wanglei, hejinyang, Lazy_Linux, mengqinggang,
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 | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
index e31395e13d5..bccd36d452e 100644
--- a/include/elf/loongarch.h
+++ b/include/elf/loongarch.h
@@ -250,6 +250,18 @@ 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 rd,%le_hi20_r (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LE_HI20_R, 110)
+
+/* TLS-LE-ADD
+ add.d rd,rj,rk,%le_add_r (sym). */
+RELOC_NUMBER (R_LARCH_TLS_LE_ADD_R, 111)
+
+/* TLS-LE-ST
+ st.w/addi.w/ld.w rd,rj,%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] 9+ messages in thread
* [PATCH v3 3/5] LoongArch: opcodes: Add support for tls le relax.
2023-12-15 10:06 [PATCH v3 0/5] LoongArch tls le model linker relaxation support changjiachen
2023-12-15 10:06 ` [PATCH v3 1/5] LoongArch: bfd: Add support for tls le relax changjiachen
2023-12-15 10:06 ` [PATCH v3 2/5] LoongArch: include: " changjiachen
@ 2023-12-15 10:06 ` changjiachen
2023-12-15 10:06 ` [PATCH v3 4/5] LoongArch: gas: " changjiachen
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: changjiachen @ 2023-12-15 10:06 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
cailulu, luweining, wanglei, hejinyang, Lazy_Linux, mengqinggang,
changjiachen
Add new opcode for tls le relax.
opcode/ChangeLog:
* loongarch-opc.c: Add new loongarch opcode.
---
opcodes/loongarch-opc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index 15c7da6340c..38d96e96207 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -398,7 +398,8 @@ static struct loongarch_opcode loongarch_fix_opcodes[] =
{ 0x00080000, 0xfffe0000, "bytepick.w", "r0:5,r5:5,r10:5,u15:2", 0, 0, 0, 0 },
{ 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", 0, 0, 0, 0 }, /* In general add.d insn */
+ { 0x00108000, 0xffff8000, "add.d", "r0:5,r5:5,r10:5,s10:5", 0, 0, 0, 0 }, /* TLS LE model add.d insn */
{ 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] 9+ messages in thread
* [PATCH v3 4/5] LoongArch: gas: Add support for tls le relax.
2023-12-15 10:06 [PATCH v3 0/5] LoongArch tls le model linker relaxation support changjiachen
` (2 preceding siblings ...)
2023-12-15 10:06 ` [PATCH v3 3/5] LoongArch: opcodes: " changjiachen
@ 2023-12-15 10:06 ` changjiachen
2023-12-15 10:06 ` [PATCH v3 5/5] LoongArch: ld: " changjiachen
2023-12-15 12:34 ` [PATCH v3 0/5] LoongArch tls le model linker relaxation support Xi Ruoyao
5 siblings, 0 replies; 9+ messages in thread
From: changjiachen @ 2023-12-15 10:06 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
cailulu, luweining, wanglei, hejinyang, Lazy_Linux, mengqinggang,
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 59232832cf7..c97288fe0a1 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..0a343c11225 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)
--
2.40.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v3 5/5] LoongArch: ld: Add support for tls le relax.
2023-12-15 10:06 [PATCH v3 0/5] LoongArch tls le model linker relaxation support changjiachen
` (3 preceding siblings ...)
2023-12-15 10:06 ` [PATCH v3 4/5] LoongArch: gas: " changjiachen
@ 2023-12-15 10:06 ` changjiachen
2023-12-15 12:34 ` [PATCH v3 0/5] LoongArch tls le model linker relaxation support Xi Ruoyao
5 siblings, 0 replies; 9+ messages in thread
From: changjiachen @ 2023-12-15 10:06 UTC (permalink / raw)
To: binutils
Cc: xuchenghua, chenglulu, liuzhensong, xry111, i.swmail, maskray,
cailulu, luweining, wanglei, hejinyang, Lazy_Linux, mengqinggang,
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/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 | 19 +++
.../relax-bound-check-tls-le.s | 48 ++++++
ld/testsuite/ld-loongarch-elf/relax-tls-le.s | 17 ++
ld/testsuite/ld-loongarch-elf/relax.exp | 151 +++++++++++++++++-
.../tls-relax-compatible-check-new.s | 29 ++++
.../tls-relax-compatible-check-old.s | 27 ++++
6 files changed, 290 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 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..da62cd0224b
--- /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,%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 00000000000..bf605f2bf23
--- /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,%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 24d79ed5c20..5999b37f811 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 00000000000..194c7cf6833
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-new.s
@@ -0,0 +1,29 @@
+ .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 00000000000..c50b77f3f5f
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/tls-relax-compatible-check-old.s
@@ -0,0 +1,27 @@
+ .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.40.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3 0/5] LoongArch tls le model linker relaxation support.
2023-12-15 10:06 [PATCH v3 0/5] LoongArch tls le model linker relaxation support changjiachen
` (4 preceding siblings ...)
2023-12-15 10:06 ` [PATCH v3 5/5] LoongArch: ld: " changjiachen
@ 2023-12-15 12:34 ` Xi Ruoyao
2023-12-19 5:33 ` 常佳琛
5 siblings, 1 reply; 9+ messages in thread
From: Xi Ruoyao @ 2023-12-15 12:34 UTC (permalink / raw)
To: changjiachen, binutils
Cc: xuchenghua, chenglulu, liuzhensong, i.swmail, maskray, cailulu,
luweining, wanglei, hejinyang, Lazy_Linux, mengqinggang
On Fri, 2023-12-15 at 18:06 +0800, changjiachen wrote:
> First, after a test, the R_LARCH_TLS_LE_ADD_R can be generated using ".reloc.,R_LARCH_TLS_LE_ADD_R,sym",
> or "%le_add_r(sym)". However,".reloc" generates R_LARCH_TLS_LE_ADD_R relocation directly, and it is not
> easy to add "R_LARCH_RELAX" relocation. "%le_add_r(sym)" Adds the R_LARCH_TLS_LE_ADD_R and R_LARCH_RELAX
> relocation commands, which is easier to implement.
>
> Of course, there is another way to generate ".reloc.,R_LARCH_TLS_LE_ADD_R,sym" and
> ".reloc.,R_LARCH_RELAX,sym" directly in gcc. However, this implementation causes the
> -mrelax/-mno-relax option to be set in both gcc and gas, which can be confusing.
GCC 14 already have -mrelax/-mno-relax options. This is not confusing
at all.
> One problem with this is that add.d $r12,$r12,$r2 and add.d $r12,$r12,$r2,
> %le_add_r(sym) are too similar, so I have to add comments in loongarch_fix_opcodes[].
> The goal is to make it as clear as possible to developers.
No, normal developers (not Binutils developers) should not be mandated
to read Binutils code to understand something. OTOH they should read
the documentation of GAS. So make it clear somewhere in the doc.
And I've told you if you must go with an additional operand in add.d,
you should reject things like:
add.d $a0,$a0,$a0,8
but now:
$ cat t.s
add.d $a0,$a0,$a0,8
$ gas/as-new t.s
$ binutils/objdump -d a.out
a.out: file format elf64-loongarch
Disassembly of section .text:
0000000000000000 <.text>:
0: 0010b084 add.d $a0, $a0, $t0
Now is it clear that this behavior is unacceptable?
Is it too difficult or unreasonable to make it an error with message
"the fourth operand of the add.d instruction must be %le_add_r"?! Or
didn't I make it clear?
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re:Re: [PATCH v3 0/5] LoongArch tls le model linker relaxation support.
2023-12-15 12:34 ` [PATCH v3 0/5] LoongArch tls le model linker relaxation support Xi Ruoyao
@ 2023-12-19 5:33 ` 常佳琛
2023-12-19 10:21 ` Xi Ruoyao
0 siblings, 1 reply; 9+ messages in thread
From: 常佳琛 @ 2023-12-19 5:33 UTC (permalink / raw)
To: Xi Ruoyao, binutils
Cc: xuchenghua, chenglulu, liuzhensong, i.swmail, maskray, cailulu,
luweining, wanglei, hejinyang, Lazy_Linux, mengqinggang
[-- Attachment #1: Type: text/plain, Size: 3012 bytes --]
From: Xi Ruoyao <xry111@xry111.site>
Date: 2023-12-15 20:34:50
To: changjiachen <changjiachen@stu.xupt.edu.cn>,binutils@sourceware.org
Cc: xuchenghua@loongson.cn,chenglulu@loongson.cn,liuzhensong@loongson.cn,i.swmail@xen0n.name,maskray@google.com,cailulu@loongson.cn,luweining@loongson.cn,wanglei@loongson.cn,hejinyang@loongson.cn,Lazy_Linux@126.com,mengqinggang@loongson.cn
Subject: Re: [PATCH v3 0/5] LoongArch tls le model linker relaxation support.>On Fri, 2023-12-15 at 18:06 +0800, changjiachen wrote:
>> First, after a test, the R_LARCH_TLS_LE_ADD_R can be generated using ".reloc.,R_LARCH_TLS_LE_ADD_R,sym",
>> or "%le_add_r(sym)". However,".reloc" generates R_LARCH_TLS_LE_ADD_R relocation directly, and it is not
>> easy to add "R_LARCH_RELAX" relocation. "%le_add_r(sym)" Adds the R_LARCH_TLS_LE_ADD_R and R_LARCH_RELAX
>> relocation commands, which is easier to implement.
>>
>> Of course, there is another way to generate ".reloc.,R_LARCH_TLS_LE_ADD_R,sym" and
>> ".reloc.,R_LARCH_RELAX,sym" directly in gcc. However, this implementation causes the
>> -mrelax/-mno-relax option to be set in both gcc and gas, which can be confusing.
>
>GCC 14 already have -mrelax/-mno-relax options. This is not confusing
>at all.
>
>> One problem with this is that add.d $r12,$r12,$r2 and add.d $r12,$r12,$r2,
>> %le_add_r(sym) are too similar, so I have to add comments in loongarch_fix_opcodes[].
>> The goal is to make it as clear as possible to developers.
>
>No, normal developers (not Binutils developers) should not be mandated
>to read Binutils code to understand something. OTOH they should read
>the documentation of GAS. So make it clear somewhere in the doc.
>
>And I've told you if you must go with an additional operand in add.d,
>you should reject things like:
>
>add.d $a0,$a0,$a0,8
>
>but now:
>
>$ cat t.s
>add.d $a0,$a0,$a0,8
>$ gas/as-new t.s
>$ binutils/objdump -d a.out
>
>a.out: file format elf64-loongarch
>
>
>Disassembly of section .text:
>
>0000000000000000 <.text>:
> 0: 0010b084 add.d $a0, $a0, $t0
>
>Now is it clear that this behavior is unacceptable?
>
>Is it too difficult or unreasonable to make it an error with message
>"the fourth operand of the add.d instruction must be %le_add_r"?! Or
>didn't I make it clear?
Hello, I understand what you mean. For the fourth operand of tls add.d instruction,
I have made the following modifications.
For the case of "add.d $a0,$a0,$a0,8", that is, when the fourth operand of the tls add.d
instruction is not %le_add_r(sym), the modified assembler throws a "no match insn add.d $a0,$a0,$a0,8".
example:
a.s
add.d $a0,$a0,$a0,8
$ gas/as-new a.s
a.s: Assembler messages:
a.s:1: error:no match insn: add.d $a0,$a0,$a0,8
Can such modification solve the problem you raised?
I will add this change to v4 patch if possible.
I am very much looking forward to your suggestions again.
>
>--
>Xi Ruoyao <xry111@xry111.site>
>School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Re: [PATCH v3 0/5] LoongArch tls le model linker relaxation support.
2023-12-19 5:33 ` 常佳琛
@ 2023-12-19 10:21 ` Xi Ruoyao
0 siblings, 0 replies; 9+ messages in thread
From: Xi Ruoyao @ 2023-12-19 10:21 UTC (permalink / raw)
To: 常佳琛, binutils
Cc: xuchenghua, chenglulu, liuzhensong, i.swmail, maskray, cailulu,
luweining, wanglei, hejinyang, Lazy_Linux, mengqinggang
On Tue, 2023-12-19 at 13:33 +0800, 常佳琛 wrote:
> For the case of "add.d $a0,$a0,$a0,8", that is, when the fourth operand of the tls add.d
> instruction is not %le_add_r(sym), the modified assembler throws a "no match insn add.d $a0,$a0,$a0,8".
>
> example:
> a.s
> add.d $a0,$a0,$a0,8
> $ gas/as-new a.s
> a.s: Assembler messages: a.s:1: error:no match insn: add.d $a0,$a0,$a0,8
Ok to me. Thanks.
--
Xi Ruoyao <xry111@xry111.site>
School of Aerospace Science and Technology, Xidian University
^ permalink raw reply [flat|nested] 9+ messages in thread