]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
LoongArch: Add pointer mangling support.
authorcaiyinyu <caiyinyu@loongson.cn>
Wed, 10 Aug 2022 02:21:46 +0000 (10:21 +0800)
committercaiyinyu <caiyinyu@loongson.cn>
Fri, 12 Aug 2022 01:30:56 +0000 (09:30 +0800)
sysdeps/loongarch/__longjmp.S
sysdeps/loongarch/setjmp.S
sysdeps/unix/sysv/linux/loongarch/sysdep.h

index 37e7384413b0fc463a12d45fe75c5b483fbbe645..c2c5b56a800cbfe5154cbe9298e2d43e02cff583 100644 (file)
 #include <sys/asm.h>
 
 ENTRY (__longjmp)
+#ifdef PTR_MANGLE
+       REG_L t0, a0, 0*SZREG
+       PTR_DEMANGLE (ra, t0, t1, t2)
+       REG_L t0, a0, 1*SZREG
+       PTR_DEMANGLE2 (sp, t0, t1)
+#else
        REG_L ra, a0, 0*SZREG
        REG_L sp, a0, 1*SZREG
+#endif
        REG_L x,  a0, 2*SZREG
        REG_L fp, a0, 3*SZREG
        REG_L s0, a0, 4*SZREG
index 3afb9f39486834c3615f659cc7ef813e7f5abbcd..ec4ddc72dabfa1c3e1c25dea1e43d70a308de21c 100644 (file)
@@ -29,8 +29,15 @@ ENTRY (setjmp)
 END (setjmp)
 
 ENTRY (__sigsetjmp)
+#ifdef PTR_MANGLE
+       PTR_MANGLE (t0, ra, t1, t2)
+       REG_S t0, a0, 0*SZREG
+       PTR_MANGLE2 (t0, sp, t1)
+       REG_S t0, a0, 1*SZREG
+#else
        REG_S ra, a0, 0*SZREG
        REG_S sp, a0, 1*SZREG
+#endif
        REG_S x,  a0, 2*SZREG
        REG_S fp, a0, 3*SZREG
        REG_S s0, a0, 4*SZREG
index 8a398adb7087fd921a2bf62e3d2d360bd8d2917f..157cbd6c6b725302c961653c5206f43443b87a69 100644 (file)
@@ -314,8 +314,65 @@ extern long int __syscall_error (long int neg_errno);
 
 #endif /* ! __ASSEMBLER__ */
 
-/* Pointer mangling is not supported.  */
-#define PTR_MANGLE(var) (void) (var)
-#define PTR_DEMANGLE(var) (void) (var)
+/* Pointer mangling is supported for LoongArch.  */
+
+/* Load or store to/from a got-relative EXPR into/from G, using T.
+   Note G and T are register names.  */
+#define LDST_GLOBAL(OP, G, T,  EXPR) \
+  pcalau12i T, %got_pc_hi20(EXPR); \
+  OP       T, T, %got_pc_lo12(EXPR); \
+  OP       G, T, 0;
+
+/* Load or store to/from a pc-relative EXPR into/from G, using T.
+   Note G and T are register names.  */
+#define LDST_PCREL(OP, G, T,  EXPR) \
+  pcalau12i T, %pc_hi20(EXPR); \
+  OP       G, T, %pc_lo12(EXPR);
+
+#if (IS_IN (rtld) \
+     || (!defined SHARED && (IS_IN (libc) \
+     || IS_IN (libpthread))))
+
+#ifdef __ASSEMBLER__
+#define PTR_MANGLE(dst, src, guard, tmp) \
+  LDST_PCREL (REG_L, guard, tmp, __pointer_chk_guard_local); \
+  PTR_MANGLE2 (dst, src, guard);
+#define PTR_DEMANGLE(dst, src, guard, tmp) \
+  LDST_PCREL (REG_L, guard, tmp, __pointer_chk_guard_local); \
+  PTR_DEMANGLE2 (dst, src, guard);
+/* Use PTR_MANGLE2 for efficiency if guard is already loaded.  */
+#define PTR_MANGLE2(dst, src, guard) \
+  xor  dst, src, guard;
+#define PTR_DEMANGLE2(dst, src, guard) \
+  PTR_MANGLE2 (dst, src, guard);
+#else
+extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
+#define PTR_MANGLE(var) \
+  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard_local)
+#define PTR_DEMANGLE(var) PTR_MANGLE (var)
+#endif
+
+#else
+
+#ifdef __ASSEMBLER__
+#define PTR_MANGLE(dst, src, guard, tmp) \
+  LDST_GLOBAL (REG_L, guard, tmp, __pointer_chk_guard); \
+  PTR_MANGLE2 (dst, src, guard);
+#define PTR_DEMANGLE(dst, src, guard, tmp) \
+  LDST_GLOBAL (REG_L, guard, tmp, __pointer_chk_guard); \
+  PTR_DEMANGLE2 (dst, src, guard);
+/* Use PTR_MANGLE2 for efficiency if guard is already loaded.  */
+#define PTR_MANGLE2(dst, src, guard) \
+  xor dst, src, guard;
+#define PTR_DEMANGLE2(dst, src, guard) \
+  PTR_MANGLE2 (dst, src, guard);
+#else
+extern uintptr_t __pointer_chk_guard attribute_relro;
+#define PTR_MANGLE(var) \
+  (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_guard)
+#define PTR_DEMANGLE(var) PTR_MANGLE (var)
+#endif
+
+#endif
 
 #endif /* linux/loongarch/sysdep.h */