From 485a9bb9f02c45f15bdb326d32a232037b1de31b Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Wed, 5 Oct 2005 20:15:22 +0000 Subject: [PATCH] * sysdeps/arm/dl-machine.h: Include . (elf_machine_type_class, elf_machine_rel, elf_machine_rela): Handle TLS relocations. * sysdeps/unix/sysv/linux/arm/Makefile: Build __aeabi_read_tp. * sysdeps/unix/sysv/linux/arm/sysdep.h (INTERNAL_SYSCALL_RAW): Renamed from INTERNAL_SYSCALL. (INTERNAL_SYSCALL, INTERNAL_SYSCALL_ARM): New macros. * sysdeps/arm/dl-tls.h, sysdeps/arm/elf/configure.in, sysdeps/arm/elf/configure, sysdeps/arm/libc-tls.c, sysdeps/arm/linuxthreads/tls.h, sysdeps/arm/tls-macros.h, sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S, sysdeps/unix/sysv/linux/arm/libc-aeabi_read_tp.S: New files. --- ChangeLog.arm | 15 ++ sysdeps/arm/dl-machine.h | 51 ++++++- sysdeps/arm/dl-tls.h | 29 ++++ sysdeps/arm/elf/configure | 45 ++++++ sysdeps/arm/elf/configure.in | 35 +++++ sysdeps/arm/libc-tls.c | 37 +++++ sysdeps/arm/linuxthreads/tls.h | 172 +++++++++++++++++++++++ sysdeps/arm/tls-macros.h | 51 +++++++ sysdeps/unix/sysv/linux/arm/Makefile | 10 ++ sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S | 34 +++++ sysdeps/unix/sysv/linux/arm/libc-aeabi_read_tp.S | 1 + sysdeps/unix/sysv/linux/arm/sysdep.h | 14 +- 12 files changed, 488 insertions(+), 6 deletions(-) create mode 100644 sysdeps/arm/dl-tls.h create mode 100644 sysdeps/arm/elf/configure create mode 100644 sysdeps/arm/elf/configure.in create mode 100644 sysdeps/arm/libc-tls.c create mode 100644 sysdeps/arm/linuxthreads/tls.h create mode 100644 sysdeps/arm/tls-macros.h create mode 100644 sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S create mode 100644 sysdeps/unix/sysv/linux/arm/libc-aeabi_read_tp.S diff --git a/ChangeLog.arm b/ChangeLog.arm index 2579d71..0c0568e 100644 --- a/ChangeLog.arm +++ b/ChangeLog.arm @@ -1,5 +1,20 @@ 2005-10-05 Daniel Jacobowitz + * sysdeps/arm/dl-machine.h: Include . + (elf_machine_type_class, elf_machine_rel, elf_machine_rela): Handle + TLS relocations. + * sysdeps/unix/sysv/linux/arm/Makefile: Build __aeabi_read_tp. + * sysdeps/unix/sysv/linux/arm/sysdep.h (INTERNAL_SYSCALL_RAW): Renamed + from INTERNAL_SYSCALL. + (INTERNAL_SYSCALL, INTERNAL_SYSCALL_ARM): New macros. + * sysdeps/arm/dl-tls.h, sysdeps/arm/elf/configure.in, + sysdeps/arm/elf/configure, sysdeps/arm/libc-tls.c, + sysdeps/arm/linuxthreads/tls.h, sysdeps/arm/tls-macros.h, + sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S, + sysdeps/unix/sysv/linux/arm/libc-aeabi_read_tp.S: New files. + +2005-10-05 Daniel Jacobowitz + * sysdeps/arm/atomicity.h: Delete. * sysdeps/arm/bits/atomic.h: New file. diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h index be03e7b..2534be1 100644 --- a/sysdeps/arm/dl-machine.h +++ b/sysdeps/arm/dl-machine.h @@ -24,6 +24,7 @@ #define ELF_MACHINE_NAME "ARM" #include +#include #define VALID_ELF_ABIVERSION(ver) (ver == 0) #define VALID_ELF_OSABI(osabi) \ @@ -193,13 +194,22 @@ _dl_start_user:\n\ .previous\n\ "); -/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so - PLT entries should not be allowed to define the value. +/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or + TLS variable, so undefined references should not be allowed to + define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one of the main executable's symbols, as for a COPY reloc. */ +#if defined USE_TLS && (!defined RTLD_BOOTSTRAP || USE___THREAD) +# define elf_machine_type_class(type) \ + ((((type) == R_ARM_JUMP_SLOT || (type) == R_ARM_TLS_DTPMOD32 \ + || (type) == R_ARM_TLS_DTPOFF32 || (type) == R_ARM_TLS_TPOFF32) \ + * ELF_RTYPE_CLASS_PLT) \ + | (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY)) +#else #define elf_machine_type_class(type) \ ((((type) == R_ARM_JUMP_SLOT) * ELF_RTYPE_CLASS_PLT) \ | (((type) == R_ARM_COPY) * ELF_RTYPE_CLASS_COPY)) +#endif /* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */ #define ELF_MACHINE_JMP_SLOT R_ARM_JUMP_SLOT @@ -399,7 +409,24 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, value = (*reloc_addr & 0xff000000) | (newvalue & 0x00ffffff); *reloc_addr = value; } - break; + break; +#if defined USE_TLS && !defined RTLD_BOOTSTRAP + case R_ARM_TLS_DTPMOD32: + /* Get the information from the link map returned by the + resolv function. */ + if (sym_map != NULL) + *reloc_addr = sym_map->l_tls_modid; + break; + + case R_ARM_TLS_DTPOFF32: + *reloc_addr += sym->st_value; + break; + + case R_ARM_TLS_TPOFF32: + CHECK_STATIC_TLS (map, sym_map); + *reloc_addr += sym->st_value + sym_map->l_tls_offset; + break; +#endif default: _dl_reloc_bad_type (map, r_type, 0); break; @@ -480,6 +507,24 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, *reloc_addr = value; } break; +#if defined USE_TLS && !defined RTLD_BOOTSTRAP + case R_ARM_TLS_DTPMOD32: + /* Get the information from the link map returned by the + resolv function. */ + if (sym_map != NULL) + *reloc_addr = sym_map->l_tls_modid; + break; + + case R_ARM_TLS_DTPOFF32: + *reloc_addr = sym->st_value + reloc->r_addend; + break; + + case R_ARM_TLS_TPOFF32: + CHECK_STATIC_TLS (map, sym_map); + *reloc_addr = (sym->st_value + sym_map->l_tls_offset + + reloc->r_addend); + break; +#endif default: _dl_reloc_bad_type (map, r_type, 0); break; diff --git a/sysdeps/arm/dl-tls.h b/sysdeps/arm/dl-tls.h new file mode 100644 index 0000000..e0324a7 --- /dev/null +++ b/sysdeps/arm/dl-tls.h @@ -0,0 +1,29 @@ +/* Thread-local storage handling in the ELF dynamic linker. ARM version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + + +/* Type used for the representation of TLS information in the GOT. */ +typedef struct +{ + unsigned long int ti_module; + unsigned long int ti_offset; +} tls_index; + + +extern void *__tls_get_addr (tls_index *ti); diff --git a/sysdeps/arm/elf/configure b/sysdeps/arm/elf/configure new file mode 100644 index 0000000..234fc20 --- /dev/null +++ b/sysdeps/arm/elf/configure @@ -0,0 +1,45 @@ +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/arm/elf. + +if test "$usetls" != no; then +# Check for support of thread-local storage handling in assembler and +# linker. +echo "$as_me:$LINENO: checking for ARM TLS support" >&5 +echo $ECHO_N "checking for ARM TLS support... $ECHO_C" >&6 +if test "${libc_cv_arm_tls+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat > conftest.s <<\EOF + .section ".tdata", "awT", %progbits + .globl foo +foo: .long 1 + .section ".tbss", "awT", %nobits + .globl bar +bar: .skip 4 + .text +.word foo(tpoff) +.word foo(tlsgd) +EOF +if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + libc_cv_arm_tls=yes +else + libc_cv_arm_tls=no +fi +rm -f conftest* +fi +echo "$as_me:$LINENO: result: $libc_cv_arm_tls" >&5 +echo "${ECHO_T}$libc_cv_arm_tls" >&6 +if test $libc_cv_arm_tls = yes; then + cat >>confdefs.h <<\_ACEOF +#define HAVE_TLS_SUPPORT 1 +_ACEOF + +fi +fi + +#AC_DEFINE(PI_STATIC_AND_HIDDEN) diff --git a/sysdeps/arm/elf/configure.in b/sysdeps/arm/elf/configure.in new file mode 100644 index 0000000..1045296 --- /dev/null +++ b/sysdeps/arm/elf/configure.in @@ -0,0 +1,35 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/arm/elf. + +if test "$usetls" != no; then +# Check for support of thread-local storage handling in assembler and +# linker. +AC_CACHE_CHECK(for ARM TLS support, libc_cv_arm_tls, [dnl +cat > conftest.s <<\EOF + .section ".tdata", "awT", %progbits + .globl foo +foo: .long 1 + .section ".tbss", "awT", %nobits + .globl bar +bar: .skip 4 + .text +.word foo(tpoff) +.word foo(tlsgd) +EOF +dnl +if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then + libc_cv_arm_tls=yes +else + libc_cv_arm_tls=no +fi +rm -f conftest*]) +if test $libc_cv_arm_tls = yes; then + AC_DEFINE(HAVE_TLS_SUPPORT) +fi +fi + +dnl It is always possible to access static and hidden symbols in an +dnl position independent way. +dnl NOTE: This feature was added by the GCC TLS patches. We should test for +dnl it. Until we do, don't define it. +#AC_DEFINE(PI_STATIC_AND_HIDDEN) diff --git a/sysdeps/arm/libc-tls.c b/sysdeps/arm/libc-tls.c new file mode 100644 index 0000000..53c2923 --- /dev/null +++ b/sysdeps/arm/libc-tls.c @@ -0,0 +1,37 @@ +/* Thread-local storage handling in the ELF dynamic linker. ARM version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +#if USE_TLS + +/* On ARM, linker optimizations are not required, so __tls_get_addr + can be called even in statically linked binaries. In this case module + must be always 1 and PT_TLS segment exist in the binary, otherwise it + would not link. */ + +void * +__tls_get_addr (tls_index *ti) +{ + dtv_t *dtv = THREAD_DTV (); + return (char *) dtv[1].pointer.val + ti->ti_offset; +} + +#endif diff --git a/sysdeps/arm/linuxthreads/tls.h b/sysdeps/arm/linuxthreads/tls.h new file mode 100644 index 0000000..8057a54 --- /dev/null +++ b/sysdeps/arm/linuxthreads/tls.h @@ -0,0 +1,172 @@ +/* Definitions for thread-local data handling. linuxthreads/ARM version. + Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _TLS_H +#define _TLS_H + +#ifndef __ASSEMBLER__ + +# include +# include +# include + +/* Type for the dtv. */ +typedef union dtv +{ + size_t counter; + struct + { + void *val; + bool is_static; + } pointer; +} dtv_t; + +typedef struct +{ + dtv_t *dtv; + + /* Reserved for the thread implementation. Unused in LinuxThreads. */ + void *private; +} tcbhead_t; +#endif + + +/* We can support TLS only if the floating-stack support is available. + However, we want to compile in the support and test at runtime whether + the running kernel can support it or not. To avoid bothering with the + TLS support code at all, use configure --without-tls. + + We need USE_TLS to be consistently defined, for ldsodefs.h conditionals. + But some of the code below can cause problems in building libpthread + (e.g. useldt.h will defined FLOATING_STACKS when it shouldn't). */ + +/* LinuxThreads can only support TLS if both floating stacks and support + from the tools are available. + + We have to define USE_TLS consistently, or ldsodefs.h will lay out types + differently between an NPTL build and a LinuxThreads build. It can be set + for libc.so and not libpthread.so, but only if we provide appropriate padding + in the _pthread_descr_struct. + + Currently nothing defines FLOATING_STACKS. We could assume this based on + kernel version once the TLS patches are available in kernel.org. + + To avoid bothering with the TLS support code at all, use configure + --without-tls. */ + +#if defined HAVE_TLS_SUPPORT \ + && (defined FLOATING_STACKS || !defined IS_IN_libpthread) + +/* Signal that TLS support is available. */ +# define USE_TLS 1 + +/* Include padding in _pthread_descr_struct so that libc can find p_errno, + if libpthread will only include the padding because of the !IS_IN_libpthread + check. */ +#ifndef FLOATING_STACKS +# define INCLUDE_TLS_PADDING 1 +#endif + +# ifndef __ASSEMBLER__ +/* Get system call information. */ +# include + +/* This is the size of the initial TCB. */ +# define TLS_INIT_TCB_SIZE sizeof (tcbhead_t) + +/* Alignment requirements for the initial TCB. */ +# define TLS_INIT_TCB_ALIGN __alignof__ (tcbhead_t) + +/* This is the size of the TCB. */ +# define TLS_TCB_SIZE sizeof (tcbhead_t) + +/* Alignment requirements for the TCB. */ +# define TLS_TCB_ALIGN __alignof__ (tcbhead_t) + +/* This is the size we need before TCB. */ +# define TLS_PRE_TCB_SIZE sizeof (struct _pthread_descr_struct) + +/* The DTV is allocated at the TP; the TCB is placed elsewhere. */ +# define TLS_DTV_AT_TP 1 + +/* Install the dtv pointer. The pointer passed is to the element with + index -1 which contain the length. */ +# define INSTALL_DTV(TCBP, DTVP) \ + (((tcbhead_t *) (TCBP))->dtv = (DTVP) + 1) + +/* Install new dtv for current thread. */ +# define INSTALL_NEW_DTV(DTV) \ + (((tcbhead_t *)__builtin_thread_pointer ())->dtv = (DTV)) + +/* Return dtv of given thread descriptor. */ +# define GET_DTV(TCBP) \ + (((tcbhead_t *) (TCBP))->dtv) + +/* Code to initially initialize the thread pointer. This might need + special attention since 'errno' is not yet available and if the + operation can cause a failure 'errno' must not be touched. */ +# define TLS_INIT_TP(TCBP, SECONDCALL) \ + ({ INTERNAL_SYSCALL_DECL (err); \ + long result_var; \ + result_var = INTERNAL_SYSCALL_ARM (set_tls, err, 1, (TCBP)); \ + INTERNAL_SYSCALL_ERROR_P (result_var, err) \ + ? "unknown error" : NULL; }) + +/* Return the address of the dtv for the current thread. */ +# define THREAD_DTV() \ + (((tcbhead_t *)__builtin_thread_pointer ())->dtv) + +/* Return the thread descriptor for the current thread. */ +# undef THREAD_SELF +# define THREAD_SELF \ + ((pthread_descr)__builtin_thread_pointer () - 1) + +# undef INIT_THREAD_SELF +# define INIT_THREAD_SELF(DESCR, NR) \ + TLS_INIT_TP ((struct _pthread_descr_struct *)(DESCR) + 1, 0) + +/* Get the thread descriptor definition. */ +# include + +/* ??? Generic bits of LinuxThreads may call these macros with + DESCR set to NULL. We are expected to be able to reference + the "current" value. + + In our case, we'd really prefer to use DESCR, since lots of + PAL_code calls would be expensive. We can only trust that + the compiler does its job and unifies the multiple + __builtin_thread_pointer instances. */ + +#define THREAD_GETMEM(descr, member) \ + ((void) sizeof (descr), THREAD_SELF->member) +#define THREAD_GETMEM_NC(descr, member) \ + ((void) sizeof (descr), THREAD_SELF->member) +#define THREAD_SETMEM(descr, member, value) \ + ((void) sizeof (descr), THREAD_SELF->member = (value)) +#define THREAD_SETMEM_NC(descr, member, value) \ + ((void) sizeof (descr), THREAD_SELF->member = (value)) + +/* Initializing the thread pointer will generate a SIGILL if the syscall + is not available. */ +#define TLS_INIT_TP_EXPENSIVE 1 + +# endif /* HAVE_TLS_SUPPORT */ +#endif /* __ASSEMBLER__ */ + +#endif /* tls.h */ diff --git a/sysdeps/arm/tls-macros.h b/sysdeps/arm/tls-macros.h new file mode 100644 index 0000000..94aa3a8 --- /dev/null +++ b/sysdeps/arm/tls-macros.h @@ -0,0 +1,51 @@ +#define TLS_LE(x) \ + ({ int *__result; \ + void *tp = __builtin_thread_pointer (); \ + asm ("ldr %0, 1f; " \ + "add %0, %1, %0; " \ + "b 2f; " \ + "1: .word " #x "(tpoff); " \ + "2: " \ + : "=&r" (__result) : "r" (tp)); \ + __result; }) + +#define TLS_IE(x) \ + ({ int *__result; \ + void *tp = __builtin_thread_pointer (); \ + asm ("ldr %0, 1f; " \ + "3: ldr %0, [pc, %0];" \ + "add %0, %1, %0; " \ + "b 2f; " \ + "1: .word " #x "(gottpoff) + (. - 3b - 8); " \ + "2: " \ + : "=&r" (__result) : "r" (tp)); \ + __result; }) + +#define TLS_LD(x) \ + ({ char *__result; \ + int __offset; \ + extern void *__tls_get_addr (void *); \ + asm ("ldr %0, 2f; " \ + "1: add %0, pc, %0; " \ + "b 3f; " \ + "2: .word " #x "(tlsldm) + (. - 1b - 8); " \ + "3: " \ + : "=r" (__result)); \ + __result = (char *)__tls_get_addr (__result); \ + asm ("ldr %0, 1f; " \ + "b 2f; " \ + "1: .word " #x "(tlsldo); " \ + "2: " \ + : "=r" (__offset)); \ + (int *) (__result + __offset); }) + +#define TLS_GD(x) \ + ({ int *__result; \ + extern void *__tls_get_addr (void *); \ + asm ("ldr %0, 2f; " \ + "1: add %0, pc, %0; " \ + "b 3f; " \ + "2: .word " #x "(tlsgd) + (. - 1b - 8); " \ + "3: " \ + : "=r" (__result)); \ + (int *)__tls_get_addr (__result); }) diff --git a/sysdeps/unix/sysv/linux/arm/Makefile b/sysdeps/unix/sysv/linux/arm/Makefile index 0ccdbe8..d91b968 100644 --- a/sysdeps/unix/sysv/linux/arm/Makefile +++ b/sysdeps/unix/sysv/linux/arm/Makefile @@ -1,3 +1,13 @@ +ifeq ($(subdir),csu) +sysdep_routines += aeabi_read_tp libc-aeabi_read_tp +static-only-routines += aeabi_read_tp +shared-only-routines += libc-aeabi_read_tp +endif + +ifeq ($(subdir),elf) +sysdep-rtld-routines += aeabi_read_tp +endif + ifeq ($(subdir),misc) sysdep_routines += ioperm sysdep_headers += sys/elf.h sys/io.h diff --git a/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S b/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S new file mode 100644 index 0000000..4a7b951 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/aeabi_read_tp.S @@ -0,0 +1,34 @@ +/* Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +#ifdef HAVE_TLS_SUPPORT + +/* GCC will emit calls to this routine under -mtp=soft. Linux has an + equivalent helper function (which clobbers fewer registers than + a normal function call) in a high page of memory; tail call to the + helper. */ + + .hidden __aeabi_read_tp +ENTRY (__aeabi_read_tp) + mov r0, #0xffff0fff + sub pc, r0, #31 +END (__aeabi_read_tp) + +#endif diff --git a/sysdeps/unix/sysv/linux/arm/libc-aeabi_read_tp.S b/sysdeps/unix/sysv/linux/arm/libc-aeabi_read_tp.S new file mode 100644 index 0000000..6132afc --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/libc-aeabi_read_tp.S @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h b/sysdeps/unix/sysv/linux/arm/sysdep.h index f42a5c8..4df3e37 100644 --- a/sysdeps/unix/sysv/linux/arm/sysdep.h +++ b/sysdeps/unix/sysv/linux/arm/sysdep.h @@ -179,20 +179,28 @@ __local_syscall_error: \ #undef INTERNAL_SYSCALL_DECL #define INTERNAL_SYSCALL_DECL(err) do { } while (0) -#undef INTERNAL_SYSCALL -#define INTERNAL_SYSCALL(name, err, nr, args...) \ +#undef INTERNAL_SYSCALL_RAW +#define INTERNAL_SYSCALL_RAW(name, err, nr, args...) \ ({ unsigned int _sys_result; \ { \ register int _a1 asm ("a1"); \ LOAD_ARGS_##nr (args) \ asm volatile ("swi %1 @ syscall " #name \ : "=r" (_a1) \ - : "i" (SYS_ify(name)) ASM_ARGS_##nr \ + : "i" (name) ASM_ARGS_##nr \ : "memory"); \ _sys_result = _a1; \ } \ (int) _sys_result; }) +#undef INTERNAL_SYSCALL +#define INTERNAL_SYSCALL(name, err, nr, args...) \ + INTERNAL_SYSCALL_RAW(SYS_ify(name), err, nr, args) + +#undef INTERNAL_SYSCALL_ARM +#define INTERNAL_SYSCALL_ARM(name, err, nr, args...) \ + INTERNAL_SYSCALL_RAW(__ARM_NR_##name, err, nr, args) + #undef INTERNAL_SYSCALL_ERROR_P #define INTERNAL_SYSCALL_ERROR_P(val, err) \ ((unsigned int) (val) >= 0xfffff001u) -- 2.7.4