This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH, ARM] PR target/68059 libgcc should not use __write for printing fatal error


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]