diff options
Diffstat (limited to 'sysdeps')
33 files changed, 1349 insertions, 114 deletions
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 230c39a631..a14e8af92f 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -748,7 +748,7 @@ extern int _dl_starting_up_internal attribute_hidden; #endif /* Random data provided by the kernel. */ -extern void *_dl_random attribute_hidden; +extern void *_dl_random attribute_hidden attribute_relro; /* OS-dependent function to open the zero-fill device. */ extern int _dl_sysdep_open_zero_fill (void); /* dl-sysdep.c */ diff --git a/sysdeps/gnu/Makefile b/sysdeps/gnu/Makefile index 5b9a0a56ed..b33d1004a5 100644 --- a/sysdeps/gnu/Makefile +++ b/sysdeps/gnu/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1996,1997,1998,1999,2001,2002,2003,2004,2005,2006 +# Copyright (C) 1996,1997,1998,1999,2001,2002,2003,2004,2005,2006,2010 # Free Software Foundation, Inc. # This file is part of the GNU C Library. @@ -77,3 +77,16 @@ endif ifeq ($(subdir),misc) sysdep_headers += sys/mtio.h endif + + +ifeq ($(subdir),csu) +routines += unwind-resume +shared-only-routines += unwind-resume +CFLAGS-unwind-resume.c += -fexceptions -fasynchronous-unwind-tables +endif + +ifeq ($(subdir),rt) +librt-sysdep_routines += rt-unwind-resume +librt-shared-only-routines += rt-unwind-resume +CFLAGS-rt-unwind-resume.c += -fexceptions -fasynchronous-unwind-tables +endif diff --git a/sysdeps/gnu/rt-unwind-resume.c b/sysdeps/gnu/rt-unwind-resume.c new file mode 100644 index 0000000000..743e675d4d --- /dev/null +++ b/sysdeps/gnu/rt-unwind-resume.c @@ -0,0 +1 @@ +#include <unwind-resume.c> diff --git a/sysdeps/gnu/unwind-resume.c b/sysdeps/gnu/unwind-resume.c new file mode 100644 index 0000000000..69f3e04c43 --- /dev/null +++ b/sysdeps/gnu/unwind-resume.c @@ -0,0 +1,65 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Jakub Jelinek <jakub@redhat.com>. + + 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; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <dlfcn.h> +#include <stdio.h> +#include <unwind.h> +#include <libgcc_s.h> + +static void (*libgcc_s_resume) (struct _Unwind_Exception *exc); +static _Unwind_Reason_Code (*libgcc_s_personality) + (int, _Unwind_Action, _Unwind_Exception_Class, struct _Unwind_Exception *, + struct _Unwind_Context *); + +static void +init (void) +{ + void *resume, *personality; + void *handle; + + handle = __libc_dlopen (LIBGCC_S_SO); + + if (handle == NULL + || (resume = __libc_dlsym (handle, "_Unwind_Resume")) == NULL + || (personality = __libc_dlsym (handle, "__gcc_personality_v0")) == NULL) + __libc_fatal (LIBGCC_S_SO " must be installed for pthread_cancel to work\n"); + + libgcc_s_resume = resume; + libgcc_s_personality = personality; +} + +void +_Unwind_Resume (struct _Unwind_Exception *exc) +{ + if (__builtin_expect (libgcc_s_resume == NULL, 0)) + init (); + libgcc_s_resume (exc); +} + +_Unwind_Reason_Code +__gcc_personality_v0 (int version, _Unwind_Action actions, + _Unwind_Exception_Class exception_class, + struct _Unwind_Exception *ue_header, + struct _Unwind_Context *context) +{ + if (__builtin_expect (libgcc_s_personality == NULL, 0)) + init (); + return libgcc_s_personality (version, actions, exception_class, + ue_header, context); +} diff --git a/sysdeps/mach/hurd/dl-sysdep.c b/sysdeps/mach/hurd/dl-sysdep.c index 2440682903..6f2787456f 100644 --- a/sysdeps/mach/hurd/dl-sysdep.c +++ b/sysdeps/mach/hurd/dl-sysdep.c @@ -1,5 +1,5 @@ /* Operating system support for run-time dynamic linker. Hurd version. - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004 + Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2010 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -116,7 +116,8 @@ static void fmh(void) { ElfW(Addr) _dl_sysdep_start (void **start_argptr, void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phent, - ElfW(Addr) *user_entry)) + ElfW(Addr) *user_entry, + ElfW(auxv_t) *auxv)) { void go (intptr_t *argdata) { @@ -197,7 +198,7 @@ unfmh(); /* XXX */ up and leave us to transfer control to USER_ENTRY. */ (*dl_main) ((const ElfW(Phdr) *) _dl_hurd_data->phdr, _dl_hurd_data->phdrsz / sizeof (ElfW(Phdr)), - &_dl_hurd_data->user_entry); + &_dl_hurd_data->user_entry, NULL); /* The call above might screw a few things up. diff --git a/sysdeps/posix/cuserid.c b/sysdeps/posix/cuserid.c index 11c827a686..a74ff84368 100644 --- a/sysdeps/posix/cuserid.c +++ b/sysdeps/posix/cuserid.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1996, 1998, 1999, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1996, 1998, 1999, 2001, 2010 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 @@ -44,5 +44,6 @@ cuserid (s) if (s == NULL) s = name; - return strncpy (s, pwptr->pw_name, L_cuserid); + s[L_cuserid - 1] = '\0'; + return strncpy (s, pwptr->pw_name, L_cuserid - 1); } diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index 62c38f69be..2e0c7248f0 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -702,6 +702,7 @@ gaih_inet (const char *name, const struct gaih_service *service, while (!no_more) { + no_data = 0; nss_gethostbyname4_r fct4 = __nss_lookup_function (nip, "gethostbyname4_r"); if (fct4 != NULL) @@ -816,17 +817,18 @@ gaih_inet (const char *name, const struct gaih_service *service, canon = name; } } - - break; + status = NSS_STATUS_SUCCESS; + } + else + { + /* We can have different states for AF_INET and + AF_INET6. Try to find a useful one for both. */ + if (inet6_status == NSS_STATUS_TRYAGAIN) + status = NSS_STATUS_TRYAGAIN; + else if (status == NSS_STATUS_UNAVAIL + && inet6_status != NSS_STATUS_UNAVAIL) + status = inet6_status; } - - /* We can have different states for AF_INET and - AF_INET6. Try to find a useful one for both. */ - if (inet6_status == NSS_STATUS_TRYAGAIN) - status = NSS_STATUS_TRYAGAIN; - else if (status == NSS_STATUS_UNAVAIL - && inet6_status != NSS_STATUS_UNAVAIL) - status = inet6_status; } else status = NSS_STATUS_UNAVAIL; diff --git a/sysdeps/posix/remove.c b/sysdeps/posix/remove.c index c44af92d74..ae5bbdbdc9 100644 --- a/sysdeps/posix/remove.c +++ b/sysdeps/posix/remove.c @@ -1,5 +1,5 @@ /* ANSI C `remove' function to delete a file or directory. POSIX.1 version. - Copyright (C) 1995,96,97,2002,2003 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,2002,2003,2010 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 @@ -21,6 +21,12 @@ #include <stdio.h> #include <unistd.h> + +#ifndef IS_NO_DIRECTORY_ERROR +# define IS_NO_DIRECTORY_ERROR errno != EPERM +#endif + + int remove (file) const char *file; @@ -28,7 +34,7 @@ remove (file) /* First try to unlink since this is more frequently the necessary action. */ if (__unlink (file) != 0 /* If it is indeed a directory... */ - && (errno != EISDIR + && (IS_NO_DIRECTORY_ERROR /* ...try to remove it. */ || __rmdir (file) != 0)) /* Cannot remove the object for whatever reason. */ diff --git a/sysdeps/powerpc/powerpc32/power7/memcpy.S b/sysdeps/powerpc/powerpc32/power7/memcpy.S new file mode 100644 index 0000000000..e3dfd2ff92 --- /dev/null +++ b/sysdeps/powerpc/powerpc32/power7/memcpy.S @@ -0,0 +1,469 @@ +/* Optimized memcpy implementation for PowerPC32/POWER7. + Copyright (C) 2010 Free Software Foundation, Inc. + Contributed by Luis Machado <luisgpm@br.ibm.com>. + 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., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ + +#include <sysdep.h> +#include <bp-sym.h> +#include <bp-asm.h> + +/* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]); + Returns 'dst'. */ + + .machine power7 +EALIGN (BP_SYM (memcpy), 5, 0) + CALL_MCOUNT + + stwu 1,-32(1) + cfi_adjust_cfa_offset(32) + stw 30,20(1) + cfi_offset(30,(20-32)) + stw 31,24(1) + mr 30,3 + cmplwi cr1,5,31 + neg 0,3 + cfi_offset(31,-8) + ble cr1, L(copy_LT_32) /* If move < 32 bytes use short move + code. */ + + andi. 11,3,7 /* Check alignment of DST. */ + clrlwi 10,4,29 /* Check alignment of SRC. */ + cmplw cr6,10,11 /* SRC and DST alignments match? */ + mr 12,4 + mr 31,5 + bne cr6,L(copy_GE_32_unaligned) + + srwi 9,5,3 /* Number of full quadwords remaining. */ + + beq L(copy_GE_32_aligned_cont) + + clrlwi 0,0,29 + mtcrf 0x01,0 + subf 31,0,5 + + /* Get the SRC aligned to 8 bytes. */ + +1: bf 31,2f + lbz 6,0(12) + addi 12,12,1 + stb 6,0(3) + addi 3,3,1 +2: bf 30,4f + lhz 6,0(12) + addi 12,12,2 + sth 6,0(3) + addi 3,3,2 +4: bf 29,0f + lwz 6,0(12) + addi 12,12,4 + stw 6,0(3) + addi 3,3,4 +0: + clrlwi 10,12,29 /* Check alignment of SRC again. */ + srwi 9,31,3 /* Number of full doublewords remaining. */ + +L(copy_GE_32_aligned_cont): + + clrlwi 11,31,29 + mtcrf 0x01,9 + + srwi 8,31,5 + cmplwi cr1,9,4 + cmplwi cr6,11,0 + mr 11,12 + + /* Copy 1~3 doublewords so the main loop starts + at a multiple of 32 bytes. */ + + bf 30,1f + lfd 6,0(12) + lfd 7,8(12) + addi 11,12,16 + mtctr 8 + stfd 6,0(3) + stfd 7,8(3) + addi 10,3,16 + bf 31,4f + lfd 0,16(12) + stfd 0,16(3) + blt cr1,3f + addi 11,12,24 + addi 10,3,24 + b 4f + + .align 4 +1: /* Copy 1 doubleword and set the counter. */ + mr 10,3 + mtctr 8 + bf 31,4f + lfd 6,0(12) + addi 11,12,8 + stfd 6,0(3) + addi 10,3,8 + + .align 4 +4: /* Main aligned copy loop. Copies 32-bytes at a time. */ + lfd 6,0(11) + lfd 7,8(11) + lfd 8,16(11) + lfd 0,24(11) + addi 11,11,32 + + stfd 6,0(10) + stfd 7,8(10) + stfd 8,16(10) + stfd 0,24(10) + addi 10,10,32 + bdnz 4b +3: + + /* Check for tail bytes. */ + + clrrwi 0,31,3 + mtcrf 0x01,31 + beq cr6,0f + +.L9: + add 3,3,0 + add 12,12,0 + + /* At this point we have a tail of 0-7 bytes and we know that the + destination is doubleword-aligned. */ +4: /* Copy 4 bytes. */ + bf 29,2f + + lwz 6,0(12) + addi 12,12,4 + stw 6,0(3) + addi 3,3,4 +2: /* Copy 2 bytes. */ + bf 30,1f + + lhz 6,0(12) + addi 12,12,2 + sth 6,0(3) + addi 3,3,2 +1: /* Copy 1 byte. */ + bf 31,0f + + lbz 6,0(12) + stb 6,0(3) +0: /* Return original DST pointer. */ + mr 3,30 + lwz 30,20(1) + lwz 31,24(1) + addi 1,1,32 + blr + + /* Handle copies of 0~31 bytes. */ + .align 4 +L(copy_LT_32): + cmplwi cr6,5,8 + mr 12,4 + mtcrf 0x01,5 + ble cr6,L(copy_LE_8) + + /* At least 9 bytes to go. */ + neg 8,4 + clrrwi 11,4,2 + andi. 0,8,3 + cmplwi cr1,5,16 + mr 10,5 + beq L(copy_LT_32_aligned) + + /* Force 4-bytes alignment for SRC. */ + mtocrf 0x01,0 + subf 10,0,5 +2: bf 30,1f + + lhz 6,0(12) + addi 12,12,2 + sth 6,0(3) + addi 3,3,2 +1: bf 31,L(end_4bytes_alignment) + + lbz 6,0(12) + addi 12,12,1 + stb 6,0(3) + addi 3,3,1 + + .align 4 +L(end_4bytes_alignment): + cmplwi cr1,10,16 + mtcrf 0x01,10 + +L(copy_LT_32_aligned): + /* At least 6 bytes to go, and SRC is word-aligned. */ + blt cr1,8f + + /* Copy 16 bytes. */ + lwz 6,0(12) + lwz 7,4(12) + stw 6,0(3) + lwz 8,8(12) + stw 7,4(3) + lwz 6,12(12) + addi 12,12,16 + stw 8,8(3) + stw 6,12(3) + addi 3,3,16 +8: /* Copy 8 bytes. */ + bf 28,4f + + lwz 6,0(12) + lwz 7,4(12) + addi 12,12,8 + stw 6,0(3) + stw 7,4(3) + addi 3,3,8 +4: /* Copy 4 bytes. */ + bf 29,2f + + lwz 6,0(12) + addi 12,12,4 + stw 6,0(3) + addi 3,3,4 +2: /* Copy 2-3 bytes. */ + bf 30,1f + + lhz 6,0(12) + sth 6,0(3) + bf 31,0f + lbz 7,2(12) + stb 7,2(3) + + /* Return original DST pointer. */ + mr 3,30 + lwz 30,20(1) + addi 1,1,32 + blr + + .align 4 +1: /* Copy 1 byte. */ + bf 31,0f + + lbz 6,0(12) + stb 6,0(3) +0: /* Return original DST pointer. */ + mr 3,30 + lwz 30,20(1) + addi 1,1,32 + blr + + /* Handles copies of 0~8 bytes. */ + .align 4 +L(copy_LE_8): + bne cr6,4f + + /* Though we could've used lfd/stfd here, they are still + slow for unaligned cases. */ + + lwz 6,0(4) + lwz 7,4(4) + stw 6,0(3) + stw 7,4(3) + + /* Return original DST pointer. */ + mr 3,30 + lwz 30,20(1) + addi 1,1,32 + blr + + .align 4 +4: /* Copies 4~7 bytes. */ + bf 29,2b + + lwz 6,0(4) + stw 6,0(3) + bf 30,5f + lhz 7,4(4) + sth 7,4(3) + bf 31,0f + lbz 8,6(4) + stb 8,6(3) + + /* Return original DST pointer. */ + mr 3,30 + lwz 30,20(1) + addi 1,1,32 + blr + + .align 4 +5: /* Copy 1 byte. */ + bf 31,0f + + lbz 6,4(4) + stb 6,4(3) + +0: /* Return original DST pointer. */ + mr 3,30 + lwz 30,20(1) + addi 1,1,32 + blr + + /* Handle copies of 32+ bytes where DST is aligned (to quadword) but + SRC is not. Use aligned quadword loads from SRC, shifted to realign + the data, allowing for aligned DST stores. */ + .align 4 +L(copy_GE_32_unaligned): + andi. 11,3,15 /* Check alignment of DST. */ + clrlwi 0,0,28 /* Number of bytes until the 1st + quadword of DST. */ + srwi 9,5,4 /* Number of full quadwords remaining. */ + + beq L(copy_GE_32_unaligned_cont) + + /* SRC is not quadword aligned, get it aligned. */ + + mtcrf 0x01,0 + subf 31,0,5 + + /* Vector instructions work best when proper alignment (16-bytes) + is present. Move 0~15 bytes as needed to get DST quadword-aligned. */ +1: /* Copy 1 byte. */ + bf 31,2f + + lbz 6,0(12) + addi 12,12,1 + stb 6,0(3) + addi 3,3,1 +2: /* Copy 2 bytes. */ + bf 30,4f + + lhz 6,0(12) + addi 12,12,2 + sth 6,0(3) + addi 3,3,2 +4: /* Copy 4 bytes. */ + bf 29,8f + + lwz 6,0(12) + addi 12,12,4 + stw 6,0(3) + addi 3,3,4 +8: /* Copy 8 bytes. */ + bf 28,0f + + lfd 6,0(12) + addi 12,12,8 + stfd 6,0(3) + addi 3,3,8 +0: + clrlwi 10,12,28 /* Check alignment of SRC. */ + srdi 9,31,4 /* Number of full quadwords remaining. */ + + /* The proper alignment is present, it is OK to copy the bytes now. */ +L(copy_GE_32_unaligned_cont): + + /* Setup two indexes to speed up the indexed vector operations. */ + clrlwi 11,31,28 + li 6,16 /* Index for 16-bytes offsets. */ + li 7,32 /* Index for 32-bytes offsets. */ + cmplwi cr1,11,0 + srdi 8,31,5 /* Setup the loop counter. */ + mr 10,3 + mr 11,12 + mtcrf 0x01,9 + cmplwi cr6,9,1 + lvsl 5,0,12 + lvx 3,0,12 + bf 31,L(setup_unaligned_loop) + + /* Copy another 16 bytes to align to 32-bytes due to the loop . */ + lvx 4,12,6 + vperm 6,3,4,5 + addi 11,12,16 + addi 10,3,16 + stvx 6,0,3 + vor 3,4,4 + +L(setup_unaligned_loop): + mtctr 8 + ble cr6,L(end_unaligned_loop) + + /* Copy 32 bytes at a time using vector instructions. */ + .align 4 +L(unaligned_loop): + + /* Note: vr6/vr10 may contain data that was already copied, + but in order to get proper alignment, we may have to copy + some portions again. This is faster than having unaligned + vector instructions though. */ + + lvx 4,11,6 /* vr4 = r11+16. */ + vperm 6,3,4,5 /* Merge the correctly-aligned portions + of vr3/vr4 into vr6. */ + lvx 3,11,7 /* vr3 = r11+32. */ + vperm 10,4,3,5 /* Merge the correctly-aligned portions + of vr3/vr4 into vr10. */ + addi 11,11,32 + stvx 6,0,10 + stvx 10,10,6 + addi 10,10,32 + + bdnz L(unaligned_loop) + + .align 4 +L(end_unaligned_loop): + + /* Check for tail bytes. */ + clrrwi 0,31,4 + mtcrf 0x01,31 + beq cr1,0f + + add 3,3,0 + add 12,12,0 + + /* We have 1~15 tail bytes to copy, and DST is quadword aligned. */ +8: /* Copy 8 bytes. */ + bf 28,4f + + lwz 6,0(12) + lwz 7,4(12) + addi 12,12,8 + stw 6,0(3) + stw 7,4(3) + addi 3,3,8 +4: /* Copy 4 bytes. */ + bf 29,2f + + lwz 6,0(12) + addi 12,12,4 + stw 6,0(3) + addi 3,3,4 +2: /* Copy 2~3 bytes. */ + bf 30,1f + + lhz 6,0(12) + addi 12,12,2 + sth 6,0(3) + addi 3,3,2 +1: /* Copy 1 byte. */ + bf 31,0f + + lbz 6,0(12) + stb 6,0(3) +0: /* Return original DST pointer. */ + mr 3,30 + lwz 30,20(1) + lwz 31,24(1) + addi 1,1,32 + blr + +END (BP_SYM (memcpy)) +libc_hidden_builtin_def (memcpy) diff --git a/sysdeps/powerpc/powerpc64/power7/memcpy.S b/sysdeps/powerpc/powerpc64/power7/memcpy.S new file mode 100644 index 0000000000..2e5beed15e --- /dev/null +++ b/sysdeps/powerpc/powerpc64/power7/memcpy.S @@ -0,0 +1,449 @@ +/* Optimized memcpy implementation for PowerPC64/POWER7. + Copyright (C) 2010 Free Software Foundation, Inc. + Contributed by Luis Machado <luisgpm@br.ibm.com>. + 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., 51 Franklin Street, Fifth Floor, Boston MA + 02110-1301 USA. */ + +#include <sysdep.h> +#include <bp-sym.h> +#include <bp-asm.h> + + +/* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]); + Returns 'dst'. */ + + .machine power7 +EALIGN (BP_SYM (memcpy), 5, 0) + CALL_MCOUNT 3 + + cmpldi cr1,5,31 + neg 0,3 + std 3,-16(1) + std 31,-8(1) + cfi_offset(31,-8) + ble cr1, L(copy_LT_32) /* If move < 32 bytes use short move + code. */ + + andi. 11,3,7 /* Check alignment of DST. */ + + + clrldi 10,4,61 /* Check alignment of SRC. */ + cmpld cr6,10,11 /* SRC and DST alignments match? */ + mr 12,4 + mr 31,5 + bne cr6,L(copy_GE_32_unaligned) + + srdi 9,5,3 /* Number of full quadwords remaining. */ + + beq L(copy_GE_32_aligned_cont) + + clrldi 0,0,61 + mtcrf 0x01,0 + subf 31,0,5 + + /* Get the SRC aligned to 8 bytes. */ + +1: bf 31,2f + lbz 6,0(12) + addi 12,12,1 + stb 6,0(3) + addi 3,3,1 +2: bf 30,4f + lhz 6,0(12) + addi 12,12,2 + sth 6,0(3) + addi 3,3,2 +4: bf 29,0f + lwz 6,0(12) + addi 12,12,4 + stw 6,0(3) + addi 3,3,4 +0: + clrldi 10,12,61 /* Check alignment of SRC again. */ + srdi 9,31,3 /* Number of full doublewords remaining. */ + +L(copy_GE_32_aligned_cont): + + clrldi 11,31,61 + mtcrf 0x01,9 + + srdi 8,31,5 + cmpldi cr1,9,4 + cmpldi cr6,11,0 + mr 11,12 + + /* Copy 1~3 doublewords so the main loop starts + at a multiple of 32 bytes. */ + + bf 30,1f + ld 6,0(12) + ld 7,8(12) + addi 11,12,16 + mtctr 8 + std 6,0(3) + std 7,8(3) + addi 10,3,16 + bf 31,4f + ld 0,16(12) + std 0,16(3) + blt cr1,3f + addi 11,12,24 + addi 10,3,24 + b 4f + + .align 4 +1: /* Copy 1 doubleword and set the counter. */ + mr 10,3 + mtctr 8 + bf 31,4f + ld 6,0(12) + addi 11,12,8 + std 6,0(3) + addi 10,3,8 + + /* Main aligned copy loop. Copies 32-bytes at a time. */ + .align 4 +4: + ld 6,0(11) + ld 7,8(11) + ld 8,16(11) + ld 0,24(11) + addi 11,11,32 + + std 6,0(10) + std 7,8(10) + std 8,16(10) + std 0,24(10) + addi 10,10,32 + bdnz 4b +3: + + /* Check for tail bytes. */ + rldicr 0,31,0,60 + mtcrf 0x01,31 + beq cr6,0f + +.L9: + add 3,3,0 + add 12,12,0 + + /* At this point we have a tail of 0-7 bytes and we know that the + destination is doubleword-aligned. */ +4: /* Copy 4 bytes. */ + bf 29,2f + + lwz 6,0(12) + addi 12,12,4 + stw 6,0(3) + addi 3,3,4 +2: /* Copy 2 bytes. */ + bf 30,1f + + lhz 6,0(12) + addi 12,12,2 + sth 6,0(3) + addi 3,3,2 +1: /* Copy 1 byte. */ + bf 31,0f + + lbz 6,0(12) + stb 6,0(3) +0: /* Return original DST pointer. */ + ld 31,-8(1) + ld 3,-16(1) + blr + + /* Handle copies of 0~31 bytes. */ + .align 4 +L(copy_LT_32): + cmpldi cr6,5,8 + mr 12,4 + mtcrf 0x01,5 + ble cr6,L(copy_LE_8) + + /* At least 9 bytes to go. */ + neg 8,4 + clrrdi 11,4,2 + andi. 0,8,3 + cmpldi cr1,5,16 + mr 10,5 + beq L(copy_LT_32_aligned) + + /* Force 4-bytes alignment for SRC. */ + mtocrf 0x01,0 + subf 10,0,5 +2: bf 30,1f + + lhz 6,0(12) + addi 12,12,2 + sth 6,0(3) + addi 3,3,2 +1: bf 31,L(end_4bytes_alignment) + + lbz 6,0(12) + addi 12,12,1 + stb 6,0(3) + addi 3,3,1 + + .align 4 +L(end_4bytes_alignment): + cmpldi cr1,10,16 + mtcrf 0x01,10 + +L(copy_LT_32_aligned): + /* At least 6 bytes to go, and SRC is word-aligned. */ + blt cr1,8f + + /* Copy 16 bytes. */ + lwz 6,0(12) + lwz 7,4(12) + stw 6,0(3) + lwz 8,8(12) + stw 7,4(3) + lwz 6,12(12) + addi 12,12,16 + stw 8,8(3) + stw 6,12(3) + addi 3,3,16 +8: /* Copy 8 bytes. */ + bf 28,4f + + lwz 6,0(12) + lwz 7,4(12) + addi 12,12,8 + stw 6,0(3) + stw 7,4(3) + addi 3,3,8 +4: /* Copy 4 bytes. */ + bf 29,2f + + lwz 6,0(12) + addi 12,12,4 + stw 6,0(3) + addi 3,3,4 +2: /* Copy 2-3 bytes. */ + bf 30,1f + + lhz 6,0(12) + sth 6,0(3) + bf 31,0f + lbz 7,2(12) + stb 7,2(3) + ld 3,-16(1) + blr + + .align 4 +1: /* Copy 1 byte. */ + bf 31,0f + + lbz 6,0(12) + stb 6,0(3) +0: /* Return original DST pointer. */ + ld 3,-16(1) + blr + + /* Handles copies of 0~8 bytes. */ + .align 4 +L(copy_LE_8): + bne cr6,4f + + /* Though we could've used ld/std here, they are still + slow for unaligned cases. */ + + lwz 6,0(4) + lwz 7,4(4) + stw 6,0(3) + stw 7,4(3) + ld 3,-16(1) /* Return original DST pointers. */ + blr + + .align 4 +4: /* Copies 4~7 bytes. */ + bf 29,2b + + lwz 6,0(4) + stw 6,0(3) + bf 30,5f + lhz 7,4(4) + sth 7,4(3) + bf 31,0f + lbz 8,6(4) + stb 8,6(3) + ld 3,-16(1) + blr + + .align 4 +5: /* Copy 1 byte. */ + bf 31,0f + + lbz 6,4(4) + stb 6,4(3) + +0: /* Return original DST pointer. */ + ld 3,-16(1) + blr + + /* Handle copies of 32+ bytes where DST is aligned (to quadword) but + SRC is not. Use aligned quadword loads from SRC, shifted to realign + the data, allowing for aligned DST stores. */ + .align 4 +L(copy_GE_32_unaligned): + clrldi 0,0,60 /* Number of bytes until the 1st + quadword. */ + andi. 11,3,15 /* Check alignment of DST (against + quadwords). */ + srdi 9,5,4 /* Number of full quadwords remaining. */ + + beq L(copy_GE_32_unaligned_cont) + + /* SRC is not quadword aligned, get it aligned. */ + + mtcrf 0x01,0 + subf 31,0,5 + + /* Vector instructions work best when proper alignment (16-bytes) + is present. Move 0~15 bytes as needed to get DST quadword-aligned. */ +1: /* Copy 1 byte. */ + bf 31,2f + + lbz 6,0(12) + addi 12,12,1 + stb 6,0(3) + addi 3,3,1 +2: /* Copy 2 bytes. */ + bf 30,4f + + lhz 6,0(12) + addi 12,12,2 + sth 6,0(3) + addi 3,3,2 +4: /* Copy 4 bytes. */ + bf 29,8f + + lwz 6,0(12) + addi 12,12,4 + stw 6,0(3) + addi 3,3,4 +8: /* Copy 8 bytes. */ + bf 28,0f + + ld 6,0(12) + addi 12,12,8 + std 6,0(3) + addi 3,3,8 +0: + clrldi 10,12,60 /* Check alignment of SRC. */ + srdi 9,31,4 /* Number of full quadwords remaining. */ + + /* The proper alignment is present, it is OK to copy the bytes now. */ +L(copy_GE_32_unaligned_cont): + + /* Setup two indexes to speed up the indexed vector operations. */ + clrldi 11,31,60 + li 6,16 /* Index for 16-bytes offsets. */ + li 7,32 /* Index for 32-bytes offsets. */ + cmpldi cr1,11,0 + srdi 8,31,5 /* Setup the loop counter. */ + mr 10,3 + mr 11,12 + mtcrf 0x01,9 + cmpldi cr6,9,1 + lvsl 5,0,12 + lvx 3,0,12 + bf 31,L(setup_unaligned_loop) + + /* Copy another 16 bytes to align to 32-bytes due to the loop . */ + lvx 4,12,6 + vperm 6,3,4,5 + addi 11,12,16 + addi 10,3,16 + stvx 6,0,3 + vor 3,4,4 + +L(setup_unaligned_loop): + mtctr 8 + ble cr6,L(end_unaligned_loop) + + /* Copy 32 bytes at a time using vector instructions. */ + .align 4 +L(unaligned_loop): + + /* Note: vr6/vr10 may contain data that was already copied, + but in order to get proper alignment, we may have to copy + some portions again. This is faster than having unaligned + vector instructions though. */ + + lvx 4,11,6 /* vr4 = r11+16. */ + vperm 6,3,4,5 /* Merge the correctly-aligned portions + of vr3/vr4 into vr6. */ + lvx 3,11,7 /* vr3 = r11+32. */ + vperm 10,4,3,5 /* Merge the correctly-aligned portions + of vr3/vr4 into vr10. */ + addi 11,11,32 + stvx 6,0,10 + stvx 10,10,6 + addi 10,10,32 + + bdnz L(unaligned_loop) + + .align 4 +L(end_unaligned_loop): + + /* Check for tail bytes. */ + rldicr 0,31,0,59 + mtcrf 0x01,31 + beq cr1,0f + + add 3,3,0 + add 12,12,0 + + /* We have 1~15 tail bytes to copy, and DST is quadword aligned. */ +8: /* Copy 8 bytes. */ + bf 28,4f + + lwz 6,0(12) + lwz 7,4(12) + addi 12,12,8 + stw 6,0(3) + stw 7,4(3) + addi 3,3,8 +4: /* Copy 4 bytes. */ + bf 29,2f + + lwz 6,0(12) + addi 12,12,4 + stw 6,0(3) + addi 3,3,4 +2: /* Copy 2~3 bytes. */ + bf 30,1f + + lhz 6,0(12) + addi 12,12,2 + sth 6,0(3) + addi 3,3,2 +1: /* Copy 1 byte. */ + bf 31,0f + + lbz 6,0(12) + stb 6,0(3) +0: /* Return original DST pointer. */ + ld 31,-8(1) + ld 3,-16(1) + blr + +END_GEN_TB (BP_SYM (memcpy),TB_TOCLESS) +libc_hidden_builtin_def (memcpy) diff --git a/sysdeps/unix/getlogin.c b/sysdeps/unix/getlogin.c index 4752685f86..b0ad97cfa5 100644 --- a/sysdeps/unix/getlogin.c +++ b/sysdeps/unix/getlogin.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1992, 1996, 1997 Free Software Foundation, Inc. +/* Copyright (C) 1991, 1992, 1996, 1997, 2010 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 @@ -25,16 +25,20 @@ #include <utmp.h> +static char name[UT_NAMESIZE + 1]; + /* Return the login name of the user, or NULL if it can't be determined. The returned pointer, if not NULL, is good only until the next call. */ +#ifdef STATIC +STATIC +#endif char * getlogin (void) { char tty_pathname[2 + 2 * NAME_MAX]; char *real_tty_path = tty_pathname; char *result = NULL; - static char name[UT_NAMESIZE + 1]; struct utmp *ut, line, buffer; /* Get name of tty connected to fd 0. Return NULL if not a tty or diff --git a/sysdeps/unix/getlogin_r.c b/sysdeps/unix/getlogin_r.c index ba7badd054..bf3c889e13 100644 --- a/sysdeps/unix/getlogin_r.c +++ b/sysdeps/unix/getlogin_r.c @@ -1,5 +1,5 @@ /* Reentrant function to return the current login name. Unix version. - Copyright (C) 1991,92,96,97,98,2002 Free Software Foundation, Inc. + Copyright (C) 1991,92,96,97,98,2002,2010 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 @@ -31,6 +31,9 @@ If it cannot be determined or some other error occurred, return the error code. Otherwise return 0. */ +#ifdef STATIC +STATIC +#endif int getlogin_r (name, name_len) char *name; @@ -96,4 +99,6 @@ getlogin_r (name, name_len) return result; } +#ifndef STATIC libc_hidden_def (getlogin_r) +#endif diff --git a/sysdeps/unix/readdir_r.c b/sysdeps/unix/readdir_r.c index f84709e737..93727912c1 100644 --- a/sysdeps/unix/readdir_r.c +++ b/sysdeps/unix/readdir_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,02 +/* Copyright (C) 1991,92,93,94,95,96,97,98,99,2000,02,10 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -113,7 +113,17 @@ __READDIR_R (DIR *dirp, DIRENT_TYPE *entry, DIRENT_TYPE **result) while (dp->d_ino == 0); if (dp != NULL) - *result = memcpy (entry, dp, reclen); + { +#ifdef GETDENTS_64BIT_ALIGNED + /* The d_reclen value might include padding which is not part of + the DIRENT_TYPE data structure. */ + reclen = MIN (reclen, sizeof (DIRENT_TYPE)); +#endif + *result = memcpy (entry, dp, reclen); +#ifdef GETDENTS_64BIT_ALIGNED + entry->d_reclen = reclen; +#endif + } else *result = NULL; diff --git a/sysdeps/unix/sysv/linux/bits/socket.h b/sysdeps/unix/sysv/linux/bits/socket.h index aa78087a72..dba3a3914b 100644 --- a/sysdeps/unix/sysv/linux/bits/socket.h +++ b/sysdeps/unix/sysv/linux/bits/socket.h @@ -1,5 +1,5 @@ /* System-specific socket constants and types. Linux version. - Copyright (C) 1991, 1992, 1994-2001, 2004, 2006, 2007, 2008, 2009 + Copyright (C) 1991, 1992, 1994-2001, 2004, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -232,6 +232,8 @@ enum #define MSG_NOSIGNAL MSG_NOSIGNAL MSG_MORE = 0x8000, /* Sender will send more. */ #define MSG_MORE MSG_MORE + MSG_WAITFORONE = 0x10000, /* Wait for at least one packet to return.*/ +#define MSG_WAITFORONE MSG_WAITFORONE MSG_CMSG_CLOEXEC = 0x40000000 /* Set close_on_exit for file descriptor received through diff --git a/sysdeps/unix/sysv/linux/clock_getres.c b/sysdeps/unix/sysv/linux/clock_getres.c index 581ff22c7c..933580b609 100644 --- a/sysdeps/unix/sysv/linux/clock_getres.c +++ b/sysdeps/unix/sysv/linux/clock_getres.c @@ -1,5 +1,5 @@ /* clock_getres -- Get the resolution of a POSIX clockid_t. Linux version. - Copyright (C) 2003,2004,2005,2006, 2008 Free Software Foundation, Inc. + Copyright (C) 2003,2004,2005,2006,2008,2010 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 @@ -44,6 +44,9 @@ SYSDEP_GETRES_CPUTIME \ case CLOCK_REALTIME: \ case CLOCK_MONOTONIC: \ + case CLOCK_MONOTONIC_RAW: \ + case CLOCK_REALTIME_COARSE: \ + case CLOCK_MONOTONIC_COARSE: \ SYSCALL_GETRES # define __libc_missing_posix_timers 0 @@ -80,6 +83,9 @@ maybe_syscall_getres (clockid_t clock_id, struct timespec *res) SYSDEP_GETRES_CPUTIME \ case CLOCK_REALTIME: \ case CLOCK_MONOTONIC: \ + case CLOCK_MONOTONIC_RAW: \ + case CLOCK_REALTIME_COARSE: \ + case CLOCK_MONOTONIC_COARSE: \ retval = maybe_syscall_getres (clock_id, res); \ if (retval == 0) \ break; \ diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c index cd536a0fc0..dd3755cce7 100644 --- a/sysdeps/unix/sysv/linux/clock_gettime.c +++ b/sysdeps/unix/sysv/linux/clock_gettime.c @@ -1,5 +1,5 @@ /* clock_gettime -- Get current time from a POSIX clockid_t. Linux version. - Copyright (C) 2003,2004,2005,2006,2007 Free Software Foundation, Inc. + Copyright (C) 2003,2004,2005,2006,2007,2010 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 @@ -80,6 +80,9 @@ maybe_syscall_gettime (clockid_t clock_id, struct timespec *tp) SYSDEP_GETTIME_CPUTIME \ case CLOCK_REALTIME: \ case CLOCK_MONOTONIC: \ + case CLOCK_MONOTONIC_RAW: \ + case CLOCK_REALTIME_COARSE: \ + case CLOCK_MONOTONIC_COARSE: \ retval = maybe_syscall_gettime (clock_id, tp); \ if (retval == 0) \ break; \ diff --git a/sysdeps/unix/sysv/linux/clock_settime.c b/sysdeps/unix/sysv/linux/clock_settime.c index 217ae3f29b..8c52456fdd 100644 --- a/sysdeps/unix/sysv/linux/clock_settime.c +++ b/sysdeps/unix/sysv/linux/clock_settime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2004, 2006, 2010 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 @@ -45,7 +45,7 @@ maybe_syscall_settime_cpu (clockid_t clock_id, const struct timespec *tp) INTERNAL_SYSCALL_DECL (err); int r = INTERNAL_SYSCALL (clock_settime, err, 2, clock_id, tp); if (!INTERNAL_SYSCALL_ERROR_P (r, err)) - return 0; + return 0; e = INTERNAL_SYSCALL_ERRNO (r, err); # ifndef __ASSUME_POSIX_TIMERS @@ -90,6 +90,7 @@ extern int __libc_missing_posix_timers attribute_hidden; /* The REALTIME clock might be available. Try the syscall first. */ # define SYSDEP_SETTIME \ case CLOCK_REALTIME: \ + case CLOCK_REALTIME_COARSE: \ { \ int e = EINVAL; \ \ diff --git a/sysdeps/unix/sysv/linux/dl-sysdep.c b/sysdeps/unix/sysv/linux/dl-sysdep.c index 08ae9aa86d..34e8808928 100644 --- a/sysdeps/unix/sysv/linux/dl-sysdep.c +++ b/sysdeps/unix/sysv/linux/dl-sysdep.c @@ -47,12 +47,12 @@ frob_brk (void) Later Linux kernels have changed this behavior so that the initial break value is rounded up to the page boundary before we start. */ - extern void *__curbrk attribute_hidden; - extern void _end attribute_hidden; - void *const endpage = (void *) 0 + (((__curbrk - (void *) 0) + extern char *__curbrk attribute_hidden; + extern char _end[] attribute_hidden; + char *const endpage = (void *) 0 + (((__curbrk - (char *) 0) + GLRO(dl_pagesize) - 1) & -GLRO(dl_pagesize)); - if (__builtin_expect (__curbrk >= &_end && __curbrk < endpage, 0)) + if (__builtin_expect (__curbrk >= _end && __curbrk < endpage, 0)) __brk (endpage); #endif } diff --git a/sysdeps/unix/sysv/linux/getlogin.c b/sysdeps/unix/sysv/linux/getlogin.c new file mode 100644 index 0000000000..4d15db093d --- /dev/null +++ b/sysdeps/unix/sysv/linux/getlogin.c @@ -0,0 +1,39 @@ +/* Copyright (C) 2010 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 <pwd.h> +#include <unistd.h> +#include <not-cancel.h> + +#define STATIC static +#define getlogin getlogin_fd0 +#include <sysdeps/unix/getlogin.c> +#undef getlogin + + +/* Return the login name of the user, or NULL if it can't be determined. + The returned pointer, if not NULL, is good only until the next call. */ + +char * +getlogin (void) +{ + if (__getlogin_r_loginuid (name, sizeof (name)) == 0) + return name; + + return getlogin_fd0 (); +} diff --git a/sysdeps/unix/sysv/linux/getlogin_r.c b/sysdeps/unix/sysv/linux/getlogin_r.c new file mode 100644 index 0000000000..d07846ccb8 --- /dev/null +++ b/sysdeps/unix/sysv/linux/getlogin_r.c @@ -0,0 +1,100 @@ +/* Copyright (C) 2010 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 <pwd.h> +#include <unistd.h> +#include <not-cancel.h> + +#define STATIC static +static int getlogin_r_fd0 (char *name, size_t namesize); +#define getlogin_r getlogin_r_fd0 +#include <sysdeps/unix/getlogin_r.c> +#undef getlogin_r + + +int +attribute_hidden +__getlogin_r_loginuid (name, namesize) + char *name; + size_t namesize; +{ + int fd = open_not_cancel_2 ("/proc/self/loginuid", O_RDONLY); + if (fd == -1) + return 1; + + ssize_t n = TEMP_FAILURE_RETRY (read_not_cancel (fd, name, namesize)); + close_not_cancel_no_status (fd); + + uid_t uid; + char *endp; + if (n <= 0 + || (uid = strtoul (name, &endp, 10), endp == name || *endp != '\0')) + return 1; + + size_t buflen = 1024; + char *buf = alloca (buflen); + bool use_malloc = false; + struct passwd pwd; + struct passwd *tpwd; + int res; + + while ((res = __getpwuid_r (uid, &pwd, buf, buflen, &tpwd)) != 0) + if (__libc_use_alloca (2 * buflen)) + extend_alloca (buf, buflen, 2 * buflen); + else + { + buflen *= 2; + char *newp = realloc (use_malloc ? buf : NULL, buflen); + if (newp == NULL) + { + fail: + if (use_malloc) + free (buf); + return 1; + } + buf = newp; + use_malloc = true; + } + + if (tpwd == NULL) + goto fail; + + strncpy (name, pwd.pw_name, namesize - 1); + name[namesize - 1] = '\0'; + + if (use_malloc) + free (buf); + + return 0; +} + + +/* Return the login name of the user, or NULL if it can't be determined. + The returned pointer, if not NULL, is good only until the next call. */ + +int +getlogin_r (name, namesize) + char *name; + size_t namesize; +{ + if (__getlogin_r_loginuid (name, namesize) == 0) + return 0; + + return getlogin_r_fd0 (name, namesize); +} +libc_hidden_def (getlogin_r) diff --git a/sysdeps/unix/sysv/linux/getpagesize.c b/sysdeps/unix/sysv/linux/getpagesize.c index 6d03b3bbf2..0866079511 100644 --- a/sysdeps/unix/sysv/linux/getpagesize.c +++ b/sysdeps/unix/sysv/linux/getpagesize.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1991,1992,1995-1997,2000,2002,2004 +/* Copyright (C) 1991,1992,1995-1997,2000,2002,2004,2010 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -17,30 +17,37 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <assert.h> #include <unistd.h> #include <sys/param.h> #include <ldsodefs.h> +#include <kernel-features.h> /* Return the system page size. */ int __getpagesize () { +#ifdef __ASSUME_AT_PAGESIZE + assert (GLRO(dl_pagesize) != 0); + return GLRO(dl_pagesize); +#else if (GLRO(dl_pagesize) != 0) return GLRO(dl_pagesize); -#ifdef EXEC_PAGESIZE +# ifdef EXEC_PAGESIZE return EXEC_PAGESIZE; -#else /* No EXEC_PAGESIZE. */ -#ifdef NBPG -#ifndef CLSIZE -#define CLSIZE 1 -#endif /* No CLSIZE. */ +# else /* No EXEC_PAGESIZE. */ +# ifdef NBPG +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* No CLSIZE. */ return NBPG * CLSIZE; -#else /* No NBPG. */ +# else /* No NBPG. */ return NBPC; -#endif /* NBPG. */ -#endif /* EXEC_PAGESIZE. */ +# endif /* NBPG. */ +# endif /* EXEC_PAGESIZE. */ +#endif } libc_hidden_def (__getpagesize) weak_alias (__getpagesize, getpagesize) diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c index 97e20d249b..af454b650d 100644 --- a/sysdeps/unix/sysv/linux/getsysstats.c +++ b/sysdeps/unix/sysv/linux/getsysstats.c @@ -1,5 +1,5 @@ /* Determine various system internal values, Linux version. - Copyright (C) 1996-2003, 2006, 2007, 2009 Free Software Foundation, Inc. + Copyright (C) 1996-2003,2006,2007,2009,2010 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -117,18 +117,6 @@ next_line (int fd, char *const buffer, char **cp, char **re, if (nl == NULL) nl = *re - 1; } - else if (nl + 5 >= *re) - { - memmove (buffer, nl, *re - nl); - *re = buffer + (*re - nl); - nl = *cp = buffer; - - ssize_t n = read_not_cancel (fd, *re, buffer_end - *re); - if (n < 0) - return NULL; - - *re += n; - } *cp = nl + 1; assert (*cp <= *re); diff --git a/sysdeps/unix/sysv/linux/i386/fcntl.c b/sysdeps/unix/sysv/linux/i386/fcntl.c index 5544d6e0d9..e82a60a885 100644 --- a/sysdeps/unix/sysv/linux/i386/fcntl.c +++ b/sysdeps/unix/sysv/linux/i386/fcntl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000,2002,2003,2004,2006,2009 Free Software Foundation, Inc. +/* Copyright (C) 2000,2002-2004,2006,2009,2010 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 @@ -25,23 +25,23 @@ #include <sys/syscall.h> #include <kernel-features.h> -#if __ASSUME_FCNTL64 == 0 +#ifndef __ASSUME_FCNTL64 /* This variable is shared with all files that check for fcntl64. */ int __have_no_fcntl64; #endif #ifdef __ASSUME_F_GETOWN_EX # define miss_F_GETOWN_EX 0 -#else +#elif !defined __ASSUME_FCNTL64 static int miss_F_GETOWN_EX; #endif -#if defined NO_CANCELLATION && __ASSUME_FCNTL64 == 0 +#if defined NO_CANCELLATION && !defined __ASSUME_FCNTL64 # define __fcntl_nocancel __libc_fcntl #endif -#if !defined NO_CANCELLATION || __ASSUME_FCNTL64 == 0 +#if !defined NO_CANCELLATION || !defined __ASSUME_FCNTL64 int __fcntl_nocancel (int fd, int cmd, ...) { @@ -52,7 +52,7 @@ __fcntl_nocancel (int fd, int cmd, ...) arg = va_arg (ap, void *); va_end (ap); -#if __ASSUME_FCNTL64 == 0 +#ifndef __ASSUME_FCNTL64 # ifdef __NR_fcntl64 if (! __have_no_fcntl64) { @@ -135,11 +135,11 @@ __fcntl_nocancel (int fd, int cmd, ...) if (!INTERNAL_SYSCALL_ERROR_P (res, err)) return fex.type == F_OWNER_GID ? -fex.pid : fex.pid; -#ifndef __ASSUME_F_GETOWN_EX +# ifndef __ASSUME_F_GETOWN_EX if (INTERNAL_SYSCALL_ERRNO (res, err) == EINVAL) miss_F_GETOWN_EX = 1; else -#endif +# endif { __set_errno (INTERNAL_SYSCALL_ERRNO (res, err)); return -1; @@ -168,21 +168,21 @@ __libc_fcntl (int fd, int cmd, ...) arg = va_arg (ap, void *); va_end (ap); -#if __ASSUME_FCNTL64 > 0 +# ifdef __ASSUME_FCNTL64 if (SINGLE_THREAD_P || (cmd != F_SETLKW && cmd != F_SETLKW64)) return INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg); int oldtype = LIBC_CANCEL_ASYNC (); int result = INLINE_SYSCALL (fcntl64, 3, fd, cmd, arg); -#else +# 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 +# endif LIBC_CANCEL_RESET (oldtype); diff --git a/sysdeps/unix/sysv/linux/i386/readdir64_r.c b/sysdeps/unix/sysv/linux/i386/readdir64_r.c index c6da57b75e..f96f16a6f2 100644 --- a/sysdeps/unix/sysv/linux/i386/readdir64_r.c +++ b/sysdeps/unix/sysv/linux/i386/readdir64_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2004 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2004, 2010 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 @@ -19,6 +19,7 @@ #define __READDIR_R __readdir64_r #define __GETDENTS __getdents64 #define DIRENT_TYPE struct dirent64 +#define GETDENTS_64BIT_ALIGNED 1 #include <sysdeps/unix/readdir_r.c> diff --git a/sysdeps/unix/sysv/linux/ifaddrs.c b/sysdeps/unix/sysv/linux/ifaddrs.c index 149bd1c3ba..84f223ddbd 100644 --- a/sysdeps/unix/sysv/linux/ifaddrs.c +++ b/sysdeps/unix/sysv/linux/ifaddrs.c @@ -1,5 +1,5 @@ /* getifaddrs -- get names and addresses of all network interfaces - Copyright (C) 2003-2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2003-2008, 2009, 2010 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 @@ -315,17 +315,19 @@ map_newlink (int index, struct ifaddrs_storage *ifas, int *map, int max) else if (map[i] == index) return i; } - /* This should never be reached. If this will be reached, we have - a very big problem. */ - abort (); + + /* This means interfaces changed inbetween the reading of the + RTM_GETLINK and RTM_GETADDR information. We have to repeat + everything. */ + return -1; } /* Create a linked list of `struct ifaddrs' structures, one for each network interface on the host machine. If successful, store the list in *IFAP and return 0. On errors, return -1 and set `errno'. */ -int -getifaddrs (struct ifaddrs **ifap) +static int +getifaddrs_internal (struct ifaddrs **ifap) { struct netlink_handle nh = { 0, 0, 0, NULL, NULL }; struct netlink_res *nlp; @@ -481,6 +483,13 @@ getifaddrs (struct ifaddrs **ifap) kernel. */ ifa_index = map_newlink (ifim->ifi_index - 1, ifas, map_newlink_data, newlink); + if (__builtin_expect (ifa_index == -1, 0)) + { + try_again: + result = -EAGAIN; + free (ifas); + goto exit_free; + } ifas[ifa_index].ifa.ifa_flags = ifim->ifi_flags; while (RTA_OK (rta, rtasize)) @@ -565,9 +574,11 @@ getifaddrs (struct ifaddrs **ifap) that we have holes in the interface part of the list, but we always have already the interface for this address. */ ifa_index = newlink + newaddr_idx; - ifas[ifa_index].ifa.ifa_flags - = ifas[map_newlink (ifam->ifa_index - 1, ifas, - map_newlink_data, newlink)].ifa.ifa_flags; + int idx = map_newlink (ifam->ifa_index - 1, ifas, + map_newlink_data, newlink); + if (__builtin_expect (idx == -1, 0)) + goto try_again; + ifas[ifa_index].ifa.ifa_flags = ifas[idx].ifa.ifa_flags; if (ifa_index > 0) ifas[ifa_index - 1].ifa.ifa_next = &ifas[ifa_index].ifa; ++newaddr_idx; @@ -747,9 +758,13 @@ getifaddrs (struct ifaddrs **ifap) /* If we didn't get the interface name with the address, use the name from the interface entry. */ if (ifas[ifa_index].ifa.ifa_name == NULL) - ifas[ifa_index].ifa.ifa_name - = ifas[map_newlink (ifam->ifa_index - 1, ifas, - map_newlink_data, newlink)].ifa.ifa_name; + { + int idx = map_newlink (ifam->ifa_index - 1, ifas, + map_newlink_data, newlink); + if (__builtin_expect (idx == -1, 0)) + goto try_again; + ifas[ifa_index].ifa.ifa_name = ifas[idx].ifa.ifa_name; + } /* Calculate the netmask. */ if (ifas[ifa_index].ifa.ifa_addr @@ -826,6 +841,22 @@ getifaddrs (struct ifaddrs **ifap) return result; } + + +/* Create a linked list of `struct ifaddrs' structures, one for each + network interface on the host machine. If successful, store the + list in *IFAP and return 0. On errors, return -1 and set `errno'. */ +int +getifaddrs (struct ifaddrs **ifap) +{ + int res; + + do + res = getifaddrs_internal (ifap); + while (res == -EAGAIN); + + return res; +} libc_hidden_def (getifaddrs) diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index f48e644e09..275668b23c 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -1,6 +1,6 @@ /* Set flags signalling availability of kernel features based on given kernel version number. - Copyright (C) 1999-2006, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 1999-2009, 2010 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 @@ -65,7 +65,7 @@ # define __ASSUME_LCHOWN_SYSCALL 1 #endif -/* When did the `setresuid' sysall became available? */ +/* When did the `setresuid' syscall became available? */ #if __LINUX_KERNEL_VERSION >= 131584 && !defined __sparc__ # define __ASSUME_SETRESUID_SYSCALL 1 #endif @@ -126,7 +126,7 @@ #endif /* I know for sure that these are in 2.3.35 on powerpc. But PowerPC64 does not - support separate 64-bit syscalls, already 64-bit */ + support separate 64-bit syscalls, already 64-bit. */ #if __LINUX_KERNEL_VERSION >= 131875 && defined __powerpc__ \ && !defined __powerpc64__ # define __ASSUME_TRUNCATE64_SYSCALL 1 @@ -158,8 +158,8 @@ # define __ASSUME_LDT_WORKS 1 #endif -/* Linux 2.4.0 on PPC introduced a correct IPC64. But PowerPC64 does not - support a separate 64-bit sys call, already 64-bit */ +/* Linux 2.4.0 on PPC introduced a correct IPC64. But PowerPC64 does not + support a separate 64-bit syscall, already 64-bit. */ #if __LINUX_KERNEL_VERSION >= 132096 && defined __powerpc__ \ && !defined __powerpc64__ # define __ASSUME_IPC64 1 @@ -208,7 +208,7 @@ # define __ASSUME_GETDENTS64_SYSCALL 1 #endif -/* When did O_DIRECTORY became available? Early in 2.3 but when? +/* When did O_DIRECTORY become available? Early in 2.3 but when? Be safe, use 2.3.99. */ #if __LINUX_KERNEL_VERSION >= 131939 # define __ASSUME_O_DIRECTORY 1 @@ -412,7 +412,7 @@ /* Starting with version 2.6.9, SSI_IEEE_RAISE_EXCEPTION exists. */ #if __LINUX_KERNEL_VERSION >= 0x020609 && defined __alpha__ -#define __ASSUME_IEEE_RAISE_EXCEPTION 1 +# define __ASSUME_IEEE_RAISE_EXCEPTION 1 #endif /* On sparc64 stat64/lstat64/fstat64 syscalls were introduced in 2.6.12. */ diff --git a/sysdeps/unix/sysv/linux/ldsodefs.h b/sysdeps/unix/sysv/linux/ldsodefs.h index 0965f1496f..5d5b1b4c06 100644 --- a/sysdeps/unix/sysv/linux/ldsodefs.h +++ b/sysdeps/unix/sysv/linux/ldsodefs.h @@ -1,5 +1,5 @@ /* Run-time dynamic linker data structures for loaded ELF shared objects. - Copyright (C) 2001, 2002, 2003, 2006, 2009 Free Software Foundation, Inc. + Copyright (C) 2001, 2002, 2003, 2006, 2009, 2010 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 @@ -19,6 +19,7 @@ #ifndef _LDSODEFS_H +#include <libc-abis.h> #include <kernel-features.h> /* Get the real definitions. */ @@ -58,7 +59,8 @@ extern void _dl_non_dynamic_init (void) internal_function; || memcmp (hdr, expected2, size) == 0) #define VALID_ELF_OSABI(osabi) (osabi == ELFOSABI_SYSV \ || osabi == ELFOSABI_LINUX) -#define VALID_ELF_ABIVERSION(ver) (ver == 0) +#define VALID_ELF_ABIVERSION(osabi,ver) \ + (ver == 0 || (osabi == ELFOSABI_LINUX && ver < LIBC_ABI_MAX)) #define MORE_ELF_HEADER_DATA \ static const unsigned char expected2[EI_PAD] = \ { \ @@ -69,8 +71,7 @@ extern void _dl_non_dynamic_init (void) internal_function; [EI_CLASS] = ELFW(CLASS), \ [EI_DATA] = byteorder, \ [EI_VERSION] = EV_CURRENT, \ - [EI_OSABI] = ELFOSABI_LINUX, \ - [EI_ABIVERSION] = 0 \ + [EI_OSABI] = ELFOSABI_LINUX \ } #endif /* ldsodefs.h */ diff --git a/sysdeps/unix/sysv/linux/mmap64.c b/sysdeps/unix/sysv/linux/mmap64.c index d3c68cd106..b24b3f0c8b 100644 --- a/sysdeps/unix/sysv/linux/mmap64.c +++ b/sysdeps/unix/sysv/linux/mmap64.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1999,2000,2001,2002,2006 Free Software Foundation, Inc. +/* Copyright (C) 1999,2000,2001,2002,2006,2010 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Jakub Jelinek <jakub@redhat.com>, 1999. @@ -30,8 +30,13 @@ #ifdef __NR_mmap2 /* This is always 12, even on architectures where PAGE_SHIFT != 12. */ -# ifndef MMAP2_PAGE_SHIFT -# define MMAP2_PAGE_SHIFT 12 +# if MMAP2_PAGE_SHIFT == -1 +static int page_shift; +# else +# ifndef MMAP2_PAGE_SHIFT +# define MMAP2_PAGE_SHIFT 12 +# endif +# define page_shift MMAP2_PAGE_SHIFT # endif # ifndef __ASSUME_MMAP2_SYSCALL @@ -44,7 +49,15 @@ void * __mmap64 (void *addr, size_t len, int prot, int flags, int fd, off64_t offset) { #ifdef __NR_mmap2 - if (offset & ((1 << MMAP2_PAGE_SHIFT) - 1)) +# if MMAP2_PAGE_SHIFT == -1 + if (page_shift == 0) + { + int page_size = getpagesize (); + while ((1 << ++page_shift) != page_size) + ; + } +# endif + if (offset & ((1 << page_shift) - 1)) { __set_errno (EINVAL); return MAP_FAILED; diff --git a/sysdeps/unix/sysv/linux/remove.c b/sysdeps/unix/sysv/linux/remove.c new file mode 100644 index 0000000000..4abf34a73d --- /dev/null +++ b/sysdeps/unix/sysv/linux/remove.c @@ -0,0 +1,2 @@ +#define IS_NO_DIRECTORY_ERROR errno != EISDIR +#include <sysdeps/posix/remove.c> diff --git a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h index a41220d14e..923b4616ca 100644 --- a/sysdeps/unix/sysv/linux/sys/mount.h +++ b/sysdeps/unix/sysv/linux/sys/mount.h @@ -123,8 +123,10 @@ enum #define MNT_FORCE MNT_FORCE MNT_DETACH = 2, /* Just detach from the tree. */ #define MNT_DETACH MNT_DETACH - MNT_EXPIRE = 4 /* Mark for expiry. */ + MNT_EXPIRE = 4, /* Mark for expiry. */ #define MNT_EXPIRE MNT_EXPIRE + UMOUNT_NOFOLLOW = 8 /* Don't follow symlink on umount. */ +#define UMOUNT_NOFOLLOW UMOUNT_NOFOLLOW }; diff --git a/sysdeps/x86_64/multiarch/init-arch.c b/sysdeps/x86_64/multiarch/init-arch.c index 50b2a38fbd..efb89b6c92 100644 --- a/sysdeps/x86_64/multiarch/init-arch.c +++ b/sysdeps/x86_64/multiarch/init-arch.c @@ -1,6 +1,6 @@ /* Initialize CPU feature data. This file is part of the GNU C Library. - Copyright (C) 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Ulrich Drepper <drepper@redhat.com>. The GNU C Library is free software; you can redistribute it and/or @@ -18,6 +18,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <atomic.h> #include <cpuid.h> #include "init-arch.h" @@ -26,7 +27,7 @@ struct cpu_features __cpu_features attribute_hidden; static void -get_common_indeces (void) +get_common_indeces (unsigned int *family, unsigned int *model) { __cpuid (1, __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax, __cpu_features.cpuid[COMMON_CPUID_INDEX_1].ebx, @@ -34,8 +35,8 @@ get_common_indeces (void) __cpu_features.cpuid[COMMON_CPUID_INDEX_1].edx); unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax; - __cpu_features.family = (eax >> 8) & 0x0f; - __cpu_features.model = (eax >> 4) & 0x0f; + *family = (eax >> 8) & 0x0f; + *model = (eax >> 4) & 0x0f; } @@ -45,27 +46,30 @@ __init_cpu_features (void) unsigned int ebx; unsigned int ecx; unsigned int edx; + unsigned int family = 0; + unsigned int model = 0; + enum cpu_features_kind kind; __cpuid (0, __cpu_features.max_cpuid, ebx, ecx, edx); /* This spells out "GenuineIntel". */ if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69) { - __cpu_features.kind = arch_kind_intel; + kind = arch_kind_intel; - get_common_indeces (); + get_common_indeces (&family, &model); unsigned int eax = __cpu_features.cpuid[COMMON_CPUID_INDEX_1].eax; unsigned int extended_family = (eax >> 20) & 0xff; unsigned int extended_model = (eax >> 12) & 0xf0; if (__cpu_features.family == 0x0f) { - __cpu_features.family += extended_family; - __cpu_features.model += extended_model; + family += extended_family; + model += extended_model; } else if (__cpu_features.family == 0x06) { - __cpu_features.model += extended_model; + model += extended_model; switch (__cpu_features.model) { case 0x1a: @@ -85,12 +89,17 @@ __init_cpu_features (void) /* This spells out "AuthenticAMD". */ else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65) { - __cpu_features.kind = arch_kind_amd; + kind = arch_kind_amd; - get_common_indeces (); + get_common_indeces (&family, &model); } else - __cpu_features.kind = arch_kind_other; + kind = arch_kind_other; + + __cpu_features.family = family; + __cpu_features.model = model; + atomic_write_barrier (); + __cpu_features.kind = kind; } #undef __get_cpu_features diff --git a/sysdeps/x86_64/multiarch/init-arch.h b/sysdeps/x86_64/multiarch/init-arch.h index 69492cb3bf..5c73813404 100644 --- a/sysdeps/x86_64/multiarch/init-arch.h +++ b/sysdeps/x86_64/multiarch/init-arch.h @@ -1,5 +1,5 @@ /* This file is part of the GNU C Library. - Copyright (C) 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -52,7 +52,7 @@ enum extern struct cpu_features { - enum + enum cpu_features_kind { arch_kind_unknown = 0, arch_kind_intel, diff --git a/sysdeps/x86_64/multiarch/strpbrk-c.c b/sysdeps/x86_64/multiarch/strpbrk-c.c index c58dcb5605..bbf5c49d89 100644 --- a/sysdeps/x86_64/multiarch/strpbrk-c.c +++ b/sysdeps/x86_64/multiarch/strpbrk-c.c @@ -1,4 +1,8 @@ -#define USE_AS_STRPBRK -#define STRCSPN_SSE2 __strpbrk_sse2 -#define STRCSPN_SSE42 __strpbrk_sse42 -#include "strcspn-c.c" +/* Don't define multiple versions for strpbrk in static library since we + need strpbrk before the initialization happened. */ +#ifdef SHARED +# define USE_AS_STRPBRK +# define STRCSPN_SSE2 __strpbrk_sse2 +# define STRCSPN_SSE42 __strpbrk_sse42 +# include "strcspn-c.c" +#endif |