This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, ARM] PR target/68059 libgcc should not use __write for printing fatal error
- From: Szabolcs Nagy <szabolcs dot nagy at arm dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 05 Nov 2015 12:30:16 +0000
- Subject: [PATCH, ARM] PR target/68059 libgcc should not use __write for printing fatal error
- Authentication-results: sourceware.org; auth=none
libgcc/config/arm/linux-atomic-64bit.c uses __write to print an error
message if the 64bit xchg method is not available in the kernel.
__write is not part of the public libc abi. Since this code is only
run on linux the write syscall can be invoked directly.
And __builtin_trap is a simpler way to crash than abort.
The new behaviour on a linux kernel before v3.1:
# ./a.out
A newer kernel is required to run this binary. (__kernel_cmpxchg64 helper)
Illegal instruction
OK for trunk and backporting?
libgcc/ChangeLog:
2015-11-05 Szabolcs Nagy <szabolcs.nagy@arm.com>
PR target/68059
* config/arm/linux-atomic-64bit.c (__write): Remove declaration.
(abort): Likewise.
(linux_write): Define.
diff --git a/libgcc/config/arm/linux-atomic-64bit.c b/libgcc/config/arm/linux-atomic-64bit.c
index cdf713c..aba3334 100644
--- a/libgcc/config/arm/linux-atomic-64bit.c
+++ b/libgcc/config/arm/linux-atomic-64bit.c
@@ -33,9 +33,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
kernels; we check for that in an init section and bail out rather
unceremoneously. */
-extern unsigned int __write (int fd, const void *buf, unsigned int count);
-extern void abort (void);
-
/* Kernel helper for compare-and-exchange. */
typedef int (__kernel_cmpxchg64_t) (const long long* oldval,
const long long* newval,
@@ -45,6 +42,19 @@ typedef int (__kernel_cmpxchg64_t) (const long long* oldval,
/* Kernel helper page version number. */
#define __kernel_helper_version (*(unsigned int *)0xffff0ffc)
+static void
+linux_write (int fd, const void *buf, unsigned int count)
+{
+ register long r7 asm ("r7") = 4; /* Linux __NR_write. */
+ register long r0 asm ("r0") = fd;
+ register long r1 asm ("r1") = (long)buf;
+ register long r2 asm ("r2") = count;
+ asm volatile ("svc 0"
+ :
+ : "r" (r7), "r" (r0), "r" (r1), "r" (r2)
+ : "memory");
+}
+
/* Check that the kernel has a new enough version at load. */
static void __check_for_sync8_kernelhelper (void)
{
@@ -53,11 +63,9 @@ static void __check_for_sync8_kernelhelper (void)
const char err[] = "A newer kernel is required to run this binary. "
"(__kernel_cmpxchg64 helper)\n";
/* At this point we need a way to crash with some information
- for the user - I'm not sure I can rely on much else being
- available at this point, so do the same as generic-morestack.c
- write () and abort (). */
- __write (2 /* stderr. */, err, sizeof (err));
- abort ();
+ for the user. */
+ linux_write (2 /* stderr. */, err, sizeof (err));
+ __builtin_trap ();
}
};