[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
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
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?
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);
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.
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.
在 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) \
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>
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.
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.
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.
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.
>
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.
>
在 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.
>>
@@ -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
@@ -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
@@ -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 */