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