Переглянути джерело

loongarch64: add TLSDESC support

Xing Li 6 місяців тому
батько
коміт
61399d4bd0
3 змінених файлів з 39 додано та 0 видалено
  1. 1 0
      arch/loongarch64/reloc.h
  2. 1 0
      include/elf.h
  3. 37 0
      src/ldso/loongarch64/tlsdesc.s

+ 1 - 0
arch/loongarch64/reloc.h

@@ -17,6 +17,7 @@
 #define REL_TPOFF       R_LARCH_TLS_TPREL64
 #define REL_RELATIVE    R_LARCH_RELATIVE
 #define REL_SYMBOLIC    R_LARCH_64
+#define REL_TLSDESC     R_LARCH_TLS_DESC64
 
 #define CRTJMP(pc,sp) __asm__ __volatile__( \
 	"move $sp, %1 ; jr %0" : : "r"(pc), "r"(sp) : "memory" )

+ 1 - 0
include/elf.h

@@ -3329,6 +3329,7 @@ enum
 #define R_LARCH_TLS_TPREL32                 10
 #define R_LARCH_TLS_TPREL64                 11
 #define R_LARCH_IRELATIVE                   12
+#define R_LARCH_TLS_DESC64                  14
 #define R_LARCH_MARK_LA                     20
 #define R_LARCH_MARK_PCREL                  21
 #define R_LARCH_SOP_PUSH_PCREL              22

+ 37 - 0
src/ldso/loongarch64/tlsdesc.s

@@ -0,0 +1,37 @@
+.text
+.global __tlsdesc_static
+.hidden __tlsdesc_static
+.type __tlsdesc_static,%function
+__tlsdesc_static:
+	ld.d $a0, $a0, 8
+	jr $ra
+# size_t __tlsdesc_dynamic(size_t *a)
+# {
+#      struct {size_t modidx,off;} *p = (void*)a[1];
+#      size_t *dtv = *(size_t**)(tp - 8);
+#      return dtv[p->modidx] + p->off - tp;
+# }
+.global __tlsdesc_dynamic
+.hidden __tlsdesc_dynamic
+.type __tlsdesc_dynamic,%function
+__tlsdesc_dynamic:
+	addi.d $sp, $sp, -16
+	st.d $t1, $sp, 0
+	st.d $t2, $sp, 8
+
+	ld.d $t2, $tp, -8 # t2=dtv
+
+	ld.d $a0, $a0, 8  # a0=&{modidx,off}
+	ld.d $t1, $a0, 8  # t1=off
+	ld.d $a0, $a0, 0  # a0=modidx
+	slli.d $a0, $a0, 3  # a0=8*modidx
+
+	add.d $a0, $a0, $t2  # a0=dtv+8*modidx
+	ld.d $a0, $a0, 0  # a0=dtv[modidx]
+	add.d $a0, $a0, $t1 # a0=dtv[modidx]+off
+	sub.d $a0, $a0, $tp # a0=dtv[modidx]+off-tp
+
+	ld.d $t1, $sp, 0
+	ld.d $t2, $sp, 8
+	addi.d $sp, $sp, 16
+	jr $ra