From: Daniel Jacobowitz Date: Mon, 10 Oct 2005 15:29:32 +0000 (+0000) Subject: Add ARM EABI port. X-Git-Tag: glibc-2.16-ports-before-merge~1015 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f10eff5832a482175932652149a25eb76cf88a29;p=thirdparty%2Fglibc.git Add ARM EABI port. --- diff --git a/ChangeLog.arm b/ChangeLog.arm index edb7517a602..35119cacd3a 100644 --- a/ChangeLog.arm +++ b/ChangeLog.arm @@ -1,3 +1,62 @@ +2005-10-10 Daniel Jacobowitz + + * sysdeps/arm/dl-machine.h (_dl_start_user): Preserve eight-byte + stack alignment. + + * sysdeps/arm/elf/start.S (_start): Add unwind markers for EABI + targets. + + * sysdeps/arm/preconfigure: Set machine for EABI targets. Remove + obsolete Thumb support. + + * sysdeps/arm/shlib-versions: Add EABI support. + + * sysdeps/unix/sysv/linux/arm/mmap64.S (__mmap64): Allow for padding + in the argument list for EABI targets. + + * sysdeps/arm/fpu/feholdexcpt.c, sysdeps/arm/fpu/fesetround.c: Add + libm_hidden_def. + + * sysdeps/arm/dl-sysdep.h, sysdeps/arm/eabi/Makefile, + sysdeps/arm/eabi/Versions, sysdeps/arm/eabi/__longjmp.S, + sysdeps/arm/eabi/aeabi_assert.c, sysdeps/arm/eabi/aeabi_atexit.c, + sysdeps/arm/eabi/aeabi_errno_addr.c, sysdeps/arm/eabi/aeabi_lcsts.c, + sysdeps/arm/eabi/aeabi_localeconv.c, sysdeps/arm/eabi/aeabi_math.c, + sysdeps/arm/eabi/aeabi_mb_cur_max.c, sysdeps/arm/eabi/aeabi_memclr.c, + sysdeps/arm/eabi/aeabi_memcpy.c, sysdeps/arm/eabi/aeabi_memmove.c + sysdeps/arm/eabi/aeabi_memset.c, sysdeps/arm/eabi/aeabi_sighandlers.S, + sysdeps/arm/eabi/aeabi_unwind_cpp_pr1.c, sysdeps/arm/eabi/bits/fenv.h, + sysdeps/arm/eabi/bits/huge_val.h, sysdeps/arm/eabi/bits/setjmp.h, + sysdeps/arm/eabi/fclrexcpt.c, sysdeps/arm/eabi/fedisblxcpt.c, + sysdeps/arm/eabi/feenablxcpt.c, sysdeps/arm/eabi/fegetenv.c, + sysdeps/arm/eabi/fegetexcept.c, sysdeps/arm/eabi/fegetround.c, + sysdeps/arm/eabi/feholdexcpt.c, sysdeps/arm/eabi/fesetenv.c, + sysdeps/arm/eabi/fesetround.c, sysdeps/arm/eabi/find_exidx.c, + sysdeps/arm/eabi/fpu_control.h, sysdeps/arm/eabi/fraiseexcpt.c, + sysdeps/arm/eabi/fsetexcptflg.c, sysdeps/arm/eabi/ftestexcept.c, + sysdeps/arm/eabi/setjmp.S, sysdeps/unix/sysv/linux/arm/eabi/configure, + sysdeps/arm/eabi/rtld-global-offsets.sym, sysdeps/arm/eabi/setfpucw.c, + sysdeps/unix/sysv/linux/arm/eabi/configure.in, + sysdeps/unix/sysv/linux/arm/eabi/epoll_ctl.c, + sysdeps/unix/sysv/linux/arm/eabi/epoll_wait.c, + sysdeps/unix/sysv/linux/arm/eabi/fcntl.c, + sysdeps/unix/sysv/linux/arm/eabi/fstatfs64.c, + sysdeps/unix/sysv/linux/arm/eabi/fxstat64.c, + sysdeps/unix/sysv/linux/arm/eabi/kernel_epoll.h, + sysdeps/unix/sysv/linux/arm/eabi/kernel_stat.h, + sysdeps/unix/sysv/linux/arm/eabi/lockf64.c, + sysdeps/unix/sysv/linux/arm/eabi/lxstat64.c, + sysdeps/unix/sysv/linux/arm/eabi/oldgetrlimit.c, + sysdeps/unix/sysv/linux/arm/eabi/oldsetrlimit.c, + sysdeps/unix/sysv/linux/arm/eabi/semop.c, + sysdeps/unix/sysv/linux/arm/eabi/semtimedop.c, + sysdeps/unix/sysv/linux/arm/eabi/statfs64.c, + sysdeps/unix/sysv/linux/arm/eabi/syscalls.list, + sysdeps/unix/sysv/linux/arm/eabi/uname.c, + sysdeps/unix/sysv/linux/arm/eabi/xstat64.c, + sysdeps/unix/sysv/linux/arm/eabi/xstatconv.c, + sysdeps/unix/sysv/linux/arm/eabi/xstatconv.h: New files. + 2005-10-10 Daniel Jacobowitz * sysdeps/arm/memset.S (memset): Correct handling of negative diff --git a/sysdeps/arm/dl-machine.h b/sysdeps/arm/dl-machine.h index 2534be151e5..80117065802 100644 --- a/sysdeps/arm/dl-machine.h +++ b/sysdeps/arm/dl-machine.h @@ -157,22 +157,19 @@ _dl_start_user:\n\ add sl, pc, sl\n\ .L_GOT_GOT:\n\ ldr r4, [sl, r4]\n\ - @ get the original arg count\n\ - ldr r1, [sp]\n\ @ save the entry point in another register\n\ mov r6, r0\n\ - @ adjust the stack pointer to skip the extra args\n\ - add sp, sp, r4, lsl #2\n\ - @ subtract _dl_skip_args from original arg count\n\ - sub r1, r1, r4\n\ + @ get the original arg count\n\ + ldr r1, [sp]\n\ @ get the argv address\n\ add r2, sp, #4\n\ - @ store the new argc in the new stack location\n\ - str r1, [sp]\n\ + @ Fix up the stack if necessary.\n\ + cmp r4, #0\n\ + bne .L_fixup_stack\n\ +.L_done_fixup:\n\ @ compute envp\n\ add r3, r2, r1, lsl #2\n\ add r3, r3, #4\n\ -\n\ @ now we call _dl_init\n\ ldr r0, .L_LOADED\n\ ldr r0, [sl, r0]\n\ @@ -183,12 +180,45 @@ _dl_start_user:\n\ add r0, sl, r0\n\ @ jump to the user_s entry point\n\ " BX(r6) "\n\ +\n\ + @ iWMMXt and EABI targets require the stack to be eight byte\n\ + @ aligned - shuffle arguments etc.\n\ +.L_fixup_stack:\n\ + @ subtract _dl_skip_args from original arg count\n\ + sub r1, r1, r4\n\ + @ store the new argc in the new stack location\n\ + str r1, [sp]\n\ + @ find the first unskipped argument\n\ + mov r3, r2\n\ + add r4, r2, r4, lsl #2\n\ + @ shuffle argv down\n\ +1: ldr r5, [r4], #4\n\ + str r5, [r3], #4\n\ + cmp r5, #0\n\ + bne 1b\n\ + @ shuffle envp down\n\ +1: ldr r5, [r4], #4\n\ + str r5, [r3], #4\n\ + cmp r5, #0\n\ + bne 1b\n\ + @ shuffle auxv down\n\ +1: ldmia r4!, {r0, r5}\n\ + stmia r3!, {r0, r5}\n\ + cmp r0, #0\n\ + bne 1b\n\ + @ Update _dl_argv\n\ + ldr r3, .L_ARGV\n\ + str r2, [sl, r3]\n\ + b .L_done_fixup\n\ +\n\ .L_GET_GOT:\n\ .word _GLOBAL_OFFSET_TABLE_ - .L_GOT_GOT - 4\n\ .L_SKIP_ARGS:\n\ .word _dl_skip_args(GOTOFF)\n\ .L_FINI_PROC:\n\ .word _dl_fini(GOTOFF)\n\ +.L_ARGV:\n\ + .word _dl_argv(GOTOFF)\n\ .L_LOADED:\n\ .word _rtld_local(GOTOFF)\n\ .previous\n\ diff --git a/sysdeps/arm/dl-sysdep.h b/sysdeps/arm/dl-sysdep.h new file mode 100644 index 00000000000..cd678f4e434 --- /dev/null +++ b/sysdeps/arm/dl-sysdep.h @@ -0,0 +1,24 @@ +/* System-specific settings for dynamic linker code. Alpha version. + Copyright (C) 2002, 2003, 2004, 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_next + +/* _dl_argv cannot be attribute_relro, because _dl_start_user + might write into it after _dl_start returns. */ +#define DL_ARGV_NOT_RELRO 1 diff --git a/sysdeps/arm/eabi/Makefile b/sysdeps/arm/eabi/Makefile new file mode 100644 index 00000000000..34b0027e354 --- /dev/null +++ b/sysdeps/arm/eabi/Makefile @@ -0,0 +1,22 @@ +ifeq ($(subdir),csu) +aeabi_constants = aeabi_lcsts aeabi_sighandlers aeabi_math +aeabi_routines = aeabi_assert aeabi_localeconv aeabi_errno_addr \ + aeabi_mb_cur_max aeabi_atexit aeabi_memclr aeabi_memcpy \ + aeabi_memmove aeabi_memset + +sysdep_routines += $(aeabi_constants) $(aeabi_routines) +static-only-routines += $(aeabi_constants) $(aeabi_routines) + +# get offset to rtld_global._dl_hwcap +gen-as-const-headers += rtld-global-offsets.sym +endif + +ifeq ($(subdir),elf) +sysdep_routines += aeabi_unwind_cpp_pr1 find_exidx +shared-only-routines += aeabi_unwind_cpp_pr1 +sysdep-rtld-routines += aeabi_unwind_cpp_pr1 +endif + +ifeq ($(subdir),math) +$(objpfx)libm.so: $(elfobjdir)/ld.so +endif diff --git a/sysdeps/arm/eabi/Versions b/sysdeps/arm/eabi/Versions new file mode 100644 index 00000000000..6d7a73421a4 --- /dev/null +++ b/sysdeps/arm/eabi/Versions @@ -0,0 +1,6 @@ +libc { + GLIBC_2.4 { + # Helper routines + __gnu_Unwind_Find_exidx; + } +} diff --git a/sysdeps/arm/eabi/__longjmp.S b/sysdeps/arm/eabi/__longjmp.S new file mode 100644 index 00000000000..56776338a09 --- /dev/null +++ b/sysdeps/arm/eabi/__longjmp.S @@ -0,0 +1,85 @@ +/* longjmp for ARM. + Copyright (C) 1997, 1998, 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#define _SETJMP_H +#define _ASM +#include +#define __ASSEMBLY__ +#include +#include + +/* __longjmp(jmpbuf, val) */ + +ENTRY (__longjmp) + mov ip, r0 + movs r0, r1 /* get the return value in place */ + moveq r0, #1 /* can't let setjmp() return zero! */ + + LOADREGS(ia, ip!, {v1-v6, sl, fp, sp, lr}) + +#ifdef IS_IN_rtld + ldr a2, 1f + ldr a3, Lrtld_local_ro +0: add a2, pc, a2 + add a2, a2, a3 + ldr a2, [a2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] +#else +#ifdef PIC + ldr a2, 1f + ldr a3, Lrtld_global_ro +0: add a2, pc, a2 + ldr a2, [a2, a3] + ldr a2, [a2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] +#else + ldr a2, Lhwcap + ldr a2, [a2, #0] +#endif +#endif + + tst a2, #HWCAP_VFP + beq Lno_vfp + + /* Restore the VFP registers. */ + /* Following instruction is fldmiax ip!, {d8-d15}. */ + ldc p11, cr8, [r12], #68 + /* Restore the floating-point status register. */ + ldr r1, [ip], #4 + /* Following instruction is fmxr fpscr, r1. */ + mcr p10, 7, r1, cr1, cr0, 0 +Lno_vfp: + + DO_RET(lr) + +#ifdef IS_IN_rtld +1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8 +Lrtld_local_ro: + .long C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF) +#else +#ifdef PIC +1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8 +Lrtld_global_ro: + .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) +#else +Lhwcap: + .long C_SYMBOL_NAME(_dl_hwcap) +#endif +#endif + +END (__longjmp) diff --git a/sysdeps/arm/eabi/aeabi_assert.c b/sysdeps/arm/eabi/aeabi_assert.c new file mode 100644 index 00000000000..ccedbe609b9 --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_assert.c @@ -0,0 +1,27 @@ +/* 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. */ + +#include +#include + +void attribute_hidden +__aeabi_assert (const char *assertion, const char *file, + unsigned int line) +{ + __assert_fail (assertion, file, line, NULL); +} diff --git a/sysdeps/arm/eabi/aeabi_atexit.c b/sysdeps/arm/eabi/aeabi_atexit.c new file mode 100644 index 00000000000..b12cda48e2f --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_atexit.c @@ -0,0 +1,28 @@ +/* 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 + +/* Register a function to be called by exit or when a shared library + is unloaded. This routine is like __cxa_atexit, but uses the + calling sequence required by the ARM EABI. */ +int attribute_hidden +__aeabi_atexit (void *arg, void (*func) (void *), void *d) +{ + return __cxa_atexit (func, arg, d); +} diff --git a/sysdeps/arm/eabi/aeabi_errno_addr.c b/sysdeps/arm/eabi/aeabi_errno_addr.c new file mode 100644 index 00000000000..748edd3ba1b --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_errno_addr.c @@ -0,0 +1,26 @@ +/* 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. */ + +#include + +attribute_hidden +volatile int * +__aeabi_errno_addr (void) +{ + return &errno; +} diff --git a/sysdeps/arm/eabi/aeabi_lcsts.c b/sysdeps/arm/eabi/aeabi_lcsts.c new file mode 100644 index 00000000000..6ca2ea33a45 --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_lcsts.c @@ -0,0 +1,67 @@ +/* Link-time constants for ARM EABI. + 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. */ + +/* The ARM EABI requires that we provide ISO compile-time constants as + link-time constants. Some portable applications may reference these. */ + +#include +#include +#include +#include +#include +#include +#include + +#define eabi_constant2(X,Y) const int __aeabi_##X attribute_hidden = Y +#define eabi_constant(X) const int __aeabi_##X attribute_hidden = X + +eabi_constant (EDOM); +eabi_constant (ERANGE); +eabi_constant (EILSEQ); + +eabi_constant (MB_LEN_MAX); + +eabi_constant (LC_COLLATE); +eabi_constant (LC_CTYPE); +eabi_constant (LC_MONETARY); +eabi_constant (LC_NUMERIC); +eabi_constant (LC_TIME); +eabi_constant (LC_ALL); + +/* The value of __aeabi_JMP_BUF_SIZE is the number of doublewords in a + jmp_buf. */ +eabi_constant2 (JMP_BUF_SIZE, sizeof (jmp_buf) / 8); + +eabi_constant (SIGABRT); +eabi_constant (SIGFPE); +eabi_constant (SIGILL); +eabi_constant (SIGINT); +eabi_constant (SIGSEGV); +eabi_constant (SIGTERM); + +eabi_constant2 (IOFBF, _IOFBF); +eabi_constant2 (IOLBF, _IOLBF); +eabi_constant2 (IONBF, _IONBF); +eabi_constant (BUFSIZ); +eabi_constant (FOPEN_MAX); +eabi_constant (TMP_MAX); +eabi_constant (FILENAME_MAX); +eabi_constant (L_tmpnam); + +eabi_constant (CLOCKS_PER_SEC); diff --git a/sysdeps/arm/eabi/aeabi_localeconv.c b/sysdeps/arm/eabi/aeabi_localeconv.c new file mode 100644 index 00000000000..2dd82df2183 --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_localeconv.c @@ -0,0 +1,26 @@ +/* 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. */ + +#include + +attribute_hidden +struct lconv * +__aeabi_localeconv (void) +{ + return localeconv (); +} diff --git a/sysdeps/arm/eabi/aeabi_math.c b/sysdeps/arm/eabi/aeabi_math.c new file mode 100644 index 00000000000..b33330d7358 --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_math.c @@ -0,0 +1,25 @@ +/* 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. */ + +#include + +const double __aeabi_HUGE_VAL attribute_hidden = HUGE_VAL; +const long double __aeabi_HUGE_VALL attribute_hidden = HUGE_VALL; +const float __aeabi_HUGE_VALF attribute_hidden = HUGE_VALF; +const float __aeabi_INFINITY attribute_hidden = INFINITY; +const float __aeabi_NAN attribute_hidden = NAN; diff --git a/sysdeps/arm/eabi/aeabi_mb_cur_max.c b/sysdeps/arm/eabi/aeabi_mb_cur_max.c new file mode 100644 index 00000000000..62e4c4bba0b --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_mb_cur_max.c @@ -0,0 +1,28 @@ +/* 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. */ + +#include +#include +#include +#include + +int attribute_hidden +__aeabi_MB_CUR_MAX (void) +{ + return MB_CUR_MAX; +} diff --git a/sysdeps/arm/eabi/aeabi_memclr.c b/sysdeps/arm/eabi/aeabi_memclr.c new file mode 100644 index 00000000000..8add8afcead --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_memclr.c @@ -0,0 +1,31 @@ +/* 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 + +/* Clear memory. Can't alias to bzero because it's not defined in the + same translation unit. */ +void attribute_hidden +__aeabi_memclr (void *dest, size_t n) +{ + __bzero (dest, n); +} + +/* Versions of the above which may assume memory alignment. */ +strong_alias (__aeabi_memclr, attribute_hidden __aeabi_memclr4) +strong_alias (__aeabi_memclr, attribute_hidden __aeabi_memclr8) diff --git a/sysdeps/arm/eabi/aeabi_memcpy.c b/sysdeps/arm/eabi/aeabi_memcpy.c new file mode 100644 index 00000000000..d7cd40313e4 --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_memcpy.c @@ -0,0 +1,32 @@ +/* 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 + +/* Copy memory like memcpy, but no return value required. Can't alias + to memcpy because it's not defined in the same translation + unit. */ +void attribute_hidden +__aeabi_memcpy (void *dest, const void *src, size_t n) +{ + memcpy (dest, src, n); +} + +/* Versions of the above which may assume memory alignment. */ +strong_alias (__aeabi_memcpy, attribute_hidden __aeabi_memcpy4) +strong_alias (__aeabi_memcpy, attribute_hidden __aeabi_memcpy8) diff --git a/sysdeps/arm/eabi/aeabi_memmove.c b/sysdeps/arm/eabi/aeabi_memmove.c new file mode 100644 index 00000000000..32ed3b1383b --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_memmove.c @@ -0,0 +1,32 @@ +/* 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 + +/* Copy memory like memmove, but no return value required. Can't + alias to memmove because it's not defined in the same translation + unit. */ +void attribute_hidden +__aeabi_memmove (void *dest, const void *src, size_t n) +{ + memmove (dest, src, n); +} + +/* Versions of the above which may assume memory alignment. */ +strong_alias (__aeabi_memmove, attribute_hidden __aeabi_memmove4) +strong_alias (__aeabi_memmove, attribute_hidden __aeabi_memmove8) diff --git a/sysdeps/arm/eabi/aeabi_memset.c b/sysdeps/arm/eabi/aeabi_memset.c new file mode 100644 index 00000000000..d7232af3989 --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_memset.c @@ -0,0 +1,31 @@ +/* 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 + +/* Set memory like memset, but different argument order and no return + value required. */ +void attribute_hidden +__aeabi_memset (void *dest, size_t n, int c) +{ + memset (dest, c, n); +} + +/* Versions of the above which may assume memory alignment. */ +strong_alias (__aeabi_memset, attribute_hidden __aeabi_memset4) +strong_alias (__aeabi_memset, attribute_hidden __aeabi_memset8) diff --git a/sysdeps/arm/eabi/aeabi_sighandlers.S b/sysdeps/arm/eabi/aeabi_sighandlers.S new file mode 100644 index 00000000000..586ba88f5cc --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_sighandlers.S @@ -0,0 +1,37 @@ +/* Link-time constants for ARM EABI - signal handlers. + 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. */ + +/* The ARM EABI defines these as "functions". */ + +#include + + .global __aeabi_SIG_DFL + .hidden __aeabi_SIG_DFL + .type __aeabi_SIG_DFL, %function + .set __aeabi_SIG_DFL, 0 + + .global __aeabi_SIG_IGN + .hidden __aeabi_SIG_IGN + .type __aeabi_SIG_IGN, %function + .set __aeabi_SIG_IGN, 1 + + .global __aeabi_SIG_ERR + .hidden __aeabi_SIG_ERR + .type __aeabi_SIG_ERR, %function + .set __aeabi_SIG_ERR, -1 diff --git a/sysdeps/arm/eabi/aeabi_unwind_cpp_pr1.c b/sysdeps/arm/eabi/aeabi_unwind_cpp_pr1.c new file mode 100644 index 00000000000..91df013ad4b --- /dev/null +++ b/sysdeps/arm/eabi/aeabi_unwind_cpp_pr1.c @@ -0,0 +1,52 @@ +/* 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. */ + +/* Because some objects in ld.so and libc.so are built with + -fexceptions, we end up with references to this personality + routine. However, these libraries are not linked against + libgcc_eh.a, so we need a dummy definition. This routine will + never actually be called. */ + +#include + +attribute_hidden +void +__aeabi_unwind_cpp_pr0 (void) +{ +#ifndef IS_IN_rtld + abort (); +#endif +} + +attribute_hidden +void +__aeabi_unwind_cpp_pr1 (void) +{ +#ifndef IS_IN_rtld + abort (); +#endif +} + +attribute_hidden +void +__aeabi_unwind_cpp_pr2 (void) +{ +#ifndef IS_IN_rtld + abort (); +#endif +} diff --git a/sysdeps/arm/eabi/bits/fenv.h b/sysdeps/arm/eabi/bits/fenv.h new file mode 100644 index 00000000000..49e386222d6 --- /dev/null +++ b/sysdeps/arm/eabi/bits/fenv.h @@ -0,0 +1,74 @@ +/* Copyright (C) 2004, 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef _FENV_H +# error "Never use directly; include instead." +#endif + +/* Define bits representing exceptions in the FPU status word. */ +enum + { + FE_INVALID = 1, +#define FE_INVALID FE_INVALID + FE_DIVBYZERO = 2, +#define FE_DIVBYZERO FE_DIVBYZERO + FE_OVERFLOW = 4, +#define FE_OVERFLOW FE_OVERFLOW + FE_UNDERFLOW = 8, +#define FE_UNDERFLOW FE_UNDERFLOW + FE_INEXACT = 16, +#define FE_INEXACT FE_INEXACT + }; + +/* Amount to shift by to convert an exception to a mask bit. */ +#define FE_EXCEPT_SHIFT 8 + +/* All supported exceptions. */ +#define FE_ALL_EXCEPT \ + (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) + +/* VFP supports all of the four defined rounding modes. */ +enum + { + FE_TONEAREST = 0, +#define FE_TONEAREST FE_TONEAREST + FE_UPWARD = 0x400000, +#define FE_UPWARD FE_UPWARD + FE_DOWNWARD = 0x800000, +#define FE_DOWNWARD FE_DOWNWARD + FE_TOWARDZERO = 0xc00000 +#define FE_TOWARDZERO FE_TOWARDZERO + }; + +/* Type representing exception flags. */ +typedef unsigned int fexcept_t; + +/* Type representing floating-point environment. */ +typedef struct + { + unsigned int __cw; + } +fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((fenv_t *) -1l) + +#ifdef __USE_GNU +/* Floating-point environment where none of the exceptions are masked. */ +# define FE_NOMASK_ENV ((__const fenv_t *) -2) +#endif diff --git a/sysdeps/arm/eabi/bits/huge_val.h b/sysdeps/arm/eabi/bits/huge_val.h new file mode 100644 index 00000000000..11ca11f18ea --- /dev/null +++ b/sysdeps/arm/eabi/bits/huge_val.h @@ -0,0 +1,55 @@ +/* `HUGE_VAL' constant for IEEE 754 machines (where it is infinity). + Used by and functions for overflow. + Copyright (C) 1992, 1995, 1996, 1997, 1999, 2000, 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 _MATH_H +# error "Never use directly; include instead." +#endif + +/* IEEE positive infinity (-HUGE_VAL is negative infinity). */ + +#if __GNUC_PREREQ(3,3) +# define HUGE_VAL (__builtin_huge_val()) +#elif __GNUC_PREREQ(2,96) +# define HUGE_VAL (__extension__ 0x1.0p2047) +#elif defined __GNUC__ + +# define HUGE_VAL \ + (__extension__ \ + ((union { unsigned __l __attribute__((__mode__(__DI__))); double __d; }) \ + { __l: 0x7ff0000000000000ULL }).__d) + +#else /* not GCC */ + +# include + +typedef union { unsigned char __c[8]; double __d; } __huge_val_t; + +# if __BYTE_ORDER == __BIG_ENDIAN +# define __HUGE_VAL_bytes { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } +# endif +# if __BYTE_ORDER == __LITTLE_ENDIAN +# define __HUGE_VAL_bytes { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f } +# endif + +static __huge_val_t __huge_val = { __HUGE_VAL_bytes }; +# define HUGE_VAL (__huge_val.__d) + +#endif /* GCC. */ diff --git a/sysdeps/arm/eabi/bits/setjmp.h b/sysdeps/arm/eabi/bits/setjmp.h new file mode 100644 index 00000000000..3bb92dd7278 --- /dev/null +++ b/sysdeps/arm/eabi/bits/setjmp.h @@ -0,0 +1,45 @@ +/* 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. */ + +/* Define the machine-dependent type `jmp_buf'. ARM EABI version. */ + +#ifndef _BITS_SETJMP_H +#define _BITS_SETJMP_H 1 + +#if !defined _SETJMP_H && !defined _PTHREAD_H +# error "Never include directly; use instead." +#endif + +#ifndef _ASM +/* The exact set of registers saved may depend on the particular core + in use, as some coprocessor registers may need to be saved. The C + Library ABI requires that the buffer be 8-byte aligned, and + recommends that the buffer contain 64 words. The first 28 words + are occupied by v1-v6, sl, fp, sp, pc, d8-d15, and fpscr. (Note + that d8-15 require 17 words, due to the use of fstmx.) */ +typedef int __jmp_buf[64] __attribute__((aligned (8))); +#endif + +#define __JMP_BUF_SP 8 + +/* Test if longjmp to JMPBUF would unwind the frame + containing a local variable at ADDRESS. */ +#define _JMPBUF_UNWINDS(jmpbuf, address) \ + ((void *) (address) < (void *) (jmpbuf[__JMP_BUF_SP])) + +#endif diff --git a/sysdeps/arm/eabi/fclrexcpt.c b/sysdeps/arm/eabi/fclrexcpt.c new file mode 100644 index 00000000000..6e5d242805f --- /dev/null +++ b/sysdeps/arm/eabi/fclrexcpt.c @@ -0,0 +1,61 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1997,98,99,2000,01,05 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include +#include +#include +#include + +int +__feclearexcept (int excepts) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + unsigned long int temp; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + /* Get the current floating point status. */ + _FPU_GETCW (temp); + + /* Clear the relevant bits. */ + temp = (temp & ~FE_ALL_EXCEPT) | (temp & FE_ALL_EXCEPT & ~excepts); + + /* Put the new data in effect. */ + _FPU_SETCW (temp); + + /* Success. */ + return 0; + } + + /* Unsupported, so fail. */ + return 1; +} + +#include +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__feclearexcept, __old_feclearexcept) +compat_symbol (libm, __old_feclearexcept, feclearexcept, GLIBC_2_1); +#endif + +versioned_symbol (libm, __feclearexcept, feclearexcept, GLIBC_2_2); diff --git a/sysdeps/arm/eabi/fedisblxcpt.c b/sysdeps/arm/eabi/fedisblxcpt.c new file mode 100644 index 00000000000..414d34b1e36 --- /dev/null +++ b/sysdeps/arm/eabi/fedisblxcpt.c @@ -0,0 +1,51 @@ +/* Disable floating-point exceptions. + Copyright (C) 2001, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Philip Blundell , 2001. + + 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include +#include +#include +#include + +int +fedisableexcept (int excepts) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + unsigned long int new_exc, old_exc; + + _FPU_GETCW(new_exc); + + old_exc = (new_exc >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; + + excepts &= FE_ALL_EXCEPT; + + new_exc &= ~(excepts << FE_EXCEPT_SHIFT); + + _FPU_SETCW(new_exc); + + return old_exc; + } + + /* Unsupported, so return -1 for failure. */ + return -1; +} diff --git a/sysdeps/arm/eabi/feenablxcpt.c b/sysdeps/arm/eabi/feenablxcpt.c new file mode 100644 index 00000000000..e104bc4f653 --- /dev/null +++ b/sysdeps/arm/eabi/feenablxcpt.c @@ -0,0 +1,51 @@ +/* Enable floating-point exceptions. + Copyright (C) 2001, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Philip Blundell , 2001. + + 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include +#include +#include +#include + +int +feenableexcept (int excepts) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + unsigned long int new_exc, old_exc; + + _FPU_GETCW(new_exc); + + old_exc = (new_exc >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; + + excepts &= FE_ALL_EXCEPT; + + new_exc |= (excepts << FE_EXCEPT_SHIFT); + + _FPU_SETCW(new_exc); + + return old_exc; + } + + /* Unsupported, so return -1 for failure. */ + return -1; +} diff --git a/sysdeps/arm/eabi/fegetenv.c b/sysdeps/arm/eabi/fegetenv.c new file mode 100644 index 00000000000..178d22a4245 --- /dev/null +++ b/sysdeps/arm/eabi/fegetenv.c @@ -0,0 +1,51 @@ +/* Store current floating-point environment. + Copyright (C) 1997,98,99,2000,01,05 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include +#include +#include +#include + +int +__fegetenv (fenv_t *envp) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + unsigned long int temp; + _FPU_GETCW (temp); + envp->__cw = temp; + + /* Success. */ + return 0; + } + + /* Unsupported, so fail. */ + return 1; +} + +#include +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__fegetenv, __old_fegetenv) +compat_symbol (libm, __old_fegetenv, fegetenv, GLIBC_2_1); +#endif + +versioned_symbol (libm, __fegetenv, fegetenv, GLIBC_2_2); diff --git a/sysdeps/arm/eabi/fegetexcept.c b/sysdeps/arm/eabi/fegetexcept.c new file mode 100644 index 00000000000..811c8ae25a1 --- /dev/null +++ b/sysdeps/arm/eabi/fegetexcept.c @@ -0,0 +1,43 @@ +/* Get floating-point exceptions. + Copyright (C) 2001, 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Philip Blundell , 2001 + + 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include +#include +#include +#include + +int +fegetexcept (void) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + unsigned long temp; + + _FPU_GETCW (temp); + + return (temp >> FE_EXCEPT_SHIFT) & FE_ALL_EXCEPT; + } + + /* Unsupported. Return all exceptions disabled. */ + return 0; +} diff --git a/sysdeps/arm/eabi/fegetround.c b/sysdeps/arm/eabi/fegetround.c new file mode 100644 index 00000000000..1c4be04e65c --- /dev/null +++ b/sysdeps/arm/eabi/fegetround.c @@ -0,0 +1,43 @@ +/* Return current rounding direction. + Copyright (C) 2004, 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include +#include +#include +#include + +int +fegetround (void) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + unsigned int temp; + + /* Get the current environment. */ + _FPU_GETCW (temp); + + return temp & FE_TOWARDZERO; + } + + /* The current soft-float implementation only handles TONEAREST. */ + return FE_TONEAREST; +} diff --git a/sysdeps/arm/eabi/feholdexcpt.c b/sysdeps/arm/eabi/feholdexcpt.c new file mode 100644 index 00000000000..9872ea17be2 --- /dev/null +++ b/sysdeps/arm/eabi/feholdexcpt.c @@ -0,0 +1,54 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 1997, 1998, 1999, 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include +#include +#include +#include + +int +feholdexcept (fenv_t *envp) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + unsigned long int temp; + + /* Store the environment. */ + _FPU_GETCW(temp); + envp->__cw = temp; + + /* Now set all exceptions to non-stop. */ + temp &= ~(FE_ALL_EXCEPT << FE_EXCEPT_SHIFT); + + /* And clear all exception flags. */ + temp &= ~FE_ALL_EXCEPT; + + _FPU_SETCW(temp); + + return 0; + } + + /* Unsupported, so fail. */ + return 1; +} + +libm_hidden_def (feholdexcept) diff --git a/sysdeps/arm/eabi/fesetenv.c b/sysdeps/arm/eabi/fesetenv.c new file mode 100644 index 00000000000..bf253848bc4 --- /dev/null +++ b/sysdeps/arm/eabi/fesetenv.c @@ -0,0 +1,57 @@ +/* Install given floating-point environment. + Copyright (C) 2004, 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include +#include +#include +#include + +int +__fesetenv (const fenv_t *envp) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + unsigned int temp; + + _FPU_GETCW (temp); + temp &= _FPU_RESERVED; + + if (envp == FE_DFL_ENV) + temp |= _FPU_DEFAULT; + else if (envp == FE_NOMASK_ENV) + temp |= _FPU_IEEE; + else + temp |= envp->__cw & ~_FPU_RESERVED; + + _FPU_SETCW (temp); + + /* Success. */ + return 0; + } + + /* Unsupported, so fail. */ + return 1; +} + +#include +libm_hidden_ver (__fesetenv, fesetenv) +versioned_symbol (libm, __fesetenv, fesetenv, GLIBC_2_2); diff --git a/sysdeps/arm/eabi/fesetround.c b/sysdeps/arm/eabi/fesetround.c new file mode 100644 index 00000000000..f6e20cb72d1 --- /dev/null +++ b/sysdeps/arm/eabi/fesetround.c @@ -0,0 +1,57 @@ +/* Set current rounding direction. + Copyright (C) 2004, 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include +#include +#include +#include + +int +fesetround (int round) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + fpu_control_t temp; + + switch (round) + { + case FE_TONEAREST: + case FE_UPWARD: + case FE_DOWNWARD: + case FE_TOWARDZERO: + _FPU_GETCW (temp); + temp = (temp & ~FE_TOWARDZERO) | round; + _FPU_SETCW (temp); + return 0; + default: + return 1; + } + } + else if (round == FE_TONEAREST) + /* This is the only supported rounding mode for soft-fp. */ + return 0; + + /* Unsupported, so fail. */ + return 1; +} + +libm_hidden_def (fesetround) diff --git a/sysdeps/arm/eabi/find_exidx.c b/sysdeps/arm/eabi/find_exidx.c new file mode 100644 index 00000000000..9e4f4012ff2 --- /dev/null +++ b/sysdeps/arm/eabi/find_exidx.c @@ -0,0 +1,80 @@ +/* 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 + +struct unw_eh_callback_data +{ + _Unwind_Ptr pc; + _Unwind_Ptr exidx_start; + int exidx_len; +}; + + +/* Callback to determins if the PC lies within an object, and remember the + location of the exception index table if it does. */ + +static int +find_exidx_callback (struct dl_phdr_info * info, size_t size, void * ptr) +{ + struct unw_eh_callback_data * data; + const ElfW(Phdr) *phdr; + int i; + int match; + _Unwind_Ptr load_base; + + data = (struct unw_eh_callback_data *) ptr; + load_base = info->dlpi_addr; + phdr = info->dlpi_phdr; + + match = 0; + for (i = info->dlpi_phnum; i > 0; i--, phdr++) + { + if (phdr->p_type == PT_LOAD) + { + _Unwind_Ptr vaddr = phdr->p_vaddr + load_base; + if (data->pc >= vaddr && data->pc < vaddr + phdr->p_memsz) + match = 1; + } + else if (phdr->p_type == PT_ARM_EXIDX) + { + data->exidx_start = (_Unwind_Ptr) (phdr->p_vaddr + load_base); + data->exidx_len = phdr->p_memsz; + } + } + + return match; +} + + +/* Find the exception index table containing PC. */ + +_Unwind_Ptr +__gnu_Unwind_Find_exidx (_Unwind_Ptr pc, int * pcount) +{ + struct unw_eh_callback_data data; + + data.pc = pc; + data.exidx_start = 0; + if (dl_iterate_phdr (find_exidx_callback, &data) <= 0) + return 0; + + *pcount = data.exidx_len / 8; + return data.exidx_start; +} diff --git a/sysdeps/arm/eabi/fpu_control.h b/sysdeps/arm/eabi/fpu_control.h new file mode 100644 index 00000000000..55d77649c30 --- /dev/null +++ b/sysdeps/arm/eabi/fpu_control.h @@ -0,0 +1,51 @@ +/* FPU control word definitions. ARM VFP version. + Copyright (C) 2004, 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H + +/* masking of interrupts */ +#define _FPU_MASK_IM 0x00000100 /* invalid operation */ +#define _FPU_MASK_ZM 0x00000200 /* divide by zero */ +#define _FPU_MASK_OM 0x00000400 /* overflow */ +#define _FPU_MASK_UM 0x00000800 /* underflow */ +#define _FPU_MASK_PM 0x00001000 /* inexact */ + +/* Some bits in the FPSCR are not yet defined. They must be preserved when + modifying the contents. */ +#define _FPU_RESERVED 0x0e08e0e0 +#define _FPU_DEFAULT 0x00000000 +/* Default + exceptions enabled. */ +#define _FPU_IEEE (_FPU_DEFAULT | 0x00001f00) + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Macros for accessing the hardware control word. */ +/* This is fmrx %0, fpscr. */ +#define _FPU_GETCW(cw) \ + __asm__ __volatile__ ("mrc p10, 7, %0, cr1, cr0, 0" : "=r" (cw)) +/* This is fmxr fpscr, %0. */ +#define _FPU_SETCW(cw) \ + __asm__ __volatile__ ("mcr p10, 7, %0, cr1, cr0, 0" : : "r" (cw)) + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif /* _FPU_CONTROL_H */ diff --git a/sysdeps/arm/eabi/fraiseexcpt.c b/sysdeps/arm/eabi/fraiseexcpt.c new file mode 100644 index 00000000000..c0ab419673f --- /dev/null +++ b/sysdeps/arm/eabi/fraiseexcpt.c @@ -0,0 +1,110 @@ +/* Raise given exceptions. + Copyright (C) 2004, 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include +#include + +#include +#include +#include +#include + +int +feraiseexcept (int excepts) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + int fpscr; + const float fp_zero = 0.0, fp_one = 1.0, fp_max = FLT_MAX, + fp_min = FLT_MIN, fp_1e32 = 1.0e32f, fp_two = 2.0, + fp_three = 3.0; + + /* Raise exceptions represented by EXPECTS. But we must raise only + one signal at a time. It is important that if the overflow/underflow + exception and the inexact exception are given at the same time, + the overflow/underflow exception follows the inexact exception. After + each exception we read from the fpscr, to force the exception to be + raised immediately. */ + + /* There are additional complications because this file may be compiled + without VFP support enabled, and we also can't assume that the + assembler has VFP instructions enabled. To get around this we use the + generic coprocessor mnemonics and avoid asking GCC to put float values + in VFP registers. */ + + /* First: invalid exception. */ + if (FE_INVALID & excepts) + __asm__ __volatile__ ( + "ldc p10, cr0, %1\n\t" /* flds s0, %1 */ + "cdp p10, 8, cr0, cr0, cr0, 0\n\t" /* fdivs s0, s0, s0 */ + "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */ + : "m" (fp_zero) + : "s0"); + + /* Next: division by zero. */ + if (FE_DIVBYZERO & excepts) + __asm__ __volatile__ ( + "ldc p10, cr0, %1\n\t" /* flds s0, %1 */ + "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */ + "cdp p10, 8, cr0, cr0, cr0, 1\n\t" /* fdivs s0, s0, s1 */ + "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */ + : "m" (fp_one), "m" (fp_zero) + : "s0", "s1"); + + /* Next: overflow. */ + if (FE_OVERFLOW & excepts) + /* There's no way to raise overflow without also raising inexact. */ + __asm__ __volatile__ ( + "ldc p10, cr0, %1\n\t" /* flds s0, %1 */ + "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */ + "cdp p10, 3, cr0, cr0, cr0, 1\n\t" /* fadds s0, s0, s1 */ + "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */ + : "m" (fp_max), "m" (fp_1e32) + : "s0", "s1"); + + /* Next: underflow. */ + if (FE_UNDERFLOW & excepts) + __asm__ __volatile__ ( + "ldc p10, cr0, %1\n\t" /* flds s0, %1 */ + "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */ + "cdp p10, 8, cr0, cr0, cr0, 1\n\t" /* fdivs s0, s0, s1 */ + "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */ + : "m" (fp_min), "m" (fp_three) + : "s0", "s1"); + + /* Last: inexact. */ + if (FE_INEXACT & excepts) + __asm__ __volatile__ ( + "ldc p10, cr0, %1\n\t" /* flds s0, %1 */ + "ldcl p10, cr0, %2\n\t" /* flds s1, %2 */ + "cdp p10, 8, cr0, cr0, cr0, 1\n\t" /* fdivs s0, s0, s1 */ + "mrc p10, 7, %0, cr1, cr0, 0" : "=r" (fpscr) /* fmrx %0, fpscr */ + : "m" (fp_two), "m" (fp_three) + : "s0", "s1"); + + /* Success. */ + return 0; + } + + /* Unsupported, so fail. */ + return 1; +} + +libm_hidden_def (feraiseexcept) diff --git a/sysdeps/arm/eabi/fsetexcptflg.c b/sysdeps/arm/eabi/fsetexcptflg.c new file mode 100644 index 00000000000..e76d746196a --- /dev/null +++ b/sysdeps/arm/eabi/fsetexcptflg.c @@ -0,0 +1,60 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1997,98,99,2000,01,05 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include +#include + +#include +#include +#include +#include + +int +__fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + fexcept_t temp; + + /* Get the current environment. */ + _FPU_GETCW (temp); + + /* Set the desired exception mask. */ + temp &= ~((excepts & FE_ALL_EXCEPT) << FE_EXCEPT_SHIFT); + temp |= (*flagp & excepts & FE_ALL_EXCEPT) << FE_EXCEPT_SHIFT; + + /* Save state back to the FPU. */ + _FPU_SETCW (temp); + + /* Success. */ + return 0; + } + + /* Unsupported, so fail. */ + return 1; +} + +#include +#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2) +strong_alias (__fesetexceptflag, __old_fesetexceptflag) +compat_symbol (libm, __old_fesetexceptflag, fesetexceptflag, GLIBC_2_1); +#endif + +versioned_symbol (libm, __fesetexceptflag, fesetexceptflag, GLIBC_2_2); diff --git a/sysdeps/arm/eabi/ftestexcept.c b/sysdeps/arm/eabi/ftestexcept.c new file mode 100644 index 00000000000..230ccbdcec7 --- /dev/null +++ b/sysdeps/arm/eabi/ftestexcept.c @@ -0,0 +1,43 @@ +/* Test exception in current environment. + Copyright (C) 1997, 1998, 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#include + +#include +#include +#include +#include + +int +fetestexcept (int excepts) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + fexcept_t temp; + + /* Get current exceptions. */ + _FPU_GETCW(temp); + + return temp & excepts & FE_ALL_EXCEPT; + } + + /* Unsupported, return 0. */ + return 0; +} diff --git a/sysdeps/arm/eabi/rtld-global-offsets.sym b/sysdeps/arm/eabi/rtld-global-offsets.sym new file mode 100644 index 00000000000..ff4e97f2a6e --- /dev/null +++ b/sysdeps/arm/eabi/rtld-global-offsets.sym @@ -0,0 +1,7 @@ +#define SHARED 1 + +#include + +#define rtld_global_ro_offsetof(mem) offsetof (struct rtld_global_ro, mem) + +RTLD_GLOBAL_RO_DL_HWCAP_OFFSET rtld_global_ro_offsetof (_dl_hwcap) diff --git a/sysdeps/arm/eabi/setfpucw.c b/sysdeps/arm/eabi/setfpucw.c new file mode 100644 index 00000000000..2bd1f55619a --- /dev/null +++ b/sysdeps/arm/eabi/setfpucw.c @@ -0,0 +1,47 @@ +/* Set the FPU control word. + Copyright (C) 1996, 1997, 1999, 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 + +#include +#include +#include +#include + +void +__setfpucw (fpu_control_t set) +{ + if (GLRO (dl_hwcap) & HWCAP_VFP) + { + fpu_control_t cw; + + /* Fetch the current control word. */ + _FPU_GETCW (cw); + + /* Preserve the reserved bits, and set the rest as the user + specified (or the default, if the user gave zero). */ + cw &= _FPU_RESERVED; + cw |= set & ~_FPU_RESERVED; + + _FPU_SETCW (cw); + } + + /* Do nothing if a VFP unit isn't present. */ +} diff --git a/sysdeps/arm/eabi/setjmp.S b/sysdeps/arm/eabi/setjmp.S new file mode 100644 index 00000000000..d9ad26a9167 --- /dev/null +++ b/sysdeps/arm/eabi/setjmp.S @@ -0,0 +1,85 @@ +/* setjmp for ARM. + Copyright (C) 1997, 1998, 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 General Public License + along with GCC; see the file COPYING. If not, write to the Free + Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#include +#define _SETJMP_H +#define _ASM +#include +#define __ASSEMBLY__ +#include +#include + +ENTRY (__sigsetjmp) + mov ip, r0 + + /* Save registers */ + stmia ip!, {v1-v6, sl, fp, sp, lr} + + /* Check if we have a VFP unit. */ +#ifdef IS_IN_rtld + ldr a3, 1f + ldr a4, Lrtld_local_ro +0: add a3, pc, a3 + add a3, a3, a4 + ldr a3, [a3, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] +#else +#ifdef PIC + ldr a3, 1f + ldr a4, Lrtld_global_ro +0: add a3, pc, a3 + ldr a3, [a3, a4] + ldr a3, [a3, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] +#else + ldr a3, Lhwcap + ldr a3, [a3, #0] +#endif +#endif + + tst a3, #HWCAP_VFP + beq Lno_vfp + + /* Store the VFP registers. */ + /* Following instruction is fstmiax ip!, {d8-d15}. */ + stc p11, cr8, [r12], #68 + /* Store the floating-point status register. */ + /* Following instruction is fmrx r2, fpscr. */ + mrc p10, 7, r2, cr1, cr0, 0 + str r2, [ip], #4 +Lno_vfp: + + /* Make a tail call to __sigjmp_save; it takes the same args. */ + B PLTJMP(C_SYMBOL_NAME(__sigjmp_save)) + +#ifdef IS_IN_rtld +1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8 +Lrtld_local_ro: + .long C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF) +#else +#ifdef PIC +1: .long _GLOBAL_OFFSET_TABLE_ - 0b - 8 +Lrtld_global_ro: + .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) +#else +Lhwcap: + .long C_SYMBOL_NAME(_dl_hwcap) +#endif +#endif + +END (__sigsetjmp) + diff --git a/sysdeps/arm/elf/start.S b/sysdeps/arm/elf/start.S index cc076aba5ca..2e0a8b1d636 100644 --- a/sysdeps/arm/elf/start.S +++ b/sysdeps/arm/elf/start.S @@ -1,5 +1,6 @@ /* Startup code for ARM & ELF - Copyright (C) 1995, 1996, 1997, 1998, 2001, 2002 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1998, 2001, 2002, 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 @@ -62,6 +63,10 @@ .globl _start .type _start,#function _start: +#if !defined(__USING_SJLJ_EXCEPTIONS__) + /* Protect against unhandled exceptions. */ + .fnstart +#endif /* Fetch address of fini */ ldr ip, =__libc_csu_fini @@ -93,6 +98,11 @@ _start: /* should never get here....*/ bl abort +#if !defined(__USING_SJLJ_EXCEPTIONS__) + .cantunwind + .fnend +#endif + /* Define a symbol for the first piece of initialized data. */ .data .globl __data_start diff --git a/sysdeps/arm/fpu/feholdexcpt.c b/sysdeps/arm/fpu/feholdexcpt.c index 203b068aae0..ae8c6a6d6bc 100644 --- a/sysdeps/arm/fpu/feholdexcpt.c +++ b/sysdeps/arm/fpu/feholdexcpt.c @@ -35,3 +35,5 @@ feholdexcept (fenv_t *envp) return 0; } + +libm_hidden_def (feholdexcept) diff --git a/sysdeps/arm/fpu/fesetround.c b/sysdeps/arm/fpu/fesetround.c index bdb849ff608..2733e7f5dd8 100644 --- a/sysdeps/arm/fpu/fesetround.c +++ b/sysdeps/arm/fpu/fesetround.c @@ -25,3 +25,5 @@ fesetround (int round) /* We only support FE_TONEAREST, so there is no need for any work. */ return (round == FE_TONEAREST)?0:1; } + +libm_hidden_def (fesetround) diff --git a/sysdeps/arm/preconfigure b/sysdeps/arm/preconfigure index e63848dc746..337e84f163d 100644 --- a/sysdeps/arm/preconfigure +++ b/sysdeps/arm/preconfigure @@ -1,4 +1,13 @@ case "$machine" in -arm*) base_machine=arm machine=arm/arm32/$machine ;; -thumb*) base_machine=thumb machine=arm/thumb/$machine ;; +arm*) + base_machine=arm + case $config_os in + linux-gnueabi) + machine=arm/eabi/$machine + ;; + *) + machine=arm/$machine + ;; + esac + ;; esac diff --git a/sysdeps/arm/shlib-versions b/sysdeps/arm/shlib-versions index d603d6ebbeb..ed6603f0768 100644 --- a/sysdeps/arm/shlib-versions +++ b/sysdeps/arm/shlib-versions @@ -1 +1,4 @@ +arm.*-.*-linux-gnueabi DEFAULT GLIBC_2.4 + +arm.*-.*-linux-gnueabi ld=ld-linux.so.3 arm.*-.*-linux.* ld=ld-linux.so.2 diff --git a/sysdeps/unix/sysv/linux/arm/eabi/configure b/sysdeps/unix/sysv/linux/arm/eabi/configure new file mode 100644 index 00000000000..bb6a261fb7c --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/configure @@ -0,0 +1,5 @@ +# This file is generated from configure.in by Autoconf. DO NOT EDIT! + # Local configure fragment for sysdeps/unix/sysv/linux/arm/eabi. + +arch_minimum_kernel=2.4.17 +libc_cv_gcc_unwind_find_fde=no diff --git a/sysdeps/unix/sysv/linux/arm/eabi/configure.in b/sysdeps/unix/sysv/linux/arm/eabi/configure.in new file mode 100644 index 00000000000..14c25a5ccd8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/configure.in @@ -0,0 +1,5 @@ +GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory. +# Local configure fragment for sysdeps/unix/sysv/linux/arm/eabi. + +arch_minimum_kernel=2.4.17 +libc_cv_gcc_unwind_find_fde=no diff --git a/sysdeps/unix/sysv/linux/arm/eabi/epoll_ctl.c b/sysdeps/unix/sysv/linux/arm/eabi/epoll_ctl.c new file mode 100644 index 00000000000..eac925b92b9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/epoll_ctl.c @@ -0,0 +1,37 @@ +/* epoll_ctl wrapper for ARM EABI. + 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 +#include + +#include + +int +epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event) +{ + struct kernel_epoll_event k_event; + + k_event.events = __event->events; + memcpy (&k_event.data, &__event->data, sizeof (k_event.data)); + + return INLINE_SYSCALL (epoll_ctl, 4, __epfd, __op, __fd, &k_event); +} + +libc_hidden_def (epoll_ctl) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/epoll_wait.c b/sysdeps/unix/sysv/linux/arm/eabi/epoll_wait.c new file mode 100644 index 00000000000..463e30fb140 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/epoll_wait.c @@ -0,0 +1,54 @@ +/* epoll_ctl wrapper for ARM EABI. + 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 +#include +#include + +#include + +int +epoll_wait (int __epfd, struct epoll_event *__events, + int __maxevents, int __timeout); +{ + struct kernel_epoll_event *k_events; + int result; + + k_events = malloc (sizeof (struct kernel_epoll_event) * __maxevents); + if (k_events == NULL) + { + __set_errno (ENOMEM); + return -1; + } + + result = INLINE_SYSCALL (epoll_wait, 4, __epfd, __events, k_events, + __timeout); + + for (i = 0; i < result; i++) + { + __events[i].events = k_events[i].events; + memcpy (&__events[i].data, &k_events[i].data, sizeof (k_events[i].data)); + } + + free (k_events); + return result; +} + +libc_hidden_def (epoll_wait) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/fcntl.c b/sysdeps/unix/sysv/linux/arm/eabi/fcntl.c new file mode 100644 index 00000000000..7394c6aab66 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/fcntl.c @@ -0,0 +1,229 @@ +/* Copyright (C) 2000, 2002, 2003, 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. */ + +#include +#include +#include /* Must come before . */ +#include +#include + +#include +#include "kernel-features.h" + +#if __ASSUME_FCNTL64 == 0 +/* This variable is shared with all files that check for fcntl64. */ +int __have_no_fcntl64; +#endif + +struct kernel_flock64 { + short l_type; + short l_whence; + off64_t l_start; + off64_t l_len; + pid_t l_pid; +} __attribute__((packed)); + +#if defined NO_CANCELLATION && __ASSUME_FCNTL64 == 0 +# define __fcntl_nocancel __libc_fcntl +#endif + +static inline void +__flock64_to_kernel (struct kernel_flock64 *kfl64, + const struct flock64 *fl64) +{ + kfl64->l_type = fl64->l_type; + kfl64->l_whence = fl64->l_whence; + kfl64->l_start = fl64->l_start; + kfl64->l_len = fl64->l_len; + kfl64->l_pid = fl64->l_pid; +} + +static inline void +__flock64_from_kernel (struct flock64 *fl64, + const struct kernel_flock64 *kfl64) +{ + fl64->l_type = kfl64->l_type; + fl64->l_whence = kfl64->l_whence; + fl64->l_start = kfl64->l_start; + fl64->l_len = kfl64->l_len; + fl64->l_pid = kfl64->l_pid; +} + +#if !defined NO_CANCELLATION || __ASSUME_FCNTL64 == 0 +int +__fcntl_nocancel (int fd, int cmd, ...) +{ + va_list ap; + void *arg; + struct kernel_flock64 kfl; + struct flock64 *orig_arg; + + va_start (ap, cmd); + arg = va_arg (ap, void *); + va_end (ap); + +#if __ASSUME_FCNTL64 == 0 +# ifdef __NR_fcntl64 + if (! __have_no_fcntl64) + { + orig_arg = arg; + if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) + { + arg = &kfl; + __flock64_to_kernel (&kfl, orig_arg); + } + + int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg); + if (result >= 0 || errno != ENOSYS) + { + if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) + __flock64_from_kernel (orig_arg, &kfl); + return result; + } + + __have_no_fcntl64 = 1; + } +# endif + switch (cmd) + { + case F_GETLK64: + /* Convert arg from flock64 to flock and back. */ + { + struct flock fl; + struct flock64 *fl64 = arg; + int res; + + fl.l_start = (off_t)fl64->l_start; + /* Check if we can represent the values with the smaller type. */ + if ((off64_t) fl.l_start != fl64->l_start) + { + eoverflow: + __set_errno (EOVERFLOW); + return -1; + } + fl.l_len = (off_t) fl64->l_len; + /* Check if we can represent the values with the smaller type. */ + if ((off64_t) fl.l_len != fl64->l_len) + goto eoverflow; + + fl.l_type = fl64->l_type; + fl.l_whence = fl64->l_whence; + fl.l_pid = fl64->l_pid; + + res = INLINE_SYSCALL (fcntl, 3, fd, F_GETLK, &fl); + if (res != 0) + return res; + /* Everything ok, convert back. */ + fl64->l_type = fl.l_type; + fl64->l_whence = fl.l_whence; + fl64->l_start = fl.l_start; + fl64->l_len = fl.l_len; + fl64->l_pid = fl.l_pid; + + return 0; + } + case F_SETLK64: + case F_SETLKW64: + /* Try to convert arg from flock64 to flock. */ + { + struct flock fl; + struct flock64 *fl64 = arg; + + fl.l_start = (off_t) fl64->l_start; + /* Check if we can represent the values with the smaller type. */ + if ((off64_t) fl.l_start != fl64->l_start) + goto eoverflow; + + fl.l_len = (off_t)fl64->l_len; + /* Check if we can represent the values with the smaller type. */ + if ((off64_t) fl.l_len != fl64->l_len) + { + __set_errno (EOVERFLOW); + return -1; + } + fl.l_type = fl64->l_type; + fl.l_whence = fl64->l_whence; + fl.l_pid = fl64->l_pid; + assert (F_SETLK - F_SETLKW == F_SETLK64 - F_SETLKW64); + return INLINE_SYSCALL (fcntl, 3, fd, cmd + F_SETLK - F_SETLK64, &fl); + } + default: + return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg); + } + return -1; +#else + return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg); +#endif /* !__ASSUME_FCNTL64 */ +} +#endif /* NO_CANCELLATION || !__ASSUME_FCNTL64 */ + + +#ifndef __fcntl_nocancel +int +__libc_fcntl (int fd, int cmd, ...) +{ + va_list ap; + void *arg; + struct kernel_flock64 kfl; + struct flock64 *orig_arg; + + va_start (ap, cmd); + arg = va_arg (ap, void *); + va_end (ap); + +#if __ASSUME_FCNTL64 > 0 + orig_arg = arg; + if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) + { + arg = &kfl; + __flock64_to_kernel (&kfl, orig_arg); + } + + if (SINGLE_THREAD_P || (cmd != F_SETLKW && cmd != F_SETLKW64)) + { + int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg); + if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) + __flock64_from_kernel (orig_arg, &kfl); + return result; + } + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg); + + if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) + __flock64_from_kernel (orig_arg, &kfl); +#else + if (SINGLE_THREAD_P || (cmd != F_SETLKW && cmd != F_SETLKW64)) + return __fcntl_nocancel (fd, cmd, arg); + + int oldtype = LIBC_CANCEL_ASYNC (); + + int result = __fcntl_nocancel (fd, cmd, arg); +#endif + + LIBC_CANCEL_RESET (oldtype); + + return result; +} +#endif +libc_hidden_def (__libc_fcntl) + +weak_alias (__libc_fcntl, __fcntl) +libc_hidden_weak (__fcntl) +weak_alias (__libc_fcntl, fcntl) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/fstatfs64.c b/sysdeps/unix/sysv/linux/arm/eabi/fstatfs64.c new file mode 100644 index 00000000000..9057b2c840c --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/fstatfs64.c @@ -0,0 +1,76 @@ +/* Return information about the filesystem on which FD resides. + Copyright (C) 1996,1997,1998,1999,2000,2003,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 +#include +#include +#include + +/* Defined in statfs64.c. */ +extern int __no_statfs64 attribute_hidden; + +/* Return information about the filesystem on which FD resides. */ +int +__fstatfs64 (int fd, struct statfs64 *buf) +{ +#ifdef __NR_fstatfs64 +# if __ASSUME_STATFS64 == 0 + if (! __no_statfs64) +# endif + { + /* The EABI structure is the same as the old ABI structure, except + that it has four additional bytes of padding - at the end. We can + ignore them. */ + int result = INLINE_SYSCALL (fstatfs64, 3, fd, sizeof (*buf) - 4, buf); + +# if __ASSUME_STATFS64 == 0 + if (result == 0 || errno != ENOSYS) +# endif + return result; + +# if __ASSUME_STATFS64 == 0 + __no_statfs64 = 1; +# endif + } +#endif + +#if __ASSUME_STATFS64 == 0 + struct statfs buf32; + + if (__fstatfs (fd, &buf32) < 0) + return -1; + + buf->f_type = buf32.f_type; + buf->f_bsize = buf32.f_bsize; + buf->f_blocks = buf32.f_blocks; + buf->f_bfree = buf32.f_bfree; + buf->f_bavail = buf32.f_bavail; + buf->f_files = buf32.f_files; + buf->f_ffree = buf32.f_ffree; + buf->f_fsid = buf32.f_fsid; + buf->f_namelen = buf32.f_namelen; + buf->f_frsize = buf32.f_frsize; + memcpy (buf->f_spare, buf32.f_spare, sizeof (buf32.f_spare)); + + return 0; +#endif +} +weak_alias (__fstatfs64, fstatfs64) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/fxstat64.c b/sysdeps/unix/sysv/linux/arm/eabi/fxstat64.c new file mode 100644 index 00000000000..ae6637e2a23 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/fxstat64.c @@ -0,0 +1,100 @@ +/* fxstat64 using old-style Unix fstat system call. + Copyright (C) 1997-2002, 2003, 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 +#include +#include + +#include +#include +#include + +#include "kernel-features.h" + +#if __ASSUME_STAT64_SYSCALL == 0 +# include +#endif + +#ifdef __NR_fstat64 +# if __ASSUME_STAT64_SYSCALL == 0 +/* The variable is shared between all wrappers around *stat64 calls. */ +extern int __have_no_stat64; +# endif +#endif + +/* Get information about the file FD in BUF. */ + +int +___fxstat64 (int vers, int fd, struct stat64 *buf) +{ + int result; + struct kernel_stat64 kbuf64; + +#if __ASSUME_STAT64_SYSCALL > 0 + result = INLINE_SYSCALL (fstat64, 2, fd, CHECK_1 (&kbuf64)); + if (result == 0) + result = __xstat64_kernel64_conv (vers, &kbuf64, buf); +# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0 + if (__builtin_expect (!result, 1) && buf->__st_ino != (__ino_t) buf->st_ino) + buf->st_ino = buf->__st_ino; +# endif + return result; +#else + struct kernel_stat kbuf; +# if defined __NR_fstat64 + if (! __have_no_stat64) + { + int saved_errno = errno; + result = INLINE_SYSCALL (fstat64, 2, fd, CHECK_1 (&kbuf64)); + + if (result != -1 || errno != ENOSYS) + { + if (result == 0) + result = __xstat64_kernel64_conv (vers, &kbuf64, buf); +# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0 + if (!result && buf->__st_ino != (__ino_t)buf->st_ino) + buf->st_ino = buf->__st_ino; +# endif + return result; + } + + __set_errno (saved_errno); + __have_no_stat64 = 1; + } +# endif + result = INLINE_SYSCALL (fstat, 2, fd, __ptrvalue (&kbuf)); + if (result == 0) + result = __xstat64_conv (vers, &kbuf, buf); + + return result; +#endif +} + +#include + +#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) +versioned_symbol (libc, ___fxstat64, __fxstat64, GLIBC_2_2); +strong_alias (___fxstat64, __old__fxstat64) +compat_symbol (libc, __old__fxstat64, __fxstat64, GLIBC_2_1); +hidden_ver (___fxstat64, __fxstat64) +#else +strong_alias (___fxstat64, __fxstat64) +hidden_def (__fxstat64) +#endif diff --git a/sysdeps/unix/sysv/linux/arm/eabi/kernel_epoll.h b/sysdeps/unix/sysv/linux/arm/eabi/kernel_epoll.h new file mode 100644 index 00000000000..410b5c07399 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/kernel_epoll.h @@ -0,0 +1,23 @@ +/* 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. */ + +struct kernel_epoll_event +{ + uint32_t events; /* Epoll events */ + epoll_data_t data; /* User data variable */ +} __attribute__ ((packed,aligned(4))); diff --git a/sysdeps/unix/sysv/linux/arm/eabi/kernel_stat.h b/sysdeps/unix/sysv/linux/arm/eabi/kernel_stat.h new file mode 100644 index 00000000000..a4a8472fa29 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/kernel_stat.h @@ -0,0 +1,59 @@ +/* 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 + +/* kernel_stat64 is just like stat64, except packed. The EABI aligns + st_size to an eight byte boundary but the old ABI only aligns it to + four. Similarly st_blocks. */ +struct kernel_stat64 + { + __dev_t st_dev; /* Device. */ + unsigned int __pad1; + + __ino_t __st_ino; /* 32bit file serial number. */ + __mode_t st_mode; /* File mode. */ + __nlink_t st_nlink; /* Link count. */ + __uid_t st_uid; /* User ID of the file's owner. */ + __gid_t st_gid; /* Group ID of the file's group.*/ + __dev_t st_rdev; /* Device number, if device. */ + unsigned int __pad2; + __off64_t st_size; /* Size of file, in bytes. */ + __blksize_t st_blksize; /* Optimal block size for I/O. */ + + __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */ +#ifdef __USE_MISC + /* Nanosecond resolution timestamps are stored in a format + equivalent to 'struct timespec'. This is the type used + whenever possible but the Unix namespace rules do not allow the + identifier 'timespec' to appear in the header. + Therefore we have to handle the use of this header in strictly + standard-compliant sources special. */ + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ +#else + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ +#endif + __ino64_t st_ino; /* File serial number. */ + } __attribute__ ((packed,aligned(4))); diff --git a/sysdeps/unix/sysv/linux/arm/eabi/lockf64.c b/sysdeps/unix/sysv/linux/arm/eabi/lockf64.c new file mode 100644 index 00000000000..79dcceb09dc --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/lockf64.c @@ -0,0 +1,202 @@ +/* Copyright (C) 1994, 1996, 1997, 1998, 1999, 2000, 2003 + 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 +#include +#include +#include +#include + +#include "kernel-features.h" + +/* lockf is a simplified interface to fcntl's locking facilities. */ + +#ifdef __NR_fcntl64 +# if __ASSUME_FCNTL64 == 0 +/* This variable is shared with all files that check for fcntl64. The + declaration is in fcntl.c. */ +extern int __have_no_fcntl64; +# endif +#endif + +struct kernel_flock64 { + short l_type; + short l_whence; + off64_t l_start; + off64_t l_len; + pid_t l_pid; +} __attribute__((packed)); + +int +lockf64 (int fd, int cmd, off64_t len64) +{ +#if __ASSUME_FCNTL64 == 0 + struct flock fl; + off_t len = (off_t) len64; +#endif +#ifdef __NR_fcntl64 + struct kernel_flock64 fl64; + int cmd64; +#endif + +#if __ASSUME_FCNTL64 == 0 + memset ((char *) &fl, '\0', sizeof (fl)); + + /* lockf is always relative to the current file position. */ + fl.l_whence = SEEK_CUR; + fl.l_start = 0; + fl.l_len = len; +#endif +#ifdef __NR_fcntl64 +# if __ASSUME_FCNTL64 == 0 + if (!__have_no_fcntl64) + { +# endif + memset ((char *) &fl64, '\0', sizeof (fl64)); + fl64.l_whence = SEEK_CUR; + fl64.l_start = 0; + fl64.l_len = len64; +# if __ASSUME_FCNTL64 == 0 + } +# endif +#endif + +#if __ASSUME_FCNTL64 == 0 && !defined __NR_fcntl64 + if (len64 != (off64_t) len) + { + /* We can't represent the length. */ + __set_errno (EOVERFLOW); + return -1; + } +#endif + switch (cmd) + { + case F_TEST: + /* Test the lock: return 0 if FD is unlocked or locked by this process; + return -1, set errno to EACCES, if another process holds the lock. */ +#if __ASSUME_FCNTL64 > 0 + fl64.l_type = F_RDLCK; + if (INLINE_SYSCALL (fcntl64, 3, fd, F_GETLK64, &fl64) < 0) + return -1; + if (fl64.l_type == F_UNLCK || fl64.l_pid == __getpid ()) + return 0; + __set_errno (EACCES); + return -1; +#else +# ifdef __NR_fcntl64 + if (!__have_no_fcntl64) + { + int res; + + fl64.l_type = F_RDLCK; + res = INLINE_SYSCALL (fcntl64, 3, fd, F_GETLK64, &fl64); + /* If errno == ENOSYS try the 32bit interface if len64 can + be represented with 32 bits. */ + + if (res == 0) + { + if (fl64.l_type == F_UNLCK || fl64.l_pid == __getpid ()) + return 0; + __set_errno (EACCES); + return -1; + } + else if (errno == ENOSYS) + __have_no_fcntl64 = 1; + else + /* res < 0 && errno != ENOSYS. */ + return -1; + if (len64 != (off64_t) len) + { + /* We can't represent the length. */ + __set_errno (EOVERFLOW); + return -1; + } + } +# endif + fl.l_type = F_RDLCK; + if (__fcntl (fd, F_GETLK, &fl) < 0) + return -1; + if (fl.l_type == F_UNLCK || fl.l_pid == __getpid ()) + return 0; + __set_errno (EACCES); + return -1; +#endif + case F_ULOCK: +#if __ASSUME_FCNTL64 == 0 + fl.l_type = F_UNLCK; + cmd = F_SETLK; +#endif +#ifdef __NR_fcntl64 + fl64.l_type = F_UNLCK; + cmd64 = F_SETLK64; +#endif + break; + case F_LOCK: +#if __ASSUME_FCNTL64 == 0 + fl.l_type = F_WRLCK; + cmd = F_SETLKW; +#endif +#ifdef __NR_fcntl64 + fl64.l_type = F_WRLCK; + cmd64 = F_SETLKW64; +#endif + break; + case F_TLOCK: +#if __ASSUME_FCNTL64 == 0 + fl.l_type = F_WRLCK; + cmd = F_SETLK; +#endif +#ifdef __NR_fcntl64 + fl64.l_type = F_WRLCK; + cmd64 = F_SETLK64; +#endif + break; + + default: + __set_errno (EINVAL); + return -1; + } +#if __ASSUME_FCNTL64 > 0 + return INLINE_SYSCALL (fcntl64, 3, fd, cmd64, &fl64); +#else +# ifdef __NR_fcntl64 + + if (!__have_no_fcntl64) + { + int res = INLINE_SYSCALL (fcntl64, 3, fd, cmd64, &fl64); + + /* If errno == ENOSYS try the 32bit interface if len64 can + be represented with 32 bits. */ + if (res == 0 || errno != ENOSYS) + return res; + + __have_no_fcntl64 = 1; + + if (len64 != (off64_t) len) + { + /* We can't represent the length. */ + __set_errno (EOVERFLOW); + return -1; + } + } +# endif + return __fcntl (fd, cmd, &fl); +#endif +} diff --git a/sysdeps/unix/sysv/linux/arm/eabi/lxstat64.c b/sysdeps/unix/sysv/linux/arm/eabi/lxstat64.c new file mode 100644 index 00000000000..bb5be399ee7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/lxstat64.c @@ -0,0 +1,99 @@ +/* lxstat64 using old-style Unix lstat system call. + Copyright (C) 1997-2002, 2003, 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 +#include +#include + +#include +#include +#include + +#include "kernel-features.h" + +#if __ASSUME_STAT64_SYSCALL == 0 +# include +#endif + +#ifdef __NR_lstat64 +# if __ASSUME_STAT64_SYSCALL == 0 +/* The variable is shared between all wrappers around *stat64 calls. */ +extern int __have_no_stat64; +# endif +#endif + +/* Get information about the file NAME in BUF. */ +int +___lxstat64 (int vers, const char *name, struct stat64 *buf) +{ + int result; + struct kernel_stat64 kbuf64; + +#ifdef __ASSUME_STAT64_SYSCALL + result = INLINE_SYSCALL (lstat64, 2, CHECK_STRING (name), CHECK_1 (&kbuf64)); + if (result == 0) + result = __xstat64_kernel64_conv (vers, &kbuf64, buf); +# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0 + if (__builtin_expect (!result, 1) && buf->__st_ino != (__ino_t) buf->st_ino) + buf->st_ino = buf->__st_ino; +# endif + return result; +#else + struct kernel_stat kbuf; +# ifdef __NR_lstat64 + if (! __have_no_stat64) + { + int saved_errno = errno; + result = INLINE_SYSCALL (lstat64, 2, CHECK_STRING (name), CHECK_1 (&kbuf64)); + + if (result != -1 || errno != ENOSYS) + { + if (result == 0) + result = __xstat64_kernel64_conv (vers, &kbuf64, buf); +# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0 + if (!result && buf->__st_ino != (__ino_t) buf->st_ino) + buf->st_ino = buf->__st_ino; +# endif + return result; + } + + __set_errno (saved_errno); + __have_no_stat64 = 1; + } +# endif + result = INLINE_SYSCALL (lstat, 2, CHECK_STRING (name), __ptrvalue (&kbuf)); + if (result == 0) + result = __xstat64_conv (vers, &kbuf, buf); + + return result; +#endif +} + +#include + +#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) +versioned_symbol (libc, ___lxstat64, __lxstat64, GLIBC_2_2); +strong_alias (___lxstat64, __old__lxstat64) +compat_symbol (libc, __old__lxstat64, __lxstat64, GLIBC_2_1); +hidden_ver (___lxstat64, __lxstat64) +#else +strong_alias (___lxstat64, __lxstat64); +hidden_def (__lxstat64) +#endif diff --git a/sysdeps/unix/sysv/linux/arm/eabi/oldgetrlimit.c b/sysdeps/unix/sysv/linux/arm/eabi/oldgetrlimit.c new file mode 100644 index 00000000000..6e25b021ab5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/oldgetrlimit.c @@ -0,0 +1 @@ +/* Empty. */ diff --git a/sysdeps/unix/sysv/linux/arm/eabi/oldsetrlimit.c b/sysdeps/unix/sysv/linux/arm/eabi/oldsetrlimit.c new file mode 100644 index 00000000000..6e25b021ab5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/oldsetrlimit.c @@ -0,0 +1 @@ +/* Empty. */ diff --git a/sysdeps/unix/sysv/linux/arm/eabi/semop.c b/sysdeps/unix/sysv/linux/arm/eabi/semop.c new file mode 100644 index 00000000000..42b2036140c --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/semop.c @@ -0,0 +1,67 @@ +/* Copyright (C) 1995, 1997, 1998, 1999, 2000, 2005 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , August 1995. + + 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 +#include +#include +#include +#include +#include + +struct kernel_sembuf +{ + unsigned short int sem_num; /* semaphore number */ + short int sem_op; /* semaphore operation */ + short int sem_flg; /* operation flag */ + short int __pad1; +}; + +/* Perform user-defined atomical operation of array of semaphores. */ + +int +semop (semid, sops, nsops) + int semid; + struct sembuf *sops; + size_t nsops; +{ + struct kernel_sembuf *ksops = alloca (sizeof (ksops[0]) * nsops); + size_t i; + int result; + + for (i = 0; i < nsops; i++) + { + ksops[i].sem_num = sops[i].sem_num; + ksops[i].sem_op = sops[i].sem_op; + ksops[i].sem_flg = sops[i].sem_flg; + } + + result = INLINE_SYSCALL (ipc, 5, IPCOP_semop, + semid, (int) nsops, 0, CHECK_N (ksops, nsops)); + + for (i = 0; i < nsops; i++) + { + sops[i].sem_num = ksops[i].sem_num; + sops[i].sem_op = ksops[i].sem_op; + sops[i].sem_flg = ksops[i].sem_flg; + } + + return result; +} diff --git a/sysdeps/unix/sysv/linux/arm/eabi/semtimedop.c b/sysdeps/unix/sysv/linux/arm/eabi/semtimedop.c new file mode 100644 index 00000000000..463dea4ecb4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/semtimedop.c @@ -0,0 +1,69 @@ +/* Copyright (C) 1995, 1997, 1998, 1999, 2000, 2005 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , August 1995. + + 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 +#include +#include +#include +#include +#include + +struct kernel_sembuf +{ + unsigned short int sem_num; /* semaphore number */ + short int sem_op; /* semaphore operation */ + short int sem_flg; /* operation flag */ + short int __pad1; +}; + +/* Perform user-defined atomical operation of array of semaphores. */ + +int +semtimedop (semid, sops, nsops, timeout) + int semid; + struct sembuf *sops; + size_t nsops; + const struct timespec *timeout; +{ + struct kernel_sembuf *ksops = alloca (sizeof (ksops[0]) * nsops); + size_t i; + int result; + + for (i = 0; i < nsops; i++) + { + ksops[i].sem_num = sops[i].sem_num; + ksops[i].sem_op = sops[i].sem_op; + ksops[i].sem_flg = sops[i].sem_flg; + } + + result = INLINE_SYSCALL (ipc, 6, IPCOP_semtimedop, + semid, (int) nsops, 0, CHECK_N (sops, nsops), + timeout); + + for (i = 0; i < nsops; i++) + { + sops[i].sem_num = ksops[i].sem_num; + sops[i].sem_op = ksops[i].sem_op; + sops[i].sem_flg = ksops[i].sem_flg; + } + + return result; +} diff --git a/sysdeps/unix/sysv/linux/arm/eabi/statfs64.c b/sysdeps/unix/sysv/linux/arm/eabi/statfs64.c new file mode 100644 index 00000000000..3c74453c5f0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/statfs64.c @@ -0,0 +1,77 @@ +/* Return information about the filesystem on which FILE resides. + Copyright (C) 1996-2000,2003,2004,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 +#include +#include +#include + + +# if __ASSUME_STATFS64 == 0 +int __no_statfs64 attribute_hidden; +#endif + +/* Return information about the filesystem on which FILE resides. */ +int +__statfs64 (const char *file, struct statfs64 *buf) +{ +#ifdef __NR_statfs64 +# if __ASSUME_STATFS64 == 0 + if (! __no_statfs64) +# endif + { + /* The EABI structure is the same as the old ABI structure, except + that it has four additional bytes of padding - at the end. We can + ignore them. */ + int result = INLINE_SYSCALL (statfs64, 3, file, sizeof (*buf) - 4, buf); + +# if __ASSUME_STATFS64 == 0 + if (result == 0 || errno != ENOSYS) +# endif + return result; + +# if __ASSUME_STATFS64 == 0 + __no_statfs64 = 1; +# endif + } +#endif + +#if __ASSUME_STATFS64 == 0 + struct statfs buf32; + + if (__statfs (file, &buf32) < 0) + return -1; + + buf->f_type = buf32.f_type; + buf->f_bsize = buf32.f_bsize; + buf->f_blocks = buf32.f_blocks; + buf->f_bfree = buf32.f_bfree; + buf->f_bavail = buf32.f_bavail; + buf->f_files = buf32.f_files; + buf->f_ffree = buf32.f_ffree; + buf->f_fsid = buf32.f_fsid; + buf->f_namelen = buf32.f_namelen; + buf->f_frsize = buf32.f_frsize; + memcpy (buf->f_spare, buf32.f_spare, sizeof (buf32.f_spare)); + + return 0; +#endif +} +weak_alias (__statfs64, statfs64) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/syscalls.list b/sysdeps/unix/sysv/linux/arm/eabi/syscalls.list new file mode 100644 index 00000000000..85bc04ff1df --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/syscalls.list @@ -0,0 +1,4 @@ +# File name Caller Syscall name # args Strong name Weak names + +epoll_ctl EXTRA epoll_ctl i:iiip epoll_ctl +epoll_wait EXTRA epoll_wait i:ipii epoll_wait diff --git a/sysdeps/unix/sysv/linux/arm/eabi/uname.c b/sysdeps/unix/sysv/linux/arm/eabi/uname.c new file mode 100644 index 00000000000..82482e45521 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/uname.c @@ -0,0 +1,43 @@ +/* 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 +#include +#include +#include + +/* The kernel's struct utsname is two bytes larger than a userland struct + utsname due to the APCS structure size boundary. */ + +int +__uname (struct utsname *__name) +{ + char buf[sizeof (struct utsname) + 2]; + int result = INLINE_SYSCALL (uname, 1, buf); + + if (result == 0) + memcpy (__name, buf, sizeof (struct utsname)); + + return result; +} + +libc_hidden_def (__uname) +strong_alias (__uname, uname) +libc_hidden_weak (uname) diff --git a/sysdeps/unix/sysv/linux/arm/eabi/xstat64.c b/sysdeps/unix/sysv/linux/arm/eabi/xstat64.c new file mode 100644 index 00000000000..5edafd8aaeb --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/xstat64.c @@ -0,0 +1,103 @@ +/* xstat64 using old-style Unix stat system call. + Copyright (C) 1991, 1995-2002, 2003, 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 +#include +#include + +#include +#include +#include + +#include "kernel-features.h" + +#if __ASSUME_STAT64_SYSCALL == 0 +# include +#endif + +#ifdef __NR_stat64 +# if __ASSUME_STAT64_SYSCALL == 0 +/* The variable is shared between all wrappers around *stat64 calls. + This is the definition. */ +int __have_no_stat64; +# endif +#endif + +/* Get information about the file NAME in BUF. */ + +int +___xstat64 (int vers, const char *name, struct stat64 *buf) +{ + int result; + struct kernel_stat64 kbuf64; + +#if __ASSUME_STAT64_SYSCALL > 0 + result = INLINE_SYSCALL (stat64, 2, CHECK_STRING (name), CHECK_1 (&kbuf64)); + if (result == 0) + result = __xstat64_kernel64_conv (vers, &kbuf64, buf); +# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0 + if (__builtin_expect (!result, 1) && buf->__st_ino != (__ino_t) buf->st_ino) + buf->st_ino = buf->__st_ino; +# endif + return result; +#else + struct kernel_stat kbuf; +# if defined __NR_stat64 + if (! __have_no_stat64) + { + int saved_errno = errno; + result = INLINE_SYSCALL (stat64, 2, CHECK_STRING (name), CHECK_1 (&kbuf64)); + + if (result != -1 || errno != ENOSYS) + { + if (result == 0) + result = __xstat64_kernel64_conv (vers, &kbuf64, buf); +# if defined _HAVE_STAT64___ST_INO && __ASSUME_ST_INO_64_BIT == 0 + if (!result && buf->__st_ino != (__ino_t) buf->st_ino) + buf->st_ino = buf->__st_ino; +# endif + return result; + } + + __set_errno (saved_errno); + __have_no_stat64 = 1; + } +# endif + + result = INLINE_SYSCALL (stat, 2, CHECK_STRING (name), __ptrvalue (&kbuf)); + if (result == 0) + result = __xstat64_conv (vers, &kbuf, buf); + + return result; +#endif +} + + +#include + +#if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) +versioned_symbol (libc, ___xstat64, __xstat64, GLIBC_2_2); +strong_alias (___xstat64, __old__xstat64) +compat_symbol (libc, __old__xstat64, __xstat64, GLIBC_2_1); +hidden_ver (___xstat64, __xstat64) +#else +strong_alias (___xstat64, __xstat64) +hidden_def (__xstat64) +#endif diff --git a/sysdeps/unix/sysv/linux/arm/eabi/xstatconv.c b/sysdeps/unix/sysv/linux/arm/eabi/xstatconv.c new file mode 100644 index 00000000000..28c4dae9517 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/xstatconv.c @@ -0,0 +1,341 @@ +/* Convert between the kernel's `struct stat' format, and libc's. + Copyright (C) 1991,1995-1997,2000,2002,2003 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 +#include + +#ifdef STAT_IS_KERNEL_STAT + +/* Dummy. */ +struct kernel_stat; + +#else + +#include + + +#if !defined __ASSUME_STAT64_SYSCALL || defined XSTAT_IS_XSTAT64 +int +__xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf) +{ + switch (vers) + { + case _STAT_VER_KERNEL: + /* Nothing to do. The struct is in the form the kernel expects. + We should have short-circuted before we got here, but for + completeness... */ + *(struct kernel_stat *) ubuf = *kbuf; + break; + + case _STAT_VER_LINUX: + { + struct stat *buf = ubuf; + + /* Convert to current kernel version of `struct stat'. */ + buf->st_dev = kbuf->st_dev; +#ifdef _HAVE_STAT___PAD1 + buf->__pad1 = 0; +#endif + buf->st_ino = kbuf->st_ino; + buf->st_mode = kbuf->st_mode; + buf->st_nlink = kbuf->st_nlink; + buf->st_uid = kbuf->st_uid; + buf->st_gid = kbuf->st_gid; + buf->st_rdev = kbuf->st_rdev; +#ifdef _HAVE_STAT___PAD2 + buf->__pad2 = 0; +#endif + buf->st_size = kbuf->st_size; + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; +#ifdef _HAVE_STAT_NSEC + buf->st_atim.tv_sec = kbuf->st_atim.tv_sec; + buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec; + buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec; + buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec; + buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec; + buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec; +#else + buf->st_atime = kbuf->st_atime; + buf->st_mtime = kbuf->st_mtime; + buf->st_ctime = kbuf->st_ctime; +#endif +#ifdef _HAVE_STAT___UNUSED1 + buf->__unused1 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED2 + buf->__unused2 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED3 + buf->__unused3 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED4 + buf->__unused4 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED5 + buf->__unused5 = 0; +#endif + } + break; + + default: + __set_errno (EINVAL); + return -1; + } + + return 0; +} +#endif + +int +__xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf) +{ +#ifdef XSTAT_IS_XSTAT64 + return __xstat_conv (vers, kbuf, ubuf); +#else + switch (vers) + { + case _STAT_VER_LINUX: + { + struct stat64 *buf = ubuf; + + /* Convert to current kernel version of `struct stat64'. */ + buf->st_dev = kbuf->st_dev; +#ifdef _HAVE_STAT64___PAD1 + buf->__pad1 = 0; +#endif + buf->st_ino = kbuf->st_ino; +#ifdef _HAVE_STAT64___ST_INO + buf->__st_ino = kbuf->st_ino; +#endif + buf->st_mode = kbuf->st_mode; + buf->st_nlink = kbuf->st_nlink; + buf->st_uid = kbuf->st_uid; + buf->st_gid = kbuf->st_gid; + buf->st_rdev = kbuf->st_rdev; +#ifdef _HAVE_STAT64___PAD2 + buf->__pad2 = 0; +#endif + buf->st_size = kbuf->st_size; + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; +#ifdef _HAVE_STAT64_NSEC + buf->st_atim.tv_sec = kbuf->st_atim.tv_sec; + buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec; + buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec; + buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec; + buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec; + buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec; +#else + buf->st_atime = kbuf->st_atime; + buf->st_mtime = kbuf->st_mtime; + buf->st_ctime = kbuf->st_ctime; +#endif +#ifdef _HAVE_STAT64___UNUSED1 + buf->__unused1 = 0; +#endif +#ifdef _HAVE_STAT64___UNUSED2 + buf->__unused2 = 0; +#endif +#ifdef _HAVE_STAT64___UNUSED3 + buf->__unused3 = 0; +#endif +#ifdef _HAVE_STAT64___UNUSED4 + buf->__unused4 = 0; +#endif +#ifdef _HAVE_STAT64___UNUSED5 + buf->__unused5 = 0; +#endif + } + break; + + /* If struct stat64 is different from struct stat then + _STAT_VER_KERNEL does not make sense. */ + case _STAT_VER_KERNEL: + default: + __set_errno (EINVAL); + return -1; + } + + return 0; +#endif +} + +int +__xstat32_conv (int vers, void *kbuf_, struct stat *buf) +{ + struct kernel_stat64 *kbuf = kbuf_; + + switch (vers) + { + case _STAT_VER_LINUX: + { + /* Convert current kernel version of `struct stat64' to + `struct stat'. */ + buf->st_dev = kbuf->st_dev; +#ifdef _HAVE_STAT___PAD1 + buf->__pad1 = 0; +#endif +#ifdef _HAVE_STAT64___ST_INO +# if __ASSUME_ST_INO_64_BIT == 0 + if (kbuf->st_ino == 0) + buf->st_ino = kbuf->__st_ino; + else +# endif + { + buf->st_ino = kbuf->st_ino; + if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino) + && buf->st_ino != kbuf->st_ino) + { + __set_errno (EOVERFLOW); + return -1; + } + } +#else + buf->st_ino = kbuf->st_ino; + if (sizeof (buf->st_ino) != sizeof (kbuf->st_ino) + && buf->st_ino != kbuf->st_ino) + { + __set_errno (EOVERFLOW); + return -1; + } +#endif + buf->st_mode = kbuf->st_mode; + buf->st_nlink = kbuf->st_nlink; + buf->st_uid = kbuf->st_uid; + buf->st_gid = kbuf->st_gid; + buf->st_rdev = kbuf->st_rdev; +#ifdef _HAVE_STAT___PAD2 + buf->__pad2 = 0; +#endif + buf->st_size = kbuf->st_size; + /* Check for overflow. */ + if (sizeof (buf->st_size) != sizeof (kbuf->st_size) + && buf->st_size != kbuf->st_size) + { + __set_errno (EOVERFLOW); + return -1; + } + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; + /* Check for overflow. */ + if (sizeof (buf->st_blocks) != sizeof (kbuf->st_blocks) + && buf->st_blocks != kbuf->st_blocks) + { + __set_errno (EOVERFLOW); + return -1; + } +#ifdef _HAVE_STAT_NSEC + buf->st_atim.tv_sec = kbuf->st_atim.tv_sec; + buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec; + buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec; + buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec; + buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec; + buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec; +#else + buf->st_atime = kbuf->st_atime; + buf->st_mtime = kbuf->st_mtime; + buf->st_ctime = kbuf->st_ctime; +#endif + +#ifdef _HAVE_STAT___UNUSED1 + buf->__unused1 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED2 + buf->__unused2 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED3 + buf->__unused3 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED4 + buf->__unused4 = 0; +#endif +#ifdef _HAVE_STAT___UNUSED5 + buf->__unused5 = 0; +#endif + } + break; + + /* If struct stat64 is different from struct stat then + _STAT_VER_KERNEL does not make sense. */ + case _STAT_VER_KERNEL: + default: + __set_errno (EINVAL); + return -1; + } + + return 0; +} + +int +__xstat64_kernel64_conv (int vers, void *kbuf_, struct stat64 *buf) +{ + struct kernel_stat64 *kbuf = kbuf_; + + switch (vers) + { + case _STAT_VER_LINUX: + { + /* Convert current kernel version of `struct stat64' to + user version of `struct stat64'. */ + buf->st_dev = kbuf->st_dev; +#ifdef _HAVE_STAT64___PAD1 + buf->__pad1 = kbuf->__pad1; +#endif +#ifdef _HAVE_STAT64___ST_INO + buf->__st_ino = kbuf->__st_ino; +#endif + buf->st_mode = kbuf->st_mode; + buf->st_nlink = kbuf->st_nlink; + buf->st_uid = kbuf->st_uid; + buf->st_gid = kbuf->st_gid; + buf->st_rdev = kbuf->st_rdev; +#ifdef _HAVE_STAT64___PAD2 + buf->__pad2 = kbuf->__pad2; +#endif + buf->st_size = kbuf->st_size; + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; +#ifdef _HAVE_STAT64_NSEC + buf->st_atim.tv_sec = kbuf->st_atim.tv_sec; + buf->st_atim.tv_nsec = kbuf->st_atim.tv_nsec; + buf->st_mtim.tv_sec = kbuf->st_mtim.tv_sec; + buf->st_mtim.tv_nsec = kbuf->st_mtim.tv_nsec; + buf->st_ctim.tv_sec = kbuf->st_ctim.tv_sec; + buf->st_ctim.tv_nsec = kbuf->st_ctim.tv_nsec; +#else + buf->st_atime = kbuf->st_atime; + buf->st_mtime = kbuf->st_mtime; + buf->st_ctime = kbuf->st_ctime; +#endif + buf->st_ino = kbuf->st_ino; + } + break; + + case _STAT_VER_KERNEL: + default: + __set_errno (EINVAL); + return -1; + } + + return 0; +} + +#endif diff --git a/sysdeps/unix/sysv/linux/arm/eabi/xstatconv.h b/sysdeps/unix/sysv/linux/arm/eabi/xstatconv.h new file mode 100644 index 00000000000..abe65f4a809 --- /dev/null +++ b/sysdeps/unix/sysv/linux/arm/eabi/xstatconv.h @@ -0,0 +1,28 @@ +/* Convert between the kernel's `struct stat' format, and libc's. + Copyright (C) 1991,1995-1997,2000,2002,2003 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 "kernel-features.h" + +#ifndef STAT_IS_KERNEL_STAT +extern int __xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf); +extern int __xstat64_conv (int vers, struct kernel_stat *kbuf, void *ubuf); +#endif +extern int __xstat32_conv (int vers, void *kbuf, struct stat *buf); +extern int __xstat64_kernel64_conv (int vers, struct kernel_stat64 *kbuf, + struct stat64 *buf); diff --git a/sysdeps/unix/sysv/linux/arm/mmap64.S b/sysdeps/unix/sysv/linux/arm/mmap64.S index 5899140f1c5..bb5e1dc261b 100644 --- a/sysdeps/unix/sysv/linux/arm/mmap64.S +++ b/sysdeps/unix/sysv/linux/arm/mmap64.S @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2003 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2003, 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 @@ -23,21 +23,31 @@ #include "kernel-features.h" +/* For the EABI, there are four extra bytes of padding in the + incoming arguments to mmap64, to preserve alignment. */ +#ifdef __ARM_EABI__ +# define INITIAL_OFFSET 8 +#else +# define INITIAL_OFFSET 4 +#endif + +#ifdef __ARMEB__ +# define LOW_OFFSET INITIAL_OFFSET + 4 +/* The initial + 4 is for the stack postdecrement. */ +# define HIGH_OFFSET 4 + INITIAL_OFFSET + 0 +#else +# define LOW_OFFSET INITIAL_OFFSET + 0 +# define HIGH_OFFSET 4 + INITIAL_OFFSET + 4 +#endif + /* The mmap2 system call takes six arguments, all in registers. */ .text ENTRY (__mmap64) #ifdef __NR_mmap2 -#ifdef __ARMEB__ - ldr ip, [sp, $8] @ offset low part + ldr ip, [sp, $LOW_OFFSET] str r5, [sp, #-4]! - ldr r5, [sp, $8] @ offset high part + ldr r5, [sp, $HIGH_OFFSET] str r4, [sp, #-4]! -#else - ldr ip, [sp, $4] @ offset low part - str r5, [sp, #-4]! - ldr r5, [sp, $12] @ offset high part - str r4, [sp, #-4]! -#endif movs r4, ip, lsl $20 @ check that offset is page-aligned mov ip, ip, lsr $12 moveqs r4, r5, lsr $12 @ check for overflow