[PATCH, ARM] PR target/68059 libgcc should not use __write for printing fatal error
Richard Earnshaw
Richard.Earnshaw@foss.arm.com
Thu Nov 5 15:59:00 GMT 2015
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.nagy@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 ();
> }
> };
>
>
More information about the Gcc-patches
mailing list