511 lines
18 KiB
Diff
511 lines
18 KiB
Diff
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
|
|
|