[1/1] LoongArch: Add pointer mangling support.

Message ID 20220811040056.3164122-1-caiyinyu@loongson.cn
State Committed
Commit 1c9bc1b6e50293a1b7037a7bfbf835868a55baed
Headers
Series [1/1] LoongArch: Add pointer mangling support. |

Checks

Context Check Description
dj/TryBot-apply_patch success Patch applied to master at the time it was sent
dj/TryBot-32bit success Build for i686

Commit Message

caiyinyu Aug. 11, 2022, 4 a.m. UTC
  Tested on LoongArch machine: gcc 13.0.0, Linux kernel 5.19.0 rc2,
binutils branch master 2eb132bdfb9.

[1]
XPASS: conform/UNIX98/ndbm.h/linknamespace
XPASS: conform/XOPEN2K/ndbm.h/linknamespace
XPASS: conform/XOPEN2K8/ndbm.h/linknamespace
XPASS: conform/XPG42/ndbm.h/linknamespace
UNSUPPORTED: crypt/cert
UNSUPPORTED: elf/tst-env-setuid
UNSUPPORTED: elf/tst-env-setuid-tunables
XPASS: elf/tst-protected1a
XPASS: elf/tst-protected1b
UNSUPPORTED: elf/tst-valgrind-smoke
UNSUPPORTED: misc/tst-adjtimex
UNSUPPORTED: misc/tst-clock_adjtime
UNSUPPORTED: misc/tst-ntp_adjtime
UNSUPPORTED: misc/tst-pkey
UNSUPPORTED: misc/tst-rseq
UNSUPPORTED: misc/tst-rseq-disable
UNSUPPORTED: nptl/test-cond-printers
UNSUPPORTED: nptl/test-condattr-printers
UNSUPPORTED: nptl/test-mutex-printers
UNSUPPORTED: nptl/test-mutexattr-printers
UNSUPPORTED: nptl/test-rwlock-printers
UNSUPPORTED: nptl/test-rwlockattr-printers
UNSUPPORTED: nptl/tst-rseq-nptl
UNSUPPORTED: stdlib/tst-secure-getenv
UNSUPPORTED: time/tst-clock_settime
UNSUPPORTED: time/tst-settimeofday
Summary of test results:
   4580 PASS 
     20 UNSUPPORTED
     12 XFAIL 
      6 XPASS

---
 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(-)
  

Comments

Joseph Myers Aug. 15, 2022, 8:52 p.m. UTC | #1
On Thu, 11 Aug 2022, caiyinyu wrote:

> Tested on LoongArch machine: gcc 13.0.0, Linux kernel 5.19.0 rc2,
> binutils branch master 2eb132bdfb9.

This appears to have broken the build-many-glibcs.py build ("Fatal error: 
unknown reloc hint: pc_hi20").  Is that something that would be fixed by 
using binutils 2.39 branch instead of 2.38 branch in build-many-glibcs.py?
  
Xi Ruoyao Aug. 16, 2022, 1:28 a.m. UTC | #2
On Thu, 2022-08-11 at 12:00 +0800, caiyinyu wrote:
> +/* 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); \

Should this be "ld.d T, T, %got_pc_lo12(EXPR)"?  Or if OP is a store
we'll store into GOT and break it.

Or if we don't need to support store just rename it to "LD_GLOBAL".

> +  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);
  
Xi Ruoyao Aug. 16, 2022, 1:30 a.m. UTC | #3
On Mon, 2022-08-15 at 20:52 +0000, Joseph Myers wrote:
> On Thu, 11 Aug 2022, caiyinyu wrote:
> 
> > Tested on LoongArch machine: gcc 13.0.0, Linux kernel 5.19.0 rc2,
> > binutils branch master 2eb132bdfb9.
> 
> This appears to have broken the build-many-glibcs.py build ("Fatal error: 
> unknown reloc hint: pc_hi20").  Is that something that would be fixed by 
> using binutils 2.39 branch instead of 2.38 branch in build-many-glibcs.py?

No, we must use Binutils-2.40 for new relocation types like %pc_hi20. 
Maybe we can add a configure check to fallback to "la.pcrel"/"la.got"
macros for Binutils <= 2.39.
  
Xi Ruoyao Aug. 16, 2022, 1:59 a.m. UTC | #4
On Tue, 2022-08-16 at 09:30 +0800, Xi Ruoyao via Libc-alpha wrote:
> On Mon, 2022-08-15 at 20:52 +0000, Joseph Myers wrote:
> > On Thu, 11 Aug 2022, caiyinyu wrote:
> > 
> > > Tested on LoongArch machine: gcc 13.0.0, Linux kernel 5.19.0 rc2,
> > > binutils branch master 2eb132bdfb9.
> > 
> > This appears to have broken the build-many-glibcs.py build ("Fatal
> > error: 
> > unknown reloc hint: pc_hi20").  Is that something that would be
> > fixed by 
> > using binutils 2.39 branch instead of 2.38 branch in build-many-
> > glibcs.py?
> 
> No, we must use Binutils-2.40 for new relocation types like %pc_hi20. 
> Maybe we can add a configure check to fallback to "la.pcrel"/"la.got"
> macros for Binutils <= 2.39.

Hmm... AFAIK our ld.so is already broken with Binutils <= 2.39, so
perhaps we should just claim Binutils <= 2.39 are not supported.
  
caiyinyu Aug. 16, 2022, 6:34 a.m. UTC | #5
在 2022/8/16 上午9:28, Xi Ruoyao 写道:
> On Thu, 2022-08-11 at 12:00 +0800, caiyinyu wrote:
>> +/* 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); \
> Should this be "ld.d T, T, %got_pc_lo12(EXPR)"?  Or if OP is a store
> we'll store into GOT and break it.
>
> Or if we don't need to support store just rename it to "LD_GLOBAL".
>
>> +  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);

My mistake. We don't need to support store here.

I thought you were ok with this patch so that it has been included.

I made the following change in next patch:

BTW,the macro REG_L can be ld.d for 64-bits system or ld.w for 32-bits and

now it's ld.d.

 >>>>>>>>>>>>>>

diff --git a/sysdeps/unix/sysv/linux/loongarch/sysdep.h 
b/sysdeps/unix/sysv/linux/loongarch/sysdep.h
index 157cbd6c6b..7acd31d024 100644
--- a/sysdeps/unix/sysv/linux/loongarch/sysdep.h
+++ b/sysdeps/unix/sysv/linux/loongarch/sysdep.h
@@ -316,18 +316,18 @@ extern long int __syscall_error (long int neg_errno);

  /* Pointer mangling is supported for LoongArch.  */

-/* Load or store to/from a got-relative EXPR into/from G, using T.
+/* Load a got-relative EXPR into G, using T.
     Note G and T are register names.  */
-#define LDST_GLOBAL(OP, G, T,  EXPR) \
+#define LD_GLOBAL(G, T,  EXPR) \
    pcalau12i T, %got_pc_hi20(EXPR); \
-  OP       T, T, %got_pc_lo12(EXPR); \
-  OP       G, T, 0;
+  REG_L            T, T, %got_pc_lo12(EXPR); \
+  REG_L            G, T, 0;

-/* Load or store to/from a pc-relative EXPR into/from G, using T.
+/* Load a pc-relative EXPR into G, using T.
     Note G and T are register names.  */
-#define LDST_PCREL(OP, G, T,  EXPR) \
+#define LD_PCREL(G, T,  EXPR) \
    pcalau12i T, %pc_hi20(EXPR); \
-  OP       G, T, %pc_lo12(EXPR);
+  REG_L            G, T, %pc_lo12(EXPR);

  #if (IS_IN (rtld) \
       || (!defined SHARED && (IS_IN (libc) \
@@ -335,10 +335,10 @@ extern long int __syscall_error (long int neg_errno);

  #ifdef __ASSEMBLER__
  #define PTR_MANGLE(dst, src, guard, tmp) \
-  LDST_PCREL (REG_L, guard, tmp, __pointer_chk_guard_local); \
+  LD_PCREL (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); \
+  LD_PCREL (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) \
@@ -356,10 +356,10 @@ extern uintptr_t __pointer_chk_guard_local 
attribute_relro attribute_hidden;

  #ifdef __ASSEMBLER__
  #define PTR_MANGLE(dst, src, guard, tmp) \
-  LDST_GLOBAL (REG_L, guard, tmp, __pointer_chk_guard); \
+  LD_GLOBAL (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); \
+  LD_GLOBAL (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) \

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


>
  
Joseph Myers Aug. 16, 2022, 3:23 p.m. UTC | #6
On Tue, 16 Aug 2022, Xi Ruoyao via Libc-alpha wrote:

> On Tue, 2022-08-16 at 09:30 +0800, Xi Ruoyao via Libc-alpha wrote:
> > On Mon, 2022-08-15 at 20:52 +0000, Joseph Myers wrote:
> > > On Thu, 11 Aug 2022, caiyinyu wrote:
> > > 
> > > > Tested on LoongArch machine: gcc 13.0.0, Linux kernel 5.19.0 rc2,
> > > > binutils branch master 2eb132bdfb9.
> > > 
> > > This appears to have broken the build-many-glibcs.py build ("Fatal
> > > error: 
> > > unknown reloc hint: pc_hi20").  Is that something that would be
> > > fixed by 
> > > using binutils 2.39 branch instead of 2.38 branch in build-many-
> > > glibcs.py?
> > 
> > No, we must use Binutils-2.40 for new relocation types like %pc_hi20. 
> > Maybe we can add a configure check to fallback to "la.pcrel"/"la.got"
> > macros for Binutils <= 2.39.
> 
> Hmm... AFAIK our ld.so is already broken with Binutils <= 2.39, so
> perhaps we should just claim Binutils <= 2.39 are not supported.

Requiring unreleased versions is bad for users and distributors; it would 
be better to backport whatever binutils patches are required to 2.39 
branch (assuming they are LoongArch-specific patches, rather than changes 
to architecture-independent parts of binutils that are risky for other 
architectures) and add configure tests to work around any that don't get 
backported.
  
Xi Ruoyao Aug. 17, 2022, 7:43 a.m. UTC | #7
On Tue, 2022-08-16 at 15:23 +0000, Joseph Myers wrote:

> > > No, we must use Binutils-2.40 for new relocation types like %pc_hi20. 
> > > Maybe we can add a configure check to fallback to "la.pcrel"/"la.got"
> > > macros for Binutils <= 2.39.
> > 
> > Hmm... AFAIK our ld.so is already broken with Binutils <= 2.39, so
> > perhaps we should just claim Binutils <= 2.39 are not supported.
> 
> Requiring unreleased versions is bad for users and distributors; it would 
> be better to backport whatever binutils patches are required to 2.39 
> branch (assuming they are LoongArch-specific patches, rather than changes 
> to architecture-independent parts of binutils that are risky for other
> architectures) and add configure tests to work around any that don't get 
> backported.

I share your feeling...  But the fix needed by ld.so (bc2a35c in
binutils-gdb.git) is after two commits massively changing the relocation
types.  Backporting the relocation type changes is completely
unacceptable (such an attempt will do nothing except annoying Nick
Clifton :). And bc2a35c alone cannot be backported trivially.

I've published a separate version of bc2a35c as the attachment of
https://sourceware.org/pipermail/libc-alpha/2022-July/140949.html, but
it's not a trivial backport: I had to change some code where bc2a35a
does not change or the path for "old" relocation types would just
overflow the heap buffer and corrupt the heap.  And my backport is not
reviewed or tested carefully.

P. S. Currently building Glibc requires Binutils >= 2.40, but building
the kernel modules requires Binutils <= 2.39.  This effectively forces
every LoongArch distribution to ship two toolchains :(.  I hope we can
end this madness soon.
  
Joseph Myers Aug. 17, 2022, 4:46 p.m. UTC | #8
On Wed, 17 Aug 2022, Xi Ruoyao via Libc-alpha wrote:

> I share your feeling...  But the fix needed by ld.so (bc2a35c in
> binutils-gdb.git) is after two commits massively changing the relocation
> types.  Backporting the relocation type changes is completely
> unacceptable (such an attempt will do nothing except annoying Nick
> Clifton :). And bc2a35c alone cannot be backported trivially.

If the branch isn't usable as-is on LoongArch (which apparently is the 
state at present), there should be no problem with any backport to 
architecture-specific code, regardless of how large it is - it can't 
exactly regress from "not usable".

I note that the only GCC target supported for LoongArch is 
loongarch*-*-linux*, so there isn't really a question of being usable for 
bare-metal either.
  
caiyinyu Aug. 18, 2022, 2:25 a.m. UTC | #9
I sent a new patch: LoongArch: Fix ptr mangling/demangling features.

https://sourceware.org/pipermail/libc-alpha/2022-August/141489.html

And this patch is ok with binutils 2.39, gcc 12.0.1 kernel 5.19+

Tested all passed.

XPASS: conform/UNIX98/ndbm.h/linknamespace
XPASS: conform/XOPEN2K/ndbm.h/linknamespace
XPASS: conform/XOPEN2K8/ndbm.h/linknamespace
XPASS: conform/XPG42/ndbm.h/linknamespace
UNSUPPORTED: crypt/cert
UNSUPPORTED: elf/tst-env-setuid
UNSUPPORTED: elf/tst-env-setuid-tunables
XPASS: elf/tst-protected1a
XPASS: elf/tst-protected1b
UNSUPPORTED: elf/tst-valgrind-smoke
UNSUPPORTED: misc/tst-adjtimex
UNSUPPORTED: misc/tst-clock_adjtime
UNSUPPORTED: misc/tst-ntp_adjtime
UNSUPPORTED: misc/tst-pkey
UNSUPPORTED: misc/tst-rseq
UNSUPPORTED: misc/tst-rseq-disable
UNSUPPORTED: nptl/test-cond-printers
UNSUPPORTED: nptl/test-condattr-printers
UNSUPPORTED: nptl/test-mutex-printers
UNSUPPORTED: nptl/test-mutexattr-printers
UNSUPPORTED: nptl/test-rwlock-printers
UNSUPPORTED: nptl/test-rwlockattr-printers
UNSUPPORTED: nptl/tst-rseq-nptl
UNSUPPORTED: stdlib/tst-secure-getenv
UNSUPPORTED: time/tst-clock_settime
UNSUPPORTED: time/tst-settimeofday
Summary of test results:
    4583 PASS
      20 UNSUPPORTED
      12 XFAIL
       6 XPASS


在 2022/8/17 下午3:43, Xi Ruoyao 写道:
> On Tue, 2022-08-16 at 15:23 +0000, Joseph Myers wrote:
>
>>>> No, we must use Binutils-2.40 for new relocation types like %pc_hi20.
>>>> Maybe we can add a configure check to fallback to "la.pcrel"/"la.got"
>>>> macros for Binutils <= 2.39.
>>> Hmm... AFAIK our ld.so is already broken with Binutils <= 2.39, so
>>> perhaps we should just claim Binutils <= 2.39 are not supported.
>> Requiring unreleased versions is bad for users and distributors; it would
>> be better to backport whatever binutils patches are required to 2.39
>> branch (assuming they are LoongArch-specific patches, rather than changes
>> to architecture-independent parts of binutils that are risky for other
>> architectures) and add configure tests to work around any that don't get
>> backported.
> I share your feeling...  But the fix needed by ld.so (bc2a35c in
> binutils-gdb.git) is after two commits massively changing the relocation
> types.  Backporting the relocation type changes is completely
> unacceptable (such an attempt will do nothing except annoying Nick
> Clifton :). And bc2a35c alone cannot be backported trivially.
>
> I've published a separate version of bc2a35c as the attachment of
> https://sourceware.org/pipermail/libc-alpha/2022-July/140949.html, but
> it's not a trivial backport: I had to change some code where bc2a35a
> does not change or the path for "old" relocation types would just
> overflow the heap buffer and corrupt the heap.  And my backport is not
> reviewed or tested carefully.
>
> P. S. Currently building Glibc requires Binutils >= 2.40, but building
> the kernel modules requires Binutils <= 2.39.  This effectively forces
> every LoongArch distribution to ship two toolchains :(.  I hope we can
> end this madness soon.
>
  
Xi Ruoyao Aug. 19, 2022, 1:46 p.m. UTC | #10
On Wed, 2022-08-17 at 16:46 +0000, Joseph Myers wrote:
> On Wed, 17 Aug 2022, Xi Ruoyao via Libc-alpha wrote:
> 
> > I share your feeling...  But the fix needed by ld.so (bc2a35c in
> > binutils-gdb.git) is after two commits massively changing the relocation
> > types.  Backporting the relocation type changes is completely
> > unacceptable (such an attempt will do nothing except annoying Nick
> > Clifton :). And bc2a35c alone cannot be backported trivially.
> 
> If the branch isn't usable as-is on LoongArch (which apparently is the
> state at present), there should be no problem with any backport to 
> architecture-specific code, regardless of how large it is - it can't 
> exactly regress from "not usable".

Sorry, my memory was flawed when I wrote the last reply (due to my 2-
week vacation :( ).  It's not completely usable, only IFUNC is broken.

> I note that the only GCC target supported for LoongArch is 
> loongarch*-*-linux*, so there isn't really a question of being usable for 
> bare-metal either.
>
  
caiyinyu Aug. 21, 2022, 7:25 a.m. UTC | #11
在 2022/8/19 下午9:46, Xi Ruoyao 写道:
> On Wed, 2022-08-17 at 16:46 +0000, Joseph Myers wrote:
>> On Wed, 17 Aug 2022, Xi Ruoyao via Libc-alpha wrote:
>>
>>> I share your feeling...  But the fix needed by ld.so (bc2a35c in
>>> binutils-gdb.git) is after two commits massively changing the relocation
>>> types.  Backporting the relocation type changes is completely
>>> unacceptable (such an attempt will do nothing except annoying Nick
>>> Clifton :). And bc2a35c alone cannot be backported trivially.
>> If the branch isn't usable as-is on LoongArch (which apparently is the
>> state at present), there should be no problem with any backport to
>> architecture-specific code, regardless of how large it is - it can't
>> exactly regress from "not usable".
> Sorry, my memory was flawed when I wrote the last reply (due to my 2-
> week vacation :( ).  It's not completely usable, only IFUNC is broken.

The ifunc supports are not available on binutils 2.39, so the ifunc tests

are failed. The " LoongArch: Add pointer mangling support" patch was tested

with ifunc disabled.

The full tests were all passed by using binutils master branch. If there

are no any other comments, I will include this patch.



>
>> I note that the only GCC target supported for LoongArch is
>> loongarch*-*-linux*, so there isn't really a question of being usable for
>> bare-metal either.
>>
  

Patch

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 <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
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 */