[glibc] Enable the pointer guard in the dynamic loader
Adhemerval Zanella via Glibc-cvs <[email protected]> Tue, 16 Jun 2026 18:15:45 +0000 (GMT)
| Newsgroups | gmane.comp.lib.glibc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=d50ae543a49b139c38fdc7746454d37942f911b3 commit d50ae543a49b139c38fdc7746454d37942f911b3 Author: Adhemerval Zanella <[email protected]> Date: Fri Jun 12 13:10:11 2026 -0300 Enable the pointer guard in the dynamic loader i386, powerpc, s390, sh and sparc fell back to the generic no-op pointer_guard.h in ld.so, so the loader's own setjmp/longjmp and mangled function pointers were left unprotected (the other targets already mangle in rtld). ld.so is position-independent and sets up __pointer_chk_guard_local early in dl_main, so the loader can reach it the same way a statically linked program does: - powerpc, s390, sh, sparc: select __pointer_chk_guard_local for IS_IN (rtld) and reuse the existing PIC guard load. - i386: load it via @GOTOFF off a GOT pointer set up with LOAD_PIC_REG in the caller-provided scratch register (ld.so does not keep the GOT in %ebx at the setjmp/longjmp entry). - s390: drop the IS_IN (rtld) "#undef PTR_DEMANGLE" in __longjmp.c so the loader's longjmp demangles to match its setjmp. Checked on x86_64-linux-gnu, aarch64-linux-gnu, i686-linux-gnu, and armv7a-linux-gnueabihf. I also run elf and setjmp checks on qemu loongarch64, powerpc64, powerpc64le, and s390x systems. Reviewed-by: DJ Delorie <[email protected]> Diff: --- sysdeps/s390/__longjmp.c | 5 -- sysdeps/unix/sysv/linux/i386/pointer_guard.h | 57 ++++++++---------- sysdeps/unix/sysv/linux/powerpc/pointer_guard.h | 68 +++++++++++----------- sysdeps/unix/sysv/linux/s390/pointer_guard.h | 46 +++++++-------- sysdeps/unix/sysv/linux/sh/pointer_guard.h | 53 +++++++++-------- .../unix/sysv/linux/sparc/sparc32/pointer_guard.h | 54 ++++++++--------- .../unix/sysv/linux/sparc/sparc64/pointer_guard.h | 54 ++++++++--------- 7 files changed, 155 insertions(+), 182 deletions(-) diff --git a/sysdeps/s390/__longjmp.c b/sysdeps/s390/__longjmp.c index 78aa70a943..50d67bf42c 100644 --- a/sysdeps/s390/__longjmp.c +++ b/sysdeps/s390/__longjmp.c @@ -24,11 +24,6 @@ #include <unistd.h> #include <stap-probe.h> -/* See sysdeps/unix/sysv/linux/s390/pointer_guard.h. */ -#if IS_IN (rtld) -# undef PTR_DEMANGLE -#endif - /* Jump to the position specified by ENV, causing the setjmp call there to return VAL, or 1 if VAL is 0. */ void diff --git a/sysdeps/unix/sysv/linux/i386/pointer_guard.h b/sysdeps/unix/sysv/linux/i386/pointer_guard.h index 27fa8de465..421a902ab5 100644 --- a/sysdeps/unix/sysv/linux/i386/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/i386/pointer_guard.h @@ -19,28 +19,12 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ -# include <sysdeps/generic/pointer_guard.h> -#else -# ifdef __ASSEMBLER__ -# include <sysdep.h> +#ifdef __ASSEMBLER__ +# include <sysdep.h> /* The PIC variants clobber TMP, a register name suffix as expected by LOAD_PIC_REG (e.g. dx for %edx), to load the guard value. */ -# ifdef SHARED -/* The global guard is reached through the GOT. */ -# define PTR_MANGLE(reg, tmp) LOAD_PIC_REG (tmp); \ - movl __pointer_chk_guard@GOT(%e##tmp), %e##tmp; \ - xorl (%e##tmp), reg; \ - roll $9, reg -# define PTR_DEMANGLE(reg, tmp) \ - rorl $9, reg; \ - LOAD_PIC_REG (tmp); \ - movl __pointer_chk_guard@GOT(%e##tmp), %e##tmp; \ - xorl (%e##tmp), reg -# elif defined PIC -/* Static PIE: the module-local guard is reached via @GOTOFF. */ +# if IS_IN (rtld) || !defined SHARED +# ifdef PIC # define PTR_MANGLE(reg, tmp) LOAD_PIC_REG (tmp); \ xorl __pointer_chk_guard_local@GOTOFF(%e##tmp), reg; \ roll $9, reg @@ -49,7 +33,6 @@ LOAD_PIC_REG (tmp); \ xorl __pointer_chk_guard_local@GOTOFF(%e##tmp), reg # else -/* Position-dependent code addresses the guard directly. */ # define PTR_MANGLE(reg, tmp) xorl __pointer_chk_guard_local, reg; \ roll $9, reg # define PTR_DEMANGLE(reg, tmp) \ @@ -57,28 +40,38 @@ xorl __pointer_chk_guard_local, reg # endif # else -# include <stdbit.h> -# include <stdint.h> -# ifdef SHARED -extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_GUARD_VALUE __pointer_chk_guard -# else +# define PTR_MANGLE(reg, tmp) LOAD_PIC_REG (tmp); \ + movl __pointer_chk_guard@GOT(%e##tmp), %e##tmp; \ + xorl (%e##tmp), reg; \ + roll $9, reg +# define PTR_DEMANGLE(reg, tmp) \ + rorl $9, reg; \ + LOAD_PIC_REG (tmp); \ + movl __pointer_chk_guard@GOT(%e##tmp), %e##tmp; \ + xorl (%e##tmp), reg +# endif +#else +# include <stdbit.h> +# include <stdint.h> +# if IS_IN (rtld) || !defined SHARED extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_GUARD_VALUE __pointer_chk_guard_local -# endif -# define PTR_MANGLE(var) \ +# define PTR_GUARD_VALUE __pointer_chk_guard_local +# else +extern uintptr_t __pointer_chk_guard attribute_relro; +# define PTR_GUARD_VALUE __pointer_chk_guard +# endif +# define PTR_MANGLE(var) \ do { \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \ (var) = (__typeof (var)) stdc_rotate_left ((uintptr_t) (var), \ 2 * sizeof (uintptr_t) + 1); \ } while (0) -# define PTR_DEMANGLE(var) \ +# define PTR_DEMANGLE(var) \ do { \ (var) = (__typeof (var)) stdc_rotate_right ((uintptr_t) (var), \ 2 * sizeof (uintptr_t) + 1); \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ PTR_GUARD_VALUE); \ } while (0) -# endif #endif #endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h index 864a78ea53..9e59c9ce8e 100644 --- a/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/powerpc/pointer_guard.h @@ -19,24 +19,26 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if IS_IN (rtld) -# include <sysdeps/generic/pointer_guard.h> -#else -# ifdef __ASSEMBLER__ -# include <sysdep.h> -# ifdef SHARED -# define PTR_GUARD_SYM __pointer_chk_guard -# else -# define PTR_GUARD_SYM __pointer_chk_guard_local -# endif +#ifdef __ASSEMBLER__ +# include <sysdep.h> +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_SYM __pointer_chk_guard_local +# else +# define PTR_GUARD_SYM __pointer_chk_guard +# endif -# if defined(__PPC64__) || defined(__powerpc64__) -# define PTR_GUARD_LOAD(tmpreg) \ +# if defined(__PPC64__) || defined(__powerpc64__) +/* r2 (the TOC pointer) is always available, so load the guard's address + from the TOC/GOT and dereference it. */ +# define PTR_GUARD_LOAD(tmpreg) \ addis tmpreg,r2,PTR_GUARD_SYM@got@ha; \ ld tmpreg,PTR_GUARD_SYM@got@l(tmpreg); \ ld tmpreg,0(tmpreg) -# elif defined PIC -# define PTR_GUARD_LOAD(tmpreg) \ +# elif defined PIC +/* PiC 32-bit code has no dedicated GOT register, LR is clobbered by the + bcl, and r0 must not be used here as temporary register because it holds + the saved link register in __longjmp. */ +# define PTR_GUARD_LOAD(tmpreg) \ mflr r12; \ bcl 20,31,0f; \ 0: mflr tmpreg; \ @@ -45,36 +47,36 @@ mtlr r12; \ lwz tmpreg,PTR_GUARD_SYM@got(tmpreg); \ lwz tmpreg,0(tmpreg) -# else -# define PTR_GUARD_LOAD(tmpreg) \ - lis tmpreg,PTR_GUARD_SYM@ha; \ +# else +/* Position-dependent 32-bit code can address the variable directly. */ +# define PTR_GUARD_LOAD(tmpreg) \ + lis tmpreg,PTR_GUARD_SYM@ha; \ lwz tmpreg,PTR_GUARD_SYM@l(tmpreg) -# endif +# endif -# define PTR_MANGLE(reg, tmpreg) \ +# define PTR_MANGLE(reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ xor reg,tmpreg,reg -# define PTR_MANGLE2(reg, tmpreg) \ +# define PTR_MANGLE2(reg, tmpreg) \ xor reg,tmpreg,reg -# define PTR_MANGLE3(destreg, reg, tmpreg) \ +# define PTR_MANGLE3(destreg, reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ xor destreg,tmpreg,reg -# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) -# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) -# define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg) +# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) +# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) +# define PTR_DEMANGLE3(destreg, reg, tmpreg) PTR_MANGLE3 (destreg, reg, tmpreg) +#else +# include <stdint.h> +# if IS_IN (rtld) || !defined SHARED +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) # else -# include <stdint.h> -# ifdef SHARED extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ +# define PTR_MANGLE(var) \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_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) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif +# define PTR_DEMANGLE(var) PTR_MANGLE (var) #endif #endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/s390/pointer_guard.h b/sysdeps/unix/sysv/linux/s390/pointer_guard.h index aa75b8c42e..8fce7b15eb 100644 --- a/sysdeps/unix/sysv/linux/s390/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/s390/pointer_guard.h @@ -19,40 +19,36 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if IS_IN (rtld) -# include <sysdeps/generic/pointer_guard.h> -#else -# ifdef __ASSEMBLER__ -# ifdef SHARED -# define PTR_GUARD_LOAD(tmpreg) \ +#ifdef __ASSEMBLER__ +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_LOAD(tmpreg) \ + larl tmpreg,__pointer_chk_guard_local; \ + lg tmpreg,0(tmpreg) +# else +# define PTR_GUARD_LOAD(tmpreg) \ larl tmpreg,__pointer_chk_guard@GOTENT; \ lg tmpreg,0(tmpreg); \ lg tmpreg,0(tmpreg) -# else -# define PTR_GUARD_LOAD(tmpreg) \ - larl tmpreg,__pointer_chk_guard_local; \ - lg tmpreg,0(tmpreg) -# endif -# define PTR_MANGLE(reg, tmpreg) \ +# endif +# define PTR_MANGLE(reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ xgr reg,tmpreg -# define PTR_MANGLE2(reg, tmpreg) \ +# define PTR_MANGLE2(reg, tmpreg) \ xgr reg,tmpreg -# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) -# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) +# define PTR_DEMANGLE(reg, tmpreg) PTR_MANGLE (reg, tmpreg) +# define PTR_DEMANGLE2(reg, tmpreg) PTR_MANGLE2 (reg, tmpreg) +#else +# include <stdint.h> +# if IS_IN (rtld) || !defined SHARED +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_GUARD_VALUE __pointer_chk_guard_local # else -# include <stdint.h> -# ifdef SHARED extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_GUARD_VALUE __pointer_chk_guard -# else -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_GUARD_VALUE __pointer_chk_guard_local -# endif -# define PTR_MANGLE(var) \ - (var) = (void *) ((uintptr_t) (var) ^ PTR_GUARD_VALUE) -# define PTR_DEMANGLE(var) PTR_MANGLE (var) +# define PTR_GUARD_VALUE __pointer_chk_guard # endif +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ PTR_GUARD_VALUE) +# define PTR_DEMANGLE(var) PTR_MANGLE (var) #endif #endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/sh/pointer_guard.h b/sysdeps/unix/sysv/linux/sh/pointer_guard.h index fa989573c9..ee55ecb1bc 100644 --- a/sysdeps/unix/sysv/linux/sh/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sh/pointer_guard.h @@ -19,17 +19,17 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if IS_IN (rtld) -# include <sysdeps/generic/pointer_guard.h> -#else -# ifdef __ASSEMBLER__ -# ifdef SHARED -# define PTR_GUARD_SYM __pointer_chk_guard -# else -# define PTR_GUARD_SYM __pointer_chk_guard_local -# endif -# ifdef PIC -# define PTR_GUARD_LOAD(tmp) \ +#ifdef __ASSEMBLER__ +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_SYM __pointer_chk_guard_local +# else +# define PTR_GUARD_SYM __pointer_chk_guard +# endif +# ifdef PIC +/* The GOT pointer is computed with the usual mova/mov.l sequence which + clobbers r0; in __longjmp r0 holds the return value, so it is saved in + r3 (dead at every mangling site) and restored. */ +# define PTR_GUARD_LOAD(tmp) \ mov r0, r3; \ mova .Lptrg_got, r0; \ mov.l .Lptrg_got, tmp; \ @@ -46,8 +46,8 @@ .Lptrg_sym: \ .long PTR_GUARD_SYM@GOT; \ .Lptrg_end: -# else -# define PTR_GUARD_LOAD(tmp) \ +# else +# define PTR_GUARD_LOAD(tmp) \ mov.l .Lptrg_sym, tmp; \ mov.l @tmp, tmp; \ bra .Lptrg_end; \ @@ -56,25 +56,24 @@ .Lptrg_sym: \ .long PTR_GUARD_SYM; \ .Lptrg_end: -# endif -# define PTR_MANGLE(reg, tmp) \ +# endif +# define PTR_MANGLE(reg, tmp) \ PTR_GUARD_LOAD (tmp); xor tmp,reg -# define PTR_MANGLE2(reg, tmp) xor tmp,reg -# define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp) -# define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp) +# define PTR_MANGLE2(reg, tmp) xor tmp,reg +# define PTR_DEMANGLE(reg, tmp) PTR_MANGLE (reg, tmp) +# define PTR_DEMANGLE2(reg, tmp) PTR_MANGLE2 (reg, tmp) +#else +# include <stdint.h> +# if IS_IN (rtld) || !defined SHARED +extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; +# define PTR_MANGLE(var) \ + (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard_local) # else -# include <stdint.h> -# ifdef SHARED extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ +# define PTR_MANGLE(var) \ (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard) -# else -extern uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden; -# define PTR_MANGLE(var) \ - (var) = (void *) ((uintptr_t) (var) ^ __pointer_chk_guard_local) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif +# define PTR_DEMANGLE(var) PTR_MANGLE (var) #endif #endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h index f314f8598b..4a68203e7c 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/pointer_guard.h @@ -19,53 +19,47 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ -# include <sysdeps/generic/pointer_guard.h> -#else -# ifdef __ASSEMBLER__ -# include <sysdep.h> -# ifdef SHARED -# define PTR_GUARD_SYM __pointer_chk_guard -# else -# define PTR_GUARD_SYM __pointer_chk_guard_local -# endif -# ifdef PIC +#ifdef __ASSEMBLER__ +# include <sysdep.h> +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_SYM __pointer_chk_guard_local +# else +# define PTR_GUARD_SYM __pointer_chk_guard +# endif +# ifdef PIC /* Load the guard through the GOT. SETUP_PIC_REG_LEAF computes the GOT pointer in %o2 while preserving %o7 (the return address, which setjmp mangles), using %o3 as a scratch register. */ -# define PTR_GUARD_LOAD(tmpreg) \ +# define PTR_GUARD_LOAD(tmpreg) \ SETUP_PIC_REG_LEAF(o2, o3); \ sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \ xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \ ld [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \ ld [tmpreg], tmpreg -# else -# define PTR_GUARD_LOAD(tmpreg) \ +# else +# define PTR_GUARD_LOAD(tmpreg) \ sethi %hi(PTR_GUARD_SYM), tmpreg; \ ld [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg -# endif -# define PTR_MANGLE(dreg, reg, tmpreg) \ +# endif +# define PTR_MANGLE(dreg, reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ xor reg, tmpreg, dreg -# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) -# define PTR_MANGLE2(dreg, reg, tmpreg) \ +# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) +# define PTR_MANGLE2(dreg, reg, tmpreg) \ xor reg, tmpreg, dreg -# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) +# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) +#else +# include <stdint.h> +# if IS_IN (rtld) || !defined SHARED +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) # else -# include <stdint.h> -# ifdef SHARED extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ +# define PTR_MANGLE(var) \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_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) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif +# define PTR_DEMANGLE(var) PTR_MANGLE (var) #endif #endif /* POINTER_GUARD_H */ diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h index 6515e0dd07..4549256677 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/pointer_guard.h @@ -19,52 +19,46 @@ #ifndef POINTER_GUARD_H #define POINTER_GUARD_H -#if IS_IN (rtld) -/* We cannot use the thread descriptor because in ld.so we use setjmp - earlier than the descriptor is initialized. */ -# include <sysdeps/generic/pointer_guard.h> -#else -# ifdef __ASSEMBLER__ -# include <sysdep.h> -# ifdef SHARED -# define PTR_GUARD_SYM __pointer_chk_guard -# else -# define PTR_GUARD_SYM __pointer_chk_guard_local -# endif -# ifdef PIC +#ifdef __ASSEMBLER__ +# include <sysdep.h> +# if IS_IN (rtld) || !defined SHARED +# define PTR_GUARD_SYM __pointer_chk_guard_local +# else +# define PTR_GUARD_SYM __pointer_chk_guard +# endif +# ifdef PIC /* Load the guard through the GOT. SETUP_PIC_REG_LEAF computes the GOT pointer in %o2 while preserving %o7, using %o3 as a scratch register. */ -# define PTR_GUARD_LOAD(tmpreg) \ +# define PTR_GUARD_LOAD(tmpreg) \ SETUP_PIC_REG_LEAF(o2, o3); \ sethi %gdop_hix22(PTR_GUARD_SYM), tmpreg; \ xor tmpreg, %gdop_lox10(PTR_GUARD_SYM), tmpreg; \ ldx [%o2 + tmpreg], tmpreg, %gdop(PTR_GUARD_SYM); \ ldx [tmpreg], tmpreg -# else -# define PTR_GUARD_LOAD(tmpreg) \ +# else +# define PTR_GUARD_LOAD(tmpreg) \ sethi %hi(PTR_GUARD_SYM), tmpreg; \ ldx [tmpreg + %lo(PTR_GUARD_SYM)], tmpreg -# endif -# define PTR_MANGLE(dreg, reg, tmpreg) \ +# endif +# define PTR_MANGLE(dreg, reg, tmpreg) \ PTR_GUARD_LOAD (tmpreg); \ xor reg, tmpreg, dreg -# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) -# define PTR_MANGLE2(dreg, reg, tmpreg) \ +# define PTR_DEMANGLE(dreg, reg, tmpreg) PTR_MANGLE (dreg, reg, tmpreg) +# define PTR_MANGLE2(dreg, reg, tmpreg) \ xor reg, tmpreg, dreg -# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) +# define PTR_DEMANGLE2(dreg, reg, tmpreg) PTR_MANGLE2 (dreg, reg, tmpreg) +#else +# include <stdint.h> +# if IS_IN (rtld) || !defined SHARED +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) # else -# include <stdint.h> -# ifdef SHARED extern uintptr_t __pointer_chk_guard attribute_relro; -# define PTR_MANGLE(var) \ +# define PTR_MANGLE(var) \ (var) = (__typeof (var)) ((uintptr_t) (var) ^ __pointer_chk_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) -# endif -# define PTR_DEMANGLE(var) PTR_MANGLE (var) # endif +# define PTR_DEMANGLE(var) PTR_MANGLE (var) #endif #endif /* POINTER_GUARD_H */