On 05/11/15 12:30, Szabolcs Nagy wrote: > 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?
__morestack_fail in generic-morestack.c now uses writev(). Is there some reason we can't do the same? R. > > 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. > > arm_write_2.diff > > > 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 (); > } > }; > >