diff options
Diffstat (limited to 'sysdeps/unix/sysv')
-rw-r--r-- | sysdeps/unix/sysv/linux/loongarch/sysdep.h | 63 |
1 files changed, 60 insertions, 3 deletions
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 */ |