From 1c9bc1b6e50293a1b7037a7bfbf835868a55baed Mon Sep 17 00:00:00 2001 From: caiyinyu Date: Wed, 10 Aug 2022 10:21:46 +0800 Subject: [PATCH] LoongArch: Add pointer mangling support. --- sysdeps/loongarch/__longjmp.S | 7 ++++ sysdeps/loongarch/setjmp.S | 7 ++++ sysdeps/unix/sysv/linux/loongarch/sysdep.h | 63 ++++++++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/sysdeps/loongarch/__longjmp.S b/sysdeps/loongarch/__longjmp.S index 37e7384413..c2c5b56a80 100644 --- a/sysdeps/loongarch/__longjmp.S +++ b/sysdeps/loongarch/__longjmp.S @@ -20,8 +20,15 @@ #include 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 diff --git a/sysdeps/loongarch/setjmp.S b/sysdeps/loongarch/setjmp.S index 3afb9f3948..ec4ddc72da 100644 --- a/sysdeps/loongarch/setjmp.S +++ b/sysdeps/loongarch/setjmp.S @@ -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 diff --git a/sysdeps/unix/sysv/linux/loongarch/sysdep.h b/sysdeps/unix/sysv/linux/loongarch/sysdep.h index 8a398adb70..157cbd6c6b 100644 --- a/sysdeps/unix/sysv/linux/loongarch/sysdep.h +++ b/sysdeps/unix/sysv/linux/loongarch/sysdep.h @@ -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 */ -- 2.11.4.GIT