From drepper@redhat.com Tue Oct 1 00:31:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Tue, 01 Oct 2002 00:31:00 -0000 Subject: separately compiling libc modules for rtld References: <200210010645.g916jJ510346@magilla.sf.frob.com> Message-ID: <3D994F6A.8060709@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Roland McGrath wrote: > But it is some untested new subtlety, so if 2.3 is very imminent > I don't know if this should wait for 2.3.1. I'd rather prefer to wait for 2.3.1. This looks like a patch which can have many hidden possibilites to break something. I know that Hurd has problems. But exported symbols temporarily should be able to fix that, right? And it also doesn't introduce any permanent ABI damage. So I'd rather go this way unless you prefer to not change the code and declare 2.3.1 as the first release usable for Hurd. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9mU9q2ijCOnn/RHQRAupgAJ9BdeHtvdC3mCPI6Xcp49cEkrVMdACfSo23 g4xVDujA+Qv09trt2QdAaEc= =46PA -----END PGP SIGNATURE----- From roland@frob.com Tue Oct 1 01:25:00 2002 From: roland@frob.com (Roland McGrath) Date: Tue, 01 Oct 2002 01:25:00 -0000 Subject: separately compiling libc modules for rtld In-Reply-To: Ulrich Drepper's message of Tuesday, 1 October 2002 00:31:54 -0700 <3D994F6A.8060709@redhat.com> Message-ID: <200210010825.g918P6E10682@magilla.sf.frob.com> > I'd rather prefer to wait for 2.3.1. This looks like a patch which can > have many hidden possibilites to break something. Indeed so. > I know that Hurd has problems. But exported symbols temporarily should > be able to fix that, right? And it also doesn't introduce any permanent > ABI damage. So I'd rather go this way unless you prefer to not change > the code and declare 2.3.1 as the first release usable for Hurd. That would be ok with me, but it might be hard for the Debian/Hurd guys. There is never any question of ABI breakage that I know of, just that it works or it doesn't or it has too many PLT entries and is less optimal. It seems to me the simplest thing for now would be to make it easy to just disable all the hidden_proto stuff entirely and have Hurd do that. I'll add something. From jakub@redhat.com Tue Oct 1 01:26:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 01 Oct 2002 01:26:00 -0000 Subject: separately compiling libc modules for rtld In-Reply-To: <200210010825.g918P6E10682@magilla.sf.frob.com>; from roland@frob.com on Tue, Oct 01, 2002 at 01:25:06AM -0700 References: <3D994F6A.8060709@redhat.com> <200210010825.g918P6E10682@magilla.sf.frob.com> Message-ID: <20021001102645.Y3451@sunsite.ms.mff.cuni.cz> On Tue, Oct 01, 2002 at 01:25:06AM -0700, Roland McGrath wrote: > > I know that Hurd has problems. But exported symbols temporarily should > > be able to fix that, right? And it also doesn't introduce any permanent > > ABI damage. So I'd rather go this way unless you prefer to not change > > the code and declare 2.3.1 as the first release usable for Hurd. > > That would be ok with me, but it might be hard for the Debian/Hurd guys. > > There is never any question of ABI breakage that I know of, just that it > works or it doesn't or it has too many PLT entries and is less optimal. > It seems to me the simplest thing for now would be to make it easy to just > disable all the hidden_proto stuff entirely and have Hurd do that. > I'll add something. Yeah, I think a simple libc-symbols.h change is best for 2.3. Jakub From jakub@redhat.com Tue Oct 1 05:09:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 01 Oct 2002 05:09:00 -0000 Subject: [PATCH] {,MIN}SIGSTKSZ on IA-64 and SPARC* Message-ID: <20021001140844.D3451@sunsite.ms.mff.cuni.cz> Hi! asm-ia64/signal.h uses 128K/256K and asm-sparc*/signal.h use 4K/16K instead of 2K/8K defined by glibc. 2002-10-01 Jakub Jelinek * sysdeps/unix/sysv/linux/ia64/bits/sigstack.h (MINSIGSTKSZ, SIGSTKSZ): Changed to match kernel. * sysdeps/unix/sysv/linux/sparc/bits/sigstack.h: New file. --- libc/sysdeps/unix/sysv/linux/ia64/bits/sigstack.h.jj 2001-08-23 18:51:06.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/ia64/bits/sigstack.h 2002-10-01 14:07:57.000000000 +0200 @@ -1,5 +1,5 @@ /* sigstack, sigaltstack definitions. - Copyright (C) 1998, 2000 Free Software Foundation, Inc. + Copyright (C) 1998, 2000, 2002 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 @@ -42,10 +42,10 @@ enum }; /* Minimum stack size for a signal handler. */ -#define MINSIGSTKSZ 2048 +#define MINSIGSTKSZ 131027 /* System default stack size. */ -#define SIGSTKSZ 8192 +#define SIGSTKSZ 262144 /* Alternate, preferred interface. */ --- libc/sysdeps/unix/sysv/linux/sparc/bits/sigstack.h.jj 2002-10-01 14:08:20.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/sparc/bits/sigstack.h 2002-10-01 14:09:07.000000000 +0200 @@ -0,0 +1,55 @@ +/* sigstack, sigaltstack definitions. + Copyright (C) 1998, 1999, 2002 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 _SIGNAL_H +# error "Never include this file directly. Use instead" +#endif + + +/* Structure describing a signal stack (obsolete). */ +struct sigstack + { + void *ss_sp; /* Signal stack pointer. */ + int ss_onstack; /* Nonzero if executing on this stack. */ + }; + + +/* Possible values for `ss_flags.'. */ +enum +{ + SS_ONSTACK = 1, +#define SS_ONSTACK SS_ONSTACK + SS_DISABLE +#define SS_DISABLE SS_DISABLE +}; + +/* Minimum stack size for a signal handler. */ +#define MINSIGSTKSZ 4096 + +/* System default stack size. */ +#define SIGSTKSZ 16384 + + +/* Alternate, preferred interface. */ +typedef struct sigaltstack + { + void *ss_sp; + int ss_flags; + size_t ss_size; + } stack_t; Jakub From pb@nexus.co.uk Tue Oct 1 09:59:00 2002 From: pb@nexus.co.uk (Philip Blundell) Date: Tue, 01 Oct 2002 09:59:00 -0000 Subject: [Fwd: Memory violation in init on ARM Linux. in glibc mainline...] In-Reply-To: <1033488496.3501.2.camel@pauli> References: <3D98848F.6000308@redhat.com> <1033421269.30796.3.camel@kc> <1033488496.3501.2.camel@pauli> Message-ID: <1033491568.5568.35.camel@mill> On Tue, 2002-10-01 at 17:08, Scott Bambrough wrote: > The BFD patches would be be a great help. BTW, is there a version of > binutils that is known to work? Okay, I'll dig them out later this evening. I don't know of any version of binutils that handles this stuff correctly, though you may be able to get a working build by using an older version that doesn't even attempt to support combreloc. (Or, perhaps easier, by hacking the glibc configure script to not use it.) I think I was also running into another bug that was causing the program headers to get damaged somehow. This seemed unrelated to the first problem, though I don't remember the details offhand. Either or both of these issues might be fixed already in the trunk; I think Daniel Jacobowitz had some patches for the ARM backend a couple of weeks ago. If I get time over the next few days I will try to find out what the current status is. p. From roland@redhat.com Tue Oct 1 12:29:00 2002 From: roland@redhat.com (Roland McGrath) Date: Tue, 01 Oct 2002 12:29:00 -0000 Subject: [Fwd: Memory violation in init on ARM Linux. in glibc mainline...] In-Reply-To: Philip Blundell's message of , 1 October 2002 17:59:28 +0100 <1033491568.5568.35.camel@mill> Message-ID: <200210011928.g91JSxA23328@magilla.sf.frob.com> I don't have the full context of the problem off hand. But if it's possible to write a configure check to notice the broken -z combreloc behavior, we can put that in libc. From drepper@redhat.com Tue Oct 1 13:11:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Tue, 01 Oct 2002 13:11:00 -0000 Subject: [PATCH] {,MIN}SIGSTKSZ on IA-64 and SPARC* References: <20021001140844.D3451@sunsite.ms.mff.cuni.cz> Message-ID: <3D9A019D.2080306@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jakub Jelinek wrote: > asm-ia64/signal.h uses 128K/256K and asm-sparc*/signal.h use > 4K/16K instead of 2K/8K defined by glibc. OK, thanks, I've applied the patch. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9mgGd2ijCOnn/RHQRAh5IAKC1IvDaP3lSNk1/4U/YgxndL2/zXQCfQfNy Tm0oJANAe35r3HQAdYXa9eo= =aKUC -----END PGP SIGNATURE----- From kkojima@rr.iij4u.or.jp Tue Oct 1 22:13:00 2002 From: kkojima@rr.iij4u.or.jp (kaz Kojima) Date: Tue, 01 Oct 2002 22:13:00 -0000 Subject: Some SH patches Message-ID: <200210020513.g925D6O12889@r-rr.iij4u.or.jp> Hi! I've finally sent a SH TLS patch for binutils to the binutils mailing list. Now it assumes fixed TLS instruction sequences according to Uli's suggestion. By this, 3 TLS relocations used as markers can be removed and I moved the ELF relocation numbers of TLS relocations to the area which isn't used by any non-GNU linkers as I know. The SH TLS instruction patterns in elf/tls-macros.h is updated for the new fixed sequences. A TLS relocation handling in dl-machine.h is corrected like as i386 case. This patch includes a few tiny changes not for TLS also. I think they are almost obvious except a patch which moves __fpscr_values from crti.o to crt1.o. This will reduce the size of normal shared libraries 8 bytes :-) BTW, I'm preparing a compiler part of TLS for SH. It's not yet finished, but I have an experimental gcc patch and an updated memo . Regards, kaz -- 2002-10-02 Kaz Kojima * elf/elf.h: Change TLS ELF relocation numbers. * elf/tls-macros.h: Fix code sequences for SH TLS_LD and TLS_GD macros. * linuxthreads/sysdeps/sh/pt-machine.h: Make C code ifndef'ed with __ASSEMBLER__. * linuxthreads/sysdeps/sh/tls.h: Likewise. * linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h: New file. * sysdeps/sh/dl-machine.h (dl_machine_rela) [case R_SH_TLS_TPOFF32]: Use addend. * sysdeps/sh/elf/initfini.c: Move __fpscr_values to... * sysdeps/sh/elf/start.S: ...here. diff -urN ORIG/libc/elf/elf.h LOCAL/libc/elf/elf.h --- ORIG/libc/elf/elf.h Wed Oct 2 07:47:44 2002 +++ LOCAL/libc/elf/elf.h Wed Oct 2 08:07:07 2002 @@ -2201,21 +2201,19 @@ #define R_SH_SWITCH8 33 #define R_SH_GNU_VTINHERIT 34 #define R_SH_GNU_VTENTRY 35 -#define R_SH_TLS_GD_32 128 -#define R_SH_TLS_LD_32 129 -#define R_SH_TLS_LDO_32 130 -#define R_SH_TLS_IE_32 131 -#define R_SH_TLS_LE_32 132 -#define R_SH_TLS_DTPMOD32 133 -#define R_SH_TLS_DTPOFF32 134 -#define R_SH_TLS_TPOFF32 135 -#define R_SH_TLS_GD_MOV 136 -#define R_SH_TLS_GD_CALLMOV 137 -#define R_SH_TLS_LDM_MOV 138 -#define R_SH_TLS_LDO_MOV 139 -#define R_SH_TLS_LD_CALLMOV 140 -#define R_SH_TLS_IE_MOV 141 -#define R_SH_TLS_LE_MOV 142 +#define R_SH_TLS_GD_32 144 +#define R_SH_TLS_LD_32 145 +#define R_SH_TLS_LDO_32 146 +#define R_SH_TLS_IE_32 147 +#define R_SH_TLS_LE_32 148 +#define R_SH_TLS_DTPMOD32 149 +#define R_SH_TLS_DTPOFF32 150 +#define R_SH_TLS_TPOFF32 151 +#define R_SH_TLS_GD_MOV 152 +#define R_SH_TLS_LDM_MOV 153 +#define R_SH_TLS_LDO_MOV 154 +#define R_SH_TLS_IE_MOV 155 +#define R_SH_TLS_LE_MOV 156 #define R_SH_GOT32 160 #define R_SH_PLT32 161 #define R_SH_COPY 162 diff -urN ORIG/libc/elf/tls-macros.h LOCAL/libc/elf/tls-macros.h --- ORIG/libc/elf/tls-macros.h Wed Oct 2 07:47:44 2002 +++ LOCAL/libc/elf/tls-macros.h Wed Oct 2 08:07:07 2002 @@ -166,12 +166,11 @@ "mov.l 0f,r12\n\t" \ "add r0,r12\n\t" \ "mov.l 1f,r4\n\t" \ - "add r12,r4\n\t" \ "mova 2f,r0\n\t" \ "mov.l 2f,r1\n\t" \ "add r0,r1\n\t" \ "jsr @r1\n\t" \ - " nop\n\t" \ + " add r12,r4\n\t" \ "mov.l 3f,%0\n\t" \ "bra 4f\n\t" \ " add r0,%0\n\t" \ @@ -191,12 +190,11 @@ "mov.l 0f,r12\n\t" \ "add r0,r12\n\t" \ "mov.l 1f,r4\n\t" \ - "add r12,r4\n\t" \ "mova 2f,r0\n\t" \ "mov.l 2f,r1\n\t" \ "add r0,r1\n\t" \ "jsr @r1\n\t" \ - " nop\n\t" \ + " add r12,r4\n\t" \ "bra 3f\n\t" \ " mov r0,%0\n\t" \ ".align 2\n\t" \ diff -urN ORIG/libc/linuxthreads/sysdeps/sh/pt-machine.h LOCAL/libc/linuxthreads/sysdeps/sh/pt-machine.h --- ORIG/libc/linuxthreads/sysdeps/sh/pt-machine.h Tue Aug 27 07:07:48 2002 +++ LOCAL/libc/linuxthreads/sysdeps/sh/pt-machine.h Wed Oct 2 08:34:38 2002 @@ -22,6 +22,7 @@ #ifndef _PT_MACHINE_H #define _PT_MACHINE_H 1 +#ifndef __ASSEMBLER__ #ifndef PT_EI # define PT_EI extern inline #endif @@ -71,5 +72,6 @@ #define THREAD_GETMEM_NC(descr, member) THREAD_SELF->member #define THREAD_SETMEM(descr, member, value) THREAD_SELF->member = (value) #define THREAD_SETMEM_NC(descr, member, value) THREAD_SELF->member = (value) +#endif /* __ASSEMBLER__ */ #endif /* pt-machine.h */ diff -urN ORIG/libc/linuxthreads/sysdeps/sh/tls.h LOCAL/libc/linuxthreads/sysdeps/sh/tls.h --- ORIG/libc/linuxthreads/sysdeps/sh/tls.h Mon Aug 26 17:31:24 2002 +++ LOCAL/libc/linuxthreads/sysdeps/sh/tls.h Wed Oct 2 08:35:57 2002 @@ -20,6 +20,7 @@ #ifndef _TLS_H #define _TLS_H +#ifndef __ASSEMBLER__ #include #include @@ -109,5 +110,6 @@ THREAD_GETMEM (__descr, p_header.data.dtvp); }) #endif /* FLOATING_STACKS && HAVE_TLS_SUPPORT */ +#endif /* __ASSEMBLER__ */ #endif /* tls.h */ diff -urN ORIG/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h LOCAL/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h --- ORIG/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h Thu Jan 1 09:00:00 1970 +++ LOCAL/libc/linuxthreads/sysdeps/unix/sysv/linux/sh/smp.h Wed Oct 2 08:07:07 2002 @@ -0,0 +1,24 @@ +/* Determine whether the host has multiple processors. SH version. + Copyright (C) 2002 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library 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. */ + +static inline int +is_smp_system (void) +{ + return 0; +} diff -urN ORIG/libc/sysdeps/sh/dl-machine.h LOCAL/libc/sysdeps/sh/dl-machine.h --- ORIG/libc/sysdeps/sh/dl-machine.h Mon Aug 26 17:32:51 2002 +++ LOCAL/libc/sysdeps/sh/dl-machine.h Wed Oct 2 08:07:07 2002 @@ -573,14 +573,15 @@ case R_SH_TLS_TPOFF32: /* The offset is positive, afterward from the thread pointer. */ # ifdef RTLD_BOOTSTRAP - *reloc_addr = map->l_tls_offset + sym->st_value; + *reloc_addr = map->l_tls_offset + sym->st_value + reloc->r_addend; # else /* We know the offset of object the symbol is contained in. It is a positive value which will be added to the thread pointer. To get the variable position in the TLS block we add the offset from that of the TLS block. */ - if (sym_map != NULL && sym != NULL) - *reloc_addr = sym_map->l_tls_offset + sym->st_value; + *reloc_addr + = ((sym == NULL ? 0 : sym_map->l_tls_offset + sym->st_value) + + reloc->r_addend); # endif break; #endif /* use TLS */ diff -urN ORIG/libc/sysdeps/sh/elf/initfini.c LOCAL/libc/sysdeps/sh/elf/initfini.c --- ORIG/libc/sysdeps/sh/elf/initfini.c Fri Jul 6 13:56:03 2001 +++ LOCAL/libc/sysdeps/sh/elf/initfini.c Wed Oct 2 08:07:07 2002 @@ -71,12 +71,6 @@ .L23: .long __gmon_start__ #endif - .data - .global __fpscr_values -__fpscr_values: - .long 0 - .long 0x80000 - .previous 1: ALIGN END_INIT diff -urN ORIG/libc/sysdeps/sh/elf/start.S LOCAL/libc/sysdeps/sh/elf/start.S --- ORIG/libc/sysdeps/sh/elf/start.S Fri Jul 6 13:56:03 2001 +++ LOCAL/libc/sysdeps/sh/elf/start.S Wed Oct 2 08:07:07 2002 @@ -89,3 +89,7 @@ .long 0 .weak data_start data_start = __data_start + .global __fpscr_values +__fpscr_values: + .long 0 + .long 0x80000 From drepper@redhat.com Tue Oct 1 23:23:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Tue, 01 Oct 2002 23:23:00 -0000 Subject: Some SH patches References: <200210020513.g925D6O12889@r-rr.iij4u.or.jp> Message-ID: <3D9A90E5.20606@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 kaz Kojima wrote: > I've finally sent a SH TLS patch for binutils to the binutils > mailing list. Now it assumes fixed TLS instruction sequences > according to Uli's suggestion. Thanks, I've applied the patch. Can you send me at some point an updated version of the TLS description? - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9mpDp2ijCOnn/RHQRAgZRAKCjAzCzr4QEA2NeOj3eeKey/RCJ0ACaAhtY +4wuJI6lsuLIw5iQvgJngFM= =0V6J -----END PGP SIGNATURE----- From kkojima@rr.iij4u.or.jp Tue Oct 1 23:54:00 2002 From: kkojima@rr.iij4u.or.jp (kaz Kojima) Date: Tue, 01 Oct 2002 23:54:00 -0000 Subject: Some SH patches In-Reply-To: Your message of "Tue, 01 Oct 2002 23:23:33 -0700" <3D9A90E5.20606@redhat.com> References: <3D9A90E5.20606@redhat.com> Message-ID: <200210020654.g926sGO27079@r-rr.iij4u.or.jp> >> I've finally sent a SH TLS patch for binutils to the binutils >> mailing list. Now it assumes fixed TLS instruction sequences >> according to Uli's suggestion. > > Thanks, I've applied the patch. Thanks a lot. > Can you send me at some point an updated version of the TLS description? http://dodo.nurs.or.jp/~kkojima/gnu-on-sh/tls-sh-memo.txt is, though it's not so complete. Regards, kaz From jakub@redhat.com Wed Oct 2 03:06:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 02 Oct 2002 03:06:00 -0000 Subject: [PATCH] README.template tiny changes Message-ID: <20021002120554.G3451@sunsite.ms.mff.cuni.cz> Hi! I think we should mention x86-64 too (when we are mentioning powerpc64). Also, linux/configure says s390x minimal kernel version is 2.4. 2002-10-02 Jakub Jelinek * README.templace: Add x86-64-*-linux-gnu. s390x needs 2.4+ kernel. --- libc/README.template.jj 2002-10-02 11:58:57.000000000 +0200 +++ libc/README.template 2002-10-02 12:05:58.000000000 +0200 @@ -19,9 +19,10 @@ configurations: mips*-*-linux-gnu Linux-2.x on MIPS ia64-*-linux-gnu Linux-2.x on ia64 s390-*-linux-gnu Linux-2.x on IBM S/390 - s390x-*-linux-gnu Linux-2.x on IBM S/390 64-bit + s390x-*-linux-gnu Linux-2.4+ on IBM S/390 64-bit sh-*-linux-gnu Linux-2.x on Super Hitachi cris-*-linux-gnu Linux-2.4+ on CRIS + x86-64-*-linux-gnu Linux-2.4+ on x86-64 Former releases of this library (version 1.09.1 and perhaps earlier versions) used to run on the following configurations: Jakub From drepper@redhat.com Wed Oct 2 14:17:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Wed, 02 Oct 2002 14:17:00 -0000 Subject: [PATCH] README.template tiny changes References: <20021002120554.G3451@sunsite.ms.mff.cuni.cz> Message-ID: <3D9B626E.6090907@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jakub Jelinek wrote: > I think we should mention x86-64 too (when we are mentioning powerpc64). > Also, linux/configure says s390x minimal kernel version is 2.4. Applied. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9m2Ju2ijCOnn/RHQRAvSuAJ4whhF4rdyMHEqD4KDj0hGqMrEOUgCfQnUh fxFIl7b/vIqAGLDjZTZnTB8= =n34/ -----END PGP SIGNATURE----- From drepper@redhat.com Wed Oct 2 16:14:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Wed, 02 Oct 2002 16:14:00 -0000 Subject: no more checkins Message-ID: <3D9B7DD3.9060907@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Until further notice please don't check in anything into the CVS archive without my OK. Thanks, - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9m33T2ijCOnn/RHQRAglNAJ0TKzTlkKfs9cl9vYEzyRWvjcUgRgCgp/HT emK2XGpt8zpjjdDtLpu0Sqw= =g8Ab -----END PGP SIGNATURE----- From davidm@napali.hpl.hp.com Wed Oct 2 23:05:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Wed, 02 Oct 2002 23:05:00 -0000 Subject: Itanium 2 tuned versions of bzero, memset, and memcpy Message-ID: <200210030605.g9365UUC020000@napali.hpl.hp.com> It appears that the Itanium 2 optimized versions of these routines never were checked in (unless I'm missing something). I cleaned them up some more and if they look OK, I'd appreciate it if someone could check them in. I did run "make check" successfully and the routines have been in use as part of the Debian glibc package for some time. There is also an optimized memcmp() routine but it needs some more debugging/testing before it's ready for prime-time. --david 2002-10-02 David Mosberger * sysdeps/ia64/bzero.S: Rewritten by Sverre Jarp to tune for Itanium 2 (and Itanium). Fix unwind directives and make it fit in 80 columns. * sysdeps/ia64/memset.S: Ditto. * sysdeps/ia64/memcpy.S: Ditto. Move jump table to .rodata section. Index: sysdeps/ia64/bzero.S =================================================================== RCS file: /cvs/glibc/libc/sysdeps/ia64/bzero.S,v retrieving revision 1.3 diff -u -r1.3 bzero.S --- sysdeps/ia64/sysdeps/ia64/bzero.S 25 Aug 2002 05:25:12 -0000 1.3 +++ sysdeps/ia64/sysdeps/ia64/bzero.S 3 Oct 2002 06:00:19 -0000 @@ -1,7 +1,8 @@ /* Optimized version of the standard bzero() function. This file is part of the GNU C Library. Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. - Contributed by Dan Pop . + Contributed by Dan Pop for Itanium . + Rewritten for McKinley by Sverre Jarp, HP Labs/CERN The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -25,8 +26,11 @@ in1: count The algorithm is fairly straightforward: set byte by byte until we - we get to a word aligned address, then set word by word as much as - possible; the remaining few bytes are set one by one. */ + we get to a 16B-aligned address, then loop on 128 B chunks using an + early store as prefetching, then loop on 32B chucks, then clear remaining + words, finally clear remaining bytes. + Since a stf.spill f0 can store 16B in one go, we use this instruction + to get peak speed. */ #include #undef ret @@ -34,62 +38,278 @@ #define dest in0 #define cnt in1 -#define save_pfs loc0 -#define ptr1 loc1 -#define ptr2 loc2 -#define tmp loc3 -#define loopcnt loc4 -#define save_lc loc5 +#define tmp r31 +#define save_lc r30 +#define ptr0 r29 +#define ptr1 r28 +#define ptr2 r27 +#define ptr3 r26 +#define ptr9 r24 +#define loopcnt r23 +#define linecnt r22 +#define bytecnt r21 -ENTRY(__bzero) +// This routine uses only scratch predicate registers (p6 - p15) +#define p_scr p6 // default register for same-cycle branches +#define p_unalgn p9 +#define p_y p11 +#define p_n p12 +#define p_yy p13 +#define p_nn p14 + +#define movi0 mov + +#define MIN1 15 +#define MIN1P1HALF 8 +#define LINE_SIZE 128 +#define LSIZE_SH 7 // shift amount +#define PREF_AHEAD 8 + +#define USE_FLP +#if defined(USE_INT) +#define store st8 +#define myval r0 +#elif defined(USE_FLP) +#define store stf8 +#define myval f0 +#endif + +.align 64 +ENTRY(bzero) +{ .mmi .prologue - alloc save_pfs = ar.pfs, 2, 6, 0, 0 - .save ar.lc, save_lc - mov save_lc = ar.lc + alloc tmp = ar.pfs, 2, 0, 0, 0 + lfetch.nt1 [dest] + .save ar.lc, save_lc + movi0 save_lc = ar.lc +} { .mmi .body - mov ret0 = dest - and tmp = 7, dest - cmp.eq p6, p0 = cnt, r0 -(p6) br.cond.spnt .restore_and_exit ;; + mov ret0 = dest // return value + nop.m 0 + cmp.eq p_scr, p0 = cnt, r0 +;; } +{ .mmi + and ptr2 = -(MIN1+1), dest // aligned address + and tmp = MIN1, dest // prepare to check for alignment + tbit.nz p_y, p_n = dest, 0 // Do we have an odd address? (M_B_U) +} { .mib mov ptr1 = dest - sub loopcnt = 8, tmp - cmp.gt p6, p0 = 16, cnt -(p6) br.cond.spnt .set_few;; - cmp.eq p6, p0 = tmp, r0 -(p6) br.cond.sptk .dest_aligned - sub cnt = cnt, loopcnt - adds loopcnt = -1, loopcnt;; - mov ar.lc = loopcnt;; -.l1: - st1 [ptr1] = r0, 1 - br.cloop.dptk .l1 ;; -.dest_aligned: - adds ptr2 = 8, ptr1 - shr.u loopcnt = cnt, 4 ;; // loopcnt = cnt / 16 - cmp.eq p6, p0 = loopcnt, r0 -(p6) br.cond.spnt .one_more - and cnt = 0xf, cnt // compute the remaining cnt - adds loopcnt = -1, loopcnt;; - mov ar.lc = loopcnt;; -.l2: - st8 [ptr1] = r0, 16 - st8 [ptr2] = r0, 16 - br.cloop.dptk .l2 - cmp.le p6, p0 = 8, cnt ;; -.one_more: -(p6) st8 [ptr1] = r0, 8 -(p6) adds cnt = -8, cnt ;; - cmp.eq p6, p0 = cnt, r0 -(p6) br.cond.spnt .restore_and_exit -.set_few: - adds loopcnt = -1, cnt;; - mov ar.lc = loopcnt;; -.l3: - st1 [ptr1] = r0, 1 - br.cloop.dptk .l3 ;; + nop.i 0 +(p_scr) br.ret.dpnt.many rp // return immediately if count = 0 +;; } +{ .mib + cmp.ne p_unalgn, p0 = tmp, r0 +} { .mib // NB: # of bytes to move is 1 + sub bytecnt = (MIN1+1), tmp // higher than loopcnt + cmp.gt p_scr, p0 = 16, cnt // is it a minimalistic task? +(p_scr) br.cond.dptk.many .move_bytes_unaligned // go move just a few (M_B_U) +;; } +{ .mmi +(p_unalgn) add ptr1 = (MIN1+1), ptr2 // after alignment +(p_unalgn) add ptr2 = MIN1P1HALF, ptr2 // after alignment +(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 3 // should we do a st8 ? +;; } +{ .mib +(p_y) add cnt = -8, cnt +(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 2 // should we do a st4 ? +} { .mib +(p_y) st8 [ptr2] = r0,-4 +(p_n) add ptr2 = 4, ptr2 +;; } +{ .mib +(p_yy) add cnt = -4, cnt +(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 1 // should we do a st2 ? +} { .mib +(p_yy) st4 [ptr2] = r0,-2 +(p_nn) add ptr2 = 2, ptr2 +;; } +{ .mmi + mov tmp = LINE_SIZE+1 // for compare +(p_y) add cnt = -2, cnt +(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 0 // should we do a st1 ? +} { .mmi + nop.m 0 +(p_y) st2 [ptr2] = r0,-1 +(p_n) add ptr2 = 1, ptr2 +;; } + +{ .mmi +(p_yy) st1 [ptr2] = r0 + cmp.gt p_scr, p0 = tmp, cnt // is it a minimalistic task? +} { .mbb +(p_yy) add cnt = -1, cnt +(p_scr) br.cond.dpnt.many .fraction_of_line // go move just a few +;; } +{ .mib + nop.m 0 + shr.u linecnt = cnt, LSIZE_SH + nop.b 0 +;; } + + .align 32 +.l1b: // ------------------// L1B: store ahead into cache lines; fill later +{ .mmi + and tmp = -(LINE_SIZE), cnt // compute end of range + mov ptr9 = ptr1 // used for prefetching + and cnt = (LINE_SIZE-1), cnt // remainder +} { .mmi + mov loopcnt = PREF_AHEAD-1 // default prefetch loop + cmp.gt p_scr, p0 = PREF_AHEAD, linecnt // check against actual value +;; } +{ .mmi +(p_scr) add loopcnt = -1, linecnt + add ptr2 = 16, ptr1 // start of stores (beyond prefetch stores) + add ptr1 = tmp, ptr1 // first address beyond total range +;; } +{ .mmi + add tmp = -1, linecnt // next loop count + movi0 ar.lc = loopcnt +;; } +.pref_l1b: +{ .mib + stf.spill [ptr9] = f0, 128 // Do stores one cache line apart + nop.i 0 + br.cloop.dptk.few .pref_l1b +;; } +{ .mmi + add ptr0 = 16, ptr2 // Two stores in parallel + movi0 ar.lc = tmp +;; } +.l1bx: + { .mmi + stf.spill [ptr2] = f0, 32 + stf.spill [ptr0] = f0, 32 + ;; } + { .mmi + stf.spill [ptr2] = f0, 32 + stf.spill [ptr0] = f0, 32 + ;; } + { .mmi + stf.spill [ptr2] = f0, 32 + stf.spill [ptr0] = f0, 64 + cmp.lt p_scr, p0 = ptr9, ptr1 // do we need more prefetching? + ;; } +{ .mmb + stf.spill [ptr2] = f0, 32 +(p_scr) stf.spill [ptr9] = f0, 128 + br.cloop.dptk.few .l1bx +;; } +{ .mib + cmp.gt p_scr, p0 = 8, cnt // just a few bytes left ? +(p_scr) br.cond.dpnt.many .move_bytes_from_alignment +;; } + +.fraction_of_line: +{ .mib + add ptr2 = 16, ptr1 + shr.u loopcnt = cnt, 5 // loopcnt = cnt / 32 +;; } +{ .mib + cmp.eq p_scr, p0 = loopcnt, r0 + add loopcnt = -1, loopcnt +(p_scr) br.cond.dpnt.many .store_words +;; } +{ .mib + and cnt = 0x1f, cnt // compute the remaining cnt + movi0 ar.lc = loopcnt +;; } + .align 32 +.l2: // -----------------------------// L2A: store 32B in 2 cycles +{ .mmb + store [ptr1] = myval, 8 + store [ptr2] = myval, 8 +;; } { .mmb + store [ptr1] = myval, 24 + store [ptr2] = myval, 24 + br.cloop.dptk.many .l2 +;; } +.store_words: +{ .mib + cmp.gt p_scr, p0 = 8, cnt // just a few bytes left ? +(p_scr) br.cond.dpnt.many .move_bytes_from_alignment // Branch +;; } + +{ .mmi + store [ptr1] = myval, 8 // store + cmp.le p_y, p_n = 16, cnt // + add cnt = -8, cnt // subtract +;; } +{ .mmi +(p_y) store [ptr1] = myval, 8 // store +(p_y) cmp.le.unc p_yy, p_nn = 16, cnt +(p_y) add cnt = -8, cnt // subtract +;; } +{ .mmi // store +(p_yy) store [ptr1] = myval, 8 +(p_yy) add cnt = -8, cnt // subtract +;; } + +.move_bytes_from_alignment: +{ .mib + cmp.eq p_scr, p0 = cnt, r0 + tbit.nz.unc p_y, p0 = cnt, 2 // should we terminate with a st4 ? +(p_scr) br.cond.dpnt.few .restore_and_exit +;; } +{ .mib +(p_y) st4 [ptr1] = r0,4 + tbit.nz.unc p_yy, p0 = cnt, 1 // should we terminate with a st2 ? +;; } +{ .mib +(p_yy) st2 [ptr1] = r0,2 + tbit.nz.unc p_y, p0 = cnt, 0 // should we terminate with a st1 ? +;; } + +{ .mib +(p_y) st1 [ptr1] = r0 +;; } .restore_and_exit: - mov ar.lc = save_lc - mov ar.pfs = save_pfs - br.ret.sptk.many b0 -END(__bzero) -weak_alias (__bzero, bzero) +{ .mib + nop.m 0 + movi0 ar.lc = save_lc + br.ret.sptk.many rp +;; } + +.move_bytes_unaligned: +{ .mmi + .pred.rel "mutex",p_y, p_n + .pred.rel "mutex",p_yy, p_nn +(p_n) cmp.le p_yy, p_nn = 4, cnt +(p_y) cmp.le p_yy, p_nn = 5, cnt +(p_n) add ptr2 = 2, ptr1 +} { .mmi +(p_y) add ptr2 = 3, ptr1 +(p_y) st1 [ptr1] = r0, 1 // fill 1 (odd-aligned) byte +(p_y) add cnt = -1, cnt // [15, 14 (or less) left] +;; } +{ .mmi +(p_yy) cmp.le.unc p_y, p0 = 8, cnt + add ptr3 = ptr1, cnt // prepare last store + movi0 ar.lc = save_lc +} { .mmi +(p_yy) st2 [ptr1] = r0, 4 // fill 2 (aligned) bytes +(p_yy) st2 [ptr2] = r0, 4 // fill 2 (aligned) bytes +(p_yy) add cnt = -4, cnt // [11, 10 (o less) left] +;; } +{ .mmi +(p_y) cmp.le.unc p_yy, p0 = 8, cnt + add ptr3 = -1, ptr3 // last store + tbit.nz p_scr, p0 = cnt, 1 // will there be a st2 at the end ? +} { .mmi +(p_y) st2 [ptr1] = r0, 4 // fill 2 (aligned) bytes +(p_y) st2 [ptr2] = r0, 4 // fill 2 (aligned) bytes +(p_y) add cnt = -4, cnt // [7, 6 (or less) left] +;; } +{ .mmi +(p_yy) st2 [ptr1] = r0, 4 // fill 2 (aligned) bytes +(p_yy) st2 [ptr2] = r0, 4 // fill 2 (aligned) bytes + // [3, 2 (or less) left] + tbit.nz p_y, p0 = cnt, 0 // will there be a st1 at the end ? +} { .mmi +(p_yy) add cnt = -4, cnt +;; } +{ .mmb +(p_scr) st2 [ptr1] = r0 // fill 2 (aligned) bytes +(p_y) st1 [ptr3] = r0 // fill last byte (using ptr3) + br.ret.sptk.many rp +;; } +END(bzero) Index: sysdeps/ia64/memcpy.S =================================================================== RCS file: /cvs/glibc/libc/sysdeps/ia64/memcpy.S,v retrieving revision 1.8 diff -u -r1.8 memcpy.S --- sysdeps/ia64/sysdeps/ia64/memcpy.S 6 Jul 2001 04:55:54 -0000 1.8 +++ sysdeps/ia64/sysdeps/ia64/memcpy.S 3 Oct 2002 06:00:19 -0000 @@ -1,7 +1,8 @@ /* Optimized version of the standard memcpy() function. This file is part of the GNU C Library. Copyright (C) 2000, 2001 Free Software Foundation, Inc. - Contributed by Dan Pop . + Contributed by Dan Pop for Itanium . + Rewritten for McKinley by Sverre Jarp, HP Labs/CERN The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -26,27 +27,39 @@ in2: byte count An assembly implementation of the algorithm used by the generic C - version from glibc. The case when all three arguments are multiples - of 8 is treated separatedly, for extra performance. + version from glibc. The case when source and sest are aligned is + treated separately, for extra performance. - In this form, it assumes little endian mode. For big endian mode, + In this form, memcpy assumes little endian mode. For big endian mode, sh1 must be computed using an extra instruction: sub sh1 = 64, sh1 and the order of r[MEMLAT] and r[MEMLAT+1] must be reverted in the shrp instruction. */ +#define USE_LFETCH +#define USE_FLP #include #undef ret +#define LFETCH_DIST 500 + +#define ALIGN_UNROLL_no 4 // no. of elements +#define ALIGN_UNROLL_sh 2 // (shift amount) + +#define MEMLAT 8 +#define Nrot ((4*(MEMLAT+2) + 7) & ~7) + #define OP_T_THRES 16 #define OPSIZ 8 -#define adest r15 -#define saved_pr r17 -#define saved_lc r18 +#define loopcnt r14 +#define elemcnt r15 +#define saved_pr r16 +#define saved_lc r17 +#define adest r18 #define dest r19 -#define src r20 -#define len r21 -#define asrc r22 +#define asrc r20 +#define src r21 +#define len r22 #define tmp2 r23 #define tmp3 r24 #define tmp4 r25 @@ -54,113 +67,339 @@ #define ploop56 r27 #define loopaddr r28 #define sh1 r29 -#define loopcnt r30 -#define value r31 +#define ptr1 r30 +#define ptr2 r31 -#define LOOP(shift) \ - .align 32 ; \ -.loop##shift##: \ -(p[0]) ld8 r[0] = [asrc], 8 ; /* w1 */ \ -(p[MEMLAT+1]) st8 [dest] = value, 8 ; \ -(p[MEMLAT]) shrp value = r[MEMLAT], r[MEMLAT+1], shift ; \ - nop.b 0 ; \ - nop.b 0 ; \ - br.ctop.sptk .loop##shift ; \ - br.cond.sptk .cpyfew ; /* deal with the remaining bytes */ +#define movi0 mov + +#define p_scr p6 +#define p_xtr p7 +#define p_nxtr p8 +#define p_few p9 + +#if defined(USE_FLP) +#define load ldf8 +#define store stf8 +#define tempreg f6 +#define the_r fr +#define the_s fs +#define the_t ft +#define the_q fq +#define the_w fw +#define the_x fx +#define the_y fy +#define the_z fz +#elif defined(USE_INT) +#define load ld8 +#define store st8 +#define tempreg tmp2 +#define the_r r +#define the_s s +#define the_t t +#define the_q q +#define the_w w +#define the_x x +#define the_y y +#define the_z z +#endif + + +#if defined(USE_LFETCH) +#define LOOP(shift) \ + .align 32 ; \ +.loop##shift##: \ +{ .mmb \ +(p[0]) ld8.nt1 r[0] = [asrc], 8 ; \ +(p[0]) lfetch.nt1 [ptr1], 16 ; \ + nop.b 0 ; \ +} { .mib \ +(p[MEMLAT+1]) st8 [dest] = tmp3, 8 ; \ +(p[MEMLAT]) shrp tmp3 = r[MEMLAT], s[MEMLAT+1], shift ; \ + nop.b 0 ;; \ + } { .mmb \ +(p[0]) ld8.nt1 s[0] = [asrc], 8 ; \ +(p[0]) lfetch.nt1 [ptr2], 16 ; \ + nop.b 0 ; \ +} { .mib \ +(p[MEMLAT+1]) st8 [dest] = tmp4, 8 ; \ +(p[MEMLAT]) shrp tmp4 = s[MEMLAT], r[MEMLAT], shift ; \ + br.ctop.sptk.many .loop##shift \ +;; } \ +{ .mib \ + br.cond.sptk.many .copy_bytes ; /* deal with the remaining bytes */ \ +} +#else +#define LOOP(shift) \ + .align 32 ; \ +.loop##shift##: \ +{ .mmb \ +(p[0]) ld8.nt1 r[0] = [asrc], 8 ; \ + nop.b 0 ; \ +} { .mib \ +(p[MEMLAT+1]) st8 [dest] = tmp3, 8 ; \ +(p[MEMLAT]) shrp tmp3 = r[MEMLAT], s[MEMLAT+1], shift ; \ + nop.b 0 ;; \ + } { .mmb \ +(p[0]) ld8.nt1 s[0] = [asrc], 8 ; \ + nop.b 0 ; \ +} { .mib \ +(p[MEMLAT+1]) st8 [dest] = tmp4, 8 ; \ +(p[MEMLAT]) shrp tmp4 = s[MEMLAT], r[MEMLAT], shift ; \ + br.ctop.sptk.many .loop##shift \ +;; } \ +{ .mib \ + br.cond.sptk.many .copy_bytes ; /* deal with the remaining bytes */ \ +} +#endif -#define MEMLAT 21 -#define Nrot (((2*MEMLAT+3) + 7) & ~7) ENTRY(memcpy) +{ .mmi .prologue alloc r2 = ar.pfs, 3, Nrot - 3, 0, Nrot - .rotr r[MEMLAT + 2], q[MEMLAT + 1] - .rotp p[MEMLAT + 2] - mov ret0 = in0 // return value = dest - .save pr, saved_pr - mov saved_pr = pr // save the predicate registers - .save ar.lc, saved_lc - mov saved_lc = ar.lc // save the loop counter - .body - or tmp3 = in0, in1 ;; // tmp3 = dest | src - or tmp3 = tmp3, in2 // tmp3 = dest | src | len + .rotr r[MEMLAT+1], s[MEMLAT+2], q[MEMLAT+1], t[MEMLAT+1] + .rotp p[MEMLAT+2] + .rotf fr[MEMLAT+1], fq[MEMLAT+1], fs[MEMLAT+1], ft[MEMLAT+1] + mov ret0 = in0 // return tmp2 = dest + .save pr, saved_pr + movi0 saved_pr = pr // save the predicate registers +} { .mmi + and tmp4 = 7, in0 // check if destination is aligned mov dest = in0 // dest mov src = in1 // src +;; } +{ .mii + cmp.eq p_scr, p0 = in2, r0 // if (len == 0) + .save ar.lc, saved_lc + movi0 saved_lc = ar.lc // save the loop counter + .body + cmp.ge p_few, p0 = OP_T_THRES, in2 // is len <= OP_T_THRESH +} { .mbb mov len = in2 // len - sub tmp2 = r0, in0 // tmp2 = -dest - cmp.eq p6, p0 = in2, r0 // if (len == 0) -(p6) br.cond.spnt .restore_and_exit;;// return dest; - and tmp4 = 7, tmp3 // tmp4 = (dest | src | len) & 7 - shr.u loopcnt = len, 4 ;; // loopcnt = len / 16 - cmp.ne p6, p0 = tmp4, r0 // if ((dest | src | len) & 7 != 0) -(p6) br.cond.sptk .next // goto next; - -// The optimal case, when dest, src and len are all multiples of 8 - - and tmp3 = 0xf, len // tmp3 = len % 16 - mov pr.rot = 1 << 16 // set rotating predicates - mov ar.ec = MEMLAT + 1 ;; // set the epilog counter - cmp.ne p6, p0 = tmp3, r0 // do we have to copy an extra word? - adds loopcnt = -1, loopcnt;; // --loopcnt -(p6) ld8 value = [src], 8;; -(p6) st8 [dest] = value, 8 // copy the "extra" word - mov ar.lc = loopcnt // set the loop counter - cmp.eq p6, p0 = 8, len -(p6) br.cond.spnt .restore_and_exit;;// there was only one word to copy - adds adest = 8, dest - adds asrc = 8, src ;; +(p_scr) br.cond.dpnt.few .restore_and_exit // Branch no. 1: return dest +(p_few) br.cond.dpnt.many .copy_bytes // Branch no. 2: copy byte by byte +;; } +{ .mmi +#if defined(USE_LFETCH) + lfetch.nt1 [dest] // + lfetch.nt1 [src] // +#endif + shr.u elemcnt = len, 3 // elemcnt = len / 8 +} { .mib + cmp.eq p_scr, p0 = tmp4, r0 // is destination aligned? + sub loopcnt = 7, tmp4 // +(p_scr) br.cond.dptk.many .dest_aligned +;; } +{ .mmi + ld1 tmp2 = [src], 1 // + sub len = len, loopcnt, 1 // reduce len + movi0 ar.lc = loopcnt // +} { .mib + cmp.ne p_scr, p0 = 0, loopcnt // avoid loading beyond end-point +;; } + +.l0: // ---------------------------- // L0: Align src on 8-byte boundary +{ .mmi + st1 [dest] = tmp2, 1 // +(p_scr) ld1 tmp2 = [src], 1 // +} { .mib + cmp.lt p_scr, p0 = 1, loopcnt // avoid load beyond end-point + add loopcnt = -1, loopcnt + br.cloop.dptk.few .l0 // +;; } + +.dest_aligned: +{ .mmi + and tmp4 = 7, src // ready for alignment check + shr.u elemcnt = len, 3 // elemcnt = len / 8 +;; } +{ .mib + cmp.ne p_scr, p0 = tmp4, r0 // is source also aligned + tbit.nz p_xtr, p_nxtr = src, 3 // prepare a separate move if src +} { .mib // is not 16B aligned + add ptr2 = LFETCH_DIST, dest // prefetch address + add ptr1 = LFETCH_DIST, src +(p_scr) br.cond.dptk.many .src_not_aligned +;; } + +// The optimal case, when dest, and src are aligned + +.both_aligned: +{ .mmi + .pred.rel "mutex",p_xtr,p_nxtr +(p_xtr) cmp.gt p_scr, p0 = ALIGN_UNROLL_no+1, elemcnt // Need N + 1 to qualify +(p_nxtr) cmp.gt p_scr, p0 = ALIGN_UNROLL_no, elemcnt // Need only N to qualify + movi0 pr.rot = 1 << 16 // set rotating predicates +} { .mib +(p_scr) br.cond.dpnt.many .copy_full_words +;; } + +{ .mmi +(p_xtr) load tempreg = [src], 8 +(p_xtr) add elemcnt = -1, elemcnt + movi0 ar.ec = MEMLAT + 1 // set the epilog counter +;; } +{ .mmi +(p_xtr) add len = -8, len // + add asrc = 16, src // one bank apart (for USE_INT) + shr.u loopcnt = elemcnt, ALIGN_UNROLL_sh // cater for unrolling +;;} +{ .mmi + add loopcnt = -1, loopcnt +(p_xtr) store [dest] = tempreg, 8 // copy the "extra" word + nop.i 0 +;; } +{ .mib + add adest = 16, dest + movi0 ar.lc = loopcnt // set the loop counter +;; } + .align 32 -.l0: -(p[0]) ld8 r[0] = [src], 16 -(p[0]) ld8 q[0] = [asrc], 16 -(p[MEMLAT]) st8 [dest] = r[MEMLAT], 16 -(p[MEMLAT]) st8 [adest] = q[MEMLAT], 16 - br.ctop.dptk .l0 ;; +#if defined(USE_FLP) +.l1: // ------------------------------- // L1: Everything a multiple of 8 +{ .mmi +#if defined(USE_LFETCH) +(p[0]) lfetch.nt1 [ptr2],32 +#endif +(p[0]) ldfp8 the_r[0],the_q[0] = [src], 16 +(p[0]) add len = -32, len +} {.mmb +(p[MEMLAT]) store [dest] = the_r[MEMLAT], 8 +(p[MEMLAT]) store [adest] = the_s[MEMLAT], 8 +;; } +{ .mmi +#if defined(USE_LFETCH) +(p[0]) lfetch.nt1 [ptr1],32 +#endif +(p[0]) ldfp8 the_s[0], the_t[0] = [src], 16 +} {.mmb +(p[MEMLAT]) store [dest] = the_q[MEMLAT], 24 +(p[MEMLAT]) store [adest] = the_t[MEMLAT], 24 + br.ctop.dptk.many .l1 +;; } +#elif defined(USE_INT) +.l1: // ------------------------------- // L1: Everything a multiple of 8 +{ .mmi +(p[0]) load the_r[0] = [src], 8 +(p[0]) load the_q[0] = [asrc], 8 +(p[0]) add len = -32, len +} {.mmb +(p[MEMLAT]) store [dest] = the_r[MEMLAT], 8 +(p[MEMLAT]) store [adest] = the_q[MEMLAT], 8 +;; } +{ .mmi +(p[0]) load the_s[0] = [src], 24 +(p[0]) load the_t[0] = [asrc], 24 +} {.mmb +(p[MEMLAT]) store [dest] = the_s[MEMLAT], 24 +(p[MEMLAT]) store [adest] = the_t[MEMLAT], 24 +#if defined(USE_LFETCH) +;; } +{ .mmb +(p[0]) lfetch.nt1 [ptr2],32 +(p[0]) lfetch.nt1 [ptr1],32 +#endif + br.ctop.dptk.many .l1 +;; } +#endif + +.copy_full_words: +{ .mib + cmp.gt p_scr, p0 = 8, len // + shr.u elemcnt = len, 3 // +(p_scr) br.cond.dpnt.many .copy_bytes +;; } +{ .mii + load tempreg = [src], 8 + add loopcnt = -1, elemcnt // +;; } +{ .mii + cmp.ne p_scr, p0 = 0, loopcnt // + mov ar.lc = loopcnt // +;; } + +.l2: // ------------------------------- // L2: Max 4 words copied separately +{ .mmi + store [dest] = tempreg, 8 +(p_scr) load tempreg = [src], 8 // + add len = -8, len +} { .mib + cmp.lt p_scr, p0 = 1, loopcnt // avoid load beyond end-point + add loopcnt = -1, loopcnt + br.cloop.dptk.few .l2 +;; } + +.copy_bytes: +{ .mib + cmp.eq p_scr, p0 = len, r0 // is len == 0 ? + add loopcnt = -1, len // len--; +(p_scr) br.cond.spnt .restore_and_exit +;; } +{ .mii + ld1 tmp2 = [src], 1 + movi0 ar.lc = loopcnt + cmp.ne p_scr, p0 = 0, loopcnt // avoid load beyond end-point +;; } + +.l3: // ------------------------------- // L3: Final byte move +{ .mmi + st1 [dest] = tmp2, 1 +(p_scr) ld1 tmp2 = [src], 1 +} { .mib + cmp.lt p_scr, p0 = 1, loopcnt // avoid load beyond end-point + add loopcnt = -1, loopcnt + br.cloop.dptk.few .l3 +;; } - mov pr = saved_pr, -1 // restore the predicate registers - mov ar.lc = saved_lc // restore the loop counter +.restore_and_exit: +{ .mmi + movi0 pr = saved_pr, -1 // restore the predicate registers +;; } +{ .mib + movi0 ar.lc = saved_lc // restore the loop counter br.ret.sptk.many b0 -.next: - cmp.ge p6, p0 = OP_T_THRES, len // is len <= OP_T_THRES - and loopcnt = 7, tmp2 // loopcnt = -dest % 8 -(p6) br.cond.spnt .cpyfew // copy byte by byte - ;; - cmp.eq p6, p0 = loopcnt, r0 -(p6) br.cond.sptk .dest_aligned - sub len = len, loopcnt // len -= -dest % 8 - adds loopcnt = -1, loopcnt // --loopcnt - ;; - mov ar.lc = loopcnt -.l1: // copy -dest % 8 bytes - ld1 value = [src], 1 // value = *src++ - ;; - st1 [dest] = value, 1 // *dest++ = value - br.cloop.dptk .l1 ;; -.dest_aligned: +;; } + + +.src_not_aligned: +{ .mmi + cmp.gt p_scr, p0 = 16, len and sh1 = 7, src // sh1 = src % 8 - and tmp2 = -8, len // tmp2 = len & -OPSIZ - and asrc = -8, src // asrc = src & -OPSIZ -- align src - shr.u loopcnt = len, 3 // loopcnt = len / 8 - and len = 7, len;; // len = len % 8 - adds loopcnt = -1, loopcnt // --loopcnt - addl tmp4 = @ltoff(.table), gp - addl tmp3 = @ltoff(.loop56), gp - mov ar.ec = MEMLAT + 1 // set EC - mov pr.rot = 1 << 16;; // set rotating predicates - mov ar.lc = loopcnt // set LC - cmp.eq p6, p0 = sh1, r0 // is the src aligned? -(p6) br.cond.sptk .src_aligned - add src = src, tmp2 // src += len & -OPSIZ + shr.u loopcnt = len, 4 // element-cnt = len / 16 +} { .mib + add tmp4 = @ltoff(.table), gp + add tmp3 = @ltoff(.loop56), gp +(p_scr) br.cond.dpnt.many .copy_bytes // do byte by byte if too few +;; } +{ .mmi + and asrc = -8, src // asrc = (-8) -- align src for loop + add loopcnt = -1, loopcnt // loopcnt-- shl sh1 = sh1, 3 // sh1 = 8 * (src % 8) +} { .mmi + ld8 ptable = [tmp4] // ptable = &table ld8 ploop56 = [tmp3] // ploop56 = &loop56 - ld8 ptable = [tmp4];; // ptable = &table - add tmp3 = ptable, sh1;; // tmp3 = &table + sh1 - mov ar.ec = MEMLAT + 1 + 1 // one more pass needed - ld8 tmp4 = [tmp3];; // tmp4 = loop offset + and tmp2 = -16, len // tmp2 = len & -OPSIZ +;; } +{ .mmi + add tmp3 = ptable, sh1 // tmp3 = &table + sh1 + add src = src, tmp2 // src += len & (-16) + movi0 ar.lc = loopcnt // set LC +;; } +{ .mmi + ld8 tmp4 = [tmp3] // tmp4 = loop offset + sub len = len, tmp2 // len -= len & (-16) + movi0 ar.ec = MEMLAT + 2 // one more pass needed +;; } +{ .mmi + ld8 s[1] = [asrc], 8 // preload sub loopaddr = ploop56,tmp4 // loopadd = &loop56 - loop offset - ld8 r[1] = [asrc], 8;; // w0 - mov b6 = loopaddr;; + movi0 pr.rot = 1 << 16 // set rotating predicates +;; } +{ .mib + nop.m 0 + movi0 b6 = loopaddr br b6 // jump to the appropriate loop +;; } LOOP(8) LOOP(16) @@ -169,26 +408,9 @@ LOOP(40) LOOP(48) LOOP(56) - -.src_aligned: -.l3: -(p[0]) ld8 r[0] = [src], 8 -(p[MEMLAT]) st8 [dest] = r[MEMLAT], 8 - br.ctop.dptk .l3 ;; -.cpyfew: - cmp.eq p6, p0 = len, r0 // is len == 0 ? - adds len = -1, len // --len; -(p6) br.cond.spnt .restore_and_exit ;; - mov ar.lc = len -.l4: - ld1 value = [src], 1 - ;; - st1 [dest] = value, 1 - br.cloop.dptk .l4 ;; -.restore_and_exit: - mov pr = saved_pr, -1 // restore the predicate registers - mov ar.lc = saved_lc // restore the loop counter - br.ret.sptk.many b0 +END(memcpy) + + .rodata .align 8 .table: data8 0 // dummy entry @@ -199,5 +421,3 @@ data8 .loop56 - .loop40 data8 .loop56 - .loop48 data8 .loop56 - .loop56 - -END(memcpy) Index: sysdeps/ia64/memset.S =================================================================== RCS file: /cvs/glibc/libc/sysdeps/ia64/memset.S,v retrieving revision 1.4 diff -u -r1.4 memset.S --- sysdeps/ia64/sysdeps/ia64/memset.S 6 Jul 2001 04:55:54 -0000 1.4 +++ sysdeps/ia64/sysdeps/ia64/memset.S 3 Oct 2002 06:00:19 -0000 @@ -1,7 +1,8 @@ /* Optimized version of the standard memset() function. This file is part of the GNU C Library. - Copyright (C) 2000, 2001 Free Software Foundation, Inc. - Contributed by Dan Pop . + Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. + Contributed by Dan Pop for Itanium . + Rewritten for McKinley by Sverre Jarp, HP Labs/CERN The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -19,80 +20,373 @@ 02111-1307 USA. */ /* Return: dest - + Inputs: in0: dest in1: value in2: count The algorithm is fairly straightforward: set byte by byte until we - we get to a word aligned address, then set word by word as much as - possible; the remaining few bytes are set one by one. */ + we get to a 16B-aligned address, then loop on 128 B chunks using an + early store as prefetching, then loop on 32B chucks, then clear remaining + words, finally clear remaining bytes. + Since a stf.spill f0 can store 16B in one go, we use this instruction + to get peak speed when value = 0. */ #include #undef ret #define dest in0 -#define byteval in1 +#define value in1 #define cnt in2 -#define save_pfs loc0 -#define ptr1 loc1 -#define ptr2 loc2 -#define tmp loc3 -#define loopcnt loc4 -#define save_lc loc5 -#define wordval loc6 +#define tmp r31 +#define save_lc r30 +#define ptr0 r29 +#define ptr1 r28 +#define ptr2 r27 +#define ptr3 r26 +#define ptr9 r24 +#define loopcnt r23 +#define linecnt r22 +#define bytecnt r21 + +#define fvalue f6 + +// This routine uses only scratch predicate registers (p6 - p15) +#define p_scr p6 // default register for same-cycle branches +#define p_nz p7 +#define p_zr p8 +#define p_unalgn p9 +#define p_y p11 +#define p_n p12 +#define p_yy p13 +#define p_nn p14 + +#define movi0 mov +#define MIN1 15 +#define MIN1P1HALF 8 +#define LINE_SIZE 128 +#define LSIZE_SH 7 // shift amount +#define PREF_AHEAD 8 + +#define USE_FLP +#if defined(USE_INT) +#define store st8 +#define myval value +#elif defined(USE_FLP) +#define store stf8 +#define myval fvalue +#endif + +.align 64 ENTRY(memset) +{ .mmi .prologue - alloc save_pfs = ar.pfs, 3, 7, 0, 0 - .save ar.lc, save_lc - mov save_lc = ar.lc + alloc tmp = ar.pfs, 3, 0, 0, 0 + lfetch.nt1 [dest] + .save ar.lc, save_lc + movi0 save_lc = ar.lc +} { .mmi .body - mov ret0 = dest - and tmp = 7, dest - cmp.eq p6, p0 = cnt, r0 -(p6) br.cond.spnt .restore_and_exit ;; + mov ret0 = dest // return value + cmp.ne p_nz, p_zr = value, r0 // use stf.spill if value is zero + cmp.eq p_scr, p0 = cnt, r0 +;; } +{ .mmi + and ptr2 = -(MIN1+1), dest // aligned address + and tmp = MIN1, dest // prepare to check for alignment + tbit.nz p_y, p_n = dest, 0 // Do we have an odd address? (M_B_U) +} { .mib mov ptr1 = dest - sub loopcnt = 8, tmp - cmp.gt p6, p0 = 16, cnt -(p6) br.cond.spnt .set_few;; - cmp.eq p6, p0 = tmp, r0 -(p6) br.cond.sptk .dest_aligned - sub cnt = cnt, loopcnt - adds loopcnt = -1, loopcnt;; - mov ar.lc = loopcnt;; -.l1: - st1 [ptr1] = byteval, 1 - br.cloop.dptk .l1 ;; -.dest_aligned: - adds ptr2 = 8, ptr1 - mux1 wordval = byteval, @brcst - shr.u loopcnt = cnt, 4 ;; // loopcnt = cnt / 16 - cmp.eq p6, p0 = loopcnt, r0 -(p6) br.cond.spnt .one_more - and cnt = 0xf, cnt // compute the remaining cnt - adds loopcnt = -1, loopcnt;; - mov ar.lc = loopcnt;; -.l2: - st8 [ptr1] = wordval, 16 - st8 [ptr2] = wordval, 16 - br.cloop.dptk .l2 - cmp.le p6, p0 = 8, cnt ;; -.one_more: -(p6) st8 [ptr1] = wordval, 8 -(p6) adds cnt = -8, cnt ;; - cmp.eq p6, p0 = cnt, r0 -(p6) br.cond.spnt .restore_and_exit -.set_few: - adds loopcnt = -1, cnt;; - mov ar.lc = loopcnt;; -.l3: - st1 [ptr1] = byteval, 1 - br.cloop.dptk .l3 ;; + mux1 value = value, @brcst // create 8 identical bytes in word +(p_scr) br.ret.dpnt.many rp // return immediately if count = 0 +;; } +{ .mib + cmp.ne p_unalgn, p0 = tmp, r0 +} { .mib // NB: # of bytes to move is 1 higher + sub bytecnt = (MIN1+1), tmp // than loopcnt + cmp.gt p_scr, p0 = 16, cnt // is it a minimalistic task? +(p_scr) br.cond.dptk.many .move_bytes_unaligned // go move just a few (M_B_U) +;; } +{ .mmi +(p_unalgn) add ptr1 = (MIN1+1), ptr2 // after alignment +(p_unalgn) add ptr2 = MIN1P1HALF, ptr2 // after alignment +(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 3 // should we do a st8 ? +;; } +{ .mib +(p_y) add cnt = -8, cnt +(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 2 // should we do a st4 ? +} { .mib +(p_y) st8 [ptr2] = value, -4 +(p_n) add ptr2 = 4, ptr2 +;; } +{ .mib +(p_yy) add cnt = -4, cnt +(p_unalgn) tbit.nz.unc p_y, p_n = bytecnt, 1 // should we do a st2 ? +} { .mib +(p_yy) st4 [ptr2] = value, -2 +(p_nn) add ptr2 = 2, ptr2 +;; } +{ .mmi + mov tmp = LINE_SIZE+1 // for compare +(p_y) add cnt = -2, cnt +(p_unalgn) tbit.nz.unc p_yy, p_nn = bytecnt, 0 // should we do a st1 ? +} { .mmi + setf.sig fvalue=value // transfer value to FLP side +(p_y) st2 [ptr2] = value, -1 +(p_n) add ptr2 = 1, ptr2 +;; } + +{ .mmi +(p_yy) st1 [ptr2] = value + cmp.gt p_scr, p0 = tmp, cnt // is it a minimalistic task? +} { .mbb +(p_yy) add cnt = -1, cnt +(p_scr) br.cond.dpnt.many .fraction_of_line // go move just a few +;; } + +{ .mib + nop.m 0 + shr.u linecnt = cnt, LSIZE_SH +(p_zr) br.cond.dptk.many .l1b // Jump to use stf.spill +;; } + + .align 32 // -------- // L1A: store ahead into cache lines; fill later +{ .mmi + and tmp = -(LINE_SIZE), cnt // compute end of range + mov ptr9 = ptr1 // used for prefetching + and cnt = (LINE_SIZE-1), cnt // remainder +} { .mmi + mov loopcnt = PREF_AHEAD-1 // default prefetch loop + cmp.gt p_scr, p0 = PREF_AHEAD, linecnt // check against actual value +;; } +{ .mmi +(p_scr) add loopcnt = -1, linecnt // start of stores + add ptr2 = 8, ptr1 // (beyond prefetch stores) + add ptr1 = tmp, ptr1 // first address beyond total +;; } // range +{ .mmi + add tmp = -1, linecnt // next loop count + movi0 ar.lc = loopcnt +;; } +.pref_l1a: +{ .mib + store [ptr9] = myval, 128 // Do stores one cache line apart + nop.i 0 + br.cloop.dptk.few .pref_l1a +;; } +{ .mmi + add ptr0 = 16, ptr2 // Two stores in parallel + movi0 ar.lc = tmp +;; } +.l1ax: + { .mmi + store [ptr2] = myval, 8 + store [ptr0] = myval, 8 + ;; } + { .mmi + store [ptr2] = myval, 24 + store [ptr0] = myval, 24 + ;; } + { .mmi + store [ptr2] = myval, 8 + store [ptr0] = myval, 8 + ;; } + { .mmi + store [ptr2] = myval, 24 + store [ptr0] = myval, 24 + ;; } + { .mmi + store [ptr2] = myval, 8 + store [ptr0] = myval, 8 + ;; } + { .mmi + store [ptr2] = myval, 24 + store [ptr0] = myval, 24 + ;; } + { .mmi + store [ptr2] = myval, 8 + store [ptr0] = myval, 32 + cmp.lt p_scr, p0 = ptr9, ptr1 // do we need more prefetching? + ;; } +{ .mmb + store [ptr2] = myval, 24 +(p_scr) store [ptr9] = myval, 128 + br.cloop.dptk.few .l1ax +;; } +{ .mbb + cmp.le p_scr, p0 = 8, cnt // just a few bytes left ? +(p_scr) br.cond.dpnt.many .fraction_of_line // Branch no. 2 + br.cond.dpnt.many .move_bytes_from_alignment // Branch no. 3 +;; } + + .align 32 +.l1b: // ------------------ // L1B: store ahead into cache lines; fill later +{ .mmi + and tmp = -(LINE_SIZE), cnt // compute end of range + mov ptr9 = ptr1 // used for prefetching + and cnt = (LINE_SIZE-1), cnt // remainder +} { .mmi + mov loopcnt = PREF_AHEAD-1 // default prefetch loop + cmp.gt p_scr, p0 = PREF_AHEAD, linecnt // check against actual value +;; } +{ .mmi +(p_scr) add loopcnt = -1, linecnt + add ptr2 = 16, ptr1 // start of stores (beyond prefetch stores) + add ptr1 = tmp, ptr1 // first address beyond total range +;; } +{ .mmi + add tmp = -1, linecnt // next loop count + movi0 ar.lc = loopcnt +;; } +.pref_l1b: +{ .mib + stf.spill [ptr9] = f0, 128 // Do stores one cache line apart + nop.i 0 + br.cloop.dptk.few .pref_l1b +;; } +{ .mmi + add ptr0 = 16, ptr2 // Two stores in parallel + movi0 ar.lc = tmp +;; } +.l1bx: + { .mmi + stf.spill [ptr2] = f0, 32 + stf.spill [ptr0] = f0, 32 + ;; } + { .mmi + stf.spill [ptr2] = f0, 32 + stf.spill [ptr0] = f0, 32 + ;; } + { .mmi + stf.spill [ptr2] = f0, 32 + stf.spill [ptr0] = f0, 64 + cmp.lt p_scr, p0 = ptr9, ptr1 // do we need more prefetching? + ;; } +{ .mmb + stf.spill [ptr2] = f0, 32 +(p_scr) stf.spill [ptr9] = f0, 128 + br.cloop.dptk.few .l1bx +;; } +{ .mib + cmp.gt p_scr, p0 = 8, cnt // just a few bytes left ? +(p_scr) br.cond.dpnt.many .move_bytes_from_alignment +;; } + +.fraction_of_line: +{ .mib + add ptr2 = 16, ptr1 + shr.u loopcnt = cnt, 5 // loopcnt = cnt / 32 +;; } +{ .mib + cmp.eq p_scr, p0 = loopcnt, r0 + add loopcnt = -1, loopcnt +(p_scr) br.cond.dpnt.many .store_words +;; } +{ .mib + and cnt = 0x1f, cnt // compute the remaining cnt + movi0 ar.lc = loopcnt +;; } + .align 32 +.l2: // ---------------------------- // L2A: store 32B in 2 cycles +{ .mmb + store [ptr1] = myval, 8 + store [ptr2] = myval, 8 +;; } { .mmb + store [ptr1] = myval, 24 + store [ptr2] = myval, 24 + br.cloop.dptk.many .l2 +;; } +.store_words: +{ .mib + cmp.gt p_scr, p0 = 8, cnt // just a few bytes left ? +(p_scr) br.cond.dpnt.many .move_bytes_from_alignment // Branch +;; } + +{ .mmi + store [ptr1] = myval, 8 // store + cmp.le p_y, p_n = 16, cnt // + add cnt = -8, cnt // subtract +;; } +{ .mmi +(p_y) store [ptr1] = myval, 8 // store +(p_y) cmp.le.unc p_yy, p_nn = 16, cnt // +(p_y) add cnt = -8, cnt // subtract +;; } +{ .mmi // store +(p_yy) store [ptr1] = myval, 8 // +(p_yy) add cnt = -8, cnt // subtract +;; } + +.move_bytes_from_alignment: +{ .mib + cmp.eq p_scr, p0 = cnt, r0 + tbit.nz.unc p_y, p0 = cnt, 2 // should we terminate with a st4 ? +(p_scr) br.cond.dpnt.few .restore_and_exit +;; } +{ .mib +(p_y) st4 [ptr1] = value, 4 + tbit.nz.unc p_yy, p0 = cnt, 1 // should we terminate with a st2 ? +;; } +{ .mib +(p_yy) st2 [ptr1] = value, 2 + tbit.nz.unc p_y, p0 = cnt, 0 +;; } + +{ .mib +(p_y) st1 [ptr1] = value +;; } .restore_and_exit: - mov ar.lc = save_lc - mov ar.pfs = save_pfs - br.ret.sptk.many b0 +{ .mib + nop.m 0 + movi0 ar.lc = save_lc + br.ret.sptk.many rp +;; } + +.move_bytes_unaligned: +{ .mmi + .pred.rel "mutex",p_y, p_n + .pred.rel "mutex",p_yy, p_nn +(p_n) cmp.le p_yy, p_nn = 4, cnt +(p_y) cmp.le p_yy, p_nn = 5, cnt +(p_n) add ptr2 = 2, ptr1 +} { .mmi +(p_y) add ptr2 = 3, ptr1 +(p_y) st1 [ptr1] = value, 1 // fill 1 (odd-aligned) byte +(p_y) add cnt = -1, cnt // [15, 14 (or less) left] +;; } +{ .mmi +(p_yy) cmp.le.unc p_y, p0 = 8, cnt + add ptr3 = ptr1, cnt // prepare last store + movi0 ar.lc = save_lc +} { .mmi +(p_yy) st2 [ptr1] = value, 4 // fill 2 (aligned) bytes +(p_yy) st2 [ptr2] = value, 4 // fill 2 (aligned) bytes +(p_yy) add cnt = -4, cnt // [11, 10 (o less) left] +;; } +{ .mmi +(p_y) cmp.le.unc p_yy, p0 = 8, cnt + add ptr3 = -1, ptr3 // last store + tbit.nz p_scr, p0 = cnt, 1 // will there be a st2 at the end ? +} { .mmi +(p_y) st2 [ptr1] = value, 4 // fill 2 (aligned) bytes +(p_y) st2 [ptr2] = value, 4 // fill 2 (aligned) bytes +(p_y) add cnt = -4, cnt // [7, 6 (or less) left] +;; } +{ .mmi +(p_yy) st2 [ptr1] = value, 4 // fill 2 (aligned) bytes +(p_yy) st2 [ptr2] = value, 4 // fill 2 (aligned) bytes + // [3, 2 (or less) left] + tbit.nz p_y, p0 = cnt, 0 // will there be a st1 at the end ? +} { .mmi +(p_yy) add cnt = -4, cnt +;; } +{ .mmb +(p_scr) st2 [ptr1] = value // fill 2 (aligned) bytes +(p_y) st1 [ptr3] = value // fill last byte (using ptr3) + br.ret.sptk.many rp +;; } END(memset) + From davidm@napali.hpl.hp.com Thu Oct 3 00:03:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Thu, 03 Oct 2002 00:03:00 -0000 Subject: [patch] add alloc_pages/free_pages support Message-ID: <200210030703.g9373MV6020484@napali.hpl.hp.com> Below is a patch to add support for the new alloc_hugepages()/free_hugepages() system call. I hope I got all the details right. If not, ring... Thanks, --david 2002-10-02 David Mosberger * sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Mention sys/hugepage.h. * sysdeps/unix/sysv/linux/syscalls.list: Make alloc_hugepages and free_hugepages weak symbols. * sysdeps/unix/sysv/linux/Versions: Mention alloc_hugepages and free_hugepages. 2002-10-01 Rohit Seth , David Mosberger * sysdeps/unix/sysv/linux/syscalls.list: Add alloc_hugepages and free_hugepages. * sysdeps/unix/sysv/linux/sys/hugepage.h: New file. Index: sysdeps/unix/sysv/linux/Makefile =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/Makefile,v retrieving revision 1.121 diff -u -r1.121 Makefile --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Makefile 15 Sep 2002 02:30:28 -0000 1.121 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Makefile 3 Oct 2002 07:01:33 -0000 @@ -20,7 +20,7 @@ sys/kd.h sys/soundcard.h sys/vt.h \ sys/quota.h sys/fsuid.h \ scsi/sg.h scsi/scsi.h scsi/scsi_ioctl.h sys/pci.h \ - sys/ultrasound.h sys/raw.h sys/personality.h + sys/ultrasound.h sys/raw.h sys/personality.h sys/hugepage.h install-others += $(inst_includedir)/bits/syscall.h Index: sysdeps/unix/sysv/linux/Versions =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/Versions,v retrieving revision 1.18 diff -u -r1.18 Versions --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Versions 30 Aug 2002 01:30:55 -0000 1.18 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Versions 3 Oct 2002 07:01:33 -0000 @@ -102,6 +102,9 @@ # r* readahead; + alloc_hugepages; + free_hugepages; + #errlist-compat 126 _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; } Index: sysdeps/unix/sysv/linux/syscalls.list =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/syscalls.list,v retrieving revision 1.94 diff -u -r1.94 syscalls.list --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/syscalls.list 15 Aug 2002 08:25:16 -0000 1.94 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/syscalls.list 3 Oct 2002 07:01:33 -0000 @@ -80,3 +80,5 @@ lremovexattr EXTRA lremovexattr i:ss lremovexattr fremovexattr EXTRA fremovexattr i:is fremovexattr +alloc_hugepages EXTRA alloc_hugepages b:ianii __alloc_hugepages alloc_hugepages +free_hugepages EXTRA free_hugepages i:a __free_hugepages free_hugepages Index: sysdeps/unix/sysv/linux/sys/hugepage.h =================================================================== RCS file: sysdeps/unix/sysv/linux/sys/hugepage.h diff -N sysdeps/unix/sysv/linux/sys/hugepage.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sysdeps/unix/sysv/linux/sys/sysdeps/unix/sysv/linux/sys/hugepage.h 3 Oct 2002 07:01:33 -0000 @@ -0,0 +1,8 @@ +#ifndef _SYS_HUGEPAGE_H +#define _SYS_HUGEPAGE_H 1 + +extern void *alloc_hugepages (int key, void *addr, size_t len, int prot, + int flag); +extern int free_hugepages (void *addr); + +#endif From drepper@redhat.com Thu Oct 3 00:20:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Thu, 03 Oct 2002 00:20:00 -0000 Subject: [patch] add alloc_pages/free_pages support References: <200210030703.g9373MV6020484@napali.hpl.hp.com> Message-ID: <3D9BEF31.7050101@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 David Mosberger wrote: ee_hugepages i:a __free_hugepages free_hugepages > Index: sysdeps/unix/sysv/linux/sys/hugepage.h > =================================================================== > RCS file: sysdeps/unix/sysv/linux/sys/hugepage.h > diff -N sysdeps/unix/sysv/linux/sys/hugepage.h > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ sysdeps/unix/sysv/linux/sys/sysdeps/unix/sysv/linux/sys/hugepage.h 3 Oct 2002 07:01:33 -0000 > @@ -0,0 +1,8 @@ > +#ifndef _SYS_HUGEPAGE_H > +#define _SYS_HUGEPAGE_H 1 > + > +extern void *alloc_hugepages (int key, void *addr, size_t len, int prot, > + int flag); > +extern int free_hugepages (void *addr); > + > +#endif - - no copyright comment - - parameters have no leading __ - - no comment for the functions explaining the purpose and the parameters - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9m+812ijCOnn/RHQRAm/JAKCBTSsvsgr9tFHOoHuJOmr61OXAJwCgzKUO gNmKIAL34a6EQB/MPnP9abc= =xITk -----END PGP SIGNATURE----- From jakub@redhat.com Thu Oct 3 01:45:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Thu, 03 Oct 2002 01:45:00 -0000 Subject: [PATCH] Fix on sparc64, powerpc64 and x86_64 Message-ID: <20021003104504.Q3451@sunsite.ms.mff.cuni.cz> Hi! Sending two versions of the patch, one not touching platforms other than sparc/x86_64/powerpc, one how it should be done in the end so that route.h is not problem for mips64, hppa64 etc. Pick one. Jakub -------------- next part -------------- 2002-10-03 Jakub Jelinek * sysdeps/unix/sysv/linux/powerpc/Dist: Add net/route.h. * sysdeps/unix/sysv/linux/powerpc/net/route.h: New file. * sysdeps/unix/sysv/linux/sparc/Dist: Add net/route.h. * sysdeps/unix/sysv/linux/sparc/net/route.h: New file. * sysdeps/unix/sysv/linux/x86_64/Dist: Add net/route.h. * sysdeps/unix/sysv/linux/x86_64/net/route.h: New file. --- libc/sysdeps/unix/sysv/linux/powerpc/net/route.h.jj 2002-10-03 10:37:42.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/powerpc/net/route.h 2002-07-20 03:19:43.000000000 +0200 @@ -0,0 +1,145 @@ +/* Copyright (C) 2002 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. */ + +/* Based on the 4.4BSD and Linux version of this file. */ + +#ifndef _NET_ROUTE_H +#define _NET_ROUTE_H 1 + +#include +#include +#include +#include +#include + + +/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */ +struct rtentry + { + unsigned long int rt_pad1; + struct sockaddr rt_dst; /* Target address. */ + struct sockaddr rt_gateway; /* Gateway addr (RTF_GATEWAY). */ + struct sockaddr rt_genmask; /* Target network mask (IP). */ + unsigned short int rt_flags; + short int rt_pad2; + unsigned long int rt_pad3; + unsigned char rt_tos; + unsigned char rt_class; +#if __WORDSIZE == 64 + short int rt_pad4[3]; +#else + short int rt_pad4; +#endif + short int rt_metric; /* +1 for binary compatibility! */ + char *rt_dev; /* Forcing the device at add. */ + unsigned long int rt_mtu; /* Per route MTU/Window. */ + unsigned long int rt_window; /* Window clamping. */ + unsigned short int rt_irtt; /* Initial RTT. */ + }; +/* Compatibility hack. */ +#define rt_mss rt_mtu + + +struct in6_rtmsg + { + struct in6_addr rtmsg_dst; + struct in6_addr rtmsg_src; + struct in6_addr rtmsg_gateway; + u_int32_t rtmsg_type; + u_int16_t rtmsg_dst_len; + u_int16_t rtmsg_src_len; + u_int32_t rtmsg_metric; + unsigned long int rtmsg_info; + u_int32_t rtmsg_flags; + int rtmsg_ifindex; + }; + + +#define RTF_UP 0x0001 /* Route usable. */ +#define RTF_GATEWAY 0x0002 /* Destination is a gateway. */ + +#define RTF_HOST 0x0004 /* Host entry (net otherwise). */ +#define RTF_REINSTATE 0x0008 /* Reinstate route after timeout. */ +#define RTF_DYNAMIC 0x0010 /* Created dyn. (by redirect). */ +#define RTF_MODIFIED 0x0020 /* Modified dyn. (by redirect). */ +#define RTF_MTU 0x0040 /* Specific MTU for this route. */ +#define RTF_MSS RTF_MTU /* Compatibility. */ +#define RTF_WINDOW 0x0080 /* Per route window clamping. */ +#define RTF_IRTT 0x0100 /* Initial round trip time. */ +#define RTF_REJECT 0x0200 /* Reject route. */ +#define RTF_STATIC 0x0400 /* Manually injected route. */ +#define RTF_XRESOLVE 0x0800 /* External resolver. */ +#define RTF_NOFORWARD 0x1000 /* Forwarding inhibited. */ +#define RTF_THROW 0x2000 /* Go to next class. */ +#define RTF_NOPMTUDISC 0x4000 /* Do not send packets with DF. */ + +/* for IPv6 */ +#define RTF_DEFAULT 0x00010000 /* default - learned via ND */ +#define RTF_ALLONLINK 0x00020000 /* fallback, no routers on link */ +#define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */ + +#define RTF_LINKRT 0x00100000 /* link specific - device match */ +#define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */ + +#define RTF_CACHE 0x01000000 /* cache entry */ +#define RTF_FLOW 0x02000000 /* flow significant route */ +#define RTF_POLICY 0x04000000 /* policy route */ + +#define RTCF_VALVE 0x00200000 +#define RTCF_MASQ 0x00400000 +#define RTCF_NAT 0x00800000 +#define RTCF_DOREDIRECT 0x01000000 +#define RTCF_LOG 0x02000000 +#define RTCF_DIRECTSRC 0x04000000 + +#define RTF_LOCAL 0x80000000 +#define RTF_INTERFACE 0x40000000 +#define RTF_MULTICAST 0x20000000 +#define RTF_BROADCAST 0x10000000 +#define RTF_NAT 0x08000000 + +#define RTF_ADDRCLASSMASK 0xF8000000 +#define RT_ADDRCLASS(flags) ((__u_int32_t) flags >> 23) + +#define RT_TOS(tos) ((tos) & IPTOS_TOS_MASK) + +#define RT_LOCALADDR(flags) ((flags & RTF_ADDRCLASSMASK) \ + == (RTF_LOCAL|RTF_INTERFACE)) + +#define RT_CLASS_UNSPEC 0 +#define RT_CLASS_DEFAULT 253 + +#define RT_CLASS_MAIN 254 +#define RT_CLASS_LOCAL 255 +#define RT_CLASS_MAX 255 + + +#define RTMSG_ACK NLMSG_ACK +#define RTMSG_OVERRUN NLMSG_OVERRUN + +#define RTMSG_NEWDEVICE 0x11 +#define RTMSG_DELDEVICE 0x12 +#define RTMSG_NEWROUTE 0x21 +#define RTMSG_DELROUTE 0x22 +#define RTMSG_NEWRULE 0x31 +#define RTMSG_DELRULE 0x32 +#define RTMSG_CONTROL 0x40 + +#define RTMSG_AR_FAILED 0x51 /* Address Resolution failed. */ + +#endif /* net/route.h */ --- libc/sysdeps/unix/sysv/linux/powerpc/Dist.jj 2002-09-20 08:48:28.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/powerpc/Dist 2002-10-03 10:39:29.000000000 +0200 @@ -3,6 +3,7 @@ fe_nomask.c ipc_priv.h kernel_termios.h ldd-rewrite.sed +net/route.h oldgetrlimit64.c sys/procfs.h sys/ptrace.h --- libc/sysdeps/unix/sysv/linux/sparc/net/route.h.jj 2002-10-03 10:37:22.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/sparc/net/route.h 2002-07-20 03:19:43.000000000 +0200 @@ -0,0 +1,145 @@ +/* Copyright (C) 2002 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. */ + +/* Based on the 4.4BSD and Linux version of this file. */ + +#ifndef _NET_ROUTE_H +#define _NET_ROUTE_H 1 + +#include +#include +#include +#include +#include + + +/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */ +struct rtentry + { + unsigned long int rt_pad1; + struct sockaddr rt_dst; /* Target address. */ + struct sockaddr rt_gateway; /* Gateway addr (RTF_GATEWAY). */ + struct sockaddr rt_genmask; /* Target network mask (IP). */ + unsigned short int rt_flags; + short int rt_pad2; + unsigned long int rt_pad3; + unsigned char rt_tos; + unsigned char rt_class; +#if __WORDSIZE == 64 + short int rt_pad4[3]; +#else + short int rt_pad4; +#endif + short int rt_metric; /* +1 for binary compatibility! */ + char *rt_dev; /* Forcing the device at add. */ + unsigned long int rt_mtu; /* Per route MTU/Window. */ + unsigned long int rt_window; /* Window clamping. */ + unsigned short int rt_irtt; /* Initial RTT. */ + }; +/* Compatibility hack. */ +#define rt_mss rt_mtu + + +struct in6_rtmsg + { + struct in6_addr rtmsg_dst; + struct in6_addr rtmsg_src; + struct in6_addr rtmsg_gateway; + u_int32_t rtmsg_type; + u_int16_t rtmsg_dst_len; + u_int16_t rtmsg_src_len; + u_int32_t rtmsg_metric; + unsigned long int rtmsg_info; + u_int32_t rtmsg_flags; + int rtmsg_ifindex; + }; + + +#define RTF_UP 0x0001 /* Route usable. */ +#define RTF_GATEWAY 0x0002 /* Destination is a gateway. */ + +#define RTF_HOST 0x0004 /* Host entry (net otherwise). */ +#define RTF_REINSTATE 0x0008 /* Reinstate route after timeout. */ +#define RTF_DYNAMIC 0x0010 /* Created dyn. (by redirect). */ +#define RTF_MODIFIED 0x0020 /* Modified dyn. (by redirect). */ +#define RTF_MTU 0x0040 /* Specific MTU for this route. */ +#define RTF_MSS RTF_MTU /* Compatibility. */ +#define RTF_WINDOW 0x0080 /* Per route window clamping. */ +#define RTF_IRTT 0x0100 /* Initial round trip time. */ +#define RTF_REJECT 0x0200 /* Reject route. */ +#define RTF_STATIC 0x0400 /* Manually injected route. */ +#define RTF_XRESOLVE 0x0800 /* External resolver. */ +#define RTF_NOFORWARD 0x1000 /* Forwarding inhibited. */ +#define RTF_THROW 0x2000 /* Go to next class. */ +#define RTF_NOPMTUDISC 0x4000 /* Do not send packets with DF. */ + +/* for IPv6 */ +#define RTF_DEFAULT 0x00010000 /* default - learned via ND */ +#define RTF_ALLONLINK 0x00020000 /* fallback, no routers on link */ +#define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */ + +#define RTF_LINKRT 0x00100000 /* link specific - device match */ +#define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */ + +#define RTF_CACHE 0x01000000 /* cache entry */ +#define RTF_FLOW 0x02000000 /* flow significant route */ +#define RTF_POLICY 0x04000000 /* policy route */ + +#define RTCF_VALVE 0x00200000 +#define RTCF_MASQ 0x00400000 +#define RTCF_NAT 0x00800000 +#define RTCF_DOREDIRECT 0x01000000 +#define RTCF_LOG 0x02000000 +#define RTCF_DIRECTSRC 0x04000000 + +#define RTF_LOCAL 0x80000000 +#define RTF_INTERFACE 0x40000000 +#define RTF_MULTICAST 0x20000000 +#define RTF_BROADCAST 0x10000000 +#define RTF_NAT 0x08000000 + +#define RTF_ADDRCLASSMASK 0xF8000000 +#define RT_ADDRCLASS(flags) ((__u_int32_t) flags >> 23) + +#define RT_TOS(tos) ((tos) & IPTOS_TOS_MASK) + +#define RT_LOCALADDR(flags) ((flags & RTF_ADDRCLASSMASK) \ + == (RTF_LOCAL|RTF_INTERFACE)) + +#define RT_CLASS_UNSPEC 0 +#define RT_CLASS_DEFAULT 253 + +#define RT_CLASS_MAIN 254 +#define RT_CLASS_LOCAL 255 +#define RT_CLASS_MAX 255 + + +#define RTMSG_ACK NLMSG_ACK +#define RTMSG_OVERRUN NLMSG_OVERRUN + +#define RTMSG_NEWDEVICE 0x11 +#define RTMSG_DELDEVICE 0x12 +#define RTMSG_NEWROUTE 0x21 +#define RTMSG_DELROUTE 0x22 +#define RTMSG_NEWRULE 0x31 +#define RTMSG_DELRULE 0x32 +#define RTMSG_CONTROL 0x40 + +#define RTMSG_AR_FAILED 0x51 /* Address Resolution failed. */ + +#endif /* net/route.h */ --- libc/sysdeps/unix/sysv/linux/sparc/Dist.jj 2000-07-27 16:00:17.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/sparc/Dist 2002-10-03 10:39:47.000000000 +0200 @@ -2,3 +2,4 @@ kernel_termios.h sys/trap.h ldd-rewrite.sed sys/procfs.h +net/route.h --- libc/sysdeps/unix/sysv/linux/x86_64/net/route.h.jj 2002-10-03 10:37:03.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/x86_64/net/route.h 2002-07-20 03:19:43.000000000 +0200 @@ -0,0 +1,145 @@ +/* Copyright (C) 2002 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. */ + +/* Based on the 4.4BSD and Linux version of this file. */ + +#ifndef _NET_ROUTE_H +#define _NET_ROUTE_H 1 + +#include +#include +#include +#include +#include + + +/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */ +struct rtentry + { + unsigned long int rt_pad1; + struct sockaddr rt_dst; /* Target address. */ + struct sockaddr rt_gateway; /* Gateway addr (RTF_GATEWAY). */ + struct sockaddr rt_genmask; /* Target network mask (IP). */ + unsigned short int rt_flags; + short int rt_pad2; + unsigned long int rt_pad3; + unsigned char rt_tos; + unsigned char rt_class; +#if __WORDSIZE == 64 + short int rt_pad4[3]; +#else + short int rt_pad4; +#endif + short int rt_metric; /* +1 for binary compatibility! */ + char *rt_dev; /* Forcing the device at add. */ + unsigned long int rt_mtu; /* Per route MTU/Window. */ + unsigned long int rt_window; /* Window clamping. */ + unsigned short int rt_irtt; /* Initial RTT. */ + }; +/* Compatibility hack. */ +#define rt_mss rt_mtu + + +struct in6_rtmsg + { + struct in6_addr rtmsg_dst; + struct in6_addr rtmsg_src; + struct in6_addr rtmsg_gateway; + u_int32_t rtmsg_type; + u_int16_t rtmsg_dst_len; + u_int16_t rtmsg_src_len; + u_int32_t rtmsg_metric; + unsigned long int rtmsg_info; + u_int32_t rtmsg_flags; + int rtmsg_ifindex; + }; + + +#define RTF_UP 0x0001 /* Route usable. */ +#define RTF_GATEWAY 0x0002 /* Destination is a gateway. */ + +#define RTF_HOST 0x0004 /* Host entry (net otherwise). */ +#define RTF_REINSTATE 0x0008 /* Reinstate route after timeout. */ +#define RTF_DYNAMIC 0x0010 /* Created dyn. (by redirect). */ +#define RTF_MODIFIED 0x0020 /* Modified dyn. (by redirect). */ +#define RTF_MTU 0x0040 /* Specific MTU for this route. */ +#define RTF_MSS RTF_MTU /* Compatibility. */ +#define RTF_WINDOW 0x0080 /* Per route window clamping. */ +#define RTF_IRTT 0x0100 /* Initial round trip time. */ +#define RTF_REJECT 0x0200 /* Reject route. */ +#define RTF_STATIC 0x0400 /* Manually injected route. */ +#define RTF_XRESOLVE 0x0800 /* External resolver. */ +#define RTF_NOFORWARD 0x1000 /* Forwarding inhibited. */ +#define RTF_THROW 0x2000 /* Go to next class. */ +#define RTF_NOPMTUDISC 0x4000 /* Do not send packets with DF. */ + +/* for IPv6 */ +#define RTF_DEFAULT 0x00010000 /* default - learned via ND */ +#define RTF_ALLONLINK 0x00020000 /* fallback, no routers on link */ +#define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */ + +#define RTF_LINKRT 0x00100000 /* link specific - device match */ +#define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */ + +#define RTF_CACHE 0x01000000 /* cache entry */ +#define RTF_FLOW 0x02000000 /* flow significant route */ +#define RTF_POLICY 0x04000000 /* policy route */ + +#define RTCF_VALVE 0x00200000 +#define RTCF_MASQ 0x00400000 +#define RTCF_NAT 0x00800000 +#define RTCF_DOREDIRECT 0x01000000 +#define RTCF_LOG 0x02000000 +#define RTCF_DIRECTSRC 0x04000000 + +#define RTF_LOCAL 0x80000000 +#define RTF_INTERFACE 0x40000000 +#define RTF_MULTICAST 0x20000000 +#define RTF_BROADCAST 0x10000000 +#define RTF_NAT 0x08000000 + +#define RTF_ADDRCLASSMASK 0xF8000000 +#define RT_ADDRCLASS(flags) ((__u_int32_t) flags >> 23) + +#define RT_TOS(tos) ((tos) & IPTOS_TOS_MASK) + +#define RT_LOCALADDR(flags) ((flags & RTF_ADDRCLASSMASK) \ + == (RTF_LOCAL|RTF_INTERFACE)) + +#define RT_CLASS_UNSPEC 0 +#define RT_CLASS_DEFAULT 253 + +#define RT_CLASS_MAIN 254 +#define RT_CLASS_LOCAL 255 +#define RT_CLASS_MAX 255 + + +#define RTMSG_ACK NLMSG_ACK +#define RTMSG_OVERRUN NLMSG_OVERRUN + +#define RTMSG_NEWDEVICE 0x11 +#define RTMSG_DELDEVICE 0x12 +#define RTMSG_NEWROUTE 0x21 +#define RTMSG_DELROUTE 0x22 +#define RTMSG_NEWRULE 0x31 +#define RTMSG_DELRULE 0x32 +#define RTMSG_CONTROL 0x40 + +#define RTMSG_AR_FAILED 0x51 /* Address Resolution failed. */ + +#endif /* net/route.h */ --- libc/sysdeps/unix/sysv/linux/x86_64/Dist.jj 2002-09-03 15:30:39.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/x86_64/Dist 2002-10-03 10:41:40.000000000 +0200 @@ -3,6 +3,7 @@ ldd-rewrite.sed __start_context.S ucontext_i.h umount.c +net/route.h sys/debugreg.h sys/io.h sys/perm.h -------------- next part -------------- 2002-10-03 Jakub Jelinek * sysdeps/unix/sysv/linux/net/route.h: Include bits/wordsize.h. (struct rtentry): Make rt_pad4 6 bytes long if __WORDSIZE == 64. * sysdeps/unix/sysv/linux/alpha/Dist: Remove net/route.h. * sysdeps/unix/sysv/linux/alpha/net/route.h: Remove. * sysdeps/unix/sysv/linux/ia64/Dist: Remove net/route.h. * sysdeps/unix/sysv/linux/ia64/net/route.h: Remove. * sysdeps/unix/sysv/linux/s390/Dist: Remove net/route.h. * sysdeps/unix/sysv/linux/s390/net/route.h: Remove. --- libc/sysdeps/unix/sysv/linux/alpha/Dist.jj 2002-08-28 12:58:29.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/alpha/Dist 2002-10-03 10:44:34.000000000 +0200 @@ -9,7 +9,6 @@ ipc_priv.h kernel_sigaction.h kernel_stat.h kernel_termios.h -net/route.h oldglob.c rt_sigaction.S sizes.h --- libc/sysdeps/unix/sysv/linux/alpha/net/route.h.jj 2001-08-23 18:50:48.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/alpha/net/route.h 2002-10-03 10:44:44.000000000 +0200 @@ -1,140 +0,0 @@ -/* Copyright (C) 1997 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. */ - -/* Based on the 4.4BSD and Linux version of this file. */ - -#ifndef _NET_ROUTE_H -#define _NET_ROUTE_H 1 - -#include -#include -#include -#include - - -/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */ -struct rtentry - { - unsigned long int rt_pad1; - struct sockaddr rt_dst; /* Target address. */ - struct sockaddr rt_gateway; /* Gateway addr (RTF_GATEWAY). */ - struct sockaddr rt_genmask; /* Target network mask (IP). */ - unsigned short int rt_flags; - short int rt_pad2; - unsigned long int rt_pad3; - unsigned char rt_tos; - unsigned char rt_class; - short int rt_pad4[3]; - short int rt_metric; /* +1 for binary compatibility! */ - char *rt_dev; /* Forcing the device at add. */ - unsigned long int rt_mtu; /* Per route MTU/Window. */ - unsigned long int rt_window; /* Window clamping. */ - unsigned short int rt_irtt; /* Initial RTT. */ - }; -/* Compatibility hack. */ -#define rt_mss rt_mtu - - -struct in6_rtmsg - { - struct in6_addr rtmsg_dst; - struct in6_addr rtmsg_src; - struct in6_addr rtmsg_gateway; - u_int32_t rtmsg_type; - u_int16_t rtmsg_dst_len; - u_int16_t rtmsg_src_len; - u_int32_t rtmsg_metric; - unsigned long int rtmsg_info; - u_int32_t rtmsg_flags; - int rtmsg_ifindex; - }; - - -#define RTF_UP 0x0001 /* Route usable. */ -#define RTF_GATEWAY 0x0002 /* Destination is a gateway. */ - -#define RTF_HOST 0x0004 /* Host entry (net otherwise). */ -#define RTF_REINSTATE 0x0008 /* Reinstate route after timeout. */ -#define RTF_DYNAMIC 0x0010 /* Created dyn. (by redirect). */ -#define RTF_MODIFIED 0x0020 /* Modified dyn. (by redirect). */ -#define RTF_MTU 0x0040 /* Specific MTU for this route. */ -#define RTF_MSS RTF_MTU /* Compatibility. */ -#define RTF_WINDOW 0x0080 /* Per route window clamping. */ -#define RTF_IRTT 0x0100 /* Initial round trip time. */ -#define RTF_REJECT 0x0200 /* Reject route. */ -#define RTF_STATIC 0x0400 /* Manually injected route. */ -#define RTF_XRESOLVE 0x0800 /* External resolver. */ -#define RTF_NOFORWARD 0x1000 /* Forwarding inhibited. */ -#define RTF_THROW 0x2000 /* Go to next class. */ -#define RTF_NOPMTUDISC 0x4000 /* Do not send packets with DF. */ - -/* for IPv6 */ -#define RTF_DEFAULT 0x00010000 /* default - learned via ND */ -#define RTF_ALLONLINK 0x00020000 /* fallback, no routers on link */ -#define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */ - -#define RTF_LINKRT 0x00100000 /* link specific - device match */ -#define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */ - -#define RTF_CACHE 0x01000000 /* cache entry */ -#define RTF_FLOW 0x02000000 /* flow significant route */ -#define RTF_POLICY 0x04000000 /* policy route */ - -#define RTCF_VALVE 0x00200000 -#define RTCF_MASQ 0x00400000 -#define RTCF_NAT 0x00800000 -#define RTCF_DOREDIRECT 0x01000000 -#define RTCF_LOG 0x02000000 -#define RTCF_DIRECTSRC 0x04000000 - -#define RTF_LOCAL 0x80000000 -#define RTF_INTERFACE 0x40000000 -#define RTF_MULTICAST 0x20000000 -#define RTF_BROADCAST 0x10000000 -#define RTF_NAT 0x08000000 - -#define RTF_ADDRCLASSMASK 0xF8000000 -#define RT_ADDRCLASS(flags) ((__u_int32_t) flags >> 23) - -#define RT_TOS(tos) ((tos) & IPTOS_TOS_MASK) - -#define RT_LOCALADDR(flags) ((flags & RTF_ADDRCLASSMASK) \ - == (RTF_LOCAL|RTF_INTERFACE)) - -#define RT_CLASS_UNSPEC 0 -#define RT_CLASS_DEFAULT 253 - -#define RT_CLASS_MAIN 254 -#define RT_CLASS_LOCAL 255 -#define RT_CLASS_MAX 255 - - -#define RTMSG_ACK NLMSG_ACK -#define RTMSG_OVERRUN NLMSG_OVERRUN - -#define RTMSG_NEWDEVICE 0x11 -#define RTMSG_DELDEVICE 0x12 -#define RTMSG_NEWROUTE 0x21 -#define RTMSG_DELROUTE 0x22 -#define RTMSG_NEWRULE 0x31 -#define RTMSG_DELRULE 0x32 -#define RTMSG_CONTROL 0x40 - -#define RTMSG_AR_FAILED 0x51 /* Address Resolution failed. */ - -#endif /* net/route.h */ --- libc/sysdeps/unix/sysv/linux/ia64/Dist.jj 2002-08-27 23:19:54.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/ia64/Dist 2002-10-03 10:45:16.000000000 +0200 @@ -6,7 +6,6 @@ ioperm.c ldd-rewrite.sed __start_context.S ucontext_i.h -net/route.h sys/procfs.h sys/io.h sys/rse.h --- libc/sysdeps/unix/sysv/linux/ia64/net/route.h.jj 2001-08-23 18:51:06.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/ia64/net/route.h 2002-10-03 10:45:06.000000000 +0200 @@ -1,140 +0,0 @@ -/* Copyright (C) 1997, 2000 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. */ - -/* Based on the 4.4BSD and Linux version of this file. */ - -#ifndef _NET_ROUTE_H -#define _NET_ROUTE_H 1 - -#include -#include -#include -#include - - -/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */ -struct rtentry - { - unsigned long int rt_pad1; - struct sockaddr rt_dst; /* Target address. */ - struct sockaddr rt_gateway; /* Gateway addr (RTF_GATEWAY). */ - struct sockaddr rt_genmask; /* Target network mask (IP). */ - unsigned short int rt_flags; - short int rt_pad2; - unsigned long int rt_pad3; - unsigned char rt_tos; - unsigned char rt_class; - short int rt_pad4[3]; - short int rt_metric; /* +1 for binary compatibility! */ - char *rt_dev; /* Forcing the device at add. */ - unsigned long int rt_mtu; /* Per route MTU/Window. */ - unsigned long int rt_window; /* Window clamping. */ - unsigned short int rt_irtt; /* Initial RTT. */ - }; -/* Compatibility hack. */ -#define rt_mss rt_mtu - - -struct in6_rtmsg - { - struct in6_addr rtmsg_dst; - struct in6_addr rtmsg_src; - struct in6_addr rtmsg_gateway; - u_int32_t rtmsg_type; - u_int16_t rtmsg_dst_len; - u_int16_t rtmsg_src_len; - u_int32_t rtmsg_metric; - unsigned long int rtmsg_info; - u_int32_t rtmsg_flags; - int rtmsg_ifindex; - }; - - -#define RTF_UP 0x0001 /* Route usable. */ -#define RTF_GATEWAY 0x0002 /* Destination is a gateway. */ - -#define RTF_HOST 0x0004 /* Host entry (net otherwise). */ -#define RTF_REINSTATE 0x0008 /* Reinstate route after timeout. */ -#define RTF_DYNAMIC 0x0010 /* Created dyn. (by redirect). */ -#define RTF_MODIFIED 0x0020 /* Modified dyn. (by redirect). */ -#define RTF_MTU 0x0040 /* Specific MTU for this route. */ -#define RTF_MSS RTF_MTU /* Compatibility. */ -#define RTF_WINDOW 0x0080 /* Per route window clamping. */ -#define RTF_IRTT 0x0100 /* Initial round trip time. */ -#define RTF_REJECT 0x0200 /* Reject route. */ -#define RTF_STATIC 0x0400 /* Manually injected route. */ -#define RTF_XRESOLVE 0x0800 /* External resolver. */ -#define RTF_NOFORWARD 0x1000 /* Forwarding inhibited. */ -#define RTF_THROW 0x2000 /* Go to next class. */ -#define RTF_NOPMTUDISC 0x4000 /* Do not send packets with DF. */ - -/* for IPv6 */ -#define RTF_DEFAULT 0x00010000 /* default - learned via ND */ -#define RTF_ALLONLINK 0x00020000 /* fallback, no routers on link */ -#define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */ - -#define RTF_LINKRT 0x00100000 /* link specific - device match */ -#define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */ - -#define RTF_CACHE 0x01000000 /* cache entry */ -#define RTF_FLOW 0x02000000 /* flow significant route */ -#define RTF_POLICY 0x04000000 /* policy route */ - -#define RTCF_VALVE 0x00200000 -#define RTCF_MASQ 0x00400000 -#define RTCF_NAT 0x00800000 -#define RTCF_DOREDIRECT 0x01000000 -#define RTCF_LOG 0x02000000 -#define RTCF_DIRECTSRC 0x04000000 - -#define RTF_LOCAL 0x80000000 -#define RTF_INTERFACE 0x40000000 -#define RTF_MULTICAST 0x20000000 -#define RTF_BROADCAST 0x10000000 -#define RTF_NAT 0x08000000 - -#define RTF_ADDRCLASSMASK 0xF8000000 -#define RT_ADDRCLASS(flags) ((__u_int32_t) flags >> 23) - -#define RT_TOS(tos) ((tos) & IPTOS_TOS_MASK) - -#define RT_LOCALADDR(flags) ((flags & RTF_ADDRCLASSMASK) \ - == (RTF_LOCAL|RTF_INTERFACE)) - -#define RT_CLASS_UNSPEC 0 -#define RT_CLASS_DEFAULT 253 - -#define RT_CLASS_MAIN 254 -#define RT_CLASS_LOCAL 255 -#define RT_CLASS_MAX 255 - - -#define RTMSG_ACK NLMSG_ACK -#define RTMSG_OVERRUN NLMSG_OVERRUN - -#define RTMSG_NEWDEVICE 0x11 -#define RTMSG_DELDEVICE 0x12 -#define RTMSG_NEWROUTE 0x21 -#define RTMSG_DELROUTE 0x22 -#define RTMSG_NEWRULE 0x31 -#define RTMSG_DELRULE 0x32 -#define RTMSG_CONTROL 0x40 - -#define RTMSG_AR_FAILED 0x51 /* Address Resolution failed. */ - -#endif /* net/route.h */ --- libc/sysdeps/unix/sysv/linux/s390/net/route.h.jj 2002-07-20 03:19:43.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/s390/net/route.h 2002-10-03 10:44:00.000000000 +0200 @@ -1,145 +0,0 @@ -/* Copyright (C) 2002 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. */ - -/* Based on the 4.4BSD and Linux version of this file. */ - -#ifndef _NET_ROUTE_H -#define _NET_ROUTE_H 1 - -#include -#include -#include -#include -#include - - -/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */ -struct rtentry - { - unsigned long int rt_pad1; - struct sockaddr rt_dst; /* Target address. */ - struct sockaddr rt_gateway; /* Gateway addr (RTF_GATEWAY). */ - struct sockaddr rt_genmask; /* Target network mask (IP). */ - unsigned short int rt_flags; - short int rt_pad2; - unsigned long int rt_pad3; - unsigned char rt_tos; - unsigned char rt_class; -#if __WORDSIZE == 64 - short int rt_pad4[3]; -#else - short int rt_pad4; -#endif - short int rt_metric; /* +1 for binary compatibility! */ - char *rt_dev; /* Forcing the device at add. */ - unsigned long int rt_mtu; /* Per route MTU/Window. */ - unsigned long int rt_window; /* Window clamping. */ - unsigned short int rt_irtt; /* Initial RTT. */ - }; -/* Compatibility hack. */ -#define rt_mss rt_mtu - - -struct in6_rtmsg - { - struct in6_addr rtmsg_dst; - struct in6_addr rtmsg_src; - struct in6_addr rtmsg_gateway; - u_int32_t rtmsg_type; - u_int16_t rtmsg_dst_len; - u_int16_t rtmsg_src_len; - u_int32_t rtmsg_metric; - unsigned long int rtmsg_info; - u_int32_t rtmsg_flags; - int rtmsg_ifindex; - }; - - -#define RTF_UP 0x0001 /* Route usable. */ -#define RTF_GATEWAY 0x0002 /* Destination is a gateway. */ - -#define RTF_HOST 0x0004 /* Host entry (net otherwise). */ -#define RTF_REINSTATE 0x0008 /* Reinstate route after timeout. */ -#define RTF_DYNAMIC 0x0010 /* Created dyn. (by redirect). */ -#define RTF_MODIFIED 0x0020 /* Modified dyn. (by redirect). */ -#define RTF_MTU 0x0040 /* Specific MTU for this route. */ -#define RTF_MSS RTF_MTU /* Compatibility. */ -#define RTF_WINDOW 0x0080 /* Per route window clamping. */ -#define RTF_IRTT 0x0100 /* Initial round trip time. */ -#define RTF_REJECT 0x0200 /* Reject route. */ -#define RTF_STATIC 0x0400 /* Manually injected route. */ -#define RTF_XRESOLVE 0x0800 /* External resolver. */ -#define RTF_NOFORWARD 0x1000 /* Forwarding inhibited. */ -#define RTF_THROW 0x2000 /* Go to next class. */ -#define RTF_NOPMTUDISC 0x4000 /* Do not send packets with DF. */ - -/* for IPv6 */ -#define RTF_DEFAULT 0x00010000 /* default - learned via ND */ -#define RTF_ALLONLINK 0x00020000 /* fallback, no routers on link */ -#define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */ - -#define RTF_LINKRT 0x00100000 /* link specific - device match */ -#define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */ - -#define RTF_CACHE 0x01000000 /* cache entry */ -#define RTF_FLOW 0x02000000 /* flow significant route */ -#define RTF_POLICY 0x04000000 /* policy route */ - -#define RTCF_VALVE 0x00200000 -#define RTCF_MASQ 0x00400000 -#define RTCF_NAT 0x00800000 -#define RTCF_DOREDIRECT 0x01000000 -#define RTCF_LOG 0x02000000 -#define RTCF_DIRECTSRC 0x04000000 - -#define RTF_LOCAL 0x80000000 -#define RTF_INTERFACE 0x40000000 -#define RTF_MULTICAST 0x20000000 -#define RTF_BROADCAST 0x10000000 -#define RTF_NAT 0x08000000 - -#define RTF_ADDRCLASSMASK 0xF8000000 -#define RT_ADDRCLASS(flags) ((__u_int32_t) flags >> 23) - -#define RT_TOS(tos) ((tos) & IPTOS_TOS_MASK) - -#define RT_LOCALADDR(flags) ((flags & RTF_ADDRCLASSMASK) \ - == (RTF_LOCAL|RTF_INTERFACE)) - -#define RT_CLASS_UNSPEC 0 -#define RT_CLASS_DEFAULT 253 - -#define RT_CLASS_MAIN 254 -#define RT_CLASS_LOCAL 255 -#define RT_CLASS_MAX 255 - - -#define RTMSG_ACK NLMSG_ACK -#define RTMSG_OVERRUN NLMSG_OVERRUN - -#define RTMSG_NEWDEVICE 0x11 -#define RTMSG_DELDEVICE 0x12 -#define RTMSG_NEWROUTE 0x21 -#define RTMSG_DELROUTE 0x22 -#define RTMSG_NEWRULE 0x31 -#define RTMSG_DELRULE 0x32 -#define RTMSG_CONTROL 0x40 - -#define RTMSG_AR_FAILED 0x51 /* Address Resolution failed. */ - -#endif /* net/route.h */ --- libc/sysdeps/unix/sysv/linux/s390/Dist.jj 2002-08-27 23:19:54.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/s390/Dist 2002-10-03 10:44:09.000000000 +0200 @@ -1,5 +1,4 @@ ldd-rewrite.sed -net/route.h sys/elf.h sys/procfs.h sys/user.h --- libc/sysdeps/unix/sysv/linux/net/route.h.jj 2001-08-23 18:51:19.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/net/route.h 2002-10-03 10:43:36.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1997 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2002 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,6 +25,7 @@ #include #include #include +#include /* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */ @@ -39,7 +40,11 @@ struct rtentry unsigned long int rt_pad3; unsigned char rt_tos; unsigned char rt_class; +#if __WORDSIZE == 64 + short int rt_pad4[3]; +#else short int rt_pad4; +#endif short int rt_metric; /* +1 for binary compatibility! */ char *rt_dev; /* Forcing the device at add. */ unsigned long int rt_mtu; /* Per route MTU/Window. */ From drepper@redhat.com Thu Oct 3 01:58:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Thu, 03 Oct 2002 01:58:00 -0000 Subject: [PATCH] Fix on sparc64, powerpc64 and x86_64 References: <20021003104504.Q3451@sunsite.ms.mff.cuni.cz> Message-ID: <3D9C06E0.40506@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jakub Jelinek wrote: > Sending two versions of the patch, one not touching platforms other than > sparc/x86_64/powerpc, one how it should be done in the end so that route.h > is not problem for mips64, hppa64 etc. Pick one. The patch for the final for is harmless enough, I've applied it. Thanks, - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9nAbg2ijCOnn/RHQRAv3tAJ9srodQkjnznew92Q59yqb+LOubewCfej5F SV5BbAORVIzUHsP4nhYzXq0= =bPCA -----END PGP SIGNATURE----- From jakub@redhat.com Thu Oct 3 05:26:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Thu, 03 Oct 2002 05:26:00 -0000 Subject: [PATCH] Fix warning Message-ID: <20021003142559.R3451@sunsite.ms.mff.cuni.cz> Hi! Shut up warning on IA-64 and Alpha at least. 2002-10-03 Jakub Jelinek * sysdeps/unix/sysv/linux/_exit.c (__syscall_exit, __syscall_exit_group): New prototypes. (_exit): Convert from K&R syntax. --- libc/sysdeps/unix/sysv/linux/_exit.c.jj 2002-09-20 08:48:25.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/_exit.c 2002-10-03 14:23:22.000000000 +0200 @@ -22,10 +22,11 @@ #include #include +extern void __syscall_exit_group (int status); +extern void __syscall_exit (int status); void -_exit (status) - int status; +_exit (int status) { while (1) { Jakub From drepper@redhat.com Thu Oct 3 09:17:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Thu, 03 Oct 2002 09:17:00 -0000 Subject: [PATCH] Fix warning References: <20021003142559.R3451@sunsite.ms.mff.cuni.cz> Message-ID: <3D9C6DDC.6080202@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jakub Jelinek wrote: > void > -_exit (status) > - int status; > +_exit (int status) Why this? Should not be necessary. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9nG3c2ijCOnn/RHQRAnlTAJ4sx9jWdROQLtLWffxIadjT/RxX4QCeNQsQ jqdskhQDkCXH7R4rO0J6QTg= =Cbr3 -----END PGP SIGNATURE----- From davidm@napali.hpl.hp.com Thu Oct 3 12:37:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Thu, 03 Oct 2002 12:37:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <3D9BEF31.7050101@redhat.com> References: <200210030703.g9373MV6020484@napali.hpl.hp.com> <3D9BEF31.7050101@redhat.com> Message-ID: <15772.40078.639559.955906@napali.hpl.hp.com> >>>>> On Thu, 03 Oct 2002 00:18:09 -0700, Ulrich Drepper said: Uli> - - no copyright comment Uli> - - parameters have no leading __ Uli> - - no comment for the functions explaining the purpose and the Uli> parameters OK, how about the attached patch? It takes care of the above comments and also adds a gethugepage() function. --david 2002-10-03 David Mosberger * sysdeps/unix/sysv/linux/getsysstats.c (get_meminfo): New function. (phys_pages_info): Implementing on the basis of get_meminfo(). (__gethugepagesize): New function. * sysdeps/unix/sysv/linux/Versions: Mention gethugepagesize(). 2002-10-02 David Mosberger * sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Mention sys/hugepage.h. * sysdeps/unix/sysv/linux/syscalls.list: Make alloc_hugepages and free_hugepages weak symbols. * sysdeps/unix/sysv/linux/Versions: Mention alloc_hugepages and free_hugepages. 2002-10-01 Rohit Seth , David Mosberger * sysdeps/unix/sysv/linux/syscalls.list: Add alloc_hugepages and free_hugepages. * sysdeps/unix/sysv/linux/sys/hugepage.h: New file. 2002-10-02 David Mosberger * sysdeps/ia64/bzero.S: Rewritten by Sverre Jarp to tune for Itanium 2 (and Itanium). Fix unwind directives and make it fit in 80 columns. * sysdeps/ia64/memset.S: Ditto. * sysdeps/ia64/memcpy.S: Ditto. Move jump table to .rodata section. Index: sysdeps/unix/sysv/linux/Makefile =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/Makefile,v retrieving revision 1.121 diff -u -r1.121 Makefile --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Makefile 15 Sep 2002 02:30:28 -0000 1.121 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Makefile 3 Oct 2002 19:34:12 -0000 @@ -20,7 +20,7 @@ sys/kd.h sys/soundcard.h sys/vt.h \ sys/quota.h sys/fsuid.h \ scsi/sg.h scsi/scsi.h scsi/scsi_ioctl.h sys/pci.h \ - sys/ultrasound.h sys/raw.h sys/personality.h + sys/ultrasound.h sys/raw.h sys/personality.h sys/hugepage.h install-others += $(inst_includedir)/bits/syscall.h Index: sysdeps/unix/sysv/linux/Versions =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/Versions,v retrieving revision 1.18 diff -u -r1.18 Versions --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Versions 30 Aug 2002 01:30:55 -0000 1.18 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Versions 3 Oct 2002 19:34:12 -0000 @@ -102,6 +102,10 @@ # r* readahead; + gethugepagesize; + alloc_hugepages; + free_hugepages; + #errlist-compat 126 _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; } Index: sysdeps/unix/sysv/linux/getsysstats.c =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/getsysstats.c,v retrieving revision 1.22 diff -u -r1.22 getsysstats.c --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/getsysstats.c 21 Sep 2002 05:26:12 -0000 1.22 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/getsysstats.c 3 Oct 2002 19:34:12 -0000 @@ -230,11 +230,8 @@ #endif weak_alias (__get_nprocs_conf, get_nprocs_conf) -/* General function to get information about memory status from proc - filesystem. */ static long int -internal_function -phys_pages_info (const char *format) +get_meminfo (const char *format) { FILE *fp; char buffer[8192]; @@ -264,7 +261,7 @@ while (fgets_unlocked (buffer, sizeof buffer, fp) != NULL) if (sscanf (buffer, format, &result) == 1) { - result /= (__getpagesize () / 1024); + result /= 1024; break; } @@ -279,6 +276,20 @@ return result; } +/* General function to get information about memory status from proc + filesystem. */ +static long int +internal_function +phys_pages_info (const char *format) +{ + long int result = get_meminfo (format); + + if (result != -1) + result /= __getpagesize (); + + return result; +} + /* Return the number of pages of physical memory in the system. There is currently (as of version 2.0.21) no system call to determine the @@ -320,6 +331,12 @@ } weak_alias (__get_avphys_pages, get_avphys_pages) +long int +__gethugepagesize () +{ + return get_meminfo ("HugePageSize: %lu kB"); +} +weak_alias (__gethugepagesize, gethugepagesize); static void free_mem (void) Index: sysdeps/unix/sysv/linux/syscalls.list =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/syscalls.list,v retrieving revision 1.94 diff -u -r1.94 syscalls.list --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/syscalls.list 15 Aug 2002 08:25:16 -0000 1.94 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/syscalls.list 3 Oct 2002 19:34:12 -0000 @@ -80,3 +80,5 @@ lremovexattr EXTRA lremovexattr i:ss lremovexattr fremovexattr EXTRA fremovexattr i:is fremovexattr +alloc_hugepages EXTRA alloc_hugepages b:ianii __alloc_hugepages alloc_hugepages +free_hugepages EXTRA free_hugepages i:a __free_hugepages free_hugepages Index: sysdeps/unix/sysv/linux/sys/hugepage.h =================================================================== RCS file: sysdeps/unix/sysv/linux/sys/hugepage.h diff -N sysdeps/unix/sysv/linux/sys/hugepage.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sysdeps/unix/sysv/linux/sys/sysdeps/unix/sysv/linux/sys/hugepage.h 3 Oct 2002 19:34:12 -0000 @@ -0,0 +1,75 @@ +/* Copyright (C) 2002 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 _SYS_HUGEPAGE_H +#define _SYS_HUGEPAGE_H 1 + +/* This header file defines the huge page interface. A huge page is a + non-swappable (pinned) page of virtual memory. As the name + suggests, the size of a huge page is typically orders of magnitudes + bigger than the value returned by getpagesize(). For example, + depending on kernel configuration, on x86 it may be 2MBytes or + 4MBytes and on ia64 it is typically one of 16MB, 256MBytes, or + 4GBytes. Note that because huge pages are never swapped, they are + a relatively rare commodity and applications are expected to fall + back to allocating regular pages if a huge page cannot be + allocated. */ + +#include + +__BEGIN_DECLS + +/* Return the size of a huge page. */ + +extern long int __gethugepagesize (void) __attribute__ ((__const__)); +libc_hidden_proto (__gethugepagesize); + +/* Allocate LEN bytes worth of huge pages. LEN must be an integer + multiple of the huge page size. ADDR is the preferred starting + address for the memory. PROT is a mask of protection bits that + specify how the memory is to be mapped (PROT_NONE or any + combination of PROT_READ, PROT_WRITE, or PROT_EXEC). If KEY has is + a positive number, FLAG can be set to IPC_CREAT to request the + creation of a new shared memory segment or to zero to request + attaching to an existing shared memory segment. + + Return value: On success, alloc_hugepages() returns a pointer to + the allocated memory. On error, MAP_FAILED ((void *) -1) is + returned and ERRNO is set appropriately. + + Errors: + EINVAL LEN is not a integer multiple of gethugepagesize() + or KEY is a negative value. + + ENOENT No shared segment matching KEY was found and FLAGS + was zero. */ + +extern void *alloc_hugepages (int __key, void *__addr, size_t __len, + int __prot, int __flag); + +/* Free the huge page resources from the current process's address + space. ADDR must be an address returned by a previous call to + alloc_hugepages (). Note that for shared memory segments, the + underlying physical memory will be freed only after the last + process using them has freed them up or has exited. */ + +extern int free_hugepages (void *__addr); + +__END_DECLS + +#endif /* sys/hugepage.h */ From rth@twiddle.net Thu Oct 3 12:53:00 2002 From: rth@twiddle.net (Richard Henderson) Date: Thu, 03 Oct 2002 12:53:00 -0000 Subject: [PATCH] Fix alpha build In-Reply-To: <20020929142935.H3451@sunsite.ms.mff.cuni.cz>; from jakub@redhat.com on Sun, Sep 29, 2002 at 02:29:35PM +0200 References: <20020929142935.H3451@sunsite.ms.mff.cuni.cz> Message-ID: <20021003125318.A16410@twiddle.net> On Sun, Sep 29, 2002 at 02:29:35PM +0200, Jakub Jelinek wrote: > PARAMS(args) is not defined on Alpha. In fact, IMHO GCC doesn't need > it either, since longlong.h is only used in libgcc.a which is compiled > already by gcc, not host compiler, and without -Wtraditional. I agree. Patch pre-approved. r~ From davidm@napali.hpl.hp.com Thu Oct 3 14:44:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Thu, 03 Oct 2002 14:44:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <3D9BEF31.7050101@redhat.com> References: <200210030703.g9373MV6020484@napali.hpl.hp.com> <3D9BEF31.7050101@redhat.com> Message-ID: <15772.40078.639559.955906@napali.hpl.hp.com> >>>>> On Thu, 03 Oct 2002 00:18:09 -0700, Ulrich Drepper said: Uli> - - no copyright comment Uli> - - parameters have no leading __ Uli> - - no comment for the functions explaining the purpose and the Uli> parameters OK, how about the attached patch? It takes care of the above comments and also adds a gethugepage() function. --david 2002-10-03 David Mosberger * sysdeps/unix/sysv/linux/getsysstats.c (get_meminfo): New function. (phys_pages_info): Implementing on the basis of get_meminfo(). (__gethugepagesize): New function. * sysdeps/unix/sysv/linux/Versions: Mention gethugepagesize(). 2002-10-02 David Mosberger * sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Mention sys/hugepage.h. * sysdeps/unix/sysv/linux/syscalls.list: Make alloc_hugepages and free_hugepages weak symbols. * sysdeps/unix/sysv/linux/Versions: Mention alloc_hugepages and free_hugepages. 2002-10-01 Rohit Seth , David Mosberger * sysdeps/unix/sysv/linux/syscalls.list: Add alloc_hugepages and free_hugepages. * sysdeps/unix/sysv/linux/sys/hugepage.h: New file. 2002-10-02 David Mosberger * sysdeps/ia64/bzero.S: Rewritten by Sverre Jarp to tune for Itanium 2 (and Itanium). Fix unwind directives and make it fit in 80 columns. * sysdeps/ia64/memset.S: Ditto. * sysdeps/ia64/memcpy.S: Ditto. Move jump table to .rodata section. Index: sysdeps/unix/sysv/linux/Makefile =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/Makefile,v retrieving revision 1.121 diff -u -r1.121 Makefile --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Makefile 15 Sep 2002 02:30:28 -0000 1.121 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Makefile 3 Oct 2002 19:34:12 -0000 @@ -20,7 +20,7 @@ sys/kd.h sys/soundcard.h sys/vt.h \ sys/quota.h sys/fsuid.h \ scsi/sg.h scsi/scsi.h scsi/scsi_ioctl.h sys/pci.h \ - sys/ultrasound.h sys/raw.h sys/personality.h + sys/ultrasound.h sys/raw.h sys/personality.h sys/hugepage.h install-others += $(inst_includedir)/bits/syscall.h Index: sysdeps/unix/sysv/linux/Versions =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/Versions,v retrieving revision 1.18 diff -u -r1.18 Versions --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Versions 30 Aug 2002 01:30:55 -0000 1.18 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Versions 3 Oct 2002 19:34:12 -0000 @@ -102,6 +102,10 @@ # r* readahead; + gethugepagesize; + alloc_hugepages; + free_hugepages; + #errlist-compat 126 _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; } Index: sysdeps/unix/sysv/linux/getsysstats.c =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/getsysstats.c,v retrieving revision 1.22 diff -u -r1.22 getsysstats.c --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/getsysstats.c 21 Sep 2002 05:26:12 -0000 1.22 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/getsysstats.c 3 Oct 2002 19:34:12 -0000 @@ -230,11 +230,8 @@ #endif weak_alias (__get_nprocs_conf, get_nprocs_conf) -/* General function to get information about memory status from proc - filesystem. */ static long int -internal_function -phys_pages_info (const char *format) +get_meminfo (const char *format) { FILE *fp; char buffer[8192]; @@ -264,7 +261,7 @@ while (fgets_unlocked (buffer, sizeof buffer, fp) != NULL) if (sscanf (buffer, format, &result) == 1) { - result /= (__getpagesize () / 1024); + result /= 1024; break; } @@ -279,6 +276,20 @@ return result; } +/* General function to get information about memory status from proc + filesystem. */ +static long int +internal_function +phys_pages_info (const char *format) +{ + long int result = get_meminfo (format); + + if (result != -1) + result /= __getpagesize (); + + return result; +} + /* Return the number of pages of physical memory in the system. There is currently (as of version 2.0.21) no system call to determine the @@ -320,6 +331,12 @@ } weak_alias (__get_avphys_pages, get_avphys_pages) +long int +__gethugepagesize () +{ + return get_meminfo ("Hugepagesize: %lu kB"); +} +weak_alias (__gethugepagesize, gethugepagesize); static void free_mem (void) Index: sysdeps/unix/sysv/linux/syscalls.list =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/syscalls.list,v retrieving revision 1.94 diff -u -r1.94 syscalls.list --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/syscalls.list 15 Aug 2002 08:25:16 -0000 1.94 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/syscalls.list 3 Oct 2002 19:34:12 -0000 @@ -80,3 +80,5 @@ lremovexattr EXTRA lremovexattr i:ss lremovexattr fremovexattr EXTRA fremovexattr i:is fremovexattr +alloc_hugepages EXTRA alloc_hugepages b:ianii __alloc_hugepages alloc_hugepages +free_hugepages EXTRA free_hugepages i:a __free_hugepages free_hugepages Index: sysdeps/unix/sysv/linux/sys/hugepage.h =================================================================== RCS file: sysdeps/unix/sysv/linux/sys/hugepage.h diff -N sysdeps/unix/sysv/linux/sys/hugepage.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sysdeps/unix/sysv/linux/sys/sysdeps/unix/sysv/linux/sys/hugepage.h 3 Oct 2002 19:34:12 -0000 @@ -0,0 +1,75 @@ +/* Copyright (C) 2002 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 _SYS_HUGEPAGE_H +#define _SYS_HUGEPAGE_H 1 + +/* This header file defines the huge page interface. A huge page is a + non-swappable (pinned) page of virtual memory. As the name + suggests, the size of a huge page is typically orders of magnitudes + bigger than the value returned by getpagesize(). For example, + depending on kernel configuration, on x86 it may be 2MBytes or + 4MBytes and on ia64 it is typically one of 16MB, 256MBytes, or + 4GBytes. Note that because huge pages are never swapped, they are + a relatively rare commodity and applications are expected to fall + back to allocating regular pages if a huge page cannot be + allocated. */ + +#include + +__BEGIN_DECLS + +/* Return the size of a huge page. */ + +extern long int __gethugepagesize (void) __attribute__ ((__const__)); +libc_hidden_proto (__gethugepagesize); + +/* Allocate LEN bytes worth of huge pages. LEN must be an integer + multiple of the huge page size. ADDR is the preferred starting + address for the memory. PROT is a mask of protection bits that + specify how the memory is to be mapped (PROT_NONE or any + combination of PROT_READ, PROT_WRITE, or PROT_EXEC). If KEY has is + a positive number, FLAG can be set to IPC_CREAT to request the + creation of a new shared memory segment or to zero to request + attaching to an existing shared memory segment. + + Return value: On success, alloc_hugepages() returns a pointer to + the allocated memory. On error, MAP_FAILED ((void *) -1) is + returned and ERRNO is set appropriately. + + Errors: + EINVAL LEN is not a integer multiple of gethugepagesize() + or KEY is a negative value. + + ENOENT No shared segment matching KEY was found and FLAGS + was zero. */ + +extern void *alloc_hugepages (int __key, void *__addr, size_t __len, + int __prot, int __flag); + +/* Free the huge page resources from the current process's address + space. ADDR must be an address returned by a previous call to + alloc_hugepages (). Note that for shared memory segments, the + underlying physical memory will be freed only after the last + process using them has freed them up or has exited. */ + +extern int free_hugepages (void *__addr); + +__END_DECLS + +#endif /* sys/hugepage.h */ From davidm@napali.hpl.hp.com Thu Oct 3 15:05:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Thu, 03 Oct 2002 15:05:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <3D9BEF31.7050101@redhat.com> References: <200210030703.g9373MV6020484@napali.hpl.hp.com> <3D9BEF31.7050101@redhat.com> Message-ID: <15772.47660.333934.293189@napali.hpl.hp.com> I just resent the hugepage patch with a small change. The mail escaped before I had a chance to describe what changed: The only change in the followup patch is that the spelling of "HugePageSize" is changed to "Hugepagesize" (getsysstats.c). This is so we're in sync with the (forthcoming) kernel. Thanks, --david From davidm@napali.hpl.hp.com Thu Oct 3 15:30:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Thu, 03 Oct 2002 15:30:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <200210032146.g93LkB119076@magilla.sf.frob.com> References: <15772.47660.333934.293189@napali.hpl.hp.com> <200210032146.g93LkB119076@magilla.sf.frob.com> Message-ID: <15772.48947.101500.167377@napali.hpl.hp.com> >>>>> On Thu, 3 Oct 2002 14:46:11 -0700, Roland McGrath said: Roland> I think gethugepagesize should return size_t rather than long int. Yeah, you're probably right. getpagesize() returns "int" but that doesn't work for gethugepagesize() since McKinley already supports 4GB huge pages. Uli, do you have any other feedback or are you OK with it? Thanks, --david From drepper@redhat.com Thu Oct 3 15:34:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Thu, 03 Oct 2002 15:34:00 -0000 Subject: [patch] add alloc_pages/free_pages support References: <15772.47660.333934.293189@napali.hpl.hp.com> <200210032146.g93LkB119076@magilla.sf.frob.com> <15772.48947.101500.167377@napali.hpl.hp.com> Message-ID: <3D9CC520.8010403@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 > Uli, do you have any other feedback or are you OK with it? The header still isn't right. You cannot have the hidden macros in there. And the function prototypes are missing __THROW. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9nMUg2ijCOnn/RHQRAv2hAJwN8QLZSvSdMbaTbeTo9Vt2brUTagCbBGHP jGZMhJEXVhhH2aIkH0F4N1M= =qxLq -----END PGP SIGNATURE----- From davidm@napali.hpl.hp.com Thu Oct 3 22:48:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Thu, 03 Oct 2002 22:48:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <3D9CC520.8010403@redhat.com> References: <15772.47660.333934.293189@napali.hpl.hp.com> <200210032146.g93LkB119076@magilla.sf.frob.com> <15772.48947.101500.167377@napali.hpl.hp.com> <3D9CC520.8010403@redhat.com> Message-ID: <15772.50674.642701.846853@napali.hpl.hp.com> >>>>> On Thu, 03 Oct 2002 15:30:56 -0700, Ulrich Drepper said: Uli> The header still isn't right. You cannot have the hidden macros in Uli> there. OK, so what's the right way to declare a function that has both weak and strong variants? Just duplicate the proto, like so: extern size_t __gethugepagesize (void) __attribute__ ((__const__)); extern size_t gethugepagesize (void) __attribute__ ((__const__)); Uli> And the function prototypes are missing __THROW. For all three of them? --david From davidm@napali.hpl.hp.com Fri Oct 4 00:14:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Fri, 04 Oct 2002 00:14:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <3D9CC520.8010403@redhat.com> References: <15772.47660.333934.293189@napali.hpl.hp.com> <200210032146.g93LkB119076@magilla.sf.frob.com> <15772.48947.101500.167377@napali.hpl.hp.com> <3D9CC520.8010403@redhat.com> Message-ID: <15773.11197.780790.750761@napali.hpl.hp.com> >>>>> On Thu, 03 Oct 2002 15:30:56 -0700, Ulrich Drepper said: Uli> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 >> Uli, do you have any other feedback or are you OK with it? Uli> The header still isn't right. You cannot have the hidden Uli> macros in there. And the function prototypes are missing Uli> __THROW. OK, how is this? --david 2002-10-03 David Mosberger * sysdeps/unix/sysv/linux/getsysstats.c (get_meminfo): New function. (phys_pages_info): Implementing on the basis of get_meminfo(). (__gethugepagesize): New function. * sysdeps/unix/sysv/linux/Versions: Mention gethugepagesize(). 2002-10-02 David Mosberger * sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Mention sys/hugepage.h. * sysdeps/unix/sysv/linux/syscalls.list: Make alloc_hugepages and free_hugepages weak symbols. * sysdeps/unix/sysv/linux/Versions: Mention alloc_hugepages and free_hugepages. 2002-10-01 Rohit Seth , David Mosberger * sysdeps/unix/sysv/linux/syscalls.list: Add alloc_hugepages and free_hugepages. * sysdeps/unix/sysv/linux/sys/hugepage.h: New file. 2002-10-02 David Mosberger * sysdeps/ia64/bzero.S: Rewritten by Sverre Jarp to tune for Itanium 2 (and Itanium). Fix unwind directives and make it fit in 80 columns. * sysdeps/ia64/memset.S: Ditto. * sysdeps/ia64/memcpy.S: Ditto. Move jump table to .rodata section. Index: sysdeps/unix/sysv/linux/Makefile =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/Makefile,v retrieving revision 1.121 diff -u -r1.121 Makefile --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Makefile 15 Sep 2002 02:30:28 -0000 1.121 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Makefile 4 Oct 2002 05:45:31 -0000 @@ -20,7 +20,7 @@ sys/kd.h sys/soundcard.h sys/vt.h \ sys/quota.h sys/fsuid.h \ scsi/sg.h scsi/scsi.h scsi/scsi_ioctl.h sys/pci.h \ - sys/ultrasound.h sys/raw.h sys/personality.h + sys/ultrasound.h sys/raw.h sys/personality.h sys/hugepage.h install-others += $(inst_includedir)/bits/syscall.h Index: sysdeps/unix/sysv/linux/Versions =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/Versions,v retrieving revision 1.18 diff -u -r1.18 Versions --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Versions 30 Aug 2002 01:30:55 -0000 1.18 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Versions 4 Oct 2002 05:45:31 -0000 @@ -102,6 +102,10 @@ # r* readahead; + gethugepagesize; + alloc_hugepages; + free_hugepages; + #errlist-compat 126 _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; } Index: sysdeps/unix/sysv/linux/getsysstats.c =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/getsysstats.c,v retrieving revision 1.22 diff -u -r1.22 getsysstats.c --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/getsysstats.c 21 Sep 2002 05:26:12 -0000 1.22 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/getsysstats.c 4 Oct 2002 05:45:32 -0000 @@ -230,11 +230,8 @@ #endif weak_alias (__get_nprocs_conf, get_nprocs_conf) -/* General function to get information about memory status from proc - filesystem. */ static long int -internal_function -phys_pages_info (const char *format) +get_meminfo (const char *format) { FILE *fp; char buffer[8192]; @@ -264,7 +261,7 @@ while (fgets_unlocked (buffer, sizeof buffer, fp) != NULL) if (sscanf (buffer, format, &result) == 1) { - result /= (__getpagesize () / 1024); + result /= 1024; break; } @@ -279,6 +276,20 @@ return result; } +/* General function to get information about memory status from proc + filesystem. */ +static long int +internal_function +phys_pages_info (const char *format) +{ + long int result = get_meminfo (format); + + if (result != -1) + result /= __getpagesize (); + + return result; +} + /* Return the number of pages of physical memory in the system. There is currently (as of version 2.0.21) no system call to determine the @@ -320,6 +331,12 @@ } weak_alias (__get_avphys_pages, get_avphys_pages) +size_t +__gethugepagesize () +{ + return get_meminfo ("Hugepagesize: %lu kB"); +} +weak_alias (__gethugepagesize, gethugepagesize); static void free_mem (void) Index: sysdeps/unix/sysv/linux/syscalls.list =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/syscalls.list,v retrieving revision 1.94 diff -u -r1.94 syscalls.list --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/syscalls.list 15 Aug 2002 08:25:16 -0000 1.94 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/syscalls.list 4 Oct 2002 05:45:32 -0000 @@ -80,3 +80,5 @@ lremovexattr EXTRA lremovexattr i:ss lremovexattr fremovexattr EXTRA fremovexattr i:is fremovexattr +alloc_hugepages EXTRA alloc_hugepages b:ianii __alloc_hugepages alloc_hugepages +free_hugepages EXTRA free_hugepages i:a __free_hugepages free_hugepages Index: sysdeps/unix/sysv/linux/sys/hugepage.h =================================================================== RCS file: sysdeps/unix/sysv/linux/sys/hugepage.h diff -N sysdeps/unix/sysv/linux/sys/hugepage.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sysdeps/unix/sysv/linux/sys/sysdeps/unix/sysv/linux/sys/hugepage.h 4 Oct 2002 05:45:36 -0000 @@ -0,0 +1,78 @@ +/* Copyright (C) 2002 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 _SYS_HUGEPAGE_H +#define _SYS_HUGEPAGE_H 1 + +/* This header file defines the huge page interface. A huge page is a + non-swappable (pinned) page of virtual memory. As the name + suggests, the size of a huge page is typically orders of magnitudes + bigger than the value returned by getpagesize(). For example, + depending on kernel configuration, on x86 it may be 2MBytes or + 4MBytes and on ia64 it is typically one of 16MB, 256MBytes, or + 4GBytes. Note that because huge pages are never swapped, they are + a relatively rare commodity and applications are expected to fall + back to allocating regular pages if a huge page cannot be + allocated. */ + +#include + +#define __need_size_t +#include + +__BEGIN_DECLS + +/* Return the size of a huge page. */ + +extern size_t __gethugepagesize (void) __attribute__ ((__const__)) __THROW; +extern size_t gethugepagesize (void) __attribute__ ((__const__)) __THROW; + +/* Allocate LEN bytes worth of huge pages. LEN must be an integer + multiple of the huge page size. ADDR is the preferred starting + address for the memory. PROT is a mask of protection bits that + specify how the memory is to be mapped (PROT_NONE or any + combination of PROT_READ, PROT_WRITE, or PROT_EXEC). If KEY has is + a positive number, FLAG can be set to IPC_CREAT to request the + creation of a new shared memory segment or to zero to request + attaching to an existing shared memory segment. + + Return value: On success, alloc_hugepages() returns a pointer to + the allocated memory. On error, MAP_FAILED ((void *) -1) is + returned and ERRNO is set appropriately. + + Errors: + EINVAL LEN is not a integer multiple of gethugepagesize() + or KEY is a negative value. + + ENOENT No shared segment matching KEY was found and FLAGS + was zero. */ + +extern void *alloc_hugepages (int __key, void *__addr, size_t __len, + int __prot, int __flag) __THROW; + +/* Free the huge page resources from the current process's address + space. ADDR must be an address returned by a previous call to + alloc_hugepages (). Note that for shared memory segments, the + underlying physical memory will be freed only after the last + process using them has freed them up or has exited. */ + +extern int free_hugepages (void *__addr) __THROW; + +__END_DECLS + +#endif /* sys/hugepage.h */ From aj@suse.de Fri Oct 4 20:02:00 2002 From: aj@suse.de (Andreas Jaeger) Date: Fri, 04 Oct 2002 20:02:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <15773.11197.780790.750761@napali.hpl.hp.com> (David Mosberger's message of "Thu, 3 Oct 2002 22:48:45 -0700") References: <15772.47660.333934.293189@napali.hpl.hp.com> <200210032146.g93LkB119076@magilla.sf.frob.com> <15772.48947.101500.167377@napali.hpl.hp.com> <3D9CC520.8010403@redhat.com> <15773.11197.780790.750761@napali.hpl.hp.com> Message-ID: David Mosberger writes: >>>>>> On Thu, 03 Oct 2002 15:30:56 -0700, Ulrich Drepper said: > > Uli> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 > > > >> Uli, do you have any other feedback or are you OK with it? > > Uli> The header still isn't right. You cannot have the hidden > Uli> macros in there. And the function prototypes are missing > Uli> __THROW. > > OK, how is this? > [...] > Index: sysdeps/unix/sysv/linux/Versions > =================================================================== > RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/Versions,v > retrieving revision 1.18 > diff -u -r1.18 Versions > --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Versions 30 Aug 2002 01:30:55 -0000 1.18 > +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Versions 4 Oct 2002 05:45:31 -0000 > @@ -102,6 +102,10 @@ > # r* > readahead; > > + gethugepagesize; > + alloc_hugepages; > + free_hugepages; > + With glibc 2.3 out of the door, this has to be added with version glibc 2.3.1. > Index: sysdeps/unix/sysv/linux/sys/hugepage.h > =================================================================== > RCS file: sysdeps/unix/sysv/linux/sys/hugepage.h > diff -N sysdeps/unix/sysv/linux/sys/hugepage.h > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ sysdeps/unix/sysv/linux/sys/sysdeps/unix/sysv/linux/sys/hugepage.h 4 Oct 2002 05:45:36 -0000 > @@ -0,0 +1,78 @@ > +/* Copyright (C) 2002 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 _SYS_HUGEPAGE_H > +#define _SYS_HUGEPAGE_H 1 > + > +/* This header file defines the huge page interface. A huge page is a > + non-swappable (pinned) page of virtual memory. As the name > + suggests, the size of a huge page is typically orders of magnitudes > + bigger than the value returned by getpagesize(). For example, > + depending on kernel configuration, on x86 it may be 2MBytes or > + 4MBytes and on ia64 it is typically one of 16MB, 256MBytes, or > + 4GBytes. Note that because huge pages are never swapped, they are > + a relatively rare commodity and applications are expected to fall > + back to allocating regular pages if a huge page cannot be > + allocated. */ > + > +#include > + > +#define __need_size_t > +#include > + > +__BEGIN_DECLS > + > +/* Return the size of a huge page. */ > + > +extern size_t __gethugepagesize (void) __attribute__ ((__const__)) __THROW; The header installed in the user level include should not have the __gethugepagesize. If you need the prototype, we add it to an internal header. Andreas -- Andreas Jaeger SuSE Labs aj@suse.de private aj@arthur.inka.de http://www.suse.de/~aj From kkojima@rr.iij4u.or.jp Sat Oct 5 14:55:00 2002 From: kkojima@rr.iij4u.or.jp (kaz Kojima) Date: Sat, 05 Oct 2002 14:55:00 -0000 Subject: SH TLS macros fix Message-ID: <200210050302.g9532GO02850@r-rr.iij4u.or.jp> Hi, Uli pointed out to me that now SH TLS ABI doesn't need R_SH_TLS_*_MOV relocations. I've fixed binutils and then found the current macros for SH in elf/tls-macros.h don't match ABI. Here is a fix. BTW, I've revised my tiny TLS memo . I'll send binutils changes to binutils mailing list ASAP. Regards, kaz -- 2002-10-05 Kaz Kojima * elf/tls-macros.h: Fix SH version of macros so as to match ABI syntax. --- ORIG/libc/elf/tls-macros.h Thu Oct 3 19:42:19 2002 +++ LOCAL/libc/elf/tls-macros.h Sat Oct 5 10:10:52 2002 @@ -154,8 +154,8 @@ "bra 2f\n\t" \ " add %1,%0\n\t" \ ".align 2\n\t" \ - "0: .long _GLOBAL_OFFSET_TABLE_\n\t" \ "1: .long " #x "@gottpoff\n\t" \ + "0: .long _GLOBAL_OFFSET_TABLE_\n\t" \ "2:" \ : "=r" (__l), "=r" (__tp) : : "r0", "r12"); \ __l; }) @@ -171,17 +171,20 @@ "add r0,r1\n\t" \ "jsr @r1\n\t" \ " add r12,r4\n\t" \ - "mov.l 3f,%0\n\t" \ "bra 4f\n\t" \ - " add r0,%0\n\t" \ + " nop\n\t" \ ".align 2\n\t" \ - "0: .long _GLOBAL_OFFSET_TABLE_\n\t" \ "1: .long " #x "@tlsldm\n\t" \ "2: .long __tls_get_addr@plt\n\t" \ + "0: .long _GLOBAL_OFFSET_TABLE_\n\t" \ + "4: mov.l 3f,%0\n\t" \ + "bra 5f\n\t" \ + " add r0,%0\n\t" \ + ".align 2\n\t" \ "3: .long " #x "@dtpoff\n\t" \ - "4:" \ + "5:" \ : "=r" (__l) : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ - "r12", "pr", "t"); \ + "r12", "pr", "t"); \ __l; }) # define TLS_GD(x) \ @@ -198,12 +201,12 @@ "bra 3f\n\t" \ " mov r0,%0\n\t" \ ".align 2\n\t" \ - "0: .long _GLOBAL_OFFSET_TABLE_\n\t" \ "1: .long " #x "@tlsgd\n\t" \ "2: .long __tls_get_addr@plt\n\t" \ + "0: .long _GLOBAL_OFFSET_TABLE_\n\t" \ "3:" \ : "=r" (__l) : : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ - "r12", "pr", "t"); \ + "r12", "pr", "t"); \ __l; }) #else From roland@redhat.com Sat Oct 5 15:06:00 2002 From: roland@redhat.com (Roland McGrath) Date: Sat, 05 Oct 2002 15:06:00 -0000 Subject: __builtin_frame_address vs %esp in pt-machine.h Message-ID: <200210052155.g95LtK226078@magilla.sf.frob.com> What was the reason for this change in linuxthreads? 2001-04-12 Ulrich Drepper * sysdeps/i386/Makefile: Make sure gcc uses a frame pointer for all the files which use CURRENT_STACK_FRAME. * sysdeps/i386/pt-machine.h (CURRENT_STACK_FRAME): Define using __builtin_frame_address. * sysdeps/i386/i686/pt-machine.h: Likewise. The -fomit-frame-pointer build is broken for !FLOATING_STACKS because we failed to keep the sysdeps/i386/Makefile up to date with every source file that uses THREAD_*MEM (probably my fault). The plan of adding all such files to sysdeps/i386/Makefile seems very error prone (cf the current error) and definitely ugly. It would be safest to apply it to all the linuxthreads source files. But I don't see why we don't just use the definition that works with or without -fomit-frame-pointer. I don't get any compilation errors from reverting this change. So I wonder what motivated it. Going back to using %esp in a global register variable seems like the best way to fix the current problems to me. From drepper@redhat.com Sun Oct 6 13:24:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Sun, 06 Oct 2002 13:24:00 -0000 Subject: __builtin_frame_address vs %esp in pt-machine.h References: <200210052155.g95LtK226078@magilla.sf.frob.com> Message-ID: <3D9F6251.30000@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Roland McGrath wrote: > What was the reason for this change in linuxthreads? > > 2001-04-12 Ulrich Drepper > > * sysdeps/i386/Makefile: Make sure gcc uses a frame pointer for > all the files which use CURRENT_STACK_FRAME. > * sysdeps/i386/pt-machine.h (CURRENT_STACK_FRAME): Define using > __builtin_frame_address. > * sysdeps/i386/i686/pt-machine.h: Likewise. > > The -fomit-frame-pointer build is broken for !FLOATING_STACKS because we > failed to keep the sysdeps/i386/Makefile up to date with every source file > that uses THREAD_*MEM (probably my fault). The problem is the ptlongjmp.c code. For its use of CURRENT_STACK_FRAME the value must be as accurate as possible since otherwise the detection of frames which have to be handled might be wrong. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9n2JS2ijCOnn/RHQRAt2OAKCEdBga2IxMC/OtPCp2tQMKGWX+aQCfabYC 6c2IjgwOL7L+AI185XQGefQ= =FjmT -----END PGP SIGNATURE----- From jakub@redhat.com Mon Oct 7 00:50:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 07 Oct 2002 00:50:00 -0000 Subject: PPC32 dl-machine.c bugs Message-ID: <20021006222444.F3451@sunsite.ms.mff.cuni.cz> Hi! While looking at ppc64 dl-machine.h and comparing it with ppc32 dl-machine.[ch], I stopped on the following two issues: a) from ppc64/dl-machine.h I understand ppc is strict alignment machine, ie. unaligned stores should be done one byte at a time, right? b) finaladdr > 0x7fff && finaladdr < 0x8000 where finaladdr is uint32_t is bogus test (always 0). It should be finaladdr > 0x7fff && finaladdr < 0xffff8000 (or (finaladdr + 0x8000) < 0x10000). And __builtin_expect certainly won't hurt. 2002-10-06 Jakub Jelinek * sysdeps/powerpc/powerpc32/dl-machine.c (__process_machine_rela): Store R_PPC_UADDR32 and R_PPC_UADDR16 one byte at a time. Use __builtin_expect for R_PPC_ADDR24 overflow check. Fix R_PPC_ADDR16, R_PPC_UADDR16 and R_PPC_ADDR14* overflow check, use __builtin_expect. --- libc/sysdeps/powerpc/powerpc32/dl-machine.c.jj 2002-09-05 10:24:12.000000000 +0200 +++ libc/sysdeps/powerpc/powerpc32/dl-machine.c 2002-10-06 22:24:41.000000000 +0200 @@ -409,25 +409,37 @@ __process_machine_rela (struct link_map return; case R_PPC_ADDR32: - case R_PPC_UADDR32: case R_PPC_GLOB_DAT: case R_PPC_RELATIVE: *reloc_addr = finaladdr; return; + case R_PPC_UADDR32: + ((char *) reloc_addr)[0] = value >> 24; + ((char *) reloc_addr)[1] = value >> 16; + ((char *) reloc_addr)[2] = value >> 8; + ((char *) reloc_addr)[3] = value; + break; + case R_PPC_ADDR24: - if (finaladdr > 0x01fffffc && finaladdr < 0xfe000000) + if (__builtin_expect (finaladdr > 0x01fffffc && finaladdr < 0xfe000000, 0)) dl_reloc_overflow (map, "R_PPC_ADDR24", reloc_addr, sym, refsym); *reloc_addr = (*reloc_addr & 0xfc000003) | (finaladdr & 0x3fffffc); break; case R_PPC_ADDR16: - case R_PPC_UADDR16: - if (finaladdr > 0x7fff && finaladdr < 0x8000) + if (__builtin_expect (finaladdr > 0x7fff && finaladdr < 0xffff8000, 0)) dl_reloc_overflow (map, "R_PPC_ADDR16", reloc_addr, sym, refsym); *(Elf32_Half*) reloc_addr = finaladdr; break; + case R_PPC_UADDR16: + if (__builtin_expect (finaladdr > 0x7fff && finaladdr < 0xffff8000, 0)) + dl_reloc_overflow (map, "R_PPC_UADDR16", reloc_addr, sym, refsym); + ((char *) reloc_addr)[0] = value >> 8; + ((char *) reloc_addr)[1] = value; + break; + case R_PPC_ADDR16_LO: *(Elf32_Half*) reloc_addr = finaladdr; break; @@ -443,7 +455,7 @@ __process_machine_rela (struct link_map case R_PPC_ADDR14: case R_PPC_ADDR14_BRTAKEN: case R_PPC_ADDR14_BRNTAKEN: - if (finaladdr > 0x7fff && finaladdr < 0x8000) + if (__builtin_expect (finaladdr > 0x7fff && finaladdr < 0xffff8000, 0)) dl_reloc_overflow (map, "R_PPC_ADDR14", reloc_addr, sym, refsym); *reloc_addr = (*reloc_addr & 0xffff0003) | (finaladdr & 0xfffc); if (rinfo != R_PPC_ADDR14) Jakub From roland@redhat.com Mon Oct 7 16:09:00 2002 From: roland@redhat.com (Roland McGrath) Date: Mon, 07 Oct 2002 16:09:00 -0000 Subject: Itanium 2 tuned versions of bzero, memset, and memcpy In-Reply-To: David Mosberger's message of Wednesday, 2 October 2002 23:05:30 -0700 <200210030605.g9365UUC020000@napali.hpl.hp.com> Message-ID: <200210070750.g977ocS13619@magilla.sf.frob.com> Thanks. I will put that in for 2.3.1. From jakub@redhat.com Mon Oct 7 16:20:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 07 Oct 2002 16:20:00 -0000 Subject: [PATCH] __libc_alloca_cutoff (aka make mysql and others apps with very low RLIMIT_STACK setting happy) Message-ID: <20021008010912.K3451@sunsite.ms.mff.cuni.cz> Hi! MySQL is using very low RLIMIT_STACK setting (or is it just too low pthread_attr_setstacksize?) yet does gethostbyname from such threads and thus crashes when external connections are made to it. There is a lot of other places in glibc which use various hardcoded constants to decide whether to use alloca or fall back to malloc. The following patch deals with this by changing all such hardcoded constants (I could find) to a variable and changes resolv to also use malloc as fallback variant. I haven't changed all setrlimit and getrlimit implementations yet (nor have a nptl patch) plus did only limited testing so far, but e.g. #include #include void *foo (void *arg) { gethostbyname ("sources.redhat.com"); return 0; } int main (void) { pthread_attr_t a; pthread_t t; pthread_attr_init (&a); pthread_attr_setstacksize (&a, 16384); pthread_create (&t, &a, foo, 0); pthread_join (t, NULL); } or #include #include void *foo (void *arg) { gethostbyname ("sources.redhat.com"); return 0; } int main (void) { struct rlimit r; getrlimit (RLIMIT_STACK, &r); r.rlim_cur = 3*4096; setrlimit (RLIMIT_STACK, &r); foo (0); } work now and crashed before. Setting rlim_cur to 8192 and doing DNS lookup still crashes, since res_init.c (but other places in glibc too) use char buf[BUFSIZ]; on the stack. 2002-10-07 Jakub Jelinek * include/alloca.h (__libc_alloca_cutoff): New variable. (__libc_set_alloca_cutoff): New prototype. (__set_alloca_cutoff): New inline function. * malloc/Versions (libc: GLIBC_PRIVATE): Export __libc_alloca_cutoff and __libc_set_alloca_cutoff. * malloc/Makefile (routines): Add allocalim. * malloc/allocalim.c: New file. * resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname2_r, _nss_dns_gethostbyaddr_r): Use alloca or malloc to allocate host_buffer depending on __libc_alloca_cutoff. * resolv/nss_dns/dns-network.c (_nss_dns_getnetbyname_r, _nss_dns_getnetbyaddr_r): Use alloca or malloc to allocate net_buffer depending on __libc_alloca_cutoff. * resolv/res_query.c (res_nquery): Use alloca or malloc to allocate buf depending on __libc_alloca_cutoff. * resolv/gethnamaddr.c (gethostbyname2, gethostbyaddr): Likewise. * stdio-common/vfprintf.c (vfprintf): Use __libc_alloca_cutoff instead of hardcoded constants. * stdio-common/printf_fp.c (__printf_fp): Likewise. * string/strcoll.c (strcoll): Likewise. * string/strxfrm.c (strxfrm): Likewise. * sysdeps/posix/readv.c (__readv): Likewise. * sysdeps/posix/writev.c (__writev): Likewise. * sysdeps/unix/sysv/linux/i386/setrlimit.c (__new_setrlimit): Call __set_alloca_cutoff. * sysdeps/unix/sysv/linux/i386/getrlimit.c (__new_getrlimit): Likewise. * manager.c (__pthread_allocate_stack): Call __set_alloca_cutoff. --- libc/include/alloca.h.jj 2002-09-30 16:45:04.000000000 +0200 +++ libc/include/alloca.h 2002-10-08 00:12:01.000000000 +0200 @@ -11,4 +11,16 @@ extern void *__alloca (size_t __size); # define __alloca(size) __builtin_alloca (size) #endif /* GCC. */ +extern size_t __libc_alloca_cutoff; +libc_hidden_proto (__libc_alloca_cutoff) + +extern void __libc_set_alloca_cutoff (size_t size); +libc_hidden_proto (__libc_set_alloca_cutoff) + +extern inline void __set_alloca_cutoff (size_t size) +{ + if (__libc_alloca_cutoff > size / 4) + __libc_set_alloca_cutoff (size / 4); +} + #endif --- libc/linuxthreads/manager.c.jj 2002-08-28 12:58:03.000000000 +0200 +++ libc/linuxthreads/manager.c 2002-10-07 23:55:45.000000000 +0200 @@ -388,6 +388,7 @@ static int pthread_allocate_stack(const /* Clear the thread data structure. */ memset (new_thread, '\0', sizeof (*new_thread)); #endif + stacksize = attr->__stacksize; } else { @@ -555,6 +556,7 @@ static int pthread_allocate_stack(const # endif /* !NEED_SEPARATE_REGISTER_STACK */ #endif /* !FLOATING_STACKS */ } + __set_alloca_cutoff (stacksize); *out_new_thread = (char *) new_thread; *out_new_thread_bottom = new_thread_bottom; *out_guardaddr = guardaddr; --- libc/malloc/Versions.jj 2000-04-18 08:13:14.000000000 +0200 +++ libc/malloc/Versions 2002-10-07 23:54:46.000000000 +0200 @@ -55,4 +55,7 @@ libc { # p* posix_memalign; } + GLIBC_PRIVATE { + __libc_alloca_cutoff; __libc_set_alloca_cutoff; + } } --- libc/malloc/Makefile.jj 2002-09-20 08:48:09.000000000 +0200 +++ libc/malloc/Makefile 2002-10-07 14:28:48.000000000 +0200 @@ -36,7 +36,7 @@ distribute = thread-m.h mtrace.pl mcheck gmalloc-routines := malloc morecore # Things to include in the standalone distribution. dist-routines = $(gmalloc-routines) mcheck mtrace -routines = $(dist-routines) obstack +routines = $(dist-routines) obstack allocalim install-lib := libmcheck.a non-lib.a := libmcheck.a --- libc/malloc/allocalim.c.jj 2002-10-07 14:28:54.000000000 +0200 +++ libc/malloc/allocalim.c 2002-10-08 00:12:20.000000000 +0200 @@ -0,0 +1,36 @@ +/* Alloca upper bound handling. + Copyright (C) 2002 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 + +/* Default alloca cutoff. */ +size_t __libc_alloca_cutoff = 65536; +libc_hidden_data_def (__libc_alloca_cutoff) + +__libc_lock_define_initialized (static, lock); + +void __libc_set_alloca_cutoff (size_t size) +{ + __libc_lock_lock (lock); + if (__libc_alloca_cutoff > size) + __libc_alloca_cutoff = size; + __libc_lock_unlock (lock); +} +libc_hidden_def (__libc_set_alloca_cutoff) --- libc/resolv/nss_dns/dns-host.c.jj 2002-08-27 23:19:49.000000000 +0200 +++ libc/resolv/nss_dns/dns-host.c 2002-10-07 23:29:43.000000000 +0200 @@ -132,12 +132,13 @@ _nss_dns_gethostbyname2_r (const char *n char *buffer, size_t buflen, int *errnop, int *h_errnop) { - querybuf host_buffer; + querybuf *host_buffer; char tmp[NS_MAXDNAME]; int size, type, n; const char *cp; - int map = 0; + int map = 0, use_malloc = 0; int olderr = errno; + enum nss_status status; if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1) return NSS_STATUS_UNAVAIL; @@ -169,8 +170,21 @@ _nss_dns_gethostbyname2_r (const char *n && (cp = res_hostalias (&_res, name, tmp, sizeof (tmp))) != NULL) name = cp; - n = res_nsearch (&_res, name, C_IN, type, host_buffer.buf, - sizeof (host_buffer.buf)); + if (__libc_alloca_cutoff < MAXPACKET) + { + host_buffer = (querybuf *) malloc (sizeof (querybuf)); + if (host_buffer == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + use_malloc = 1; + } + else + host_buffer = (querybuf *) alloca (sizeof (querybuf)); + + n = res_nsearch (&_res, name, C_IN, type, host_buffer->buf, + sizeof (host_buffer->buf)); if (n < 0) { enum nss_status status = (errno == ECONNREFUSED @@ -185,11 +199,15 @@ _nss_dns_gethostbyname2_r (const char *n by having the RES_USE_INET6 bit in _res.options set, we try another lookup. */ if (af == AF_INET6 && (_res.options & RES_USE_INET6)) - n = res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf, - sizeof (host_buffer.buf)); + n = res_nsearch (&_res, name, C_IN, T_A, host_buffer->buf, + sizeof (host_buffer->buf)); if (n < 0) - return status; + { + if (use_malloc) + free (host_buffer); + return status; + } map = 1; @@ -197,8 +215,11 @@ _nss_dns_gethostbyname2_r (const char *n result->h_length = INADDRSZ;; } - return getanswer_r (&host_buffer, n, name, type, result, buffer, buflen, - errnop, h_errnop, map); + status = getanswer_r (host_buffer, n, name, type, result, buffer, buflen, + errnop, h_errnop, map); + if (use_malloc) + free (host_buffer); + return status; } @@ -236,10 +257,10 @@ _nss_dns_gethostbyaddr_r (const void *ad char *h_addr_ptrs[MAX_NR_ADDRS + 1]; char linebuffer[0]; } *host_data = (struct host_data *) buffer; - querybuf host_buffer; + querybuf *host_buffer; char qbuf[MAXDNAME+1], *qp = NULL; size_t size; - int n, status; + int n, status, use_malloc = 0; int olderr = errno; if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1) @@ -294,23 +315,40 @@ _nss_dns_gethostbyaddr_r (const void *ad break; } - n = res_nquery (&_res, qbuf, C_IN, T_PTR, (u_char *)host_buffer.buf, - sizeof host_buffer); + if (__libc_alloca_cutoff < MAXPACKET) + { + host_buffer = (querybuf *) malloc (sizeof (querybuf)); + if (host_buffer == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + use_malloc = 1; + } + else + host_buffer = (querybuf *) alloca (sizeof (querybuf)); + + n = res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer->buf, + sizeof (host_buffer->buf)); if (n < 0 && af == AF_INET6) { strcpy (qp, "ip6.int"); - n = res_nquery (&_res, qbuf, C_IN, T_PTR, (u_char *)host_buffer.buf, - sizeof host_buffer); + n = res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer->buf, + sizeof (host_buffer->buf)); } if (n < 0) { *h_errnop = h_errno; __set_errno (olderr); + if (use_malloc) + free (host_buffer); return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; } - status = getanswer_r (&host_buffer, n, qbuf, T_PTR, result, buffer, buflen, + status = getanswer_r (host_buffer, n, qbuf, T_PTR, result, buffer, buflen, errnop, h_errnop, 0 /* XXX */); + if (use_malloc) + free (host_buffer); if (status != NSS_STATUS_SUCCESS) { *h_errnop = h_errno; --- libc/resolv/nss_dns/dns-network.c.jj 2002-09-05 11:57:18.000000000 +0200 +++ libc/resolv/nss_dns/dns-network.c 2002-10-07 18:42:42.000000000 +0200 @@ -110,27 +110,47 @@ _nss_dns_getnetbyname_r (const char *nam int *herrnop) { /* Return entry for network with NAME. */ - querybuf net_buffer; - int anslen; + querybuf *net_buffer; + int anslen, use_malloc = 0; char *qbuf; + enum nss_status status; if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1) return NSS_STATUS_UNAVAIL; qbuf = strdupa (name); - anslen = res_nsearch (&_res, qbuf, C_IN, T_PTR, (u_char *) &net_buffer, - sizeof (querybuf)); + + if (__libc_alloca_cutoff < MAXPACKET) + { + net_buffer = (querybuf *) malloc (sizeof (querybuf)); + if (net_buffer == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + use_malloc = 1; + } + else + net_buffer = (querybuf *) alloca (sizeof (querybuf)); + + anslen = res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer->buf, + sizeof (net_buffer->buf)); if (anslen < 0) { /* Nothing found. */ *errnop = errno; + if (use_malloc) + free (net_buffer); return (errno == ECONNREFUSED || errno == EPFNOSUPPORT || errno == EAFNOSUPPORT) ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; } - return getanswer_r (&net_buffer, anslen, result, buffer, buflen, BYNAME); + status = getanswer_r (net_buffer, anslen, result, buffer, buflen, BYNAME); + if (use_malloc) + free (net_buffer); + return status; } @@ -141,10 +161,10 @@ _nss_dns_getnetbyaddr_r (uint32_t net, i { /* Return entry for network with NAME. */ enum nss_status status; - querybuf net_buffer; + querybuf *net_buffer; unsigned int net_bytes[4]; char qbuf[MAXDNAME]; - int cnt, anslen; + int cnt, anslen, use_malloc = 0; u_int32_t net2; int olderr = errno; @@ -181,20 +201,37 @@ _nss_dns_getnetbyaddr_r (uint32_t net, i break; } - anslen = res_nquery (&_res, qbuf, C_IN, T_PTR, (u_char *) &net_buffer, - sizeof (querybuf)); + if (__libc_alloca_cutoff < MAXPACKET) + { + net_buffer = (querybuf *) malloc (sizeof (querybuf)); + if (net_buffer == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + use_malloc = 1; + } + else + net_buffer = (querybuf *) alloca (sizeof (querybuf)); + + anslen = res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer->buf, + sizeof (net_buffer->buf)); if (anslen < 0) { /* Nothing found. */ int err = errno; __set_errno (olderr); + if (use_malloc) + free (net_buffer); return (err == ECONNREFUSED || err == EPFNOSUPPORT || err == EAFNOSUPPORT) ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; } - status = getanswer_r (&net_buffer, anslen, result, buffer, buflen, BYADDR); + status = getanswer_r (net_buffer, anslen, result, buffer, buflen, BYADDR); + if (use_malloc) + free (net_buffer); if (status == NSS_STATUS_SUCCESS) { /* Strip trailing zeros. */ --- libc/resolv/res_query.c.jj 2002-08-27 23:19:49.000000000 +0200 +++ libc/resolv/res_query.c 2002-10-07 18:03:27.000000000 +0200 @@ -108,28 +108,42 @@ res_nquery(res_state statp, u_char *answer, /* buffer to put answer */ int anslen) /* size of answer buffer */ { - u_char buf[MAXPACKET]; + u_char *buf; HEADER *hp = (HEADER *) answer; - int n; + int n, use_malloc = 0; hp->rcode = NOERROR; /* default */ + if (__libc_alloca_cutoff < MAXPACKET) { + buf = malloc (MAXPACKET); + if (buf == NULL) { + __set_h_errno (NETDB_INTERNAL); + return -1; + } + use_malloc = 1; + } else + buf = alloca (MAXPACKET); + #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; res_query(%s, %d, %d)\n", name, class, type); #endif n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL, - buf, sizeof(buf)); + buf, MAXPACKET); if (n <= 0) { #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; res_query: mkquery failed\n"); #endif RES_SET_H_ERRNO(statp, NO_RECOVERY); + if (use_malloc) + free (buf); return (n); } n = res_nsend(statp, buf, n, answer, anslen); + if (use_malloc) + free (buf); if (n < 0) { #ifdef DEBUG if (statp->options & RES_DEBUG) --- libc/resolv/gethnamaddr.c.jj 2002-09-25 11:11:53.000000000 +0200 +++ libc/resolv/gethnamaddr.c 2002-10-07 23:23:52.000000000 +0200 @@ -510,10 +510,11 @@ gethostbyname2(name, af) const char *name; int af; { - querybuf buf; + querybuf *buf; register const char *cp; char *bp; - int n, size, type, len; + int n, size, type, len, use_malloc = 0; + struct hostent *ret; extern struct hostent *_gethtbyname2(); if ((_res.options & RES_INIT) == 0 && __res_ninit(&_res) == -1) { @@ -615,13 +616,26 @@ gethostbyname2(name, af) break; } - if ((n = res_nsearch(&_res, name, C_IN, type, buf.buf, sizeof(buf.buf))) < 0) { + if (__libc_alloca_cutoff < MAXPACKET) { + buf = (querybuf *) malloc (sizeof (*buf)); + if (buf == NULL) { + __set_h_errno (NETDB_INTERNAL); + return NULL; + } + use_malloc = 1; + } else + buf = (querybuf *) alloca (sizeof (*buf)); + + if ((n = res_nsearch(&_res, name, C_IN, type, buf->buf, sizeof(buf->buf))) < 0) { dprintf("res_nsearch failed (%d)\n", n); if (errno == ECONNREFUSED) return (_gethtbyname2(name, af)); return (NULL); } - return (getanswer(&buf, n, name, type)); + ret = getanswer(buf, n, name, type); + if (use_malloc) + free (buf); + return ret; } struct hostent * @@ -633,9 +647,9 @@ gethostbyaddr(addr, len, af) const u_char *uaddr = (const u_char *)addr; static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; - int n; + int n, use_malloc = 0; socklen_t size; - querybuf buf; + querybuf *buf; register struct hostent *hp; char qbuf[MAXDNAME+1], *qp = NULL; #ifdef SUNSECURITY @@ -696,18 +710,34 @@ gethostbyaddr(addr, len, af) default: abort(); } - n = res_nquery(&_res, qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf); + + if (__libc_alloca_cutoff < MAXPACKET) { + buf = (querybuf *) malloc (sizeof (*buf)); + if (buf == NULL) { + __set_h_errno (NETDB_INTERNAL); + return NULL; + } + use_malloc = 1; + } else + buf = (querybuf *) alloca (sizeof (*buf)); + + n = res_nquery(&_res, qbuf, C_IN, T_PTR, buf->buf, sizeof buf->buf); if (n < 0 && af == AF_INET6) { strcpy(qp, "ip6.int"); - n = res_nquery(&_res, qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf); + n = res_nquery(&_res, qbuf, C_IN, T_PTR, buf->buf, sizeof buf->buf); } if (n < 0) { + if (use_malloc) + free (buf); dprintf("res_nquery failed (%d)\n", n); if (errno == ECONNREFUSED) return (_gethtbyaddr(addr, len, af)); return (NULL); } - if (!(hp = getanswer(&buf, n, qbuf, T_PTR))) + hp = getanswer(buf, n, qbuf, T_PTR); + if (use_malloc) + free (buf); + if (!hp) return (NULL); /* h_errno was set by getanswer() */ #ifdef SUNSECURITY if (af == AF_INET) { --- libc/stdio-common/vfprintf.c.jj 2002-09-30 16:45:06.000000000 +0200 +++ libc/stdio-common/vfprintf.c 2002-10-07 14:21:46.000000000 +0200 @@ -1039,7 +1039,7 @@ vfprintf (FILE *s, const CHAR_T *format, \ /* Allocate dynamically an array which definitely is long \ enough for the wide character version. */ \ - if (len < 8192) \ + if (len <= __libc_alloca_cutoff) \ string = (CHAR_T *) alloca (len * sizeof (wchar_t)); \ else if ((string = (CHAR_T *) malloc (len * sizeof (wchar_t))) \ == NULL) \ @@ -1201,7 +1201,7 @@ vfprintf (FILE *s, const CHAR_T *format, if (prec >= 0) \ { \ /* The string `s2' might not be NUL terminated. */ \ - if (prec < 32768) \ + if (prec <= __libc_alloca_cutoff) \ string = (char *) alloca (prec); \ else if ((string = (char *) malloc (prec)) == NULL) \ { \ @@ -1219,7 +1219,7 @@ vfprintf (FILE *s, const CHAR_T *format, { \ assert (__mbsinit (&mbstate)); \ s2 = (const wchar_t *) string; \ - if (len + 1 < 32768) \ + if (len + 1 < __libc_alloca_cutoff) \ string = (char *) alloca (len + 1); \ else if ((string = (char *) malloc (len + 1)) == NULL) \ { \ @@ -1448,7 +1448,7 @@ vfprintf (FILE *s, const CHAR_T *format, { /* We have to use a special buffer. The "32" is just a safe bet for all the output which is not counted in the width. */ - if (width < (int) (32768 / sizeof (CHAR_T))) + if (width <= (int) (__libc_alloca_cutoff / sizeof (CHAR_T))) workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T)) + (width + 32)); else @@ -1473,7 +1473,7 @@ vfprintf (FILE *s, const CHAR_T *format, { /* We have to use a special buffer. The "32" is just a safe bet for all the output which is not counted in the width. */ - if (width < (int) (32768 / sizeof (CHAR_T))) + if (width <= (int) (__libc_alloca_cutoff / sizeof (CHAR_T))) workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T)) + (width + 32)); else @@ -1516,7 +1516,7 @@ vfprintf (FILE *s, const CHAR_T *format, if (prec > width && prec + 32 > (int)(sizeof (work_buffer) / sizeof (work_buffer[0]))) { - if (prec < (int) (32768 / sizeof (CHAR_T))) + if (prec <= (int) (__libc_alloca_cutoff / sizeof (CHAR_T))) workend = alloca (prec + 32) + (prec + 32); else { @@ -1832,7 +1832,8 @@ do_positional: if (MAX (prec, width) + 32 > (int) (sizeof (work_buffer) / sizeof (CHAR_T))) { - if (MAX (prec, width) < (int) (32768 / sizeof (CHAR_T))) + if (MAX (prec, width) + <= (int) (__libc_alloca_cutoff / sizeof (CHAR_T))) workend = ((CHAR_T *) alloca ((MAX (prec, width) + 32) * sizeof (CHAR_T)) + (MAX (prec, width) + 32)); --- libc/stdio-common/printf_fp.c.jj 2002-10-02 10:26:33.000000000 +0200 +++ libc/stdio-common/printf_fp.c 2002-10-07 14:21:46.000000000 +0200 @@ -869,7 +869,8 @@ __printf_fp (FILE *fp, it is possible that we need two more characters in front of all the other output. If the amount of memory we have to allocate is too large use `malloc' instead of `alloca'. */ - buffer_malloced = chars_needed > 5000; + buffer_malloced + = chars_needed > __libc_alloca_cutoff / 2 / sizeof (wchar_t); if (buffer_malloced) { wbuffer = (wchar_t *) malloc ((2 + chars_needed) * sizeof (wchar_t)); --- libc/string/strcoll.c.jj 2002-09-30 16:45:06.000000000 +0200 +++ libc/string/strcoll.c 2002-10-07 14:21:46.000000000 +0200 @@ -155,7 +155,7 @@ STRCOLL (s1, s2, l) Please note that the localedef programs makes sure that `position' is not used at the first level. */ - if (s1len + s2len >= 16384) + if (s1len + s2len > __libc_alloca_cutoff) { idx1arr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1)); idx2arr = &idx1arr[s1len]; --- libc/string/strxfrm.c.jj 2002-09-30 16:45:06.000000000 +0200 +++ libc/string/strxfrm.c 2002-10-07 14:21:46.000000000 +0200 @@ -175,7 +175,7 @@ STRXFRM (STRING_TYPE *dest, const STRING values. But since there is no limit on the length of the string we have to use `malloc' if the string is too long. We should be very conservative here. */ - if (srclen >= 16384) + if (srclen > __libc_alloca_cutoff) { idxarr = (int32_t *) malloc ((srclen + 1) * (sizeof (int32_t) + 1)); rulearr = (unsigned char *) &idxarr[srclen]; --- libc/sysdeps/posix/readv.c.jj 2002-09-30 16:45:08.000000000 +0200 +++ libc/sysdeps/posix/readv.c 2002-10-07 14:21:46.000000000 +0200 @@ -55,8 +55,8 @@ __readv (int fd, const struct iovec *vec /* Allocate a temporary buffer to hold the data. We should normally use alloca since it's faster and does not require synchronization with other threads. But we cannot if the amount of memory - required is too large. Use 512k as the limit. */ - if (bytes < 512 * 1024) + required is too large. */ + if (bytes <= __libc_alloca_cutoff) buffer = (char *) __alloca (bytes); else { --- libc/sysdeps/posix/writev.c.jj 2002-09-30 16:45:08.000000000 +0200 +++ libc/sysdeps/posix/writev.c 2002-10-07 14:21:46.000000000 +0200 @@ -55,8 +55,8 @@ __writev (int fd, const struct iovec *ve /* Allocate a temporary buffer to hold the data. We should normally use alloca since it's faster and does not require synchronization with other threads. But we cannot if the amount of memory - required is too large. Use 512k as the limit. */ - if (bytes < 512 * 1024) + required is too large. */ + if (bytes <= __libc_alloca_cutoff) buffer = (char *) __alloca (bytes); else { --- libc/sysdeps/unix/sysv/linux/i386/setrlimit.c.jj 2001-08-23 18:50:59.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/i386/setrlimit.c 2002-10-08 00:32:58.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 2002 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 @@ -24,6 +24,7 @@ #include #include #include +#include #include "kernel-features.h" @@ -43,6 +44,9 @@ extern int __have_no_new_getrlimit; /* f int __new_setrlimit (enum __rlimit_resource resource, const struct rlimit *rlimits) { + if (__builtin_expect (resource == RLIMIT_STACK, 0)) + __set_alloca_cutoff (rlimits->rlim_cur); + #ifdef __ASSUME_NEW_GETRLIMIT_SYSCALL return INLINE_SYSCALL (setrlimit, 2, resource, CHECK_1 (rlimits)); #else --- libc/sysdeps/unix/sysv/linux/i386/getrlimit.c.jj 2001-08-23 18:50:54.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/i386/getrlimit.c 2002-10-08 00:32:49.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2000, 2002 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,10 +44,15 @@ int __have_no_new_getrlimit; int __new_getrlimit (enum __rlimit_resource resource, struct rlimit *rlimits) { + int result; #ifdef __ASSUME_NEW_GETRLIMIT_SYSCALL - return INLINE_SYSCALL (ugetrlimit, 2, resource, CHECK_1 (rlimits)); + result = INLINE_SYSCALL (ugetrlimit, 2, resource, CHECK_1 (rlimits)); + + if (__builtin_expect (result != -1, 1) + && __builtin_expect (resource == RLIMIT_STACK, 0)) + __set_alloca_cutoff (rlimits->rlim_cur); + return result; #else - int result; # ifdef __NR_ugetrlimit if (__have_no_new_getrlimit <= 0) @@ -57,6 +62,9 @@ __new_getrlimit (enum __rlimit_resource /* If the system call is available remember this fact and return. */ if (result != -1 || errno != ENOSYS) { + if (__builtin_expect (result != -1, 1) + && __builtin_expect (resource == RLIMIT_STACK, 0)) + __set_alloca_cutoff (rlimits->rlim_cur); __have_no_new_getrlimit = -1; return result; } @@ -79,6 +87,8 @@ __new_getrlimit (enum __rlimit_resource if (rlimits->rlim_max == RLIM_INFINITY >> 1) rlimits->rlim_max = RLIM_INFINITY; + if (__builtin_expect (resource == RLIMIT_STACK, 0)) + __set_alloca_cutoff (rlimits->rlim_cur); return result; #endif } Jakub From drepper@redhat.com Mon Oct 7 18:06:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Mon, 07 Oct 2002 18:06:00 -0000 Subject: [PATCH] __libc_alloca_cutoff (aka make mysql and others apps with very low RLIMIT_STACK setting happy) References: <20021008010912.K3451@sunsite.ms.mff.cuni.cz> Message-ID: <3DA2169B.2070004@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jakub Jelinek wrote: > --- libc/include/alloca.h.jj 2002-09-30 16:45:04.000000000 +0200 > +++ libc/include/alloca.h 2002-10-08 00:12:01.000000000 +0200 > @@ -11,4 +11,16 @@ extern void *__alloca (size_t __size); > # define __alloca(size) __builtin_alloca (size) > #endif /* GCC. */ > > +extern size_t __libc_alloca_cutoff; > +libc_hidden_proto (__libc_alloca_cutoff) We should have this variable per-thread (use __thread). Tis way a few worker threads using very small stack do not affect to whole process. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9ohab2ijCOnn/RHQRAnG+AKCOmM3rdHa+1Q2TxeRHC4wOQfR9cQCdHVoy zx1jQytduWhMy1HB9GC3MCE= =7Sy3 -----END PGP SIGNATURE----- From roland@redhat.com Mon Oct 7 21:43:00 2002 From: roland@redhat.com (Roland McGrath) Date: Mon, 07 Oct 2002 21:43:00 -0000 Subject: [PATCH] __libc_alloca_cutoff (aka make mysql and others apps with very low RLIMIT_STACK setting happy) In-Reply-To: Ulrich Drepper's message of Monday, 7 October 2002 16:19:55 -0700 <3DA2169B.2070004@redhat.com> Message-ID: <200210080106.g9816rJ27102@magilla.sf.frob.com> > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Jakub Jelinek wrote: > > > --- libc/include/alloca.h.jj 2002-09-30 16:45:04.000000000 +0200 > > +++ libc/include/alloca.h 2002-10-08 00:12:01.000000000 +0200 > > @@ -11,4 +11,16 @@ extern void *__alloca (size_t __size); > > # define __alloca(size) __builtin_alloca (size) > > #endif /* GCC. */ > > > > +extern size_t __libc_alloca_cutoff; > > +libc_hidden_proto (__libc_alloca_cutoff) > > We should have this variable per-thread (use __thread). Tis way a few > worker threads using very small stack do not affect to whole process. Conversely instead of a variable we could have a function that's given the size and returns whether to use alloca or malloc. The libc version can just say to always use alloca, I don't care about supporting tiny RLIMIT_STACK values for single-threaded programs. The libpthread version can look at the thread's stack size vs the allocation, and perhaps even look at the current stack depth. Then we don't have to diddle setrlimit and all the rest, or add the word of TLS data From drepper@redhat.com Tue Oct 8 00:21:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Tue, 08 Oct 2002 00:21:00 -0000 Subject: [PATCH] __libc_alloca_cutoff (aka make mysql and others apps with very low RLIMIT_STACK setting happy) References: <200210080106.g9816rJ27102@magilla.sf.frob.com> Message-ID: <3DA2624C.4040609@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Roland McGrath wrote: > Conversely instead of a variable we could have a function that's given the > size and returns whether to use alloca or malloc. The variable should definitely not be exported. We should always only use functions. > The libc version can > just say to always use alloca, I don't care about supporting tiny > RLIMIT_STACK values for single-threaded programs. Sure. It always worked. > The libpthread version > can look at the thread's stack size vs the allocation, and perhaps even > look at the current stack depth. Yep. We have the stack size in the thread descriptor anyway so in fact we have the thread-local variable. > Then we don't have to diddle setrlimit > and all the rest, or add the word of TLS data setrlimit is out anyway. I'm not using it in nptl at all. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9omJM2ijCOnn/RHQRAiidAJwMDY/gohRR4oUMdJmUDg9TzmcWhwCfVtYJ wJ9vAbZJfyii6TbCBU7uOE8= =OzH7 -----END PGP SIGNATURE----- From drepper@redhat.com Tue Oct 8 07:11:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Tue, 08 Oct 2002 07:11:00 -0000 Subject: [PATCH] __libc_alloca_cutoff (aka make mysql and others apps with very low RLIMIT_STACK setting happy) References: <200210080106.g9816rJ27102@magilla.sf.frob.com> <3DA2624C.4040609@redhat.com> <20021008024727.D5659@devserv.devel.redhat.com> Message-ID: <3DA2878B.2080105@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jakub Jelinek wrote: > I diddled setrlimit because people may use it to set the default > thread stack size instead of always using pthread_attr_setstacksize. That's completely stupid and unsupported. I wouldn't waste a single thought about people doing something like that. The stack limit only applies to the initial thread. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9ooeM2ijCOnn/RHQRAmo4AKDJanYc0bWNplShIRlkWvHqE1orrQCggCuF iOeEUMxihGS3Es0MLpRKTsk= =X2Fg -----END PGP SIGNATURE----- From jakub@redhat.com Wed Oct 9 02:47:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 09 Oct 2002 02:47:00 -0000 Subject: [PATCH] __libc_use_alloca (aka make mysql and others apps with very low RLIMIT_STACK setting happy; take 2) In-Reply-To: <200210080106.g9816rJ27102@magilla.sf.frob.com>; from roland@redhat.com on Mon, Oct 07, 2002 at 06:06:53PM -0700 References: <3DA2169B.2070004@redhat.com> <200210080106.g9816rJ27102@magilla.sf.frob.com> Message-ID: <20021008161121.M3451@sunsite.ms.mff.cuni.cz> On Mon, Oct 07, 2002 at 06:06:53PM -0700, Roland McGrath wrote: > > -----BEGIN PGP SIGNED MESSAGE----- > > Hash: SHA1 > > > > Jakub Jelinek wrote: > > > > > --- libc/include/alloca.h.jj 2002-09-30 16:45:04.000000000 +0200 > > > +++ libc/include/alloca.h 2002-10-08 00:12:01.000000000 +0200 > > > @@ -11,4 +11,16 @@ extern void *__alloca (size_t __size); > > > # define __alloca(size) __builtin_alloca (size) > > > #endif /* GCC. */ > > > > > > +extern size_t __libc_alloca_cutoff; > > > +libc_hidden_proto (__libc_alloca_cutoff) > > > > We should have this variable per-thread (use __thread). Tis way a few > > worker threads using very small stack do not affect to whole process. > > Conversely instead of a variable we could have a function that's given the > size and returns whether to use alloca or malloc. The libc version can > just say to always use alloca, I don't care about supporting tiny > RLIMIT_STACK values for single-threaded programs. The libpthread version > can look at the thread's stack size vs the allocation, and perhaps even > look at the current stack depth. Then we don't have to diddle setrlimit > and all the rest, or add the word of TLS data Ok, here is the next version. NPTL could use TLS variable in the inline or whatever else it wants to do. BTW: I found a bug in vfprintf.c, where it did: if (prec < (int) (32768 / sizeof (CHAR_T))) workend = alloca (prec + 32) + (prec + 32); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ else { workstart = (CHAR_T *) malloc ((prec + 32) * sizeof (CHAR_T)); if (workstart == NULL) { done = -1; goto all_done; } workend = workstart + (prec + 32); } The alloca line is wrong in wide version, it would result in clobbering area below stack. 2002-10-07 Jakub Jelinek * include/alloca.h (__libc_use_alloca, __libc_alloca_cutoff): New prototypes. (__MAX_ALLOCA_CUTOFF): Define. Include allocalim.h. * resolv/nss_dns/dns-host.c (_nss_dns_gethostbyname2_r, _nss_dns_gethostbyaddr_r): Use alloca or malloc to allocate host_buffer depending on __libc_use_alloca. * resolv/nss_dns/dns-network.c (_nss_dns_getnetbyname_r, _nss_dns_getnetbyaddr_r): Use alloca or malloc to allocate net_buffer depending on __libc_use_alloca. * resolv/res_query.c (res_nquery): Use alloca or malloc to allocate buf depending on __libc_use_alloca. * resolv/gethnamaddr.c (gethostbyname2, gethostbyaddr): Likewise. * stdio-common/vfprintf.c (vfprintf): Use __libc_use_alloca instead of hardcoded constants. Pass proper size argument to alloca and compute end for wide char version. * stdio-common/printf_fp.c (__printf_fp): Use __libc_use_alloca instead of hardcoded constants. * string/strcoll.c (strcoll): Likewise. * string/strxfrm.c (strxfrm): Likewise. * sysdeps/posix/readv.c (__readv): Likewise. * sysdeps/posix/writev.c (__writev): Likewise. * sysdeps/generic/allocalim.h: New file. * sysdeps/unix/sysv/linux/allocalim.h: New file. * descr.h (struct _pthread_descr_struct): Add p_alloca_cutoff field. * manager.c (__pthread_allocate_stack): Add out_stacksize argument. Pass stack size to caller. (pthread_handle_create): Set p_alloca_cutoff. * pthread.c (__pthread_initial_thread): Use C99 designated initializers. Set p_alloca_cutoff. (__pthread_manager_thread): Likewise. (__pthread_initialize_minimal) [USE_TLS]: Set p_alloca_cutoff for initial thread. (__pthread_init_max_stacksize): Possibly decrease p_alloca_cutoff for initial thread. (__pthread_initialize_manager) [USE_TLS]: Set p_alloca_cutoff for manager thread. * specific.c (__libc_alloca_cutoff): New function. * no-tsd.c (__libc_alloca_cutoff): New function. * Versions: Export __libc_alloca_cutoff@@GLIBC_PRIVATE from libc and libpthread. --- libc/include/alloca.h.jj 2002-09-30 16:45:04.000000000 +0200 +++ libc/include/alloca.h 2002-10-08 14:59:39.000000000 +0200 @@ -11,4 +11,11 @@ extern void *__alloca (size_t __size); # define __alloca(size) __builtin_alloca (size) #endif /* GCC. */ +extern int __libc_use_alloca (size_t size) __attribute__ ((const)); +extern int __libc_alloca_cutoff (size_t size) __attribute__ ((const)); + +#define __MAX_ALLOCA_CUTOFF 65536 + +#include + #endif --- libc/linuxthreads/sysdeps/unix/sysv/linux/allocalim.h.jj 2002-10-08 14:59:39.000000000 +0200 +++ libc/linuxthreads/sysdeps/unix/sysv/linux/allocalim.h 2002-10-08 14:59:39.000000000 +0200 @@ -0,0 +1,7 @@ +#include + +extern inline int __libc_use_alloca (size_t size) +{ + return (__builtin_expect (size <= PTHREAD_STACK_MIN / 4, 1) + || __libc_alloca_cutoff (size)); +} --- libc/linuxthreads/manager.c.jj 2002-08-28 12:58:03.000000000 +0200 +++ libc/linuxthreads/manager.c 2002-10-08 14:59:39.000000000 +0200 @@ -334,7 +334,8 @@ static int pthread_allocate_stack(const char ** out_new_thread, char ** out_new_thread_bottom, char ** out_guardaddr, - size_t * out_guardsize) + size_t * out_guardsize, + size_t * out_stacksize) { pthread_descr new_thread; char * new_thread_bottom; @@ -388,6 +389,7 @@ static int pthread_allocate_stack(const /* Clear the thread data structure. */ memset (new_thread, '\0', sizeof (*new_thread)); #endif + stacksize = attr->__stacksize; } else { @@ -559,6 +561,11 @@ static int pthread_allocate_stack(const *out_new_thread_bottom = new_thread_bottom; *out_guardaddr = guardaddr; *out_guardsize = guardsize; +#ifdef NEED_SEPARATE_REGISTER_STACK + *out_stacksize = stacksize / 2; +#else + *out_stacksize = stacksize; +#endif return 0; } @@ -575,7 +582,7 @@ static int pthread_handle_create(pthread char * new_thread_bottom; pthread_t new_thread_id; char *guardaddr = NULL; - size_t guardsize = 0; + size_t guardsize = 0, stksize = 0; int pagesize = __getpagesize(); int saved_errno = 0; @@ -608,7 +615,7 @@ static int pthread_handle_create(pthread continue; if (pthread_allocate_stack(attr, thread_segment(sseg), pagesize, &stack_addr, &new_thread_bottom, - &guardaddr, &guardsize) == 0) + &guardaddr, &guardsize, &stksize) == 0) { #ifdef USE_TLS new_thread->p_stackaddr = stack_addr; @@ -639,6 +646,8 @@ static int pthread_handle_create(pthread new_thread->p_guardsize = guardsize; new_thread->p_nr = sseg; new_thread->p_inheritsched = attr ? attr->__inheritsched : 0; + new_thread->p_alloca_cutoff = stksize / 4 > __MAX_ALLOCA_CUTOFF + ? __MAX_ALLOCA_CUTOFF : stksize / 4; /* Initialize the thread handle */ __pthread_init_lock(&__pthread_handles[sseg].h_lock); __pthread_handles[sseg].h_descr = new_thread; --- libc/linuxthreads/specific.c.jj 2002-09-28 17:06:08.000000000 +0200 +++ libc/linuxthreads/specific.c 2002-10-08 14:59:39.000000000 +0200 @@ -239,3 +239,9 @@ void **(*const __libc_internal_tsd_addre __THROW __attribute__ ((__const__)) = libc_internal_tsd_address; #endif + +int __libc_alloca_cutoff (size_t size) +{ + pthread_descr self = thread_self(); + return size <= THREAD_GETMEM_NC(self, p_alloca_cutoff); +} --- libc/linuxthreads/no-tsd.c.jj 2002-09-03 15:34:45.000000000 +0200 +++ libc/linuxthreads/no-tsd.c 2002-10-08 14:59:39.000000000 +0200 @@ -38,3 +38,8 @@ void **(*__libc_internal_tsd_address) (e __THROW __attribute__ ((__const__)); #endif /* !(USE_TLS && HAVE___THREAD) */ + +int __libc_alloca_cutoff (size_t size) +{ + return size <= __MAX_ALLOCA_CUTOFF; +} --- libc/linuxthreads/Versions.jj 2002-09-02 09:58:47.000000000 +0200 +++ libc/linuxthreads/Versions 2002-10-08 14:59:39.000000000 +0200 @@ -20,8 +20,7 @@ libc { GLIBC_PRIVATE { # Internal libc interface to libpthread __libc_internal_tsd_get; __libc_internal_tsd_set; - __libc_internal_tsd_address; - + __libc_internal_tsd_address; __libc_alloca_cutoff; } } @@ -163,7 +162,7 @@ libpthread { GLIBC_PRIVATE { # Internal libc interface to libpthread __libc_internal_tsd_get; __libc_internal_tsd_set; - __libc_internal_tsd_address; + __libc_internal_tsd_address; __libc_alloca_cutoff; __pthread_kill_other_threads_np; } } --- libc/linuxthreads/descr.h.jj 2002-08-02 11:47:38.000000000 +0200 +++ libc/linuxthreads/descr.h 2002-10-08 14:59:39.000000000 +0200 @@ -165,6 +165,8 @@ struct _pthread_descr_struct { #ifdef USE_TLS char *p_stackaddr; /* Stack address. */ #endif + size_t p_alloca_cutoff; /* Maximum size which should be allocated + using alloca() instead of malloc(). */ /* New elements must be added at the end. */ } __attribute__ ((aligned(32))); /* We need to align the structure so that doubles are aligned properly. This is 8 --- libc/linuxthreads/pthread.c.jj 2002-09-30 11:23:43.000000000 +0200 +++ libc/linuxthreads/pthread.c 2002-10-08 14:59:39.000000000 +0200 @@ -63,58 +63,20 @@ static pthread_descr manager_thread; /* Descriptor of the initial thread */ struct _pthread_descr_struct __pthread_initial_thread = { - { - { - .self = &__pthread_initial_thread /* pthread_descr self */ - } - }, - &__pthread_initial_thread, /* pthread_descr p_nextlive */ - &__pthread_initial_thread, /* pthread_descr p_prevlive */ - NULL, /* pthread_descr p_nextwaiting */ - NULL, /* pthread_descr p_nextlock */ - PTHREAD_THREADS_MAX, /* pthread_t p_tid */ - 0, /* int p_pid */ - 0, /* int p_priority */ - &__pthread_handles[0].h_lock, /* struct _pthread_fastlock * p_lock */ - 0, /* int p_signal */ - NULL, /* sigjmp_buf * p_signal_buf */ - NULL, /* sigjmp_buf * p_cancel_buf */ - 0, /* char p_terminated */ - 0, /* char p_detached */ - 0, /* char p_exited */ - NULL, /* void * p_retval */ - 0, /* int p_retval */ - NULL, /* pthread_descr p_joining */ - NULL, /* struct _pthread_cleanup_buffer * p_cleanup */ - 0, /* char p_cancelstate */ - 0, /* char p_canceltype */ - 0, /* char p_canceled */ - NULL, /* char * p_in_sighandler */ - 0, /* char p_sigwaiting */ - PTHREAD_START_ARGS_INITIALIZER(NULL), - /* struct pthread_start_args p_start_args */ - {NULL}, /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */ - {NULL}, /* void * p_libc_specific[_LIBC_TSD_KEY_N] */ - &_errno, /* int *p_errnop */ - 0, /* int p_errno */ - &_h_errno, /* int *p_h_errnop */ - 0, /* int p_h_errno */ - &_res, /* struct __res_state *p_resp */ - {}, /* struct __res_state p_res */ - 1, /* int p_userstack */ - NULL, /* void * p_guardaddr */ - 0, /* size_t p_guardsize */ - 0, /* Always index 0 */ - 0, /* int p_report_events */ - {{{0, }}, 0, NULL}, /* td_eventbuf_t p_eventbuf */ - __ATOMIC_INITIALIZER, /* struct pthread_atomic p_resume_count */ - 0, /* char p_woken_by_cancel */ - 0, /* char p_condvar_avail */ - 0, /* char p_sem_avail */ - NULL, /* struct pthread_extricate_if *p_extricate */ - NULL, /* pthread_readlock_info *p_readlock_list; */ - NULL, /* pthread_readlock_info *p_readlock_free; */ - 0 /* int p_untracked_readlock_count; */ + .p_header.data.self = &__pthread_initial_thread, + .p_nextlive = &__pthread_initial_thread, + .p_prevlive = &__pthread_initial_thread, + .p_tid = PTHREAD_THREADS_MAX, + .p_lock = &__pthread_handles[0].h_lock, + .p_start_args = PTHREAD_START_ARGS_INITIALIZER(NULL), +#if !(USE_TLS && HAVE___THREAD) + .p_errnop = &_errno, + .p_h_errnop = &_h_errno, + .p_resp = &_res, +#endif + .p_userstack = 1, + .p_resume_count = __ATOMIC_INITIALIZER, + .p_alloca_cutoff = __MAX_ALLOCA_CUTOFF }; /* Descriptor of the manager thread; none of this is used but the error @@ -123,58 +85,15 @@ struct _pthread_descr_struct __pthread_i #define manager_thread (&__pthread_manager_thread) struct _pthread_descr_struct __pthread_manager_thread = { - { - { - .self = &__pthread_manager_thread /* pthread_descr self */ - } - }, - NULL, /* pthread_descr p_nextlive */ - NULL, /* pthread_descr p_prevlive */ - NULL, /* pthread_descr p_nextwaiting */ - NULL, /* pthread_descr p_nextlock */ - 0, /* int p_tid */ - 0, /* int p_pid */ - 0, /* int p_priority */ - &__pthread_handles[1].h_lock, /* struct _pthread_fastlock * p_lock */ - 0, /* int p_signal */ - NULL, /* sigjmp_buf * p_signal_buf */ - NULL, /* sigjmp_buf * p_cancel_buf */ - 0, /* char p_terminated */ - 0, /* char p_detached */ - 0, /* char p_exited */ - NULL, /* void * p_retval */ - 0, /* int p_retval */ - NULL, /* pthread_descr p_joining */ - NULL, /* struct _pthread_cleanup_buffer * p_cleanup */ - 0, /* char p_cancelstate */ - 0, /* char p_canceltype */ - 0, /* char p_canceled */ - NULL, /* char * p_in_sighandler */ - 0, /* char p_sigwaiting */ - PTHREAD_START_ARGS_INITIALIZER(__pthread_manager), - /* struct pthread_start_args p_start_args */ - {NULL}, /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */ - {NULL}, /* void * p_libc_specific[_LIBC_TSD_KEY_N] */ - &__pthread_manager_thread.p_errno, /* int *p_errnop */ - 0, /* int p_errno */ - NULL, /* int *p_h_errnop */ - 0, /* int p_h_errno */ - NULL, /* struct __res_state *p_resp */ - {}, /* struct __res_state p_res */ - 0, /* int p_userstack */ - NULL, /* void * p_guardaddr */ - 0, /* size_t p_guardsize */ - 1, /* Always index 1 */ - 0, /* int p_report_events */ - {{{0, }}, 0, NULL}, /* td_eventbuf_t p_eventbuf */ - __ATOMIC_INITIALIZER, /* struct pthread_atomic p_resume_count */ - 0, /* char p_woken_by_cancel */ - 0, /* char p_condvar_avail */ - 0, /* char p_sem_avail */ - NULL, /* struct pthread_extricate_if *p_extricate */ - NULL, /* pthread_readlock_info *p_readlock_list; */ - NULL, /* pthread_readlock_info *p_readlock_free; */ - 0 /* int p_untracked_readlock_count; */ + .p_header.data.self = &__pthread_manager_thread, + .p_lock = &__pthread_handles[1].h_lock, + .p_start_args = PTHREAD_START_ARGS_INITIALIZER(__pthread_manager), +#if !(USE_TLS && HAVE___THREAD) + .p_errnop = &__pthread_manager_thread.p_errno, +#endif + .p_nr = 1, + .p_resume_count = __ATOMIC_INITIALIZER, + .p_alloca_cutoff = PTHREAD_STACK_MIN / 4 }; #endif @@ -418,6 +337,7 @@ __pthread_initialize_minimal(void) # if __LT_SPINLOCK_INIT != 0 self->p_resume_count = (struct pthread_atomic) __ATOMIC_INITIALIZER; # endif + self->p_alloca_cutoff = __MAX_ALLOCA_CUTOFF; /* Another variable which points to the thread descriptor. */ __pthread_main_thread = self; @@ -487,6 +407,15 @@ __pthread_init_max_stacksize(void) } #endif __pthread_max_stacksize = max_stack; + if (max_stack / 4 < __MAX_ALLOCA_CUTOFF) + { +#ifdef USE_TLS + pthread_descr self = THREAD_SELF; + self->p_alloca_cutoff = max_stack / 4; +#else + __pthread_initial_thread.p_alloca_cutoff = max_stack / 4; +#endif + } } @@ -629,6 +558,7 @@ int __pthread_initialize_manager(void) # if __LT_SPINLOCK_INIT != 0 self->p_resume_count = (struct pthread_atomic) __ATOMIC_INITIALIZER; # endif + tcb->p_alloca_cutoff = PTHREAD_STACK_MIN / 4; #else tcb = &__pthread_manager_thread; #endif --- libc/resolv/nss_dns/dns-host.c.jj 2002-08-27 23:19:49.000000000 +0200 +++ libc/resolv/nss_dns/dns-host.c 2002-10-08 14:59:39.000000000 +0200 @@ -132,12 +132,13 @@ _nss_dns_gethostbyname2_r (const char *n char *buffer, size_t buflen, int *errnop, int *h_errnop) { - querybuf host_buffer; + querybuf *host_buffer; char tmp[NS_MAXDNAME]; int size, type, n; const char *cp; - int map = 0; + int map = 0, use_malloc = 0; int olderr = errno; + enum nss_status status; if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1) return NSS_STATUS_UNAVAIL; @@ -169,8 +170,21 @@ _nss_dns_gethostbyname2_r (const char *n && (cp = res_hostalias (&_res, name, tmp, sizeof (tmp))) != NULL) name = cp; - n = res_nsearch (&_res, name, C_IN, type, host_buffer.buf, - sizeof (host_buffer.buf)); + if (!__libc_use_alloca (MAXPACKET)) + { + host_buffer = (querybuf *) malloc (sizeof (querybuf)); + if (host_buffer == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + use_malloc = 1; + } + else + host_buffer = (querybuf *) alloca (sizeof (querybuf)); + + n = res_nsearch (&_res, name, C_IN, type, host_buffer->buf, + sizeof (host_buffer->buf)); if (n < 0) { enum nss_status status = (errno == ECONNREFUSED @@ -185,11 +199,15 @@ _nss_dns_gethostbyname2_r (const char *n by having the RES_USE_INET6 bit in _res.options set, we try another lookup. */ if (af == AF_INET6 && (_res.options & RES_USE_INET6)) - n = res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf, - sizeof (host_buffer.buf)); + n = res_nsearch (&_res, name, C_IN, T_A, host_buffer->buf, + sizeof (host_buffer->buf)); if (n < 0) - return status; + { + if (use_malloc) + free (host_buffer); + return status; + } map = 1; @@ -197,8 +215,11 @@ _nss_dns_gethostbyname2_r (const char *n result->h_length = INADDRSZ;; } - return getanswer_r (&host_buffer, n, name, type, result, buffer, buflen, - errnop, h_errnop, map); + status = getanswer_r (host_buffer, n, name, type, result, buffer, buflen, + errnop, h_errnop, map); + if (use_malloc) + free (host_buffer); + return status; } @@ -236,10 +257,10 @@ _nss_dns_gethostbyaddr_r (const void *ad char *h_addr_ptrs[MAX_NR_ADDRS + 1]; char linebuffer[0]; } *host_data = (struct host_data *) buffer; - querybuf host_buffer; + querybuf *host_buffer; char qbuf[MAXDNAME+1], *qp = NULL; size_t size; - int n, status; + int n, status, use_malloc = 0; int olderr = errno; if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1) @@ -294,23 +315,40 @@ _nss_dns_gethostbyaddr_r (const void *ad break; } - n = res_nquery (&_res, qbuf, C_IN, T_PTR, (u_char *)host_buffer.buf, - sizeof host_buffer); + if (!__libc_use_alloca (MAXPACKET)) + { + host_buffer = (querybuf *) malloc (sizeof (querybuf)); + if (host_buffer == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + use_malloc = 1; + } + else + host_buffer = (querybuf *) alloca (sizeof (querybuf)); + + n = res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer->buf, + sizeof (host_buffer->buf)); if (n < 0 && af == AF_INET6) { strcpy (qp, "ip6.int"); - n = res_nquery (&_res, qbuf, C_IN, T_PTR, (u_char *)host_buffer.buf, - sizeof host_buffer); + n = res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer->buf, + sizeof (host_buffer->buf)); } if (n < 0) { *h_errnop = h_errno; __set_errno (olderr); + if (use_malloc) + free (host_buffer); return errno == ECONNREFUSED ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; } - status = getanswer_r (&host_buffer, n, qbuf, T_PTR, result, buffer, buflen, + status = getanswer_r (host_buffer, n, qbuf, T_PTR, result, buffer, buflen, errnop, h_errnop, 0 /* XXX */); + if (use_malloc) + free (host_buffer); if (status != NSS_STATUS_SUCCESS) { *h_errnop = h_errno; --- libc/resolv/nss_dns/dns-network.c.jj 2002-09-05 11:57:18.000000000 +0200 +++ libc/resolv/nss_dns/dns-network.c 2002-10-08 14:59:39.000000000 +0200 @@ -110,27 +110,47 @@ _nss_dns_getnetbyname_r (const char *nam int *herrnop) { /* Return entry for network with NAME. */ - querybuf net_buffer; - int anslen; + querybuf *net_buffer; + int anslen, use_malloc = 0; char *qbuf; + enum nss_status status; if ((_res.options & RES_INIT) == 0 && __res_ninit (&_res) == -1) return NSS_STATUS_UNAVAIL; qbuf = strdupa (name); - anslen = res_nsearch (&_res, qbuf, C_IN, T_PTR, (u_char *) &net_buffer, - sizeof (querybuf)); + + if (!__libc_use_alloca (MAXPACKET)) + { + net_buffer = (querybuf *) malloc (sizeof (querybuf)); + if (net_buffer == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + use_malloc = 1; + } + else + net_buffer = (querybuf *) alloca (sizeof (querybuf)); + + anslen = res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer->buf, + sizeof (net_buffer->buf)); if (anslen < 0) { /* Nothing found. */ *errnop = errno; + if (use_malloc) + free (net_buffer); return (errno == ECONNREFUSED || errno == EPFNOSUPPORT || errno == EAFNOSUPPORT) ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; } - return getanswer_r (&net_buffer, anslen, result, buffer, buflen, BYNAME); + status = getanswer_r (net_buffer, anslen, result, buffer, buflen, BYNAME); + if (use_malloc) + free (net_buffer); + return status; } @@ -141,10 +161,10 @@ _nss_dns_getnetbyaddr_r (uint32_t net, i { /* Return entry for network with NAME. */ enum nss_status status; - querybuf net_buffer; + querybuf *net_buffer; unsigned int net_bytes[4]; char qbuf[MAXDNAME]; - int cnt, anslen; + int cnt, anslen, use_malloc = 0; u_int32_t net2; int olderr = errno; @@ -181,20 +201,37 @@ _nss_dns_getnetbyaddr_r (uint32_t net, i break; } - anslen = res_nquery (&_res, qbuf, C_IN, T_PTR, (u_char *) &net_buffer, - sizeof (querybuf)); + if (!__libc_use_alloca (MAXPACKET)) + { + net_buffer = (querybuf *) malloc (sizeof (querybuf)); + if (net_buffer == NULL) + { + *errnop = ENOMEM; + return NSS_STATUS_UNAVAIL; + } + use_malloc = 1; + } + else + net_buffer = (querybuf *) alloca (sizeof (querybuf)); + + anslen = res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer->buf, + sizeof (net_buffer->buf)); if (anslen < 0) { /* Nothing found. */ int err = errno; __set_errno (olderr); + if (use_malloc) + free (net_buffer); return (err == ECONNREFUSED || err == EPFNOSUPPORT || err == EAFNOSUPPORT) ? NSS_STATUS_UNAVAIL : NSS_STATUS_NOTFOUND; } - status = getanswer_r (&net_buffer, anslen, result, buffer, buflen, BYADDR); + status = getanswer_r (net_buffer, anslen, result, buffer, buflen, BYADDR); + if (use_malloc) + free (net_buffer); if (status == NSS_STATUS_SUCCESS) { /* Strip trailing zeros. */ --- libc/resolv/res_query.c.jj 2002-08-27 23:19:49.000000000 +0200 +++ libc/resolv/res_query.c 2002-10-08 14:59:39.000000000 +0200 @@ -108,28 +108,42 @@ res_nquery(res_state statp, u_char *answer, /* buffer to put answer */ int anslen) /* size of answer buffer */ { - u_char buf[MAXPACKET]; + u_char *buf; HEADER *hp = (HEADER *) answer; - int n; + int n, use_malloc = 0; hp->rcode = NOERROR; /* default */ + if (!__libc_use_alloca (MAXPACKET)) { + buf = malloc (MAXPACKET); + if (buf == NULL) { + __set_h_errno (NETDB_INTERNAL); + return -1; + } + use_malloc = 1; + } else + buf = alloca (MAXPACKET); + #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; res_query(%s, %d, %d)\n", name, class, type); #endif n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL, - buf, sizeof(buf)); + buf, MAXPACKET); if (n <= 0) { #ifdef DEBUG if (statp->options & RES_DEBUG) printf(";; res_query: mkquery failed\n"); #endif RES_SET_H_ERRNO(statp, NO_RECOVERY); + if (use_malloc) + free (buf); return (n); } n = res_nsend(statp, buf, n, answer, anslen); + if (use_malloc) + free (buf); if (n < 0) { #ifdef DEBUG if (statp->options & RES_DEBUG) --- libc/resolv/gethnamaddr.c.jj 2002-09-25 11:11:53.000000000 +0200 +++ libc/resolv/gethnamaddr.c 2002-10-08 14:59:39.000000000 +0200 @@ -510,10 +510,11 @@ gethostbyname2(name, af) const char *name; int af; { - querybuf buf; + querybuf *buf; register const char *cp; char *bp; - int n, size, type, len; + int n, size, type, len, use_malloc = 0; + struct hostent *ret; extern struct hostent *_gethtbyname2(); if ((_res.options & RES_INIT) == 0 && __res_ninit(&_res) == -1) { @@ -615,13 +616,26 @@ gethostbyname2(name, af) break; } - if ((n = res_nsearch(&_res, name, C_IN, type, buf.buf, sizeof(buf.buf))) < 0) { + if (!__libc_use_alloca (MAXPACKET)) { + buf = (querybuf *) malloc (sizeof (*buf)); + if (buf == NULL) { + __set_h_errno (NETDB_INTERNAL); + return NULL; + } + use_malloc = 1; + } else + buf = (querybuf *) alloca (sizeof (*buf)); + + if ((n = res_nsearch(&_res, name, C_IN, type, buf->buf, sizeof(buf->buf))) < 0) { dprintf("res_nsearch failed (%d)\n", n); if (errno == ECONNREFUSED) return (_gethtbyname2(name, af)); return (NULL); } - return (getanswer(&buf, n, name, type)); + ret = getanswer(buf, n, name, type); + if (use_malloc) + free (buf); + return ret; } struct hostent * @@ -633,9 +647,9 @@ gethostbyaddr(addr, len, af) const u_char *uaddr = (const u_char *)addr; static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; - int n; + int n, use_malloc = 0; socklen_t size; - querybuf buf; + querybuf *buf; register struct hostent *hp; char qbuf[MAXDNAME+1], *qp = NULL; #ifdef SUNSECURITY @@ -696,18 +710,34 @@ gethostbyaddr(addr, len, af) default: abort(); } - n = res_nquery(&_res, qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf); + + if (!__libc_use_alloca (MAXPACKET)) { + buf = (querybuf *) malloc (sizeof (*buf)); + if (buf == NULL) { + __set_h_errno (NETDB_INTERNAL); + return NULL; + } + use_malloc = 1; + } else + buf = (querybuf *) alloca (sizeof (*buf)); + + n = res_nquery(&_res, qbuf, C_IN, T_PTR, buf->buf, sizeof buf->buf); if (n < 0 && af == AF_INET6) { strcpy(qp, "ip6.int"); - n = res_nquery(&_res, qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf); + n = res_nquery(&_res, qbuf, C_IN, T_PTR, buf->buf, sizeof buf->buf); } if (n < 0) { + if (use_malloc) + free (buf); dprintf("res_nquery failed (%d)\n", n); if (errno == ECONNREFUSED) return (_gethtbyaddr(addr, len, af)); return (NULL); } - if (!(hp = getanswer(&buf, n, qbuf, T_PTR))) + hp = getanswer(buf, n, qbuf, T_PTR); + if (use_malloc) + free (buf); + if (!hp) return (NULL); /* h_errno was set by getanswer() */ #ifdef SUNSECURITY if (af == AF_INET) { --- libc/stdio-common/vfprintf.c.jj 2002-09-30 16:45:06.000000000 +0200 +++ libc/stdio-common/vfprintf.c 2002-10-08 14:59:39.000000000 +0200 @@ -1039,7 +1039,7 @@ vfprintf (FILE *s, const CHAR_T *format, \ /* Allocate dynamically an array which definitely is long \ enough for the wide character version. */ \ - if (len < 8192) \ + if (__libc_use_alloca (len * sizeof (wchar_t))) \ string = (CHAR_T *) alloca (len * sizeof (wchar_t)); \ else if ((string = (CHAR_T *) malloc (len * sizeof (wchar_t))) \ == NULL) \ @@ -1201,7 +1201,7 @@ vfprintf (FILE *s, const CHAR_T *format, if (prec >= 0) \ { \ /* The string `s2' might not be NUL terminated. */ \ - if (prec < 32768) \ + if (__libc_use_alloca (prec)) \ string = (char *) alloca (prec); \ else if ((string = (char *) malloc (prec)) == NULL) \ { \ @@ -1219,7 +1219,7 @@ vfprintf (FILE *s, const CHAR_T *format, { \ assert (__mbsinit (&mbstate)); \ s2 = (const wchar_t *) string; \ - if (len + 1 < 32768) \ + if (__libc_use_alloca (len + 1)) \ string = (char *) alloca (len + 1); \ else if ((string = (char *) malloc (len + 1)) == NULL) \ { \ @@ -1448,7 +1448,7 @@ vfprintf (FILE *s, const CHAR_T *format, { /* We have to use a special buffer. The "32" is just a safe bet for all the output which is not counted in the width. */ - if (width < (int) (32768 / sizeof (CHAR_T))) + if (__libc_use_alloca ((width + 32) * sizeof (CHAR_T))) workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T)) + (width + 32)); else @@ -1473,7 +1473,7 @@ vfprintf (FILE *s, const CHAR_T *format, { /* We have to use a special buffer. The "32" is just a safe bet for all the output which is not counted in the width. */ - if (width < (int) (32768 / sizeof (CHAR_T))) + if (__libc_use_alloca ((width + 32) * sizeof (CHAR_T))) workend = ((CHAR_T *) alloca ((width + 32) * sizeof (CHAR_T)) + (width + 32)); else @@ -1516,8 +1516,9 @@ vfprintf (FILE *s, const CHAR_T *format, if (prec > width && prec + 32 > (int)(sizeof (work_buffer) / sizeof (work_buffer[0]))) { - if (prec < (int) (32768 / sizeof (CHAR_T))) - workend = alloca (prec + 32) + (prec + 32); + if (__libc_use_alloca ((prec + 32) * sizeof (CHAR_T))) + workend = ((CHAR_T *) alloca ((prec + 32) * sizeof (CHAR_T))) + + (prec + 32); else { workstart = (CHAR_T *) malloc ((prec + 32) * sizeof (CHAR_T)); @@ -1832,7 +1833,8 @@ do_positional: if (MAX (prec, width) + 32 > (int) (sizeof (work_buffer) / sizeof (CHAR_T))) { - if (MAX (prec, width) < (int) (32768 / sizeof (CHAR_T))) + if (__libc_use_alloca ((MAX (prec, width) + 32) + * sizeof (CHAR_T))) workend = ((CHAR_T *) alloca ((MAX (prec, width) + 32) * sizeof (CHAR_T)) + (MAX (prec, width) + 32)); --- libc/stdio-common/printf_fp.c.jj 2002-10-02 10:26:33.000000000 +0200 +++ libc/stdio-common/printf_fp.c 2002-10-08 14:59:39.000000000 +0200 @@ -869,7 +869,7 @@ __printf_fp (FILE *fp, it is possible that we need two more characters in front of all the other output. If the amount of memory we have to allocate is too large use `malloc' instead of `alloca'. */ - buffer_malloced = chars_needed > 5000; + buffer_malloced = ! __libc_use_alloca (chars_needed * 2 * sizeof (wchar_t)); if (buffer_malloced) { wbuffer = (wchar_t *) malloc ((2 + chars_needed) * sizeof (wchar_t)); --- libc/string/strcoll.c.jj 2002-09-30 16:45:06.000000000 +0200 +++ libc/string/strcoll.c 2002-10-08 14:59:39.000000000 +0200 @@ -155,7 +155,7 @@ STRCOLL (s1, s2, l) Please note that the localedef programs makes sure that `position' is not used at the first level. */ - if (s1len + s2len >= 16384) + if (! __libc_use_alloca (s1len + s2len)) { idx1arr = (int32_t *) malloc ((s1len + s2len) * (sizeof (int32_t) + 1)); idx2arr = &idx1arr[s1len]; --- libc/string/strxfrm.c.jj 2002-09-30 16:45:06.000000000 +0200 +++ libc/string/strxfrm.c 2002-10-08 14:59:39.000000000 +0200 @@ -175,7 +175,7 @@ STRXFRM (STRING_TYPE *dest, const STRING values. But since there is no limit on the length of the string we have to use `malloc' if the string is too long. We should be very conservative here. */ - if (srclen >= 16384) + if (! __libc_use_alloca (srclen)) { idxarr = (int32_t *) malloc ((srclen + 1) * (sizeof (int32_t) + 1)); rulearr = (unsigned char *) &idxarr[srclen]; --- libc/sysdeps/generic/allocalim.h.jj 2002-10-08 14:59:39.000000000 +0200 +++ libc/sysdeps/generic/allocalim.h 2002-10-08 14:59:39.000000000 +0200 @@ -0,0 +1,4 @@ +extern inline int __libc_use_alloca (size_t size) +{ + return size <= __MAX_ALLOCA_CUTOFF; +} --- libc/sysdeps/posix/readv.c.jj 2002-09-30 16:45:08.000000000 +0200 +++ libc/sysdeps/posix/readv.c 2002-10-08 14:59:39.000000000 +0200 @@ -55,8 +55,8 @@ __readv (int fd, const struct iovec *vec /* Allocate a temporary buffer to hold the data. We should normally use alloca since it's faster and does not require synchronization with other threads. But we cannot if the amount of memory - required is too large. Use 512k as the limit. */ - if (bytes < 512 * 1024) + required is too large. */ + if (__libc_use_alloca (bytes)) buffer = (char *) __alloca (bytes); else { --- libc/sysdeps/posix/writev.c.jj 2002-09-30 16:45:08.000000000 +0200 +++ libc/sysdeps/posix/writev.c 2002-10-08 14:59:39.000000000 +0200 @@ -55,8 +55,8 @@ __writev (int fd, const struct iovec *ve /* Allocate a temporary buffer to hold the data. We should normally use alloca since it's faster and does not require synchronization with other threads. But we cannot if the amount of memory - required is too large. Use 512k as the limit. */ - if (bytes < 512 * 1024) + required is too large. */ + if (__libc_use_alloca (bytes)) buffer = (char *) __alloca (bytes); else { Jakub From drepper@redhat.com Wed Oct 9 06:07:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Wed, 09 Oct 2002 06:07:00 -0000 Subject: [PATCH] __libc_use_alloca (aka make mysql and others apps with very low RLIMIT_STACK setting happy; take 2) References: <3DA2169B.2070004@redhat.com> <200210080106.g9816rJ27102@magilla.sf.frob.com> <20021008161121.M3451@sunsite.ms.mff.cuni.cz> Message-ID: <3DA3FB2F.1010600@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I've applied Jakub's patch now and a few more non-code changes which are necessary for a correct thread library (npt in this case). This should be about it for 2.3.1. Please test it. I just want to get the losers with tiny stacks off my back so that we can get on with the development. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9o/sv2ijCOnn/RHQRApJ3AKCGZAA2aR8lApHDK5mxviEeSukxtACfb+xQ EymApcl797bSPiEJSpzTHsE= =c9pL -----END PGP SIGNATURE----- From schwidefsky@de.ibm.com Wed Oct 9 06:15:00 2002 From: schwidefsky@de.ibm.com (Martin Schwidefsky) Date: Wed, 09 Oct 2002 06:15:00 -0000 Subject: utmp.h & utmpx.h for s390. Message-ID: <200210091505.12166.schwidefsky@de.ibm.com> Hi folks, Jakub Jelinek writes: > I haven't changed s390x, but IMHO it is better to recompile the affected > apps now in the /usr/lib -> /usr/lib64 transition which changes most > of the things anyway, than to suffer forever. All I can say is: he is right. I wanted to look into versioned symbols for the glibc functions that are affected by the utmp.h/utmpx.h change but I am too busy with other stuff right now (and I know that extreme caution is required for anything to do with versioning). I just copied the utmp.h/utmpx.h headers from powerpc/x86_64 to the s390 folder so credits go to Steven and Jakub. blue skies, Martin. 2002-10-09 Steven Munroe Jakub Jelinek * sysdeps/s390/s390-32/bits/wordsize.h (__WORDSIZE_COMPAT32): Define. * sysdeps/s390/s390-64/bits/wordsize.h (__WORDSIZE_COMPAT32): Define. * sysdeps/unix/sysv/linux/s390/bits/utmp.h: New file. * sysdeps/unix/sysv/linux/s390/bits/utmpx.h: New file. diff -urN libc-head/sysdeps/s390/s390-32/bits/wordsize.h libc-s390/sysdeps/s390/s390-32/bits/wordsize.h --- libc-head/sysdeps/s390/s390-32/bits/wordsize.h Wed Oct 2 22:52:30 2002 +++ libc-s390/sysdeps/s390/s390-32/bits/wordsize.h Wed Oct 9 14:50:44 2002 @@ -2,6 +2,7 @@ #if defined __s390x__ # define __WORDSIZE 64 +# define __WORDSIZE_COMPAT32 1 #else # define __WORDSIZE 32 #endif diff -urN libc-head/sysdeps/s390/s390-64/bits/wordsize.h libc-s390/sysdeps/s390/s390-64/bits/wordsize.h --- libc-head/sysdeps/s390/s390-64/bits/wordsize.h Wed Oct 2 22:57:48 2002 +++ libc-s390/sysdeps/s390/s390-64/bits/wordsize.h Wed Oct 9 14:51:03 2002 @@ -2,6 +2,7 @@ #if defined __s390x__ # define __WORDSIZE 64 +# define __WORDSIZE_COMPAT32 1 #else # define __WORDSIZE 32 #endif diff -urN libc-head/sysdeps/unix/sysv/linux/s390/bits/utmp.h libc-s390/sysdeps/unix/sysv/linux/s390/bits/utmp.h --- libc-head/sysdeps/unix/sysv/linux/s390/bits/utmp.h Thu Jan 1 01:00:00 1970 +++ libc-s390/sysdeps/unix/sysv/linux/s390/bits/utmp.h Wed Oct 9 14:44:48 2002 @@ -0,0 +1,126 @@ +/* The `struct utmp' type, describing entries in the utmp file. GNU version. + Copyright (C) 1993, 1996, 1997, 1998, 1999, 2002 + 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 _UTMP_H +# error "Never include directly; use instead." +#endif + +#include +#include +#include +#include + + +#define UT_LINESIZE 32 +#define UT_NAMESIZE 32 +#define UT_HOSTSIZE 256 + + +/* The structure describing an entry in the database of + previous logins. */ +struct lastlog + { +#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32 + int32_t ll_time; +#else + __time_t ll_time; +#endif + char ll_line[UT_LINESIZE]; + char ll_host[UT_HOSTSIZE]; + }; + + +/* The structure describing the status of a terminated process. This + type is used in `struct utmp' below. */ +struct exit_status + { + short int e_termination; /* Process termination status. */ + short int e_exit; /* Process exit status. */ + }; + + +/* The structure describing an entry in the user accounting database. */ +struct utmp +{ + short int ut_type; /* Type of login. */ + pid_t ut_pid; /* Process ID of login process. */ + char ut_line[UT_LINESIZE]; /* Devicename. */ + char ut_id[4]; /* Inittab ID. */ + char ut_user[UT_NAMESIZE]; /* Username. */ + char ut_host[UT_HOSTSIZE]; /* Hostname for remote login. */ + struct exit_status ut_exit; /* Exit status of a process marked + as DEAD_PROCESS. */ + +/* The fields ut_session and ut_tv must be the same size when compiled + 32- and 64-bit. This allows files and shared memory to be shared + between 32/64bit applications. For example /var/run/utmp. */ +#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32 + int32_t ut_session; /* Session ID, used for windowing. */ + struct + { + int32_t tv_sec; /* Seconds. */ + int32_t tv_usec; /* Microseconds. */ + } ut_tv; /* Time entry was made. */ +#else + long int ut_session; /* Session ID, used for windowing. */ + struct timeval ut_tv; /* Time entry was made. */ +#endif + + int32_t ut_addr_v6[4]; /* Internet address of remote host. */ + char __unused[20]; /* Reserved for future use. */ +}; + +/* Backwards compatibility hacks. */ +#define ut_name ut_user +#ifndef _NO_UT_TIME +/* We have a problem here: `ut_time' is also used otherwise. Define + _NO_UT_TIME if the compiler complains. */ +# define ut_time ut_tv.tv_sec +#endif +#define ut_xtime ut_tv.tv_sec +#define ut_addr ut_addr_v6[0] + + +/* Values for the `ut_type' field of a `struct utmp'. */ +#define EMPTY 0 /* No valid user accounting information. */ + +#define RUN_LVL 1 /* The system's runlevel. */ +#define BOOT_TIME 2 /* Time of system boot. */ +#define NEW_TIME 3 /* Time after system clock changed. */ +#define OLD_TIME 4 /* Time when system clock changed. */ + +#define INIT_PROCESS 5 /* Process spawned by the init process. */ +#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */ +#define USER_PROCESS 7 /* Normal process. */ +#define DEAD_PROCESS 8 /* Terminated process. */ + +#define ACCOUNTING 9 + +/* Old Linux name for the EMPTY type. */ +#define UT_UNKNOWN EMPTY + + +/* Tell the user that we have a modern system with UT_HOST, UT_PID, + UT_TYPE, UT_ID and UT_TV fields. */ +#define _HAVE_UT_TYPE 1 +#define _HAVE_UT_PID 1 +#define _HAVE_UT_ID 1 +#define _HAVE_UT_TV 1 +#define _HAVE_UT_HOST 1 diff -urN libc-head/sysdeps/unix/sysv/linux/s390/bits/utmpx.h libc-s390/sysdeps/unix/sysv/linux/s390/bits/utmpx.h --- libc-head/sysdeps/unix/sysv/linux/s390/bits/utmpx.h Thu Jan 1 01:00:00 1970 +++ libc-s390/sysdeps/unix/sysv/linux/s390/bits/utmpx.h Wed Oct 9 14:44:52 2002 @@ -0,0 +1,102 @@ +/* Structures and definitions for the user accounting database. GNU version. + Copyright (C) 1997, 1998, 2000, 2001, 2002 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 _UTMPX_H +# error "Never include directly; use instead." +#endif + +#include +#include + + +#ifdef __USE_GNU +# include +# define _PATH_UTMPX _PATH_UTMP +# define _PATH_WTMPX _PATH_WTMP +#endif + + +#define __UT_LINESIZE 32 +#define __UT_NAMESIZE 32 +#define __UT_HOSTSIZE 256 + + +/* The structure describing the status of a terminated process. This + type is used in `struct utmpx' below. */ +struct __exit_status + { +#ifdef __USE_GNU + short int e_termination; /* Process termination status. */ + short int e_exit; /* Process exit status. */ +#else + short int __e_termination; /* Process termination status. */ + short int __e_exit; /* Process exit status. */ +#endif + }; + + +/* The structure describing an entry in the user accounting database. */ +struct utmpx +{ + short int ut_type; /* Type of login. */ + __pid_t ut_pid; /* Process ID of login process. */ + char ut_line[__UT_LINESIZE]; /* Devicename. */ + char ut_id[4]; /* Inittab ID. */ + char ut_user[__UT_NAMESIZE]; /* Username. */ + char ut_host[__UT_HOSTSIZE]; /* Hostname for remote login. */ + struct __exit_status ut_exit; /* Exit status of a process marked + as DEAD_PROCESS. */ + +/* The fields ut_session and ut_tv must be the same size when compiled + 32- and 64-bit. This allows files and shared memory to be shared + between 32/64bit applications. */ +#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32 + __int32_t ut_session; /* Session ID, used for windowing. */ + struct + { + __int32_t tv_sec; /* Seconds. */ + __int32_t tv_usec; /* Microseconds. */ + } ut_tv; /* Time entry was made. */ +#else + long int ut_session; /* Session ID, used for windowing. */ + struct timeval ut_tv; /* Time entry was made. */ +#endif + __int32_t ut_addr_v6[4]; /* Internet address of remote host. */ + char __unused[20]; /* Reserved for future use. */ +}; + + +/* Values for the `ut_type' field of a `struct utmpx'. */ +#define EMPTY 0 /* No valid user accounting information. */ + +#ifdef __USE_GNU +# define RUN_LVL 1 /* The system's runlevel. */ +#endif +#define BOOT_TIME 2 /* Time of system boot. */ +#define NEW_TIME 3 /* Time after system clock changed. */ +#define OLD_TIME 4 /* Time when system clock changed. */ + +#define INIT_PROCESS 5 /* Process spawned by the init process. */ +#define LOGIN_PROCESS 6 /* Session leader of a logged in user. */ +#define USER_PROCESS 7 /* Normal process. */ +#define DEAD_PROCESS 8 /* Terminated process. */ + +#ifdef __USE_GNU +# define ACCOUNTING 9 /* System accounting. */ +#endif From jakub@redhat.com Wed Oct 9 07:05:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 09 Oct 2002 07:05:00 -0000 Subject: [PATCH] */lib64 for s390x In-Reply-To: <200210091505.12166.schwidefsky@de.ibm.com>; from schwidefsky@de.ibm.com on Wed, Oct 09, 2002 at 03:05:11PM +0200 References: <200210091505.12166.schwidefsky@de.ibm.com> Message-ID: <20021009151537.O3451@sunsite.ms.mff.cuni.cz> On Wed, Oct 09, 2002 at 03:05:11PM +0200, Martin Schwidefsky wrote: > All I can say is: he is right. I wanted to look into versioned symbols for > the glibc functions that are affected by the utmp.h/utmpx.h change but I > am too busy with other stuff right now (and I know that extreme caution > is required for anything to do with versioning). Don't you need following too? 2002-10-09 Jakub Jelinek * sysdeps/unix/sysv/linux/configure.in: Use */lib64 for s390x too. * sysdeps/unix/sysv/linux/configure: Rebuilt. --- libc/sysdeps/unix/sysv/linux/configure.in 28 Sep 2002 20:39:35 -0000 1.1.1.17 +++ libc/sysdeps/unix/sysv/linux/configure.in 9 Oct 2002 11:14:45 -0000 1.14 @@ -185,7 +185,8 @@ fi if test "$prefix" = "/usr" -o "$prefix" = "/usr/"; then # 64bit libraries on sparc go to /lib64 and not /lib if test "$machine" = "sparc/sparc64" -o "$machine" = "x86_64" \ - -o "$machine" = "powerpc/powerpc64"; then + -o "$machine" = "powerpc/powerpc64" \ + -o "$machine" = "s390/s390-64"; then libc_cv_slibdir="/lib64" if test "$libdir" = '${exec_prefix}/lib'; then libdir='${exec_prefix}/lib64'; --- libc/sysdeps/unix/sysv/linux/configure 28 Sep 2002 20:39:35 -0000 1.1.1.17 +++ libc/sysdeps/unix/sysv/linux/configure 9 Oct 2002 11:14:45 -0000 1.14 @@ -185,7 +185,8 @@ fi if test "$prefix" = "/usr" -o "$prefix" = "/usr/"; then # 64bit libraries on sparc go to /lib64 and not /lib if test "$machine" = "sparc/sparc64" -o "$machine" = "x86_64" \ - -o "$machine" = "powerpc/powerpc64"; then + -o "$machine" = "powerpc/powerpc64" \ + -o "$machine" = "s390/s390-64"; then libc_cv_slibdir="/lib64" if test "$libdir" = '${exec_prefix}/lib'; then libdir='${exec_prefix}/lib64'; Jakub From jakub@redhat.com Wed Oct 9 07:32:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 09 Oct 2002 07:32:00 -0000 Subject: [PATCH] Fix no-tsd.c compile on certain arches Message-ID: <20021009160552.P3451@sunsite.ms.mff.cuni.cz> Hi! With this I succeeded to build current CVS on i386/i686/alpha/alphaev6/ia64 with make check passing everywhere but on ia64 due to the well known miscompilation. It did not fail in my i686 build previously, since there stdlib.h is included from libc-tsd.h ... useldt.h. Sorry. 2002-10-09 Jakub Jelinek * no-tsd.c: Include stdlib.h. --- libc/linuxthreads/no-tsd.c 9 Oct 2002 10:32:32 -0000 1.1.1.5 +++ libc/linuxthreads/no-tsd.c 9 Oct 2002 12:01:31 -0000 1.2 @@ -19,6 +19,7 @@ #include /* for __const */ #include +#include #if !(USE_TLS && HAVE___THREAD) Jakub From schwidefsky@de.ibm.com Wed Oct 9 07:35:00 2002 From: schwidefsky@de.ibm.com (Martin Schwidefsky) Date: Wed, 09 Oct 2002 07:35:00 -0000 Subject: [PATCH] */lib64 for s390x Message-ID: >Don't you need following too? > >2002-10-09 Jakub Jelinek > >* sysdeps/unix/sysv/linux/configure.in: Use */lib64 for s390x too. >* sysdeps/unix/sysv/linux/configure: Rebuilt. We need this one IF we want to switch to the */lib64 scheme of doing things. The SuSE distribution goes this way, RedHat has not implemented it yet. Did this make it to the LSB? Or do we simply decide that this is the way to go? I personally think it is the right thing to do but how "official" is this? blue skies, Martin Linux/390 Design & Development, IBM Deutschland Entwicklung GmbH Sch?naicherstr. 220, D-71032 B?blingen, Telefon: 49 - (0)7031 - 16-2247 E-Mail: schwidefsky@de.ibm.com From jakub@redhat.com Wed Oct 9 07:48:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 09 Oct 2002 07:48:00 -0000 Subject: [PATCH] */lib64 for s390x In-Reply-To: ; from schwidefsky@de.ibm.com on Wed, Oct 09, 2002 at 04:29:55PM +0200 References: Message-ID: <20021009163548.R3451@sunsite.ms.mff.cuni.cz> On Wed, Oct 09, 2002 at 04:29:55PM +0200, Martin Schwidefsky wrote: > > >Don't you need following too? > > > >2002-10-09 Jakub Jelinek > > > >* sysdeps/unix/sysv/linux/configure.in: Use */lib64 for s390x too. > >* sysdeps/unix/sysv/linux/configure: Rebuilt. > > We need this one IF we want to switch to the */lib64 scheme of doing > things. The SuSE distribution goes this way, RedHat has not implemented > it yet. Did this make it to the LSB? Or do we simply decide that this > is the way to go? I personally think it is the right thing to do but > how "official" is this? I personally think this is the right way to go too. Jakub From schwidefsky@de.ibm.com Wed Oct 9 10:00:00 2002 From: schwidefsky@de.ibm.com (Martin Schwidefsky) Date: Wed, 09 Oct 2002 10:00:00 -0000 Subject: [PATCH] */lib64 for s390x Message-ID: > I personally think this is the right way to go too. Ok then. Ulrich: would you please apply Jakubs configure patch as well? blue skies, Martin Linux/390 Design & Development, IBM Deutschland Entwicklung GmbH Sch?naicherstr. 220, D-71032 B?blingen, Telefon: 49 - (0)7031 - 16-2247 E-Mail: schwidefsky@de.ibm.com From drepper@redhat.com Thu Oct 10 04:04:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Thu, 10 Oct 2002 04:04:00 -0000 Subject: [PATCH] Fix no-tsd.c compile on certain arches References: <20021009160552.P3451@sunsite.ms.mff.cuni.cz> Message-ID: <3DA46099.801@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Jakub Jelinek wrote: > With this I succeeded to build current CVS on i386/i686/alpha/alphaev6/ia64 > with make check passing everywhere but on ia64 due to the well known > miscompilation. I've applied the patch. Thanks, - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9pGCd2ijCOnn/RHQRAqvmAKCuuJFm/8nRGSn3996jJls+mUJAXwCeP1GZ rt3RJGxkDaM5Ej4InTlyEW0= =5vnJ -----END PGP SIGNATURE----- From jakub@redhat.com Thu Oct 10 07:22:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Thu, 10 Oct 2002 07:22:00 -0000 Subject: [PATCH] bi-arch for ppc/s390 Message-ID: <20021010130447.X3451@sunsite.ms.mff.cuni.cz> Hi! I noticed s390 and ppc don't generate bi-arch bits/syscall.h like x86-64 and sparc already do. 2002-10-10 Jakub Jelinek * sysdeps/unix/sysv/linux/powerpc/Makefile: Generate bits/syscall.h with biarch support. * sysdeps/unix/sysv/linux/s390/Makefile: New file. * sysdeps/unix/sysv/linux/sparc/Makefile (syscall-%.h): Run comm in C locale. * sysdeps/unix/sysv/linux/x86_64/Makefile (syscall-%.h): Likewise. --- libc/sysdeps/unix/sysv/linux/s390/Makefile.jj 2002-10-10 12:34:57.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/s390/Makefile 2002-10-10 12:40:00.000000000 +0200 @@ -0,0 +1,43 @@ +ifeq ($(subdir),misc) +no_syscall_list_h = 1 + +# Generate the list of SYS_* macros for the system calls (__NR_* macros). +$(objpfx)syscall-%.h $(objpfx)syscall-%.d: ../sysdeps/unix/sysv/linux/sys/syscall.h + rm -f $(@:.h=.d)-t + { \ + echo '/* Generated at libc build time from kernel syscall list. */';\ + echo ''; \ + echo '#ifndef _SYSCALL_H'; \ + echo '# error "Never use directly; include instead."'; \ + echo '#endif'; \ + echo ''; \ + SUNPRO_DEPENDENCIES='$(@:.h=.d)-t $@' \ + $(CC) -E -x c $(sysincludes) $< -U__s390x__ -D_LIBC -dM | \ + sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \ + LC_ALL=C sort > $(@:.d=.h).new32; \ + SUNPRO_DEPENDENCIES='$(@:.h=.d)-t $@' \ + $(CC) -E -x c $(sysincludes) $< -D__s390x__ -D_LIBC -dM | \ + sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \ + LC_ALL=C sort > $(@:.d=.h).new64; \ + if cmp -s $(@:.d=.h).new32 $(@:.d=.h).new64; then \ + cat $(@:.d=.h).new32; \ + else \ + echo '#include '; \ + echo ''; \ + LC_ALL=C comm -12 $(@:.d=.h).new32 $(@:.d=.h).new64; \ + echo '#if __WORDSIZE == 64'; \ + LC_ALL=C comm -13 $(@:.d=.h).new32 $(@:.d=.h).new64; \ + echo '#else'; \ + LC_ALL=C comm -23 $(@:.d=.h).new32 $(@:.d=.h).new64; \ + echo '#endif'; \ + fi; \ + rm -f $(@:.d=.h).new32 $(@:.d=.h).new64; \ + } > $(@:.d=.h).new + mv -f $(@:.d=.h).new $(@:.d=.h) + sed < $(@:.h=.d)-t > $(@:.h=.d)-t2 \ + -e 's,$(subst .,\.,$@),$(patsubst $(objpfx)%,$$(objpfx)%,\ + $(@:.d=.h) $(@:.h=.d)),' + rm -f $(@:.h=.d)-t + mv -f $(@:.h=.d)-t2 $(@:.h=.d) + +endif --- libc/sysdeps/unix/sysv/linux/powerpc/Makefile.jj 2002-09-05 12:29:54.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/powerpc/Makefile 2002-10-10 12:41:28.000000000 +0200 @@ -2,3 +2,47 @@ ifeq ($(subdir),signal) sysdep_routines += rt_sigsuspend rt_sigprocmask rt_sigtimedwait \ rt_sigqueueinfo rt_sigaction rt_sigpending endif + +ifeq ($(subdir),misc) +no_syscall_list_h = 1 + +# Generate the list of SYS_* macros for the system calls (__NR_* macros). +$(objpfx)syscall-%.h $(objpfx)syscall-%.d: ../sysdeps/unix/sysv/linux/sys/syscall.h + rm -f $(@:.h=.d)-t + { \ + echo '/* Generated at libc build time from kernel syscall list. */';\ + echo ''; \ + echo '#ifndef _SYSCALL_H'; \ + echo '# error "Never use directly; include instead."'; \ + echo '#endif'; \ + echo ''; \ + SUNPRO_DEPENDENCIES='$(@:.h=.d)-t $@' \ + $(CC) -E -x c $(sysincludes) $< -U__powerpc64__ -D_LIBC -dM | \ + sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \ + LC_ALL=C sort > $(@:.d=.h).new32; \ + SUNPRO_DEPENDENCIES='$(@:.h=.d)-t $@' \ + $(CC) -E -x c $(sysincludes) $< -D__powerpc64__ -D_LIBC -dM | \ + sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \ + LC_ALL=C sort > $(@:.d=.h).new64; \ + if cmp -s $(@:.d=.h).new32 $(@:.d=.h).new64; then \ + cat $(@:.d=.h).new32; \ + else \ + echo '#include '; \ + echo ''; \ + LC_ALL=C comm -12 $(@:.d=.h).new32 $(@:.d=.h).new64; \ + echo '#if __WORDSIZE == 64'; \ + LC_ALL=C comm -13 $(@:.d=.h).new32 $(@:.d=.h).new64; \ + echo '#else'; \ + LC_ALL=C comm -23 $(@:.d=.h).new32 $(@:.d=.h).new64; \ + echo '#endif'; \ + fi; \ + rm -f $(@:.d=.h).new32 $(@:.d=.h).new64; \ + } > $(@:.d=.h).new + mv -f $(@:.d=.h).new $(@:.d=.h) + sed < $(@:.h=.d)-t > $(@:.h=.d)-t2 \ + -e 's,$(subst .,\.,$@),$(patsubst $(objpfx)%,$$(objpfx)%,\ + $(@:.d=.h) $(@:.h=.d)),' + rm -f $(@:.h=.d)-t + mv -f $(@:.h=.d)-t2 $(@:.h=.d) + +endif --- libc/sysdeps/unix/sysv/linux/sparc/Makefile.jj 2002-04-07 17:46:25.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/sparc/Makefile 2002-10-10 13:10:53.000000000 +0200 @@ -25,11 +25,11 @@ $(objpfx)syscall-%.h $(objpfx)syscall-%. else \ echo '#include '; \ echo ''; \ - comm -12 $(@:.d=.h).new32 $(@:.d=.h).new64; \ + LC_ALL=C comm -12 $(@:.d=.h).new32 $(@:.d=.h).new64; \ echo '#if __WORDSIZE == 64'; \ - comm -13 $(@:.d=.h).new32 $(@:.d=.h).new64; \ + LC_ALL=C comm -13 $(@:.d=.h).new32 $(@:.d=.h).new64; \ echo '#else'; \ - comm -23 $(@:.d=.h).new32 $(@:.d=.h).new64; \ + LC_ALL=C comm -23 $(@:.d=.h).new32 $(@:.d=.h).new64; \ echo '#endif'; \ fi; \ rm -f $(@:.d=.h).new32 $(@:.d=.h).new64; \ --- libc/sysdeps/unix/sysv/linux/x86_64/Makefile.jj 2002-09-01 09:34:48.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/x86_64/Makefile 2002-10-10 13:10:31.000000000 +0200 @@ -27,11 +27,11 @@ $(objpfx)syscall-%.h $(objpfx)syscall-%. else \ echo '#include '; \ echo ''; \ - comm -12 $(@:.d=.h).new32 $(@:.d=.h).new64; \ + LC_ALL=C comm -12 $(@:.d=.h).new32 $(@:.d=.h).new64; \ echo '#if __WORDSIZE == 64'; \ - comm -13 $(@:.d=.h).new32 $(@:.d=.h).new64; \ + LC_ALL=C comm -13 $(@:.d=.h).new32 $(@:.d=.h).new64; \ echo '#else'; \ - comm -23 $(@:.d=.h).new32 $(@:.d=.h).new64; \ + LC_ALL=C comm -23 $(@:.d=.h).new32 $(@:.d=.h).new64; \ echo '#endif'; \ fi; \ rm -f $(@:.d=.h).new32 $(@:.d=.h).new64; \ Jakub From jakub@redhat.com Thu Oct 10 23:42:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Thu, 10 Oct 2002 23:42:00 -0000 Subject: [PATCH] Honor executables DT_RUNPATH for dlopen Message-ID: <20021010162155.Y3451@sunsite.ms.mff.cuni.cz> Hi! echo 'void f () {}' | gcc -fpic -shared -xc - -o libbar.so gcc -Wl,-rpath,.,--enable-new-dtags -xc - -ldl -o bar <<"EOF" #include int main () { void *p = dlopen ("libbar.so", RTLD_NOW); if (!p) puts (dlerror ()); return !p; } EOF ./bar test fails, because for dlopen DT_RUNPATH of the executable is not searched. Unfortunately the patch does a bunch of tests in the common path, maybe it should be reordered to check l->l_runpath_dirs.dirs != -1 right before l->l_type != lt_loaded test. 2002-10-10 Jakub Jelinek * elf/dl-load.c (_dl_map_object): Use DT_RUNPATH of the executable for dlopen searches. --- libc/elf/dl-load.c.jj 2002-10-10 13:57:28.000000000 +0200 +++ libc/elf/dl-load.c 2002-10-10 13:59:20.000000000 +0200 @@ -1751,6 +1751,14 @@ _dl_map_object (struct link_map *loader, break; } + /* If dynamically linked, try the DT_RUNPATH of the executable + itself. */ + l = GL(dl_loaded); + if (fd == -1 && l && l->l_type != lt_loaded && l != loader + && l->l_runpath_dirs.dirs != (void *) -1) + fd = open_path (name, namelen, preloaded, &l->l_runpath_dirs, + &realname, &fb); + if (fd == -1 && (__builtin_expect (! preloaded, 1) || ! INTUSE(__libc_enable_secure))) Jakub From drepper@redhat.com Fri Oct 11 04:03:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Fri, 11 Oct 2002 04:03:00 -0000 Subject: the tree is open Message-ID: <3DA672DA.40206@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 New code can go in again. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE9pnLa2ijCOnn/RHQRAtSoAJ9w5Pltq5QIu7ps0a1//iDqbeILZgCgk/is bKmHreYY4lBXguKSAxz1fV0= =gfXF -----END PGP SIGNATURE----- From roland@redhat.com Fri Oct 11 04:51:00 2002 From: roland@redhat.com (Roland McGrath) Date: Fri, 11 Oct 2002 04:51:00 -0000 Subject: -std=gnu99 Message-ID: <200210111103.g9BB3U425922@magilla.sf.frob.com> I've made libc compile using -std=gnu99 now. This didn't require changing any code (nor was it required to make any code work), though some tiny nits were changed because of new warnings. It just keeps us on our toes and reflects the fact that ISO C99 with GNU extensions is the dialect in which libc is written. In writing new libc code we are free to use C99 constructs that GCC's default mode (-std=gnu89) won't accept. However, there are now some new spurious warnings about use of the `a' flag in scanf formats. GCC's format checker can't distinguish between the pre-1999 GNU extension `a' flag for string formats and the ISO C99 new `a' format specifier for floats, and under -std=gnu99 it sees any format starting with `%a' as the latter. The runtime format parser has no trouble with either, and no valid syntax is actually ambiguous. From roland@redhat.com Sun Oct 13 12:59:00 2002 From: roland@redhat.com (Roland McGrath) Date: Sun, 13 Oct 2002 12:59:00 -0000 Subject: rtld build changes Message-ID: <200210111151.g9BBpCL26260@magilla.sf.frob.com> I have committed an updated version of the changes I posted previously to reorganize the way ld.so is built. Along with this are several cleanups and optimizations that this enables, and we may want to do more now that we have the facility. These changes are all working fine for me, but I have only tried builds on x86, ppc, and x86-64, and not done much testing beyond make check. So be on the lookout for sudden wierdness and let me know. So far two things of interest were made possible by building ld.so the new way: ld.so always uses its own private errno variable (to which all access is already serialized), and all accesses to it use GOTOFF relocs. Between this and some other optimization/cleanups, ld.so has gone from 16 relocs to 9 and that's pretty much as low as it can go. When libc is using __thread, ld.so still does not. You can now have one ld.so installed capable of loading a libc binary built to use __thread or one built without it. This also eliminates some startup overhead (including a system call) from ld.so. From jakub@redhat.com Mon Oct 14 07:27:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 14 Oct 2002 07:27:00 -0000 Subject: [PATCH] Apply i386/profil-counter.h changes to arm, sh and x86_64 too Message-ID: <20021013215856.E3451@sunsite.ms.mff.cuni.cz> Hi! These 3 arches apparently use some struct instead of struct * as argument to profil_counter, thus might see the same problem. Am not exactly sure whether all of the arches support sibcall already, at least x86_64 doesn't yet but probably will do soon, but it is better to do this now IMHO than to forget about it. 2002-10-13 Jakub Jelinek * sysdeps/unix/sysv/linux/arm/profil-counter.h (profil_counter): Add hack to prevent the compiler from clobbering the signal context. * sysdeps/unix/sysv/linux/sh/profil-counter.h (profil_counter): Likewise. * sysdeps/unix/sysv/linux/x86_64/profil-counter.h (profil_counter): Likewise. --- libc/sysdeps/unix/sysv/linux/sh/profil-counter.h.jj 2001-08-23 18:51:29.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/sh/profil-counter.h 2002-10-13 22:03:51.000000000 +0200 @@ -1,5 +1,5 @@ /* Low-level statistical profiling support function. Linux/SH version. - Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 2000, 2002 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,4 +25,9 @@ profil_counter (int signo, int _a2, int void *pc; pc = (void *) sc.sc_pc; profil_count (pc); + + /* This is a hack to prevent the compiler from implementing the + above function call as a sibcall. The sibcall would overwrite + the signal context. */ + asm volatile (""); } --- libc/sysdeps/unix/sysv/linux/arm/profil-counter.h.jj 2001-08-23 18:50:48.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/arm/profil-counter.h 2002-10-13 22:02:09.000000000 +0200 @@ -1,5 +1,5 @@ /* Low-level statistical profiling support function. Linux/ARM version. - Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 2002 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 @@ -29,4 +29,9 @@ profil_counter (int signo, int _a2, int else pc = (void *) sc.v21.arm_pc; profil_count (pc); + + /* This is a hack to prevent the compiler from implementing the + above function call as a sibcall. The sibcall would overwrite + the signal context. */ + asm volatile (""); } --- libc/sysdeps/unix/sysv/linux/x86_64/profil-counter.h.jj 2001-09-19 12:32:01.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/x86_64/profil-counter.h 2002-10-13 22:05:17.000000000 +0200 @@ -1,5 +1,5 @@ /* Low-level statistical profiling support function. Linux/x86-64 version. - Copyright (C) 2001 Free Software Foundation, Inc. + Copyright (C) 2001, 2002 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 @@ -24,4 +24,9 @@ static void profil_counter (int signo, SIGCONTEXT scp) { profil_count ((void *) GET_PC (scp)); + + /* This is a hack to prevent the compiler from implementing the + above function call as a sibcall. The sibcall would overwrite + the signal context. */ + asm volatile (""); } Jakub From jakub@redhat.com Mon Oct 14 12:38:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 14 Oct 2002 12:38:00 -0000 Subject: [PATCH] libc x86-64 __thread fix Message-ID: <20021014162717.G3451@sunsite.ms.mff.cuni.cz> Hi! 2002-10-14 Jakub Jelinek * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Include tls.h. (SYSCALL_ERROR_HANDLER): Use RTLD_PRIVATE_ERRNO sequence in ld.so even if __thread is supported. --- libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h.jj 2002-10-11 08:54:41.000000000 -0400 +++ libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h 2002-10-14 08:16:36.000000000 -0400 @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef IS_IN_rtld # include /* Defines RTLD_PRIVATE_ERRNO. */ @@ -82,22 +83,22 @@ #ifndef PIC #define SYSCALL_ERROR_HANDLER /* Nothing here; code in sysdep.S is used. */ -#elif USE___THREAD +#elif RTLD_PRIVATE_ERRNO # define SYSCALL_ERROR_HANDLER \ 0: \ - movq errno@GOTTPOFF(%rip), %rcx; \ + leaq errno(%rip), %rcx; \ xorq %rdx, %rdx; \ subq %rax, %rdx; \ - movl %edx, %fs:(%rcx); \ + movl %edx, (%rcx); \ orq $-1, %rax; \ jmp L(pseudo_end); -#elif RTLD_PRIVATE_ERRNO +#elif USE___THREAD # define SYSCALL_ERROR_HANDLER \ 0: \ - leaq errno(%rip), %rcx; \ + movq errno@GOTTPOFF(%rip), %rcx; \ xorq %rdx, %rdx; \ subq %rax, %rdx; \ - movl %edx, (%rcx); \ + movl %edx, %fs:(%rcx); \ orq $-1, %rax; \ jmp L(pseudo_end); #elif defined _LIBC_REENTRANT Jakub From roland@redhat.com Mon Oct 14 14:00:00 2002 From: roland@redhat.com (Roland McGrath) Date: Mon, 14 Oct 2002 14:00:00 -0000 Subject: [PATCH] libc x86-64 __thread fix In-Reply-To: Jakub Jelinek's message of Monday, 14 October 2002 16:27:17 +0200 <20021014162717.G3451@sunsite.ms.mff.cuni.cz> Message-ID: <200210141937.g9EJbxx13170@magilla.sf.frob.com> Something is wrong if you need that. USE___THREAD != HAVE___THREAD. Why is USE___THREAD defined in your rtld build? From jakub@redhat.com Mon Oct 14 16:13:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Mon, 14 Oct 2002 16:13:00 -0000 Subject: [PATCH] libc x86-64 __thread fix In-Reply-To: <200210141937.g9EJbxx13170@magilla.sf.frob.com>; from roland@redhat.com on Mon, Oct 14, 2002 at 12:37:59PM -0700 References: <20021014162717.G3451@sunsite.ms.mff.cuni.cz> <200210141937.g9EJbxx13170@magilla.sf.frob.com> Message-ID: <20021014230027.H3451@sunsite.ms.mff.cuni.cz> On Mon, Oct 14, 2002 at 12:37:59PM -0700, Roland McGrath wrote: > Something is wrong if you need that. USE___THREAD != HAVE___THREAD. > Why is USE___THREAD defined in your rtld build? Actually, maybe just the #include is needed. The problem was that without including tls.h uname.os etc. in libc-pic.a was calling __errno_location(), which caused rtld-errno-loc.os to be added into librtld.a. But rtld-errno-loc.os would not compile, because errno was first defined as normal variable in include/errno.h and then redefined as __thread variable in sysdeps/generic/errno-loc.c. Though IMHO putting RTLD_PRIVATE_ERRNO case before USE__THREAD shouldn't hurt. Jakub From roland@redhat.com Tue Oct 15 00:36:00 2002 From: roland@redhat.com (Roland McGrath) Date: Tue, 15 Oct 2002 00:36:00 -0000 Subject: [PATCH] libc x86-64 __thread fix In-Reply-To: Jakub Jelinek's message of Monday, 14 October 2002 23:00:27 +0200 <20021014230027.H3451@sunsite.ms.mff.cuni.cz> Message-ID: <200210142313.g9ENDAt13988@magilla.sf.frob.com> > Actually, maybe just the #include is needed. Yes, though that doesn't directly affect the build of the rtld modules. > The problem was that without including tls.h uname.os etc. in libc-pic.a Ah, I see. I was confused as to how it could be losing even if USE___THREAD was never defined at all, because !defined -> 0 is the right default for the rtld build. But that explains it, since it was the libc build of the module that indirectly loused up the rtld build. > Though IMHO putting RTLD_PRIVATE_ERRNO case before USE__THREAD > shouldn't hurt. Certainly. I just don't like these things to be mysterious. From aj@suse.de Tue Oct 15 15:26:00 2002 From: aj@suse.de (Andreas Jaeger) Date: Tue, 15 Oct 2002 15:26:00 -0000 Subject: [PATCH] */lib64 for s390x In-Reply-To: <20021009151537.O3451@sunsite.ms.mff.cuni.cz> (Jakub Jelinek's message of "Wed, 9 Oct 2002 15:15:37 +0200") References: <200210091505.12166.schwidefsky@de.ibm.com> <20021009151537.O3451@sunsite.ms.mff.cuni.cz> Message-ID: Jakub Jelinek writes: > On Wed, Oct 09, 2002 at 03:05:11PM +0200, Martin Schwidefsky wrote: >> All I can say is: he is right. I wanted to look into versioned symbols for >> the glibc functions that are affected by the utmp.h/utmpx.h change but I >> am too busy with other stuff right now (and I know that extreme caution >> is required for anything to do with versioning). > > Don't you need following too? > > 2002-10-09 Jakub Jelinek > > * sysdeps/unix/sysv/linux/configure.in: Use */lib64 for s390x too. > * sysdeps/unix/sysv/linux/configure: Rebuilt. I'm going to apply this now, Andreas > > --- libc/sysdeps/unix/sysv/linux/configure.in 28 Sep 2002 20:39:35 -0000 1.1.1.17 > +++ libc/sysdeps/unix/sysv/linux/configure.in 9 Oct 2002 11:14:45 -0000 1.14 > @@ -185,7 +185,8 @@ fi > if test "$prefix" = "/usr" -o "$prefix" = "/usr/"; then > # 64bit libraries on sparc go to /lib64 and not /lib > if test "$machine" = "sparc/sparc64" -o "$machine" = "x86_64" \ > - -o "$machine" = "powerpc/powerpc64"; then > + -o "$machine" = "powerpc/powerpc64" \ > + -o "$machine" = "s390/s390-64"; then > libc_cv_slibdir="/lib64" > if test "$libdir" = '${exec_prefix}/lib'; then > libdir='${exec_prefix}/lib64'; > --- libc/sysdeps/unix/sysv/linux/configure 28 Sep 2002 20:39:35 -0000 1.1.1.17 > +++ libc/sysdeps/unix/sysv/linux/configure 9 Oct 2002 11:14:45 -0000 1.14 > @@ -185,7 +185,8 @@ fi > if test "$prefix" = "/usr" -o "$prefix" = "/usr/"; then > # 64bit libraries on sparc go to /lib64 and not /lib > if test "$machine" = "sparc/sparc64" -o "$machine" = "x86_64" \ > - -o "$machine" = "powerpc/powerpc64"; then > + -o "$machine" = "powerpc/powerpc64" \ > + -o "$machine" = "s390/s390-64"; then > libc_cv_slibdir="/lib64" > if test "$libdir" = '${exec_prefix}/lib'; then > libdir='${exec_prefix}/lib64'; > > Jakub > Andreas -- Andreas Jaeger SuSE Labs aj@suse.de private aj@arthur.inka.de http://www.suse.de/~aj From jakub@redhat.com Tue Oct 15 15:43:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 15 Oct 2002 15:43:00 -0000 Subject: [PATCH] Use __attribute__((tls_model(""))), add hidden aliases to TLS vars Message-ID: <20021016002647.K3451@sunsite.ms.mff.cuni.cz> Hi! The following patch uses IE model for all TLS vars defined in libc, plus for errno, _res and h_errno uses a hidden alias when accessed from libc.so, so that it doesn't have to be looked up. 2002-10-16 Jakub Jelinek * include/libc-symbols.h (attribute_tls_model_ie): Define. * include/errno.h (errno): Define to __libc_errno in libc.so. Add attribute_tls_model_ie. * include/netdb.h (h_errno): Define to __libc_h_errno in libc.so. Add attribute_tls_model_ie. * include/resolv.h (_res): Define to __libc_res in libc.so. Add attribute_tls_model_ie. * inet/herrno.c (__libc_h_errno): Add hidden alias to h_errno. (h_errno): Define. * resolv/res_libc.c (__libc_res): Add hidden alias to _res. (_res): Define. * sysdeps/generic/bits/libc-tsd.h (__libc_tsd_define): Add attribute_tls_model_ie. * sysdeps/generic/errno-loc.c (errno): Only undefine if not using __thread. * sysdeps/generic/errno.c (__libc_errno): Add hidden alias to errno. * sysdeps/unix/sysv/linux/i386/sysdep.h (SYSCALL_ERROR_HANDLER): Use __libc_errno in USE___THREAD case. * sysdeps/unix/sysv/linux/x86_64/sysdep.h (SYSCALL_ERROR_HANDLER): Likewise. * configure.in (HAVE_TLS_MODEL_ATTRIBUTE): Check for __attribute__((tls_model (""))). * configure: Rebuilt. * config.h.in (HAVE_TLS_MODEL_ATTRIBUTE): Add. --- libc/include/libc-symbols.h.jj 2002-10-02 10:26:31.000000000 +0200 +++ libc/include/libc-symbols.h 2002-10-15 21:13:14.000000000 +0200 @@ -445,6 +445,12 @@ # define attribute_hidden #endif +#if defined HAVE_TLS_MODEL_ATTRIBUTE +# define attribute_tls_model_ie __attribute__ ((tls_model ("initial-exec"))) +#else +# define attribute_tls_model_ie +#endif + /* Handling on non-exported internal names. We have to do this only for shared code. */ #ifdef SHARED --- libc/include/errno.h.jj 2002-10-11 16:24:33.000000000 +0200 +++ libc/include/errno.h 2002-10-15 22:53:12.000000000 +0200 @@ -24,8 +24,12 @@ extern int errno attribute_hidden; # if USE___THREAD # undef errno -# define errno errno /* For #ifndef errno tests. */ -extern __thread int errno; +# ifndef NOT_IN_libc +# define errno __libc_errno +# else +# define errno errno /* For #ifndef errno tests. */ +# endif +extern __thread int errno attribute_tls_model_ie; # define __set_errno(val) (errno = (val)) # else # define __set_errno(val) (*__errno_location ()) = (val) --- libc/include/netdb.h.jj 2002-10-11 16:24:34.000000000 +0200 +++ libc/include/netdb.h 2002-10-15 22:55:30.000000000 +0200 @@ -6,8 +6,12 @@ # include # if USE___THREAD # undef h_errno -# define h_errno h_errno /* For #ifndef h_errno tests. */ -extern __thread int h_errno; +# ifndef NOT_IN_libc +# define h_errno __libc_h_errno +# else +# define h_errno h_errno /* For #ifndef h_errno tests. */ +# endif +extern __thread int h_errno attribute_tls_model_ie; # define __set_h_errno(x) (h_errno = (x)) # else static inline int --- libc/include/resolv.h.jj 2002-10-15 18:24:35.000000000 +0200 +++ libc/include/resolv.h 2002-10-15 22:56:02.000000000 +0200 @@ -16,7 +16,10 @@ # include # if USE___THREAD # undef _res -extern __thread struct __res_state _res; +# ifndef NOT_IN_libc +# define _res __libc_res +# endif +extern __thread struct __res_state _res attribute_tls_model_ie; # endif # else # ifndef __BIND_NOSTATIC --- libc/inet/herrno.c.jj 2002-09-11 11:21:05.000000000 +0200 +++ libc/inet/herrno.c 2002-10-15 23:55:06.000000000 +0200 @@ -27,6 +27,9 @@ #if USE_TLS && HAVE___THREAD __thread int h_errno; +extern __thread int __libc_h_errno __attribute__ ((alias ("h_errno"))) + attribute_hidden; +# define h_errno __libc_h_errno #else int h_errno = 0; weak_alias (h_errno, _h_errno) --- libc/resolv/res_libc.c.jj 2002-09-11 11:21:09.000000000 +0200 +++ libc/resolv/res_libc.c 2002-10-15 23:55:36.000000000 +0200 @@ -27,6 +27,9 @@ #if USE_TLS && HAVE___THREAD /* With __thread support, this per-thread variable is used in all cases. */ __thread struct __res_state _res; +extern __thread struct __res_state __libc_res __attribute__ ((alias ("_res"))) + attribute_hidden; +# define _res __libc_res #else /* The resolver state for use by single-threaded programs. */ struct __res_state _res; --- libc/sysdeps/generic/bits/libc-tsd.h.jj 2002-10-11 16:24:49.000000000 +0200 +++ libc/sysdeps/generic/bits/libc-tsd.h 2002-10-15 21:02:24.000000000 +0200 @@ -52,7 +52,8 @@ translate directly into variables by macro magic. */ #if USE___THREAD -# define __libc_tsd_define(CLASS, KEY) CLASS __thread void *__libc_tsd_##KEY; +# define __libc_tsd_define(CLASS, KEY) \ + CLASS __thread void *__libc_tsd_##KEY attribute_tls_model_ie; # define __libc_tsd_address(KEY) (&__libc_tsd_##KEY) # define __libc_tsd_get(KEY) (__libc_tsd_##KEY) --- libc/sysdeps/generic/errno-loc.c.jj 2002-07-23 10:05:49.000000000 +0200 +++ libc/sysdeps/generic/errno-loc.c 2002-10-15 22:57:39.000000000 +0200 @@ -20,11 +20,9 @@ #include #include -#undef errno -#if USE_TLS && HAVE___THREAD -extern __thread int errno; -#else +#if !(USE_TLS && HAVE___THREAD) +#undef errno extern int errno; #endif --- libc/sysdeps/generic/errno.c.jj 2002-10-11 12:51:23.000000000 +0200 +++ libc/sysdeps/generic/errno.c 2002-10-15 23:02:50.000000000 +0200 @@ -23,6 +23,8 @@ #if USE___THREAD __thread int errno; +extern __thread int __libc_errno __attribute__ ((alias ("errno"))) + attribute_hidden; #else /* This differs from plain `int errno;' in that it doesn't create a common definition, but a plain symbol that resides in .bss, --- libc/sysdeps/unix/sysv/linux/i386/sysdep.h.jj 2002-10-13 21:59:29.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/i386/sysdep.h 2002-10-15 23:06:09.000000000 +0200 @@ -114,7 +114,7 @@ __i686.get_pc_thunk.reg: \ # define SYSCALL_ERROR_HANDLER \ 0:SETUP_PIC_REG (cx); \ addl $_GLOBAL_OFFSET_TABLE_, %ecx; \ - movl errno@gotntpoff(%ecx), %ecx; \ + movl __libc_errno@GOTNTPOFF(%ecx), %ecx; \ xorl %edx, %edx; \ subl %eax, %edx; \ movl %edx, %gs:0(%ecx); \ --- libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h.jj 2002-10-15 20:41:01.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h 2002-10-15 23:05:18.000000000 +0200 @@ -95,7 +95,7 @@ #elif USE___THREAD # define SYSCALL_ERROR_HANDLER \ 0: \ - movq errno@GOTTPOFF(%rip), %rcx; \ + movq __libc_errno@GOTTPOFF(%rip), %rcx; \ xorq %rdx, %rdx; \ subq %rax, %rdx; \ movl %edx, %fs:(%rcx); \ --- libc/configure.in.jj 2002-10-10 14:01:48.000000000 +0200 +++ libc/configure.in 2002-10-15 21:06:39.000000000 +0200 @@ -1624,6 +1624,22 @@ if test "$libc_cv_gcc___thread" = yes; t AC_DEFINE(HAVE___THREAD) fi +if test "$libc_cv_gcc___thread" = yes; then + dnl Check whether the compiler supports the tls_model attribute. + AC_CACHE_CHECK([for tls_model attribute], libc_cv_gcc_tls_model_attr, [dnl + cat > conftest.c <<\EOF +extern __thread int a __attribute__((tls_model ("initial-exec"))); +EOF + if AC_TRY_COMMAND([${CC-cc} $CFLAGS -S -Werror conftest.c >&AC_FD_CC]); then + libc_cv_gcc_tls_model_attr=yes + else + libc_cv_gcc_tls_model_attr=no + fi + rm -f conftest*]) + if test "$libc_cv_gcc_tls_model_attr" = yes; then + AC_DEFINE(HAVE_TLS_MODEL_ATTRIBUTE) + fi +fi dnl Check whether we have the gd library available. AC_MSG_CHECKING(for libgd) --- libc/configure.jj 2002-10-10 14:01:48.000000000 +0200 +++ libc/configure 2002-10-15 21:07:16.000000000 +0200 @@ -3772,6 +3772,31 @@ EOF fi +if test "$libc_cv_gcc___thread" = yes; then + echo $ac_n "checking for tls_model attribute""... $ac_c" 1>&6 +echo "configure:3778: checking for tls_model attribute" >&5 +if eval "test \"`echo '$''{'libc_cv_gcc_tls_model_attr'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <<\EOF +extern __thread int a __attribute__((tls_model ("initial-exec"))); +EOF + if { ac_try='${CC-cc} $CFLAGS -S -Werror conftest.c >&5'; { (eval echo configure:3785: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then + libc_cv_gcc_tls_model_attr=yes + else + libc_cv_gcc_tls_model_attr=no + fi + rm -f conftest* +fi + +echo "$ac_t""$libc_cv_gcc_tls_model_attr" 1>&6 + if test "$libc_cv_gcc_tls_model_attr" = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_TLS_MODEL_ATTRIBUTE 1 +EOF + + fi +fi echo $ac_n "checking for libgd""... $ac_c" 1>&6 echo "configure:3778: checking for libgd" >&5 --- libc/config.h.in.jj 2002-10-11 16:24:28.000000000 +0200 +++ libc/config.h.in 2002-10-15 20:56:23.000000000 +0200 @@ -101,6 +101,9 @@ /* Define if the __thread keyword is supported. */ #undef HAVE___THREAD +/* Define if the compiler supports __attribute__((tls_model(""))). */ +#undef HAVE_TLS_MODEL_ATTRIBUTE + /* Define if the regparm attribute shall be used for local functions (gcc on ix86 only). */ #undef USE_REGPARMS Jakub From roland@redhat.com Tue Oct 15 20:04:00 2002 From: roland@redhat.com (Roland McGrath) Date: Tue, 15 Oct 2002 20:04:00 -0000 Subject: [PATCH] Use __attribute__((tls_model(""))), add hidden aliases to TLS vars In-Reply-To: Jakub Jelinek's message of Wednesday, 16 October 2002 00:26:47 +0200 <20021016002647.K3451@sunsite.ms.mff.cuni.cz> Message-ID: <200210152243.g9FMh4s11189@magilla.sf.frob.com> Cool, I'll put that in. I was going to get to that myself but hadn't yet installed the compiler that supports it. It occurs to me you could use libc_hidden_proto instead of macros. But that is uglier in the asm, and both ways do the same thing. One thing that concerns me is if a program (erroneously) does "__thread int errno;" (sans extern) or suchlike. Then the program and libpthread will use its errno, but libc will only set __libc_errno. It would be nice if this produced a link-time error like a multiple definition with a non-shared object would. But AFAIK no .so symbol will ever produce a multiple definition error. Perhaps we could do some hack in the linker script. From roland@redhat.com Wed Oct 16 03:12:00 2002 From: roland@redhat.com (Roland McGrath) Date: Wed, 16 Oct 2002 03:12:00 -0000 Subject: [PATCH] bi-arch for ppc/s390 In-Reply-To: Jakub Jelinek's message of Thursday, 10 October 2002 13:04:47 +0200 <20021010130447.X3451@sunsite.ms.mff.cuni.cz> Message-ID: <200210160304.g9G34LZ31277@magilla.sf.frob.com> I consolidated the code for all the platforms that use it, and included your changes. From kukuk@suse.de Wed Oct 16 14:02:00 2002 From: kukuk@suse.de (Thorsten Kukuk) Date: Wed, 16 Oct 2002 14:02:00 -0000 Subject: [PATCH] pathconf and XFS/Reiserfs link count Message-ID: <20021016090844.GA1190@suse.de> Hi, the last patch for adding XFS link count was incomplete and for Alpha, the link count for Reiserfs was also missing. Here is a patch with the missing parts: 2002-10-16 Thorsten Kukuk * sysdeps/unix/sysv/linux/pathconf.c: Add case for XFS link count. * sysdeps/unix/sysv/linux/alpha/pathconf.c: Add case for XFS and REISERFS link count. --- sysdeps/unix/sysv/linux/pathconf.c 6 Jul 2001 04:56:12 -0000 1.6 +++ sysdeps/unix/sysv/linux/pathconf.c 16 Oct 2002 09:02:23 -0000 @@ -82,6 +82,9 @@ case REISERFS_SUPER_MAGIC: return REISERFS_LINK_MAX; + case XFS_SUPER_MAGIC: + return XFS_LINK_MAX; + default: return LINUX_LINK_MAX; } --- sysdeps/unix/sysv/linux/alpha/pathconf.c 6 Jul 2001 04:56:13 -0000 1.6 +++ sysdeps/unix/sysv/linux/alpha/pathconf.c 16 Oct 2002 09:02:23 -0000 @@ -86,6 +86,13 @@ case UFS_CIGAM: return UFS_LINK_MAX; + case REISERFS_SUPER_MAGIC: + return REISERFS_LINK_MAX; + + case XFS_SUPER_MAGIC: + return XFS_LINK_MAX; + + default: return LINUX_LINK_MAX; } -- Thorsten Kukuk http://www.suse.de/~kukuk/ kukuk@suse.de SuSE Linux AG Deutschherrnstr. 15-19 D-90429 Nuernberg -------------------------------------------------------------------- Key fingerprint = A368 676B 5E1B 3E46 CFCE 2D97 F8FD 4E23 56C6 FB4B From jakub@redhat.com Wed Oct 16 15:10:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 16 Oct 2002 15:10:00 -0000 Subject: [PATCH] Apply i386/sysdep.h change to x86_64/sysdep.h too Message-ID: <20021016230251.Q3451@sunsite.ms.mff.cuni.cz> Hi! I think x86_64/sysdep.h should stay in sync. 2002-10-16 Jakub Jelinek * sysdeps/unix/sysv/linux/x86_64/sysdep.h (SYSCALL_ERROR_HANDLER): Use __libc_errno only for libc itself. --- libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h.jj 2002-10-16 23:10:03.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h 2002-10-16 23:11:07.000000000 +0200 @@ -93,9 +93,14 @@ orq $-1, %rax; \ jmp L(pseudo_end); #elif USE___THREAD +# ifndef NOT_IN_libc +# define SYSCALL_ERROR_ERRNO __libc_errno +# else +# define SYSCALL_ERROR_ERRNO errno +# endif # define SYSCALL_ERROR_HANDLER \ 0: \ - movq __libc_errno@GOTTPOFF(%rip), %rcx; \ + movq SYSCALL_ERROR_ERRNO@GOTTPOFF(%rip), %rcx;\ xorq %rdx, %rdx; \ subq %rax, %rdx; \ movl %edx, %fs:(%rcx); \ Jakub From roland@redhat.com Wed Oct 16 17:12:00 2002 From: roland@redhat.com (Roland McGrath) Date: Wed, 16 Oct 2002 17:12:00 -0000 Subject: [PATCH] pathconf and XFS/Reiserfs link count In-Reply-To: Thorsten Kukuk's message of Wednesday, 16 October 2002 11:08:44 +0200 <20021016090844.GA1190@suse.de> Message-ID: <200210162210.g9GMAEE28290@magilla.sf.frob.com> Thanks for the fix. I was unhappy with the ugly situation that made this so easy to miss, so I cleaned it up instead so that such changes now only need to be made in one file. From roland@redhat.com Wed Oct 16 17:20:00 2002 From: roland@redhat.com (Roland McGrath) Date: Wed, 16 Oct 2002 17:20:00 -0000 Subject: [PATCH] pathconf and XFS/Reiserfs link count In-Reply-To: Andi Kleen's message of , 17 October 2002 01:35:45 +0200 Message-ID: <200210170012.g9H0CkA28740@magilla.sf.frob.com> > How about moving the list to a file in /etc ? Someone would have to maintain that too. > The current version doesn't even cover all file systems included in > linux 2.4 that support hardlinks and for each new file system it'll need a > new patch too. And linux has plenty of new file systems in development. I think the current situation is utterly disgusting. The only thing that makes any kind of sense to me is direct kernel support, and I can't fathom why it wasn't done that way a long time ago. From drepper@redhat.com Wed Oct 16 17:36:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Wed, 16 Oct 2002 17:36:00 -0000 Subject: [PATCH] pathconf and XFS/Reiserfs link count In-Reply-To: <200210170012.g9H0CkA28740@magilla.sf.frob.com> References: <200210170012.g9H0CkA28740@magilla.sf.frob.com> Message-ID: <3DAE024B.9010800@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Roland McGrath wrote: > I think the current situation is utterly disgusting. The only thing that > makes any kind of sense to me is direct kernel support, and I can't fathom > why it wasn't done that way a long time ago. I' pleading for kernel sysconf, pathcond, and fpathconf support for years but nobody listens. Until then we have no choice but to use the current sources since using an external file is no option. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE9rgJM2ijCOnn/RHQRAszCAJ9K/lsxdOBmNpvn+dWETRUV6LHFrwCfXGhs YBo66WXn/RIuBSGow4s4H+0= =D0Sx -----END PGP SIGNATURE----- From drepper@redhat.com Fri Oct 18 07:59:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Fri, 18 Oct 2002 07:59:00 -0000 Subject: [PATCH] pathconf and XFS/Reiserfs link count In-Reply-To: <200210170012.g9H0CkA28740@magilla.sf.frob.com> References: <200210170012.g9H0CkA28740@magilla.sf.frob.com> <3DAE024B.9010800@redhat.com> <20021017022815.A32174@wotan.suse.de> Message-ID: <3DAE0627.90300@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Andi Kleen wrote: > Just curious: why is it no option ? Because libc wouldn't be self-contained. That non-obvious file missing could cause problems for the entire system. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE9rgYn2ijCOnn/RHQRAk5fAJ0b50PxLLtAKTKfmrgXVkCurry/DgCgysfu 89czPKF1Dg1NBMt9JiW+5RE= =QAQP -----END PGP SIGNATURE----- From jakub@redhat.com Fri Oct 18 11:59:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Fri, 18 Oct 2002 11:59:00 -0000 Subject: [PATCH] Fix {,f}pathconf Message-ID: <20021018165950.T3451@sunsite.ms.mff.cuni.cz> Hi! Recent pathconf changes broke alpha build (both linux/pathconf.c and alpha/linux/pathconf.c are redefining __pathconf). But looking at it I found that alpha/*pathconf.c is bogus, not just alpha but all linux platforms support files >= 2GB on some filesystems. Looking at the kernel, it is really a mess to find out what the maximum filesizes are, but I've at least tried. Ideally kernel would implement itself *pathconf (and even then s_maxbytes would have to be cleaned up). 2002-10-18 Jakub Jelinek * sysdeps/unix/sysv/linux/pathconf.h (statfs_link_max): Add inline. (statfs_filesize_max): New function. * sysdeps/unix/sysv/linux/linux_fsinfo.h (JFFS_SUPER_MAGIC, JFFS2_SUPER_MAGIC, JFS_SUPER_MAGIC, NTFS_SUPER_MAGIC, ROMFS_SUPER_MAGIC, UDF_SUPER_MAGIC): Define. * sysdeps/unix/sysv/linux/fpathconf.c (__fpathconf): Use statfs_filesize_max. * sysdeps/unix/sysv/linux/pathconf.c (__pathconf): Likewise. * sysdeps/unix/sysv/linux/alpha/fpathconf.c: Removed. * sysdeps/unix/sysv/linux/alpha/pathconf.c: Removed. --- libc/sysdeps/unix/sysv/linux/alpha/pathconf.c.jj 2002-10-17 13:34:33.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/alpha/pathconf.c 2002-10-18 14:02:21.000000000 +0200 @@ -1,51 +0,0 @@ -/* Get file-specific information about a file. Linux/Alpha version. - Copyright (C) 1991,95,96,98,99,2000,2001,2002 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 - -static long int linux_pathconf (const char *file, int name); - -/* Define this first, so it can be inlined. */ -#define __pathconf static linux_pathconf -#include - - -/* Get file-specific information about FILE. */ -long int -__pathconf (const char *file, int name) -{ - if (name == _PC_FILESIZEBITS) - { - /* Test whether this is on a ext2 or UFS filesystem which - support large files. */ - struct statfs fs; - - if (__statfs (file, &fs) < 0 - || (fs.f_type != EXT2_SUPER_MAGIC - && fs.f_type != UFS_MAGIC - && fs.f_type != UFS_CIGAM)) - return 32; - - /* This filesystem supported files >2GB. */ - return 64; - } - - return linux_pathconf (file, name); -} --- libc/sysdeps/unix/sysv/linux/alpha/fpathconf.c.jj 2002-10-17 13:34:33.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/alpha/fpathconf.c 2002-10-18 14:02:28.000000000 +0200 @@ -1,52 +0,0 @@ -/* Get file-specific information about a descriptor. Linux/Alpha version. - Copyright (C) 1991,95,96,98,99,2000,2001,2002 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 - - -static long int linux_fpathconf (int fd, int name); - -/* Define this first, so it can be inlined. */ -#define __fpathconf static linux_fpathconf -#include - - -/* Get file-specific information about FD. */ -long int -__pathconf (int fd, int name) -{ - if (name == _PC_FILESIZEBITS) - { - /* Test whether this is on a ext2 or UFS filesystem which - support large files. */ - struct statfs fs; - - if (__fstatfs (fd, &fs) < 0 - || (fs.f_type != EXT2_SUPER_MAGIC - && fs.f_type != UFS_MAGIC - && fs.f_type != UFS_CIGAM)) - return 32; - - /* This filesystem supported files >2GB. */ - return 64; - } - - return linux_fpathconf (fd, name); -} --- libc/sysdeps/unix/sysv/linux/pathconf.h.jj 2002-10-17 00:09:42.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/pathconf.h 2002-10-18 14:35:58.000000000 +0200 @@ -24,7 +24,7 @@ /* Used like: return statfs_link_max (__statfs (name, &buf), &buf); */ -static long int +static inline long int statfs_link_max (int result, const struct statfs *fsbuf) { if (result < 0) @@ -74,3 +74,49 @@ statfs_link_max (int result, const struc return LINUX_LINK_MAX; } } + +/* Used like: return statfs_filesize_max (__statfs (name, &buf), &buf); */ + +static inline long int +statfs_filesize_max (int result, const struct statfs *fsbuf) +{ + if (result < 0) + { + if (errno == ENOSYS) + /* Not possible, return the default value. */ + return 31; + + /* Some error occured. */ + return -1; + } + + switch (fsbuf->f_type) + { + case EXT2_SUPER_MAGIC: + case UFS_MAGIC: + case UFS_CIGAM: + case REISERFS_SUPER_MAGIC: + return 41; + + case MSDOS_SUPER_MAGIC: + case JFFS_SUPER_MAGIC: + case JFFS2_SUPER_MAGIC: + case NCP_SUPER_MAGIC: + case ROMFS_SUPER_MAGIC: + return 32; + + case XFS_SUPER_MAGIC: + return 43; + + case SMB_SUPER_MAGIC: + case NTFS_SUPER_MAGIC: + case UDF_SUPER_MAGIC: + case JFS_SUPER_MAGIC: + /* These claim s_maxbytes MAX_LFS_FILESIZE, but I don't think they + actually support that much yet. */ + return 41; + + default: + return 31; + } +} --- libc/sysdeps/unix/sysv/linux/linux_fsinfo.h.jj 2002-10-17 13:34:33.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/linux_fsinfo.h 2002-10-18 14:34:58.000000000 +0200 @@ -58,6 +58,15 @@ /* Constant that identifies the `iso9660' filesystem. */ #define ISOFS_SUPER_MAGIC 0x9660 +/* Constant that identifies the `jffs' filesystem. */ +#define JFFS_SUPER_MAGIC 0x07c0 + +/* Constant that identifies the `jffs2' filesystem. */ +#define JFFS2_SUPER_MAGIC 0x72b6 + +/* Constant that identifies the `jfs' filesystem. */ +#define JFS_SUPER_MAGIC 0x3153464a + /* Constants that identify the `minix2' filesystem. */ #define MINIX2_SUPER_MAGIC 0x2468 #define MINIX2_SUPER_MAGIC2 0x2478 @@ -75,6 +84,9 @@ /* Constants that identify the `nfs' filesystem. */ #define NFS_SUPER_MAGIC 0x6969 +/* Constants that identify the `ntfs' filesystem. */ +#define NTFS_SUPER_MAGIC 0x5346544e + /* Constants that identify the `proc' filesystem. */ #define PROC_SUPER_MAGIC 0x9fa0 @@ -84,6 +96,9 @@ /* Constants that identify the `reiser' filesystem. */ #define REISERFS_SUPER_MAGIC 0x52654973 +/* Constant that identifies the `romfs' filesystem. */ +#define ROMFS_SUPER_MAGIC 0x7275 + /* Constants that identify the `smb' filesystem. */ #define SMB_SUPER_MAGIC 0x517b @@ -91,6 +106,9 @@ #define SYSV2_SUPER_MAGIC 0x012ff7b6 #define SYSV4_SUPER_MAGIC 0x012ff7b5 +/* Constants that identify the `udf' filesystem. */ +#define UDF_SUPER_MAGIC 0x15013346 + /* Constants that identify the `ufs' filesystem. */ #define UFS_MAGIC 0x00011954 #define UFS_CIGAM 0x54190100 /* byteswapped MAGIC */ --- libc/sysdeps/unix/sysv/linux/pathconf.c.jj 2002-10-17 13:34:33.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/pathconf.c 2002-10-18 14:39:07.000000000 +0200 @@ -30,11 +30,15 @@ static long int posix_pathconf (const ch long int __pathconf (const char *file, int name) { - if (name == _PC_LINK_MAX) + struct statfs fsbuf; + + switch (name) { - struct statfs fsbuf; + case _PC_LINK_MAX: return statfs_link_max (__statfs (file, &fsbuf), &fsbuf); + case _PC_FILESIZEBITS: + return statfs_filesize_max (__statfs (file, &fsbuf), &fsbuf); + default: + return posix_pathconf (file, name); } - - return posix_pathconf (file, name); } --- libc/sysdeps/unix/sysv/linux/fpathconf.c.jj 2002-10-17 13:34:33.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/fpathconf.c 2002-10-18 14:39:37.000000000 +0200 @@ -32,11 +32,15 @@ __fpathconf (fd, name) int fd; int name; { - if (name == _PC_LINK_MAX) + struct statfs fsbuf; + + switch (name) { - struct statfs fsbuf; + case _PC_LINK_MAX: return statfs_link_max (__fstatfs (fd, &fsbuf), &fsbuf); + case _PC_FILESIZEBITS: + return statfs_filesize_max (__fstatfs (fd, &fsbuf), &fsbuf); + default: + return posix_fpathconf (fd, name); } - - return posix_fpathconf (fd, name); } Jakub From roland@redhat.com Fri Oct 18 12:04:00 2002 From: roland@redhat.com (Roland McGrath) Date: Fri, 18 Oct 2002 12:04:00 -0000 Subject: [PATCH] Fix {,f}pathconf In-Reply-To: Jakub Jelinek's message of Friday, 18 October 2002 16:59:50 +0200 <20021018165950.T3451@sunsite.ms.mff.cuni.cz> Message-ID: <200210181859.g9IIx4500417@magilla.sf.frob.com> > Recent pathconf changes broke alpha build (both linux/pathconf.c and > alpha/linux/pathconf.c are redefining __pathconf). Oops, braino on my part. > But looking at it I found that alpha/*pathconf.c is bogus, not just alpha > but all linux platforms support files >= 2GB on some filesystems. Ok, but this changes the answers seen now and I don't know what users expect. I like your changes to make the code generic, but the exact values you use are wrong. I think users will expect to see 32 or 64 and not anything else. FILESIZEBITS is not specified as the exact log2 of the maximum file size, but rather as the minimum number of bits needed to represent *as a signed integer* the maximum file size. So, for 2GB files it needs to be 32, not 31--moreover, POSIX.1 specifies that 32 is the minimum value an implementation can define. It would meet the spec to return 42 when the max size if 2^41-1, but I think it's a better plan to return 64, and in the general case to return the bitcount of the off_t equivalent type appropriate for the filesystem rather than its internal storage format limit. > Looking at the kernel, it is really a mess to find out what the maximum > filesizes are, but I've at least tried. Ideally kernel would implement > itself *pathconf (and even then s_maxbytes would have to be cleaned up). We are all agreed here, but the kernel people never helped in the past. From roland@redhat.com Fri Oct 18 12:53:00 2002 From: roland@redhat.com (Roland McGrath) Date: Fri, 18 Oct 2002 12:53:00 -0000 Subject: [PATCH] Fix {,f}pathconf In-Reply-To: Jakub Jelinek's message of Friday, 18 October 2002 16:59:50 +0200 <20021018165950.T3451@sunsite.ms.mff.cuni.cz> Message-ID: <200210181904.g9IJ45500492@magilla.sf.frob.com> I put the change in modified to return only 32 or 64. From roland@redhat.com Fri Oct 18 13:02:00 2002 From: roland@redhat.com (Roland McGrath) Date: Fri, 18 Oct 2002 13:02:00 -0000 Subject: CLOCK_* clockid_t value macros Message-ID: <200210181953.g9IJrQR18599@magilla.sf.frob.com> Is there any problem with defining the CLOCK_PROCESS_CPUTIME_ID and CLOCK_THREAD_CPUTIME_ID macros even on the systems that don't support them? I would like to consolidate the bits/time.h files and this is the only actual difference among any of the supported configurations. It seems fine to me to define them. They are not specified by POSIX.1-2001 (only CLOCK_REALTIME is), but permitted. The spec just says that clock_* will return EINVAL if given an invalid clockid_t, and so it will for CLOCK_PROCESS_CPUTIME_ID or CLOCK_THREAD_CPUTIME_ID on systems with no HP_TIMING support. I think it's reasonable that programs should need to cope with EINVAL for these when the macros are present even on machines that currently have them. One might very well have a libc where e.g. rdtsc has been disabled for hardware that doesn't support it. Does anyone see a problem with this? From roland@redhat.com Fri Oct 18 13:04:00 2002 From: roland@redhat.com (Roland McGrath) Date: Fri, 18 Oct 2002 13:04:00 -0000 Subject: __builtin_frame_address vs %esp in pt-machine.h In-Reply-To: Ulrich Drepper's message of Saturday, 5 October 2002 15:06:09 -0700 <3D9F6251.30000@redhat.com> Message-ID: <200210182002.g9IK2Jk18646@magilla.sf.frob.com> > The problem is the ptlongjmp.c code. For its use of CURRENT_STACK_FRAME > the value must be as accurate as possible since otherwise the detection > of frames which have to be handled might be wrong. I don't understand this. Its use is to check whether another frame's auto variable address might be below (off the top) of the current stack. Another frame's variable could never be between the cleanup function's %ebp and %esp--that's its own frame. So using %esp is fine there. From drepper@redhat.com Fri Oct 18 13:09:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Fri, 18 Oct 2002 13:09:00 -0000 Subject: CLOCK_* clockid_t value macros In-Reply-To: <200210181953.g9IJrQR18599@magilla.sf.frob.com> References: <200210181953.g9IJrQR18599@magilla.sf.frob.com> Message-ID: <3DB06970.8080604@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Roland McGrath wrote: > Is there any problem with defining the CLOCK_PROCESS_CPUTIME_ID and > CLOCK_THREAD_CPUTIME_ID macros even on the systems that don't support > them? > I would like to consolidate the bits/time.h files and this is the only > actual difference among any of the supported configurations. In theory it shouldn't be a problem since users have to check _POSIX_CPUTIME and _POSIX_THREAD_CPUTIME first. But there is definitely code out there which will break. I don't have personally problems with this. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE9sGlw2ijCOnn/RHQRAgk2AJ0V0+mzZx5GRgaOVhxA00amaR5uAgCfUz7t miCO9JQ1hWNrOJuI5vOxEmw= =pvYV -----END PGP SIGNATURE----- From drepper@redhat.com Fri Oct 18 20:43:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Fri, 18 Oct 2002 20:43:00 -0000 Subject: __builtin_frame_address vs %esp in pt-machine.h In-Reply-To: <200210182002.g9IK2Jk18646@magilla.sf.frob.com> References: <200210182002.g9IK2Jk18646@magilla.sf.frob.com> Message-ID: <3DB06A9E.40208@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Roland McGrath wrote: > I don't understand this. Its use is to check whether another frame's auto > variable address might be below (off the top) of the current stack. I've no time to think about the reason I had to make the change in the moment. But I added this code to fix a bug. It is a necessary change. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE9sGqf2ijCOnn/RHQRAoq1AJwMJjShrww39pgacpFPAW9f7y1x4gCgvwQl bV2oSkGoy/ukqeezpXxE6fo= =TXp9 -----END PGP SIGNATURE----- From roland@redhat.com Fri Oct 18 20:55:00 2002 From: roland@redhat.com (Roland McGrath) Date: Fri, 18 Oct 2002 20:55:00 -0000 Subject: ia64 t_scalar_t definition Message-ID: <200210190343.g9J3hNn02855@magilla.sf.frob.com> t_scalar_t and t_uscalar_t are defined as 32 bits on ia64, while on other platforms they seem to be the word size. Is that really right? These types seem only to be used by some STREAMS structures that nothing in libc itself uses, so I don't know what if anything has ever actually used these types. From roland@frob.com Mon Oct 21 02:27:00 2002 From: roland@frob.com (Roland McGrath) Date: Mon, 21 Oct 2002 02:27:00 -0000 Subject: s390x t_scalar_t definition Message-ID: <200210190355.g9J3tNC02901@magilla.sf.frob.com> The same question I just asked for ia64 goes for s390x as well. From kukuk@suse.de Tue Oct 22 06:51:00 2002 From: kukuk@suse.de (Thorsten Kukuk) Date: Tue, 22 Oct 2002 06:51:00 -0000 Subject: bits/libc-lock.h and _LIBC Message-ID: <20021021112734.A25309@suse.de> Hi, We install libc-lock.h into /usr/include/bits. But libc-lock.h is only useable, if it is compiled with -D_LIBC, which breaks now with libio.h. I suggest the following patch, or is there any reason for the ifdef _LIBC around __libc_lock_t ? We don't do this for __libc_key_t and all the other definitions. 2002-10-17 Thorsten Kukuk * sysdeps/pthread/bits/libc-lock.h: Don't protect __libc_lock_t with _LIBC. diff -u -r1.23 libc-lock.h --- ./linuxthreads/sysdeps/pthread/bits/libc-lock.h +++ ./linuxthreads/sysdeps/pthread/bits/libc-lock.h @@ -24,19 +24,9 @@ #include /* Mutex type. */ -#if defined(_LIBC) || defined(_IO_MTSAFE_IO) typedef pthread_mutex_t __libc_lock_t; typedef struct { pthread_mutex_t mutex; } __libc_lock_recursive_t; -# ifdef __USE_UNIX98 typedef pthread_rwlock_t __libc_rwlock_t; -# else -typedef struct __libc_rwlock_opaque__ __libc_rwlock_t; -# endif -#else -typedef struct __libc_lock_opaque__ __libc_lock_t; -typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; -typedef struct __libc_rwlock_opaque__ __libc_rwlock_t; -#endif /* Type for key to thread-specific data. */ typedef pthread_key_t __libc_key_t; -- Thorsten Kukuk http://www.suse.de/~kukuk/ kukuk@suse.de SuSE Linux AG Deutschherrnstr. 15-19 D-90429 Nuernberg -------------------------------------------------------------------- Key fingerprint = A368 676B 5E1B 3E46 CFCE 2D97 F8FD 4E23 56C6 FB4B From jakub@redhat.com Tue Oct 22 06:56:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 22 Oct 2002 06:56:00 -0000 Subject: [PATCH] Fix linuxthreads libpthread.a Message-ID: <20021022155125.Y3451@sunsite.ms.mff.cuni.cz> Hi! This change was done for pthread.c (__pthread_initialize_minimal) only. 2002-10-22 Jakub Jelinek * manager.c (pthread_start_thread): Call __uselocale even if [! SHARED]. Patch by Leon Kanter . --- libc/linuxthreads/manager.c.jj 2002-10-10 14:01:49.000000000 +0200 +++ libc/linuxthreads/manager.c 2002-10-22 15:57:13.000000000 +0200 @@ -283,7 +283,7 @@ pthread_start_thread(void *arg) __sched_setscheduler(THREAD_GETMEM(self, p_pid), SCHED_OTHER, &default_params); } -#if !(USE_TLS && HAVE___THREAD) && defined SHARED +#if !(USE_TLS && HAVE___THREAD) /* Initialize thread-locale current locale to point to the global one. With __thread support, the variable's initializer takes care of this. */ __uselocale (LC_GLOBAL_LOCALE); Jakub From jakub@redhat.com Tue Oct 22 07:00:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 22 Oct 2002 07:00:00 -0000 Subject: [PATCH] Fix localedef Message-ID: <20021022153746.X3451@sunsite.ms.mff.cuni.cz> Hi! localedef can create bogus archive if enlarge_archive happens in add_alias and not in add_locale. The problem is that add_locale_to_archive keeps the old locrec_offset accross archive enlargement. Another problem is that add_alias needs to be given exactly the same name as has been passed to add_locale initially, while it passed name unconditionally in the first case and already free'd memory in the second case. 2002-10-22 Jakub Jelinek * locale/programs/locarchive.c (add_alias): Change locrec_offset arg into pointer to locrec_offset. (add_locale_to_archive): Adjust callers. Free normalized_name right before returning, not immediately after add_locale, pass it to add_alias if not NULL instead of name. Rename second normalized_name occurence to nnormalized_codeset_name. --- libc/locale/programs/locarchive.c.jj 2002-10-22 15:34:50.000000000 +0200 +++ libc/locale/programs/locarchive.c 2002-10-22 15:34:37.000000000 +0200 @@ -583,8 +583,9 @@ insert_name (struct locarhandle *ah, static void add_alias (struct locarhandle *ah, const char *alias, bool replace, - const char *oldname, uint32_t locrec_offset) + const char *oldname, uint32_t *locrec_offset_p) { + uint32_t locrec_offset = *locrec_offset_p; struct locarhead *head = ah->addr; const size_t name_len = strlen (alias); struct namehashent *namehashent = insert_name (ah, alias, strlen (alias), @@ -607,10 +608,10 @@ add_alias (struct locarhandle *ah, const namehashent = insert_name (ah, oldname, strlen (oldname), true); assert (namehashent->name_offset != 0); assert (namehashent->locrec_offset != 0); - locrec_offset = namehashent->locrec_offset; + *locrec_offset_p = namehashent->locrec_offset; /* Tail call to try the whole thing again. */ - add_alias (ah, alias, replace, oldname, locrec_offset); + add_alias (ah, alias, replace, oldname, locrec_offset_p); return; } @@ -932,9 +933,9 @@ add_locale_to_archive (ah, name, data, r /* This call does the main work. */ locrec_offset = add_locale (ah, normalized_name ?: name, data, replace); - free (normalized_name); if (locrec_offset == 0) { + free (normalized_name); if (mask & XPG_NORM_CODESET) free ((char *) normalized_codeset); return -1; @@ -953,17 +954,19 @@ add_locale_to_archive (ah, name, data, r } *filedata = data[LC_CTYPE].addr; codeset = (char *) filedata + filedata->strindex[_NL_ITEM_INDEX (_NL_CTYPE_CODESET_NAME)]; + char *normalized_codeset_name = NULL; normalized_codeset = _nl_normalize_codeset (codeset, strlen (codeset)); mask |= XPG_NORM_CODESET; - asprintf (&normalized_name, "%s%s%s.%s%s%s", + asprintf (&normalized_codeset_name, "%s%s%s.%s%s%s", language, territory == NULL ? "" : "_", territory ?: "", normalized_codeset, modifier == NULL ? "" : "@", modifier ?: ""); - add_alias (ah, normalized_name, replace, name, locrec_offset); - free (normalized_name); + add_alias (ah, normalized_codeset_name, replace, + normalized_name ?: name, &locrec_offset); + free (normalized_codeset_name); } /* Now read the locale.alias files looking for lines whose @@ -1061,7 +1064,7 @@ add_locale_to_archive (ah, name, data, r && !strcmp (modifier ?: "", rhs_modifier ?: "")) /* We have a winner. */ add_alias (ah, alias, replace, - normalized_name ?: name, locrec_offset); + normalized_name ?: name, &locrec_offset); if (rhs_mask & XPG_NORM_CODESET) free ((char *) rhs_normalized_codeset); } @@ -1083,6 +1086,8 @@ add_locale_to_archive (ah, name, data, r fclose (fp); } + free (normalized_name); + if (mask & XPG_NORM_CODESET) free ((char *) normalized_codeset); Jakub From schwab@suse.de Tue Oct 22 07:00:00 2002 From: schwab@suse.de (Andreas Schwab) Date: Tue, 22 Oct 2002 07:00:00 -0000 Subject: Bad alignment in locale-archive Message-ID: This fixes invalid alignments in the locale-archive file. Andreas. 2002-10-21 Andreas Schwab * locale/programs/locarchive.c (create_archive): Properly align offsets. (enlarge_archive): Likewise. --- locale/programs/locarchive.c.~1.16.~ 2002-10-18 11:14:16.000000000 +0200 +++ locale/programs/locarchive.c 2002-10-21 13:28:27.000000000 +0200 @@ -72,6 +72,9 @@ static const char *locnames[] = #define INITIAL_NUM_SUMS 2000 +#define ALIGN(offset, alignment) \ + (((offset) + (alignment) - 1) & -(alignment)) + static void create_archive (const char *archivefname, struct locarhandle *ah) { @@ -90,7 +93,8 @@ create_archive (const char *archivefname /* Create the initial content of the archive. */ head.magic = AR_MAGIC; - head.namehash_offset = sizeof (struct locarhead); + head.namehash_offset = ALIGN (sizeof (struct locarhead), + __alignof__ (struct namehashent)); head.namehash_used = 0; head.namehash_size = next_prime (INITIAL_NUM_NAMES); @@ -99,12 +103,15 @@ create_archive (const char *archivefname head.string_used = 0; head.string_size = INITIAL_SIZE_STRINGS; - head.locrectab_offset = head.string_offset + head.string_size; + head.locrectab_offset = ALIGN (head.string_offset + head.string_size, + __alignof__ (struct locrecent)); head.locrectab_used = 0; head.locrectab_size = INITIAL_NUM_LOCREC; - head.sumhash_offset = (head.locrectab_offset - + head.locrectab_size * sizeof (struct locrecent)); + head.sumhash_offset = ALIGN (head.locrectab_offset + + (head.locrectab_size + * sizeof (struct locrecent)), + __alignof__ (struct sumhashent)); head.sumhash_used = 0; head.sumhash_size = next_prime (INITIAL_NUM_SUMS); @@ -274,13 +281,16 @@ enlarge_archive (struct locarhandle *ah, * sizeof (struct namehashent))); newhead.string_size = MAX (2 * newhead.string_used, newhead.string_size); - newhead.locrectab_offset = newhead.string_offset + newhead.string_size; + newhead.locrectab_offset = ALIGN (newhead.string_offset + + newhead.string_size, + __alignof__ (struct locrecent)); newhead.locrectab_size = MAX (2 * newhead.locrectab_used, newhead.locrectab_size); - newhead.sumhash_offset = (newhead.locrectab_offset - + (newhead.locrectab_size - * sizeof (struct locrecent))); + newhead.sumhash_offset = ALIGN (newhead.locrectab_offset + + (newhead.locrectab_size + * sizeof (struct locrecent)), + __alignof__ (struct sumhashent)); newhead.sumhash_size = MAX (next_prime (2 * newhead.sumhash_used), newhead.sumhash_size); -- Andreas Schwab, SuSE Labs, schwab@suse.de SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 N??rnberg Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." From schwab@suse.de Tue Oct 22 07:25:00 2002 From: schwab@suse.de (Andreas Schwab) Date: Tue, 22 Oct 2002 07:25:00 -0000 Subject: __syscall_execve on ia64 Message-ID: Nobody came up with a better solution. Andreas. 2002-10-21 Andreas Schwab * sysdeps/unix/sysv/linux/ia64/syscalls.list (s_execve): Set caller to EXTRA instead of execve, since the latter has a higher-priority implementation in linuxthreads. --- sysdeps/unix/sysv/linux/ia64/syscalls.list.~1.22.~ 2002-10-14 11:07:07.000000000 +0200 +++ sysdeps/unix/sysv/linux/ia64/syscalls.list 2002-10-14 16:13:45.000000000 +0200 @@ -65,7 +65,7 @@ rt_sigsuspend EXTRA rt_sigsuspend i:pi _ rt_sigtimedwait EXTRA rt_sigtimedwait i:pppi __syscall_rt_sigtimedwait rt_sigtimedwait # System calls with wrappers. -s_execve execve execve i:spp __syscall_execve +s_execve EXTRA execve i:spp __syscall_execve s_exit exit exit i:i __syscall_exit s_getcwd getcwd getcwd i:pi __syscall_getcwd getcwd s_getdents getdents getdents i:ipi __syscall_getdents getdents -- Andreas Schwab, SuSE Labs, schwab@suse.de SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 N??rnberg Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." From jakub@redhat.com Tue Oct 22 07:29:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 22 Oct 2002 07:29:00 -0000 Subject: Bad alignment in locale-archive In-Reply-To: ; from schwab@suse.de on Mon, Oct 21, 2002 at 04:21:39PM +0200 References: Message-ID: <20021022162529.Z3451@sunsite.ms.mff.cuni.cz> On Mon, Oct 21, 2002 at 04:21:39PM +0200, Andreas Schwab wrote: > This fixes invalid alignments in the locale-archive file. I don't think we should use __alignof__, what if it is different among arches with the same endianity. locale-archive format should be only endianess dependent, not anything else. Furthermore, all but one alignment is unnecessary, and in that one case (enlarge_archive's newhead.locrectab_offset = newhead.string_offset + newhead.string_size; ) it is IMHO better to make sure string_size is always multiple of 4, like: 2002-10-22 Jakub Jelinek * locale/programs/locarchive.c (enlarge_archive): Make sure string_size is always multiple of 4. Reported by Andreas Schwab . --- libc/locale/programs/locarchive.c.jj 2002-10-22 15:34:37.000000000 +0200 +++ libc/locale/programs/locarchive.c 2002-10-22 16:32:38.000000000 +0200 @@ -272,7 +272,8 @@ enlarge_archive (struct locarhandle *ah, newhead.string_offset = (newhead.namehash_offset + (newhead.namehash_size * sizeof (struct namehashent))); - newhead.string_size = MAX (2 * newhead.string_used, newhead.string_size); + newhead.string_size = MAX ((2 * newhead.string_used + 3) & -4, + newhead.string_size); newhead.locrectab_offset = newhead.string_offset + newhead.string_size; newhead.locrectab_size = MAX (2 * newhead.locrectab_used, Jakub From jakub@redhat.com Tue Oct 22 09:04:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 22 Oct 2002 09:04:00 -0000 Subject: __syscall_execve on ia64 In-Reply-To: ; from schwab@suse.de on Mon, Oct 21, 2002 at 04:28:57PM +0200 References: Message-ID: <20021022162945.A3451@sunsite.ms.mff.cuni.cz> On Mon, Oct 21, 2002 at 04:28:57PM +0200, Andreas Schwab wrote: > Nobody came up with a better solution. Well, I wrote ia64 INLINE_SYSCALL, just need to improve it a little bit (ATM it generated warnings whenever first syscall argument was a pointer) and submit. But the extra for now doesn't hurt (and once INLINE_SYSCALL is in, all the __syscall_* from ia64/syscalls.list can go away). > 2002-10-21 Andreas Schwab > > * sysdeps/unix/sysv/linux/ia64/syscalls.list (s_execve): Set > caller to EXTRA instead of execve, since the latter has a > higher-priority implementation in linuxthreads. Jakub From roland@redhat.com Tue Oct 22 09:08:00 2002 From: roland@redhat.com (Roland McGrath) Date: Tue, 22 Oct 2002 09:08:00 -0000 Subject: Bad alignment in locale-archive In-Reply-To: Jakub Jelinek's message of Tuesday, 22 October 2002 16:25:29 +0200 <20021022162529.Z3451@sunsite.ms.mff.cuni.cz> Message-ID: <200210221604.g9MG4rJ14344@magilla.sf.frob.com> I put your version of the fix in, with a comment. (Please add comments in the code for changes such as this. If it was nonobvious enough to have missed when writing it the first time, it's nonbovious enough to warrant an explanatory comment when reading the code.) I agree that the alignment should always be 4. No extant architecture that I know of needs more for these types (all structs containing uint32_t members). OTOH, if __alignof__ ever reports more for some architecture and we use 4, then we have a problem. From what we know now the files should be portable modulo byte order, but no current configuration/installation plan actually assumes they are (except maybe between 32/64 modes of bi-arch platforms). From roland@redhat.com Tue Oct 22 18:42:00 2002 From: roland@redhat.com (Roland McGrath) Date: Tue, 22 Oct 2002 18:42:00 -0000 Subject: [PATCH] Fix linuxthreads libpthread.a In-Reply-To: Jakub Jelinek's message of Tuesday, 22 October 2002 15:51:25 +0200 <20021022155125.Y3451@sunsite.ms.mff.cuni.cz> Message-ID: <200210221608.g9MG8jc14407@magilla.sf.frob.com> Oops! I forgot that one when I made it work. Thanks. From davidm@napali.hpl.hp.com Tue Oct 22 18:46:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Tue, 22 Oct 2002 18:46:00 -0000 Subject: patch to make init_array work Message-ID: <200210230142.g9N1g72n025408@napali.hpl.hp.com> The init_array support in glibc appears to be incomplete at the moment. HJ had a patch that made it all work (see http://sources.redhat.com/ml/libc-alpha/2002-03/msg00047.html) and I adapted his work for the current CVS tree. With the patch below applied, the included test cases work properly. Please apply this patch. Thanks, --david 2002-03-12 H.J. Lu * csu/init.c (__libc_preinit_array): New. Define if HAVE_INITFINI_ARRAY is defined. (__libc_init_array): Likewise. (__libc_fini_array): Likewise. * elf/Makefile (tests): Add tst-array1, tst-array2 and tst-array3 if $(have-initfini-array) is yes. (tests-static): Add tst-array3 if $(have-initfini-array) is yes. (modules-names): Add tst-array2dep if $(have-initfini-array) is yes. ($(objpfx)tst-array1.out): New target. ($(objpfx)tst-array2): Likewise. ($(objpfx)tst-array2.out): Likewise. ($(objpfx)tst-array3.out): Likewise. * elf/tst-array1.c: New file. * elf/tst-array1.exp: Likewise. * elf/tst-array2.c: Likewise. * elf/tst-array2dep.c: Likewise. * elf/tst-array2.exp: Likewise. * elf/tst-array3.c: Likewise. * sysdeps/generic/libc-start.c (__libc_start_main): Process __libc_preinit_array, __libc_init_array and __libc_fini_array if HAVE_INITFINI_ARRAY is defined. Index: csu/init.c =================================================================== RCS file: /cvs/glibc/libc/csu/init.c,v retrieving revision 1.4 diff -u -r1.4 init.c --- csu/csu/init.c 6 Jul 2001 04:54:45 -0000 1.4 +++ csu/csu/init.c 23 Oct 2002 01:34:29 -0000 @@ -25,3 +25,43 @@ const int _IO_stdin_used = _G_IO_IO_FILE_VERSION; #endif + +#ifdef HAVE_INITFINI_ARRAY +extern void (*__preinit_array_start []) (void); +extern void (*__preinit_array_end []) (void); + +void +__libc_preinit_array (void) +{ + unsigned int size, i; + + size = __preinit_array_end - __preinit_array_start; + for (i = 0; i < size; i++) + __preinit_array_start [i] (); +} + +extern void (*__init_array_start []) (void); +extern void (*__init_array_end []) (void); + +void +__libc_init_array (void) +{ + unsigned int size, i; + + size = __init_array_end - __init_array_start; + for (i = 0; i < size; i++) + __init_array_start [i] (); +} + +extern void (*__fini_array_start []) (void); +extern void (*__fini_array_end []) (void); + +void +__libc_fini_array (void) +{ + int i; + + for (i = __fini_array_end - __fini_array_start - 1; i >= 0; i--) + __fini_array_start [i] (); +} +#endif Index: elf/Makefile =================================================================== RCS file: /cvs/glibc/libc/elf/Makefile,v retrieving revision 1.241 diff -u -r1.241 Makefile --- elf/elf/Makefile 22 Oct 2002 06:22:38 -0000 1.241 +++ elf/elf/Makefile 23 Oct 2002 01:34:29 -0000 @@ -117,6 +117,9 @@ endif tests = tst-tls1 tst-tls2 tst-tls9 +ifeq (yes,$(have-initfini-array)) +tests += tst-array1 tst-array2 tst-array3 +endif ifeq (yes,$(build-static)) tests-static = tst-tls1-static tst-tls2-static ifeq (yesyesyes,$(build-static)$(build-shared)$(elf)) @@ -156,6 +159,9 @@ tst-tlsmod5 tst-tlsmod6 \ circlemod1 circlemod1a circlemod2 circlemod2a \ circlemod3 circlemod3a +ifeq (yes,$(have-initfini-array)) +modules-names += tst-array2dep +endif modules-vis-yes = vismod1 vismod2 vismod3 modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4 modules-nodlopen-yes = nodlopenmod nodlopenmod2 @@ -541,3 +547,22 @@ $(objpfx)tst-tls9-static: $(common-objpfx)dlfcn/libdl.a $(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so endif + +$(objpfx)tst-array1.out: $(objpfx)tst-array1 + $(elf-objpfx)$(rtld-installed-name) \ + --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \ + $(objpfx)tst-array1 > $@ + cmp $@ tst-array1.exp > /dev/null + +$(objpfx)tst-array2: $(objpfx)tst-array2dep.so +$(objpfx)tst-array2.out: $(objpfx)tst-array2 + $(elf-objpfx)$(rtld-installed-name) \ + --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \ + $(objpfx)tst-array2 > $@ + cmp $@ tst-array2.exp > /dev/null + +$(objpfx)tst-array3.out: $(objpfx)tst-array3 + $(elf-objpfx)$(rtld-installed-name) \ + --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \ + $(objpfx)tst-array3 > $@ + cmp $@ tst-array1.exp > /dev/null Index: elf/tst-array1.c =================================================================== RCS file: elf/tst-array1.c diff -N elf/tst-array1.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ elf/elf/tst-array1.c 23 Oct 2002 01:34:29 -0000 @@ -0,0 +1,101 @@ +#include + +static void init (void) __attribute__ ((constructor)); + +static void +init (void) +{ + write (STDOUT_FILENO, "init\n", 5); +} + +static void fini (void) __attribute__ ((destructor)); + +static void +fini (void) +{ + write (STDOUT_FILENO, "fini\n", 5); +} + +static void +preinit_0 (void) +{ + write (STDOUT_FILENO, "preinit array 0\n", 16); +} + +static void +preinit_1 (void) +{ + write (STDOUT_FILENO, "preinit array 1\n", 16); +} + +static void +preinit_2 (void) +{ + write (STDOUT_FILENO, "preinit array 2\n", 16); +} + +void +(*preinit_array []) (void) __attribute__ ((section (".preinit_array"))) = +{ + &preinit_0, + &preinit_1, + &preinit_2 +}; + +static void +init_0 (void) +{ + write (STDOUT_FILENO, "init array 0\n", 13); +} + +static void +init_1 (void) +{ + write (STDOUT_FILENO, "init array 1\n", 13); +} + +static void +init_2 (void) +{ + write (STDOUT_FILENO, "init array 2\n", 13); +} + +void +(*init_array []) (void) __attribute__ ((section (".init_array"))) = +{ + &init_0, + &init_1, + &init_2 +}; + +static void +fini_0 (void) +{ + write (STDOUT_FILENO, "fini array 0\n", 13); +} + +static void +fini_1 (void) +{ + write (STDOUT_FILENO, "fini array 1\n", 13); +} + +static void +fini_2 (void) +{ + write (STDOUT_FILENO, "fini array 2\n", 13); +} + +void +(*fini_array []) (void) __attribute__ ((section (".fini_array"))) = +{ + &fini_0, + &fini_1, + &fini_2 +}; + +int +main (void) +{ + return 0; +} Index: elf/tst-array1.exp =================================================================== RCS file: elf/tst-array1.exp diff -N elf/tst-array1.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ elf/elf/tst-array1.exp 23 Oct 2002 01:34:29 -0000 @@ -0,0 +1,11 @@ +preinit array 0 +preinit array 1 +preinit array 2 +init +init array 0 +init array 1 +init array 2 +fini array 2 +fini array 1 +fini array 0 +fini Index: elf/tst-array2.c =================================================================== RCS file: elf/tst-array2.c diff -N elf/tst-array2.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ elf/elf/tst-array2.c 23 Oct 2002 01:34:29 -0000 @@ -0,0 +1 @@ +#include "tst-array1.c" Index: elf/tst-array2.exp =================================================================== RCS file: elf/tst-array2.exp diff -N elf/tst-array2.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ elf/elf/tst-array2.exp 23 Oct 2002 01:34:29 -0000 @@ -0,0 +1,19 @@ +preinit array 0 +preinit array 1 +preinit array 2 +DSO init +DSO init array 0 +DSO init array 1 +DSO init array 2 +init +init array 0 +init array 1 +init array 2 +fini array 2 +fini array 1 +fini array 0 +fini +DSO fini array 2 +DSO fini array 1 +DSO fini array 0 +DSO fini Index: elf/tst-array2dep.c =================================================================== RCS file: elf/tst-array2dep.c diff -N elf/tst-array2dep.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ elf/elf/tst-array2dep.c 23 Oct 2002 01:34:29 -0000 @@ -0,0 +1,69 @@ +#include + +static void init (void) __attribute__ ((constructor)); + +static void +init (void) +{ + write (STDOUT_FILENO, "DSO init\n", 9); +} + +static void fini (void) __attribute__ ((destructor)); + +static void +fini (void) +{ + write (STDOUT_FILENO, "DSO fini\n", 9); +} + +static void +init_0 (void) +{ + write (STDOUT_FILENO, "DSO init array 0\n", 17); +} + +static void +init_1 (void) +{ + write (STDOUT_FILENO, "DSO init array 1\n", 17); +} + +static void +init_2 (void) +{ + write (STDOUT_FILENO, "DSO init array 2\n", 17); +} + +void +(*init_array []) (void) __attribute__ ((section (".init_array"))) = +{ + &init_0, + &init_1, + &init_2 +}; + +static void +fini_0 (void) +{ + write (STDOUT_FILENO, "DSO fini array 0\n", 17); +} + +static void +fini_1 (void) +{ + write (STDOUT_FILENO, "DSO fini array 1\n", 17); +} + +static void +fini_2 (void) +{ + write (STDOUT_FILENO, "DSO fini array 2\n", 17); +} + +void +(*fini_array []) (void) __attribute__ ((section (".fini_array"))) = +{ + &fini_0, + &fini_1, + &fini_2 +}; Index: elf/tst-array3.c =================================================================== RCS file: elf/tst-array3.c diff -N elf/tst-array3.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ elf/elf/tst-array3.c 23 Oct 2002 01:34:29 -0000 @@ -0,0 +1 @@ +#include "tst-array1.c" Index: sysdeps/generic/libc-start.c =================================================================== RCS file: /cvs/glibc/libc/sysdeps/generic/libc-start.c,v retrieving revision 1.31 diff -u -r1.31 libc-start.c --- sysdeps/generic/sysdeps/generic/libc-start.c 15 Sep 2002 05:44:24 -0000 1.31 +++ sysdeps/generic/sysdeps/generic/libc-start.c 23 Oct 2002 01:34:30 -0000 @@ -38,6 +38,16 @@ ; #endif +#ifdef HAVE_INITFINI_ARRAY +# ifdef SHARED +extern void __libc_init_array (void) __attribute__ ((weak)); +extern void __libc_fini_array (void) __attribute__ ((weak)); +# else +extern void __libc_preinit_array (void); +extern void __libc_init_array (void); +extern void __libc_fini_array (void); +# endif +#endif extern int BP_SYM (__libc_start_main) (int (*main) (int, char **, char **), int argc, @@ -122,6 +132,17 @@ if (fini) __cxa_atexit ((void (*) (void *)) fini, NULL, NULL); +#ifdef HAVE_INITFINI_ARRAY +# ifdef SHARED + if (__libc_fini_array) +# endif + __cxa_atexit ((void (*) (void *)) __libc_fini_array, NULL, NULL); + +# ifndef SHARED + __libc_preinit_array (); +# endif +#endif + /* Call the initializer of the program, if any. */ #ifdef SHARED if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) @@ -129,6 +150,13 @@ #endif if (init) (*init) (); + +#ifdef HAVE_INITFINI_ARRAY +# ifdef SHARED + if (__libc_init_array) +# endif + __libc_init_array (); +#endif #ifdef SHARED if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) From davidm@napali.hpl.hp.com Tue Oct 22 19:39:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Tue, 22 Oct 2002 19:39:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: References: <15772.47660.333934.293189@napali.hpl.hp.com> <200210032146.g93LkB119076@magilla.sf.frob.com> <15772.48947.101500.167377@napali.hpl.hp.com> <3D9CC520.8010403@redhat.com> <15773.11197.780790.750761@napali.hpl.hp.com> Message-ID: <15797.65387.878109.733469@napali.hpl.hp.com> >>>>> On Fri, 04 Oct 2002 09:11:09 +0200, Andreas Jaeger said: >> + gethugepagesize; + alloc_hugepages; + free_hugepages; + Andreas> With glibc 2.3 out of the door, this has to be added with Andreas> version glibc 2.3.1. OK, I made this change. Andreas> The header installed in the user level include should not Andreas> have the __gethugepagesize. If you need the prototype, we Andreas> add it to an internal header. Ditto. If it looks OK, please apply the attached patch. Thanks, --david 2002-10-03 David Mosberger * sysdeps/unix/sysv/linux/getsysstats.c (get_meminfo): New function. (phys_pages_info): Implementing on the basis of get_meminfo(). (__gethugepagesize): New function. * sysdeps/unix/sysv/linux/Versions: Mention gethugepagesize(). 2002-10-02 David Mosberger * sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Mention sys/hugepage.h. * sysdeps/unix/sysv/linux/syscalls.list: Make alloc_hugepages and free_hugepages weak symbols. * sysdeps/unix/sysv/linux/Versions: Mention alloc_hugepages and free_hugepages. 2002-10-01 Rohit Seth , David Mosberger * sysdeps/unix/sysv/linux/syscalls.list: Add alloc_hugepages and free_hugepages. * sysdeps/unix/sysv/linux/sys/hugepage.h: New file. Index: sysdeps/unix/sysv/linux/Makefile =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/Makefile,v retrieving revision 1.123 diff -u -r1.123 Makefile --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Makefile 16 Oct 2002 03:02:50 -0000 1.123 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Makefile 23 Oct 2002 01:42:58 -0000 @@ -20,7 +20,7 @@ sys/kd.h sys/soundcard.h sys/vt.h \ sys/quota.h sys/fsuid.h \ scsi/sg.h scsi/scsi.h scsi/scsi_ioctl.h sys/pci.h \ - sys/ultrasound.h sys/raw.h sys/personality.h + sys/ultrasound.h sys/raw.h sys/personality.h sys/hugepage.h install-others += $(inst_includedir)/bits/syscall.h Index: sysdeps/unix/sysv/linux/Versions =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/Versions,v retrieving revision 1.18 diff -u -r1.18 Versions --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Versions 30 Aug 2002 01:30:55 -0000 1.18 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/Versions 23 Oct 2002 01:42:58 -0000 @@ -105,6 +105,11 @@ #errlist-compat 126 _sys_errlist; sys_errlist; _sys_nerr; sys_nerr; } + GLIBC_2.3.1 { + gethugepagesize; + alloc_hugepages; + free_hugepages; + } GLIBC_PRIVATE { # needed by libpthread. __libc_sigaction; Index: sysdeps/unix/sysv/linux/getsysstats.c =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/getsysstats.c,v retrieving revision 1.22 diff -u -r1.22 getsysstats.c --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/getsysstats.c 21 Sep 2002 05:26:12 -0000 1.22 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/getsysstats.c 23 Oct 2002 01:42:58 -0000 @@ -230,11 +230,8 @@ #endif weak_alias (__get_nprocs_conf, get_nprocs_conf) -/* General function to get information about memory status from proc - filesystem. */ static long int -internal_function -phys_pages_info (const char *format) +get_meminfo (const char *format) { FILE *fp; char buffer[8192]; @@ -263,10 +260,7 @@ bytes are really enough. */ while (fgets_unlocked (buffer, sizeof buffer, fp) != NULL) if (sscanf (buffer, format, &result) == 1) - { - result /= (__getpagesize () / 1024); - break; - } + break; fclose (fp); } @@ -279,6 +273,20 @@ return result; } +/* General function to get information about memory status from proc + filesystem. */ +static long int +internal_function +phys_pages_info (const char *format) +{ + long int result = get_meminfo (format); + + if (result != -1) + result /= __getpagesize () / 1024; + + return result; +} + /* Return the number of pages of physical memory in the system. There is currently (as of version 2.0.21) no system call to determine the @@ -320,6 +328,17 @@ } weak_alias (__get_avphys_pages, get_avphys_pages) +size_t +__gethugepagesize () +{ + long int result = get_meminfo ("Hugepagesize: %lu kB"); + + if (result != -1) + result *= 1024; + + return result; +} +weak_alias (__gethugepagesize, gethugepagesize); static void free_mem (void) Index: sysdeps/unix/sysv/linux/syscalls.list =================================================================== RCS file: /cvs/glibc/libc/sysdeps/unix/sysv/linux/syscalls.list,v retrieving revision 1.96 diff -u -r1.96 syscalls.list --- sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/syscalls.list 14 Oct 2002 01:03:01 -0000 1.96 +++ sysdeps/unix/sysv/linux/sysdeps/unix/sysv/linux/syscalls.list 23 Oct 2002 01:42:59 -0000 @@ -82,3 +82,6 @@ removexattr EXTRA removexattr i:ss removexattr lremovexattr EXTRA lremovexattr i:ss lremovexattr fremovexattr EXTRA fremovexattr i:is fremovexattr + +alloc_hugepages EXTRA alloc_hugepages b:ianii __alloc_hugepages alloc_hugepages +free_hugepages EXTRA free_hugepages i:a __free_hugepages free_hugepages Index: sysdeps/unix/sysv/linux/sys/hugepage.h =================================================================== RCS file: sysdeps/unix/sysv/linux/sys/hugepage.h diff -N sysdeps/unix/sysv/linux/sys/hugepage.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sysdeps/unix/sysv/linux/sys/sysdeps/unix/sysv/linux/sys/hugepage.h 23 Oct 2002 01:43:01 -0000 @@ -0,0 +1,77 @@ +/* Copyright (C) 2002 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 _SYS_HUGEPAGE_H +#define _SYS_HUGEPAGE_H 1 + +/* This header file defines the huge page interface. A huge page is a + non-swappable (pinned) page of virtual memory. As the name + suggests, the size of a huge page is typically orders of magnitudes + bigger than the value returned by getpagesize(). For example, + depending on kernel configuration, on x86 it may be 2MBytes or + 4MBytes and on ia64 it is typically one of 16MB, 256MBytes, or + 4GBytes. Note that because huge pages are never swapped, they are + a relatively rare commodity and applications are expected to fall + back to allocating regular pages if a huge page cannot be + allocated. */ + +#include + +#define __need_size_t +#include + +__BEGIN_DECLS + +/* Return the size of a huge page. */ + +extern size_t gethugepagesize (void) __attribute__ ((__const__)) __THROW; + +/* Allocate LEN bytes worth of huge pages. LEN must be an integer + multiple of the huge page size. ADDR is the preferred starting + address for the memory. PROT is a mask of protection bits that + specify how the memory is to be mapped (PROT_NONE or any + combination of PROT_READ, PROT_WRITE, or PROT_EXEC). If KEY has is + a positive number, FLAG can be set to IPC_CREAT to request the + creation of a new shared memory segment or to zero to request + attaching to an existing shared memory segment. + + Return value: On success, alloc_hugepages() returns a pointer to + the allocated memory. On error, MAP_FAILED ((void *) -1) is + returned and ERRNO is set appropriately. + + Errors: + EINVAL LEN is not a integer multiple of gethugepagesize() + or KEY is a negative value. + + ENOENT No shared segment matching KEY was found and FLAGS + was zero. */ + +extern void *alloc_hugepages (int __key, void *__addr, size_t __len, + int __prot, int __flag) __THROW; + +/* Free the huge page resources from the current process's address + space. ADDR must be an address returned by a previous call to + alloc_hugepages (). Note that for shared memory segments, the + underlying physical memory will be freed only after the last + process using them has freed them up or has exited. */ + +extern int free_hugepages (void *__addr) __THROW; + +__END_DECLS + +#endif /* sys/hugepage.h */ From drepper@redhat.com Tue Oct 22 23:52:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Tue, 22 Oct 2002 23:52:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <15772.47660.333934.293189@napali.hpl.hp.com> References: <15772.47660.333934.293189@napali.hpl.hp.com> <200210032146.g93LkB119076@magilla.sf.frob.com> <15772.48947.101500.167377@napali.hpl.hp.com> <3D9CC520.8010403@redhat.com> <15773.11197.780790.750761@napali.hpl.hp.com> <15797.65387.878109.733469@napali.hpl.hp.com> Message-ID: <3DB60C2E.6050203@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 David Mosberger wrote: > If it looks OK, please apply the attached patch. Actually, I won't apply the patch. There is talk again about removing these syscalls and I surely hope it'll happen. If such mapping should happen use mmap. Until Linus makes a final decision nothing happens. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE9tgwu2ijCOnn/RHQRAhYSAKCjBPt58UJ2KCJdWjSkuZ/IbPfS3QCePlC7 p0FCE7ieK6neCU+YxqHyNP8= =DchU -----END PGP SIGNATURE----- From davidm@napali.hpl.hp.com Tue Oct 22 23:58:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Tue, 22 Oct 2002 23:58:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <3DB60C2E.6050203@redhat.com> References: <15772.47660.333934.293189@napali.hpl.hp.com> <200210032146.g93LkB119076@magilla.sf.frob.com> <15772.48947.101500.167377@napali.hpl.hp.com> <3D9CC520.8010403@redhat.com> <15773.11197.780790.750761@napali.hpl.hp.com> <15797.65387.878109.733469@napali.hpl.hp.com> <3DB60C2E.6050203@redhat.com> Message-ID: <15798.18207.411393.399100@napali.hpl.hp.com> >>>>> On Tue, 22 Oct 2002 19:40:46 -0700, Ulrich Drepper said: Uli> Actually, I won't apply the patch. There is talk again about Uli> removing these syscalls and I surely hope it'll happen. If Uli> such mapping should happen use mmap. Until Linus makes a final Uli> decision nothing happens. Linus *has* made a final decision. Those syscalls were added upon his explicit request. Go back and check the mail archives. Please apply the patch. --david From drepper@redhat.com Wed Oct 23 08:20:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Wed, 23 Oct 2002 08:20:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <15772.47660.333934.293189@napali.hpl.hp.com> References: <15772.47660.333934.293189@napali.hpl.hp.com> <200210032146.g93LkB119076@magilla.sf.frob.com> <15772.48947.101500.167377@napali.hpl.hp.com> <3D9CC520.8010403@redhat.com> <15773.11197.780790.750761@napali.hpl.hp.com> <15797.65387.878109.733469@napali.hpl.hp.com> <3DB60C2E.6050203@redhat.com> <15798.18207.411393.399100@napali.hpl.hp.com> Message-ID: <3DB648DE.9080009@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 David Mosberger wrote: > Linus *has* made a final decision. Those syscalls were added upon his > explicit request. Go back and check the mail archives. Read the current discussions. Wrong decisions can easily be undone. > Please apply the patch. No. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE9tkje2ijCOnn/RHQRAqJbAKCQqdIVo4NwT+B7cFthat6q+5QyBACeIwaB xIV7SeBJhbFi26LAQKy1JrY= =EeNN -----END PGP SIGNATURE----- From davidm@napali.hpl.hp.com Wed Oct 23 10:34:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Wed, 23 Oct 2002 10:34:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <3DB648DE.9080009@redhat.com> References: <15772.47660.333934.293189@napali.hpl.hp.com> <200210032146.g93LkB119076@magilla.sf.frob.com> <15772.48947.101500.167377@napali.hpl.hp.com> <3D9CC520.8010403@redhat.com> <15773.11197.780790.750761@napali.hpl.hp.com> <15797.65387.878109.733469@napali.hpl.hp.com> <3DB60C2E.6050203@redhat.com> <15798.18207.411393.399100@napali.hpl.hp.com> <3DB648DE.9080009@redhat.com> Message-ID: <15798.48714.502685.889728@napali.hpl.hp.com> >>>>> On Tue, 22 Oct 2002 23:59:42 -0700, Ulrich Drepper said: Uli> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Uli> David Mosberger wrote: >> Linus *has* made a final decision. Those syscalls were added >> upon his explicit request. Go back and check the mail archives. Uli> Read the current discussions. I did (assuming you're referring to the shared page table discussion; see http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&threadm=E1844h3-0002Bt-00%40w-gerrit2&rnum=4&prev=/groups%3Fq%3Dben%2Blahaise%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26scoring%3Dd%26selm%3DE1844h3-0002Bt-00%2540w-gerrit2%26rnum%3D4). There is nothing new there. Now if you'd read the original discussion, you'd see that Linus considered those objections and still preferred separate system calls. You have to realize that the huge page syscalls are NOT a replacement for transparent superpages. They serve a different purpose and have a different scope (we're talking about pages of the size of 256MB and more, not merely something that's a small multiple of the base page size). Please apply the patch. --david From drepper@redhat.com Wed Oct 23 11:46:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Wed, 23 Oct 2002 11:46:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <15772.47660.333934.293189@napali.hpl.hp.com> References: <15772.47660.333934.293189@napali.hpl.hp.com> <200210032146.g93LkB119076@magilla.sf.frob.com> <15772.48947.101500.167377@napali.hpl.hp.com> <3D9CC520.8010403@redhat.com> <15773.11197.780790.750761@napali.hpl.hp.com> <15797.65387.878109.733469@napali.hpl.hp.com> <3DB60C2E.6050203@redhat.com> <15798.18207.411393.399100@napali.hpl.hp.com> <3DB648DE.9080009@redhat.com> <15798.48714.502685.889728@napali.hpl.hp.com> Message-ID: <3DB6DDDE.3020500@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 David Mosberger wrote: > Please apply the patch. David, stop it. I won't apply anything until the decisions are truly final. When Linus says it explicitly (again) I'll add it. If you, as it seems, have something riding on this (some benchmark?) it is your problem. I'm not giving the proponents of this interface a reason for saying "it cannot be removed because it's already in use". - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE9tt3e2ijCOnn/RHQRAu6mAJ0bJY4myRu6YCSNg51cUEaEwk+qIQCgu2Ak t65rLDV1BIRD6WE7g2i5ajk= =MmAL -----END PGP SIGNATURE----- From davidm@napali.hpl.hp.com Wed Oct 23 14:51:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Wed, 23 Oct 2002 14:51:00 -0000 Subject: [patch] add alloc_pages/free_pages support In-Reply-To: <3DB6DDDE.3020500@redhat.com> References: <15772.47660.333934.293189@napali.hpl.hp.com> <200210032146.g93LkB119076@magilla.sf.frob.com> <15772.48947.101500.167377@napali.hpl.hp.com> <3D9CC520.8010403@redhat.com> <15773.11197.780790.750761@napali.hpl.hp.com> <15797.65387.878109.733469@napali.hpl.hp.com> <3DB60C2E.6050203@redhat.com> <15798.18207.411393.399100@napali.hpl.hp.com> <3DB648DE.9080009@redhat.com> <15798.48714.502685.889728@napali.hpl.hp.com> <3DB6DDDE.3020500@redhat.com> Message-ID: <15798.61055.378779.249196@napali.hpl.hp.com> >>>>> On Wed, 23 Oct 2002 10:35:26 -0700, Ulrich Drepper said: Uli> David, stop it. I won't apply anything until the decisions are Uli> truly final. When Linus says it explicitly (again) I'll add Uli> it. You ought to stop it. The interface has been discussed at great length and Linus decided for the new system calls. If you take a few minutes to read the discussions and think about it, I think you too would see why Linus decided for the current solution. Uli> If you, as it seems, have something riding on this (some Uli> benchmark?) it is your problem. I'm not giving the proponents Uli> of this interface a reason for saying "it cannot be removed Uli> because it's already in use". You're making unfounded accusations. Please remember that Linus is the Linux kernel maintainer... --david From roland@redhat.com Wed Oct 23 16:58:00 2002 From: roland@redhat.com (Roland McGrath) Date: Wed, 23 Oct 2002 16:58:00 -0000 Subject: EOVERFLOW for ftell, ftello, fgetpos? Message-ID: <200210232151.g9NLpCA28795@magilla.sf.frob.com> Aren't ftell, ftello, and fgetpos supposed to diagnose EOVERFLOW? (A program could fopen, fread pieces totalling >4GB, and then call ftell.) Right now these functions all just truncate the result of _IO_seekoff to 32 bits (and treat 4294967295 as an error). Unless someone tells me why I'm wrong about thinking this is a bug, I will fix them to detect overflow. From jakub@redhat.com Wed Oct 23 17:22:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 23 Oct 2002 17:22:00 -0000 Subject: [PATCH] Fix re_comp Message-ID: <20021024015833.G3451@sunsite.ms.mff.cuni.cz> Hi! This patch fixes massive memory leaks in re_comp (and also adds freeres for clean mtrace). 2002-10-24 Jakub Jelinek * posix/regcomp.c (re_comp): Call __regfree on re_comp_buf. (free_mem): New function. * posix/Makefile (tests): Add bug-regex14. Add bug-regex14-mem if not cross compiling. (generated): Add bug-regex14-mem and bug-regex14.mtrace. (bug-regex14-ENV): Set. (bug-regex14-mem): New rule. * posix/bug-regex14.c: New test. --- libc/posix/Makefile.jj 2002-10-24 00:05:06.000000000 +0200 +++ libc/posix/Makefile 2002-10-24 00:29:32.000000000 +0200 @@ -74,7 +74,7 @@ tests := tstgetopt testfnm runtests run tst-chmod bug-regex1 bug-regex2 bug-regex3 bug-regex4 \ tst-gnuglob tst-regex bug-regex5 bug-regex6 bug-regex7 \ bug-regex8 bug-regex9 bug-regex10 bug-regex11 bug-regex12 \ - bug-regex13 + bug-regex13 bug-regex14 ifeq (yes,$(build-shared)) test-srcs := globtest tests += wordexp-test tst-exec tst-spawn @@ -88,7 +88,8 @@ before-compile := testcases.h ptestcases # So they get cleaned up. generated := $(addprefix wordexp-test-result, 1 2 3 4 5 6 7 8 9 10) \ annexc annexc.out wordexp-tst.out bug-regex2-mem \ - bug-regex2.mtrace tst-getconf.out + bug-regex2.mtrace bug-regex14-mem bug-regex14.mtrace \ + tst-getconf.out include ../Rules @@ -148,7 +149,7 @@ endif # XXX Please note that for now we ignore the result of this test. tests: $(objpfx)annexc.out ifeq (no,$(cross-compiling)) -tests:$(objpfx)bug-regex2-mem $(objpfx)tst-getconf.out +tests:$(objpfx)bug-regex2-mem $(objpfx)bug-regex14-mem $(objpfx)tst-getconf.out endif $(objpfx)annexc.out: $(objpfx)annexc @@ -164,6 +165,11 @@ bug-regex2-ENV = MALLOC_TRACE=$(objpfx)b $(objpfx)bug-regex2-mem: $(objpfx)bug-regex2.out $(common-objpfx)malloc/mtrace $(objpfx)bug-regex2.mtrace > $@ +bug-regex14-ENV = MALLOC_TRACE=$(objpfx)bug-regex14.mtrace + +$(objpfx)bug-regex14-mem: $(objpfx)bug-regex14.out + $(common-objpfx)malloc/mtrace $(objpfx)bug-regex14.mtrace > $@ + $(objpfx)tst-getconf.out: tst-getconf.sh $(objpfx)getconf $(SHELL) -e $< $(common-objpfx) $(elf-objpfx) $(rtld-installed-name) --- libc/posix/bug-regex14.c.jj 2002-10-24 00:27:42.000000000 +0200 +++ libc/posix/bug-regex14.c 2002-10-24 00:24:34.000000000 +0200 @@ -0,0 +1,54 @@ +/* Tests re_comp and re_exec. + Copyright (C) 2002 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Isamu Hasegawa , 2002. + + 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 _REGEX_RE_COMP +#include +#include +#include +#include +#include + +int +main (void) +{ + const char *err; + size_t i; + int ret = 0; + + mtrace (); + + for (i = 0; i < 100; ++i) + { + err = re_comp ("a t.st"); + if (err) + { + printf ("re_comp failed: %s\n", err); + ret = 1; + } + + if (! re_exec ("This is a test.")) + { + printf ("re_exec failed\n"); + ret = 1; + } + } + + return ret; +} --- libc/posix/regcomp.c.jj 2002-10-24 00:05:06.000000000 +0200 +++ libc/posix/regcomp.c 2002-10-24 00:50:28.000000000 +0200 @@ -653,6 +653,7 @@ re_comp (s) const char *s; { reg_errcode_t ret; + char *fastmap; if (!s) { @@ -661,7 +662,17 @@ re_comp (s) return 0; } - if (!re_comp_buf.buffer) + if (re_comp_buf.buffer) + { + fastmap = re_comp_buf.fastmap; + re_comp_buf.fastmap = NULL; + __regfree (&re_comp_buf); + re_comp_buf.buffer = NULL; + re_comp_buf.allocated = 0; + re_comp_buf.fastmap = fastmap; + } + + if (re_comp_buf.fastmap == NULL) { re_comp_buf.fastmap = (char *) malloc (SBC_MAX); if (re_comp_buf.fastmap == NULL) @@ -683,6 +694,16 @@ re_comp (s) /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); } + +#ifdef _LIBC +static void __attribute__ ((unused)) +free_mem (void) +{ + __regfree (&re_comp_buf); +} +text_set_element (__libc_subfreeres, free_mem); +#endif + #endif /* _REGEX_RE_COMP */ /* Internal entry point. Jakub From roland@redhat.com Thu Oct 24 10:47:00 2002 From: roland@redhat.com (Roland McGrath) Date: Thu, 24 Oct 2002 10:47:00 -0000 Subject: [PATCH] Fix re_comp In-Reply-To: Jakub Jelinek's message of Thursday, 24 October 2002 01:58:33 +0200 <20021024015833.G3451@sunsite.ms.mff.cuni.cz> Message-ID: <200210240022.g9O0Mcq15669@magilla.sf.frob.com> I put the change in. From jakub@redhat.com Thu Oct 24 12:03:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Thu, 24 Oct 2002 12:03:00 -0000 Subject: [PATCH] Fix LD_DEBUG=statistics Message-ID: <20021024194725.O3451@sunsite.ms.mff.cuni.cz> Hi! ATM LD_DEBUG=statistics (or LD_TRACE_PRELINKING) fails with programs linked againt libpthread.so.0. The problem is that there are calls to _dl_debug_*printf after ld.so is re-relocated (ie. when pthread_mutex_lock changes from NULL to libpthread implementation) and before __pthread_initialize_minimal is called. Below are 2 fixes for that: due to missing sysdep.h include INTERNAL_SYSCALL was not defined even on IA-32 linux in that file, plus if INTERNAL_SYSCALL is not defined, then we should wait until __pthread_initialize_minimal is called. This happens before dl_starting_up is cleared and no threads should be started until then. In addition to this, this patch defines INTERNAL_SYSCALL on a few other arches. 2002-10-24 Jakub Jelinek * elf/dl-misc.c: Include . (_dl_starting_up, _dl_starting_up_internal): New externs. (_dl_debug_vdprintf): Only take dl_load_lock if not _dl_starting_up. * sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h (INTERNAL_SYSCALL, INTERNAL_SYSCALL_ERROR_P, INTERNAL_SYSCALL_ERRNO): New macros. (INLINE_SYSCALL): Use that. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h (INTERNAL_SYSCALL, INTERNAL_SYSCALL_ERROR_P, INTERNAL_SYSCALL_ERRNO): New macros. (INLINE_SYSCALL): Use that. * sysdeps/unix/sysv/linux/x86_64/sysdep.h (INTERNAL_SYSCALL, INTERNAL_SYSCALL_ERROR_P, INTERNAL_SYSCALL_ERRNO): New macros. (INLINE_SYSCALL): Use that. * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h: Include dl-sysdep.h. (SYSCALL_ERROR_HANDLER): Define RTLD_PRIVATE_ERRNO variant. (__INTERNAL_SYSCALL_STRING): Define. * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h: Include dl-sysdep.h. (SYSCALL_ERROR_HANDLER): Define RTLD_PRIVATE_ERRNO variant. (__INTERNAL_SYSCALL_STRING): Define. * sysdeps/unix/sysv/linux/sparc/sysdep.h (INLINE_SYSCALL): Pass __SYSCALL_STRING to inline_syscall*. (INTERNAL_SYSCALL, INTERNAL_SYSCALL_ERROR_P, INTERNAL_SYSCALL_ERRNO): New macros. (inline_syscall0, inline_syscall1, inline_syscall2, inline_syscall3, inline_syscall4, inline_syscall5, inline_syscall6): Add string argument. --- libc/elf/dl-misc.c.jj 2002-10-11 16:24:32.000000000 +0200 +++ libc/elf/dl-misc.c 2002-10-24 15:57:23.000000000 +0200 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -80,6 +81,8 @@ _dl_sysdep_read_whole_file (const char * return result; } +extern int _dl_starting_up; +extern int _dl_starting_up_internal attribute_hidden; /* Bare-bone printf implementation. This function only knows about the formats and flags needed and can handle only up to 64 stripes in @@ -251,9 +254,14 @@ _dl_debug_vdprintf (int fd, int tag_p, c #elif RTLD_PRIVATE_ERRNO /* We have to take this lock just to be sure we don't clobber the private errno when it's being used by another thread that cares about it. */ - __libc_lock_lock_recursive (GL(dl_load_lock)); - __writev (fd, iov, niov); - __libc_lock_unlock_recursive (GL(dl_load_lock)); + if (__builtin_expect (INTUSE (_dl_starting_up), 0)) + __writev (fd, iov, niov); + else + { + __libc_lock_lock_recursive (GL(dl_load_lock)); + __writev (fd, iov, niov); + __libc_lock_unlock_recursive (GL(dl_load_lock)); + } #else __writev (fd, iov, niov); #endif --- libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h.jj 2002-08-27 23:19:55.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/s390/s390-32/sysdep.h 2002-10-24 16:32:25.000000000 +0200 @@ -119,24 +119,36 @@ #endif /* __ASSEMBLER__ */ #undef INLINE_SYSCALL -#define INLINE_SYSCALL(name, nr, args...) \ - ({ \ - DECLARGS_##nr(args) \ - int err; \ - asm volatile ( \ - LOADARGS_##nr \ - "svc %b1\n\t" \ - "lr %0,%%r2\n\t" \ - : "=d" (err) \ - : "I" (__NR_##name) ASMFMT_##nr \ - : "memory", "cc", "2", "3", "4", "5", "6"); \ - if (err >= 0xfffff001) \ - { \ - __set_errno(-err); \ - err = 0xffffffff; \ - } \ +#define INLINE_SYSCALL(name, nr, args...) \ + ({ \ + unsigned int err = INTERNAL_SYSCALL (name, nr, args); \ + if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (err), 0)) \ + { \ + __set_errno (INTERNAL_SYSCALL_ERRNO (err)); \ + err = 0xffffffff; \ + } \ + (int) err; }) + +#undef INTERNAL_SYSCALL +#define INTERNAL_SYSCALL(name, nr, args...) \ + ({ \ + DECLARGS_##nr(args) \ + int err; \ + asm volatile ( \ + LOADARGS_##nr \ + "svc %b1\n\t" \ + "lr %0,%%r2\n\t" \ + : "=d" (err) \ + : "I" (__NR_##name) ASMFMT_##nr \ + : "memory", "cc", "2", "3", "4", "5", "6"); \ (int) err; }) +#undef INTERNAL_SYSCALL_ERROR_P +#define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned int) (val) >= 0xfffff001u) + +#undef INTERNAL_SYSCALL_ERRNO +#define INTERNAL_SYSCALL_ERRNO(val) (-(val)) + #define DECLARGS_0() #define DECLARGS_1(arg1) \ unsigned int gpr2 = (unsigned int) (arg1); --- libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h.jj 2002-08-27 23:19:55.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/s390/s390-64/sysdep.h 2002-10-24 17:32:28.000000000 +0200 @@ -115,6 +115,17 @@ #undef INLINE_SYSCALL #define INLINE_SYSCALL(name, nr, args...) \ ({ \ + unsigned int err = INTERNAL_SYSCALL (name, nr, args); \ + if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (err), 0)) \ + { \ + __set_errno (INTERNAL_SYSCALL_ERRNO (err)); \ + err = -1; \ + } \ + (int) err; }) + +#undef INTERNAL_SYSCALL +#define INTERNAL_SYSCALL(name, nr, args...) \ + ({ \ DECLARGS_##nr(args) \ int err; \ asm volatile ( \ @@ -124,13 +135,14 @@ : "=d" (err) \ : "I" (__NR_##name) ASMFMT_##nr \ : "memory", "cc", "2", "3", "4", "5", "6"); \ - if (err >= 0xfffff001) \ - { \ - __set_errno(-err); \ - err = -1; \ - } \ (int) err; }) +#undef INTERNAL_SYSCALL_ERROR_P +#define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned int) (val) >= 0xfffff001u) + +#undef INTERNAL_SYSCALL_ERRNO +#define INTERNAL_SYSCALL_ERRNO(val) (-(val)) + #define DECLARGS_0() #define DECLARGS_1(arg1) \ unsigned long gpr2 = (unsigned long) (arg1); --- libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h.jj 2002-04-25 22:02:29.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/sparc/sparc32/sysdep.h 2002-10-24 17:17:09.000000000 +0200 @@ -22,6 +22,10 @@ #include +#ifdef IS_IN_rtld +# include /* Defines RTLD_PRIVATE_ERRNO. */ +#endif + #undef SYS_ify #define SYS_ify(syscall_name) __NR_##syscall_name @@ -50,25 +54,35 @@ #define LOC(name) .L##name -#ifdef PIC -#define SYSCALL_ERROR_HANDLER \ - .global C_SYMBOL_NAME(__errno_location); \ - .type C_SYMBOL_NAME(__errno_location),@function; \ - save %sp,-96,%sp; \ +#if RTLD_PRIVATE_ERRNO +# define SYSCALL_ERROR_HANDLER \ + .section .gnu.linkonce.t.__sparc.get_pic.l7,"ax",@progbits; \ + .globl __sparc.get_pic.l7; \ + .hidden __sparc.get_pic.l7; \ + .type __sparc.get_pic.l7,@function; \ +__sparc.get_pic.l7: \ + retl; \ + add %o7, %l7, %l7; \ + .previous; \ + save %sp,-96,%sp; \ + sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7; \ + call __sparc.get_pic.l7; \ + add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7; \ + ld [%l7 + errno], %l0; \ + st %i0, [%l0]; \ + jmpl %i7+8, %g0; \ + restore %g0, -1, %o0; +#else +# define SYSCALL_ERROR_HANDLER \ + .global __errno_location; \ + .type __errno_location,@function; \ + save %sp, -96, %sp; \ call __errno_location; \ nop; \ - st %i0,[%o0]; \ - jmpl %i7+8,%g0; \ - restore %g0,-1,%o0; -#else -#define SYSCALL_ERROR_HANDLER \ - save %sp,-96,%sp; \ - call __errno_location; \ - nop; \ - st %i0,[%o0]; \ - jmpl %i7+8,%g0; \ - restore %g0,-1,%o0; -#endif /* PIC */ + st %i0, [%o0]; \ + jmpl %i7+8, %g0; \ + restore %g0, -1, %o0; +#endif #define PSEUDO(name, syscall_name, args) \ .text; \ @@ -97,6 +111,12 @@ " restore %%g0, -1, %%o0;" \ ".previous;" +#define __INTERNAL_SYSCALL_STRING \ + "ta 0x10;" \ + "bcs,a 1f;" \ + " sub %%g0, %%o0, %%o0;" \ + "1:" + #define __SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g7", \ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ --- libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h.jj 2001-08-23 18:51:33.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/sparc/sparc64/sysdep.h 2002-10-24 17:21:44.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1997, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1997, 2000, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Richard Henderson , 1997. @@ -22,6 +22,10 @@ #include +#ifdef IS_IN_rtld +# include /* Defines RTLD_PRIVATE_ERRNO. */ +#endif + #undef SYS_ify #define SYS_ify(syscall_name) __NR_##syscall_name @@ -43,13 +47,35 @@ C_LABEL(name); \ .type name,@function; -#define SYSCALL_ERROR_HANDLER \ +#if RTLD_PRIVATE_ERRNO +# define SYSCALL_ERROR_HANDLER \ + .section .gnu.linkonce.t.__sparc64.get_pic.l7,"ax",@progbits; \ + .globl __sparc64.get_pic.l7; \ + .hidden __sparc64.get_pic.l7; \ + .type __sparc64.get_pic.l7,@function; \ +__sparc64.get_pic.l7: \ + retl; \ + add %o7, %l7, %l7; \ + .previous; \ save %sp, -192, %sp; \ - call __errno_location; \ - nop; \ - st %i0, [%o0]; \ + sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %l7; \ + call __sparc.get_pic.l7; \ + add %l7, %lo(_GLOBAL_OFFSET_TABLE_+4), %l7; \ + ldx [%l7 + errno], %l0; \ + st %i0, [%l0]; \ jmpl %i7+8, %g0; \ - restore %g0, -1, %o0 + restore %g0, -1, %o0; +#else +# define SYSCALL_ERROR_HANDLER \ + .global __errno_location; \ + .type __errno_location,@function; \ + save %sp, -192, %sp; \ + call __errno_location; \ + nop; \ + st %i0, [%o0]; \ + jmpl %i7+8, %g0; \ + restore %g0, -1, %o0; +#endif #define PSEUDO(name, syscall_name, args) \ .text; \ @@ -88,6 +114,12 @@ "restore %%g0, -1, %%o0;" \ "1:" +#define __INTERNAL_SYSCALL_STRING \ + "ta 0x6d;" \ + "bcs,a,pt %%xcc, 1f;" \ + " sub %%g0, %%o0, %%o0;" \ + "1:" + #define __SYSCALL_CLOBBERS "g2", "g3", "g4", "g5", "g7", \ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ --- libc/sysdeps/unix/sysv/linux/sparc/sysdep.h.jj 2002-09-30 11:23:55.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/sparc/sysdep.h 2002-10-24 17:28:09.000000000 +0200 @@ -21,67 +21,78 @@ #define _LINUX_SPARC_SYSDEP_H 1 #undef INLINE_SYSCALL -#define INLINE_SYSCALL(name, nr, args...) inline_syscall##nr(name, args) +#define INLINE_SYSCALL(name, nr, args...) \ + inline_syscall##nr(__SYSCALL_STRING, name, args) -#define inline_syscall0(name,dummy...) \ +#undef INTERNAL_SYSCALL +#define INTERNAL_SYSCALL(name, nr, args...) \ + inline_syscall##nr(__INTERNAL_SYSCALL_STRING, name, args) + +#undef INTERNAL_SYSCALL_ERROR_P +#define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= -515L) + +#undef INTERNAL_SYSCALL_ERRNO +#define INTERNAL_SYSCALL_ERRNO(val) (-(val)) + +#define inline_syscall0(string,name,dummy...) \ ({ \ register long __o0 __asm__ ("o0"); \ register long __g1 __asm__ ("g1") = __NR_##name; \ - __asm __volatile (__SYSCALL_STRING : "=r" (__g1), "=r" (__o0) : \ + __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \ "0" (__g1) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) -#define inline_syscall1(name,arg1) \ +#define inline_syscall1(string,name,arg1) \ ({ \ register long __o0 __asm__ ("o0") = (long)(arg1); \ register long __g1 __asm__ ("g1") = __NR_##name; \ - __asm __volatile (__SYSCALL_STRING : "=r" (__g1), "=r" (__o0) : \ + __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \ "0" (__g1), "1" (__o0) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) -#define inline_syscall2(name,arg1,arg2) \ +#define inline_syscall2(string,name,arg1,arg2) \ ({ \ register long __o0 __asm__ ("o0") = (long)(arg1); \ register long __o1 __asm__ ("o1") = (long)(arg2); \ register long __g1 __asm__ ("g1") = __NR_##name; \ - __asm __volatile (__SYSCALL_STRING : "=r" (__g1), "=r" (__o0) : \ + __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \ "0" (__g1), "1" (__o0), "r" (__o1) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) -#define inline_syscall3(name,arg1,arg2,arg3) \ +#define inline_syscall3(string,name,arg1,arg2,arg3) \ ({ \ register long __o0 __asm__ ("o0") = (long)(arg1); \ register long __o1 __asm__ ("o1") = (long)(arg2); \ register long __o2 __asm__ ("o2") = (long)(arg3); \ register long __g1 __asm__ ("g1") = __NR_##name; \ - __asm __volatile (__SYSCALL_STRING : "=r" (__g1), "=r" (__o0) : \ + __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \ "0" (__g1), "1" (__o0), "r" (__o1), \ "r" (__o2) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) -#define inline_syscall4(name,arg1,arg2,arg3,arg4) \ +#define inline_syscall4(string,name,arg1,arg2,arg3,arg4) \ ({ \ register long __o0 __asm__ ("o0") = (long)(arg1); \ register long __o1 __asm__ ("o1") = (long)(arg2); \ register long __o2 __asm__ ("o2") = (long)(arg3); \ register long __o3 __asm__ ("o3") = (long)(arg4); \ register long __g1 __asm__ ("g1") = __NR_##name; \ - __asm __volatile (__SYSCALL_STRING : "=r" (__g1), "=r" (__o0) : \ + __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \ "0" (__g1), "1" (__o0), "r" (__o1), \ "r" (__o2), "r" (__o3) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) -#define inline_syscall5(name,arg1,arg2,arg3,arg4,arg5) \ +#define inline_syscall5(string,name,arg1,arg2,arg3,arg4,arg5) \ ({ \ register long __o0 __asm__ ("o0") = (long)(arg1); \ register long __o1 __asm__ ("o1") = (long)(arg2); \ @@ -89,14 +100,14 @@ register long __o3 __asm__ ("o3") = (long)(arg4); \ register long __o4 __asm__ ("o4") = (long)(arg5); \ register long __g1 __asm__ ("g1") = __NR_##name; \ - __asm __volatile (__SYSCALL_STRING : "=r" (__g1), "=r" (__o0) : \ + __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \ "0" (__g1), "1" (__o0), "r" (__o1), \ "r" (__o2), "r" (__o3), "r" (__o4) : \ __SYSCALL_CLOBBERS); \ __o0; \ }) -#define inline_syscall6(name,arg1,arg2,arg3,arg4,arg5,arg6) \ +#define inline_syscall6(string,name,arg1,arg2,arg3,arg4,arg5,arg6) \ ({ \ register long __o0 __asm__ ("o0") = (long)(arg1); \ register long __o1 __asm__ ("o1") = (long)(arg2); \ @@ -105,7 +116,7 @@ register long __o4 __asm__ ("o4") = (long)(arg5); \ register long __o5 __asm__ ("o5") = (long)(arg6); \ register long __g1 __asm__ ("g1") = __NR_##name; \ - __asm __volatile (__SYSCALL_STRING : "=r" (__g1), "=r" (__o0) : \ + __asm __volatile (string : "=r" (__g1), "=r" (__o0) : \ "0" (__g1), "1" (__o0), "r" (__o1), \ "r" (__o2), "r" (__o3), "r" (__o4), \ "r" (__o5) : \ --- libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h.jj 2002-10-17 13:34:36.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/x86_64/sysdep.h 2002-10-24 16:34:26.000000000 +0200 @@ -186,6 +186,17 @@ #undef INLINE_SYSCALL #define INLINE_SYSCALL(name, nr, args...) \ ({ \ + unsigned long resultvar = INTERNAL_SYSCALL (name, nr, args); \ + if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar), 0)) \ + { \ + __set_errno (INTERNAL_SYSCALL_ERRNO (resultvar)); \ + resultvar = (unsigned long) -1; \ + } \ + (long) resultvar; }) + +#undef INTERNAL_SYSCALL +#define INTERNAL_SYSCALL(name, nr, args...) \ + ({ \ unsigned long resultvar; \ LOAD_ARGS_##nr (args) \ asm volatile ( \ @@ -193,13 +204,14 @@ "syscall\n\t" \ : "=a" (resultvar) \ : "i" (__NR_##name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx"); \ - if (resultvar >= (unsigned long) -4095) \ - { \ - __set_errno (-resultvar); \ - resultvar = (unsigned long) -1; \ - } \ (long) resultvar; }) +#undef INTERNAL_SYSCALL_ERROR_P +#define INTERNAL_SYSCALL_ERROR_P(val) ((unsigned long) (val) >= -4095L) + +#undef INTERNAL_SYSCALL_ERRNO +#define INTERNAL_SYSCALL_ERRNO(val) (-(val)) + #define LOAD_ARGS_0() #define ASM_ARGS_0 Jakub From roland@redhat.com Fri Oct 25 03:38:00 2002 From: roland@redhat.com (Roland McGrath) Date: Fri, 25 Oct 2002 03:38:00 -0000 Subject: [PATCH] Fix LD_DEBUG=statistics In-Reply-To: Jakub Jelinek's message of Thursday, 24 October 2002 19:47:25 +0200 <20021024194725.O3451@sunsite.ms.mff.cuni.cz> Message-ID: <200210241903.g9OJ3EN09917@magilla.sf.frob.com> Thanks, I'm putting that in with a couple of cosmetic cleanups. From jakub@redhat.com Fri Oct 25 12:42:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Fri, 25 Oct 2002 12:42:00 -0000 Subject: init-first.c change Message-ID: <20021025123831.P3451@sunsite.ms.mff.cuni.cz> Hi! I have doubts about: 2002-10-24 Roland McGrath * sysdeps/unix/sysv/linux/init-first.c (init): Protect _dl_starting_up access with [! SHARED]. * sysdeps/unix/sysv/aix/init-first.c (init): Likewise. change. It seems to me that ATM all normal dynamically linked programs will suddenly have __libc_multiple_libcs set to 1 while they had 0 there previously. Shouldn't it actually be #ifdef SHARED? Also: /* The next variable is only here to work around a bug in gcc <= 2.7.2.2. If the address would be taken inside the expression the optimizer would try to be too smart and throws it away. Grrr. */ int *dummy_addr = &_dl_starting_up; __libc_multiple_libcs = dummy_addr && !_dl_starting_up; could be replaced with __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up; , because we don't support 2.7.2.2 any longer for glibc build. Last, there is _dl_starting_up extern in elf/dl-init.c which could be killed too. Jakub From roland@redhat.com Fri Oct 25 17:33:00 2002 From: roland@redhat.com (Roland McGrath) Date: Fri, 25 Oct 2002 17:33:00 -0000 Subject: init-first.c change In-Reply-To: Jakub Jelinek's message of Friday, 25 October 2002 12:38:31 +0200 <20021025123831.P3451@sunsite.ms.mff.cuni.cz> Message-ID: <200210251942.g9PJgJT01596@magilla.sf.frob.com> Quite right. I changed it to match the sysdeps/generic code, but that code is quite bit-rotted and I was forgetting about the view from the dlopen'd libc.so when thinking about that variable. From jakub@redhat.com Fri Oct 25 22:41:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Fri, 25 Oct 2002 22:41:00 -0000 Subject: [PATCH] Optimize some free_mem handlers, save 4K from .bss Message-ID: <20021026023351.Q3451@sunsite.ms.mff.cuni.cz> Hi! This is what I managed tonight, the rest will have to wait. It passed make check and I have even checked in debugger that __libc_freeres frees all ptrs from __libc_freeres_ptrs section. Don't have exact numbers how much it saved, because I can only compare ~ 1 day old libc.so with today's libc.so with this patch, but it has 36 fewer RELATIVE relocs, 1472 fewer bytes in .text section, 148 fewer bytes in __libc_subfreeres, 4064 fewer bytes in .bss (this is still without Roland's sigvec patch). 2002-10-25 Jakub Jelinek * include/libc-symbols.h (libc_freeres_ptr): Define. * malloc/set-freeres.c (__libc_freeres_ptrs): Define using symbol_set_define. (__libc_freeres): Free all pointers in that section. * Makerules (build-shlib): Add $(LDSEDCMD-$(@F:lib%.so=%).so) to sed commands when creating .lds script. (LDSEDCMD-c.so): Define. * inet/rcmd.c (ahostbuf): Change into char *. Add libc_freeres_ptr. (rcmd_af): Use strdup to allocate ahostbuf. * inet/rexec.c (ahostbuf): Change into char *. Add libc_freeres_ptr. (rexec_af): Use strdup to allocate ahostbuf. * stdio-common/reg-printf.c (printf_funcs): Remove. (__printf_arginfo_table): Change into printf_arginfo_function **. Add libc_freeres_ptr. (__register_printf_function): Allocate __printf_arginfo_table and __printf_function_table the first time it is called. * stdio-common/printf-parse.h (__printf_arginfo_table): Change into printf_arginfo_function **. (parse_one_spec): Add __builtin_expect. * grp/fgetgrent.c (buffer): Add libc_freeres_ptr. (free_mem): Remove. * inet/getnetgrent.c (buffer): Add libc_freeres_ptr. (free_mem): Remove. * intl/localealias.c (libc_freeres_ptr): Define if !_LIBC. (string_space, map): Add libc_freeres_ptr. (free_mem): Remove. * misc/efgcvt.c (FCVT_BUFPTR): Add libc_freeres_ptr. (free_mem): Remove. * misc/mntent.c (getmntent_buffer): Add libc_freeres_ptr. (free_mem): Remove. * crypt/md5-crypt.c (libc_freeres_ptr): Define if !_LIBC. (buffer): Add libc_freeres_ptr. (free_mem): Remove for _LIBC. * nss/getXXbyYY.c (buffer): Add libc_freeres_ptr. (free_mem): Remove. * nss/getXXent.c (buffer): Add libc_freeres_ptr. (free_mem): Remove. * pwd/fgetpwent.c (buffer): Add libc_freeres_ptr. (free_mem): Remove. * resolv/res_hconf.c (ifaddrs): Add libc_freeres_ptr. (free_mem): Remove. * shadow/fgetspent.c (buffer): Add libc_freeres_ptr. (free_mem): Remove. * sysdeps/posix/ttyname.c (getttyname_name): Add libc_freeres_ptr. (free_mem): Remove. * sysdeps/unix/sysv/linux/getsysstats.c (mount_proc): Add libc_freeres_ptr. (free_mem): Remove. * sysdeps/unix/sysv/linux/ttyname.c (getttyname_name, ttyname_buf): Add libc_freeres_ptr. (free_mem): Remove. --- libc/include/libc-symbols.h.jj 2002-10-16 23:21:24.000000000 +0200 +++ libc/include/libc-symbols.h 2002-10-25 23:49:37.000000000 +0200 @@ -253,17 +253,18 @@ /* Tacking on "\n\t#" to the section name makes gcc put it's bogus section attributes on what looks like a comment to the assembler. */ # ifdef HAVE_SECTION_QUOTES -# define link_warning(symbol, msg) \ - __make_section_unallocated (".gnu.warning." #symbol) \ - static const char __evoke_link_warning_##symbol[] \ - __attribute__ ((unused, section (".gnu.warning." #symbol "\"\n\t#\""))) \ - = msg; +# define __sec_comment "\"\n\t#\"" # else -# define link_warning(symbol, msg) \ +# define __sec_comment "\n\t#" +# endif +# define link_warning(symbol, msg) \ __make_section_unallocated (".gnu.warning." #symbol) \ static const char __evoke_link_warning_##symbol[] \ - __attribute__ ((unused, section (".gnu.warning." #symbol "\n\t#"))) = msg; -# endif + __attribute__ ((unused, section (".gnu.warning." #symbol __sec_comment))) \ + = msg; +# define libc_freeres_ptr(decl) \ + __make_section_unallocated ("__libc_freeres_ptrs, \"aw\", @nobits") \ + decl __attribute__ ((section ("__libc_freeres_ptrs" __sec_comment))) # else /* Not ELF: a.out */ # ifdef HAVE_XCOFF /* XCOFF does not support .stabs. @@ -276,10 +277,12 @@ asm (".stabs \"" msg "\",30,0,0,0\n\t" \ ".stabs \"" __SYMBOL_PREFIX #symbol "\",1,0,0,0\n"); # endif /* XCOFF */ +# define libc_freeres_ptr(decl) decl # endif #else /* We will never be heard; they will all die horribly. */ # define link_warning(symbol, msg) +# define libc_freeres_ptr(decl) decl #endif /* A canned warning for sysdeps/stub functions. */ --- libc/grp/fgetgrent.c.jj 2001-08-23 18:47:11.000000000 +0200 +++ libc/grp/fgetgrent.c 2002-10-25 23:52:05.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1996, 1997, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1991,1996,1997,1999,2000,2002 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 @@ -26,7 +26,7 @@ /* We need to protect the dynamic buffer handling. */ __libc_lock_define_initialized (static, lock); -static char *buffer; +libc_freeres_ptr (static char *buffer); /* Read one entry from the given stream. */ struct group * @@ -83,13 +83,3 @@ fgetgrent (FILE *stream) return result; } - - -/* Free all resources if necessary. */ -static void __attribute__ ((unused)) -free_mem (void) -{ - free (buffer); -} - -text_set_element (__libc_subfreeres, free_mem); --- libc/inet/rcmd.c.jj 2002-08-06 10:15:14.000000000 +0200 +++ libc/inet/rcmd.c 2002-10-26 00:03:01.000000000 +0200 @@ -101,7 +101,7 @@ int iruserok (u_int32_t raddr, int super libc_hidden_proto (iruserok_af) -static char ahostbuf[NI_MAXHOST]; +libc_freeres_ptr(static char *ahostbuf); int rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) @@ -153,11 +153,21 @@ rcmd_af(ahost, rport, locuser, remuser, pfd[1].events = POLLIN; if (res->ai_canonname){ - strncpy(ahostbuf, res->ai_canonname, sizeof(ahostbuf)); - ahostbuf[sizeof(ahostbuf)-1] = '\0'; + free (ahostbuf); + ahostbuf = strdup (res->ai_canonname); + if (ahostbuf == NULL) { +#ifdef USE_IN_LIBIO + if (_IO_fwide (stderr, 0) > 0) + __fwprintf(stderr, L"%s", + _("rcmd: Cannot allocate memory\n")); + else +#endif + fputs(_("rcmd: Cannot allocate memory\n"), + stderr); + return (-1); + } *ahost = ahostbuf; - } - else + } else *ahost = NULL; ai = res; refused = 0; --- libc/inet/rexec.c.jj 2002-08-12 15:27:47.000000000 +0200 +++ libc/inet/rexec.c 2002-10-26 00:04:57.000000000 +0200 @@ -45,7 +45,7 @@ static char sccsid[] = "@(#)rexec.c 8.1 #include int rexecoptions; -static char ahostbuf[NI_MAXHOST]; +libc_freeres_ptr (static char *ahostbuf); int rexec_af(ahost, rport, name, pass, cmd, fd2p, af) @@ -79,13 +79,15 @@ rexec_af(ahost, rport, name, pass, cmd, } if (res0->ai_canonname){ - strncpy(ahostbuf, res0->ai_canonname, sizeof(ahostbuf)); - ahostbuf[sizeof(ahostbuf)-1] = '\0'; + free (ahostbuf); + ahostbuf = strdup (res0->ai_canonname); + if (ahostbuf == NULL) { + perror ("rexec: strdup"); + return (-1); + } *ahost = ahostbuf; - } - else{ + } else *ahost = NULL; - } ruserpass(res0->ai_canonname, &name, &pass); retry: s = __socket(res0->ai_family, res0->ai_socktype, 0); --- libc/inet/getnetgrent.c.jj 2001-08-23 18:47:43.000000000 +0200 +++ libc/inet/getnetgrent.c 2002-10-26 00:08:54.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 2000, 2002 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,8 +21,8 @@ #include #include -/* Statis buffer for return value. We allocate it when needed. */ -static char *buffer; +/* Static buffer for return value. We allocate it when needed. */ +libc_freeres_ptr (static char *buffer); /* All three strings should fit in a block of 1kB size. */ #define BUFSIZE 1024 @@ -48,15 +48,3 @@ getnetgrent (char **hostp, char **userp, return __getnetgrent_r (hostp, userp, domainp, buffer, BUFSIZE); } - - -/* Make sure the memory is freed if the programs ends while in - memory-debugging mode and something actually was allocated. */ -static void -__attribute__ ((unused)) -free_mem (void) -{ - free (buffer); -} - -text_set_element (__libc_subfreeres, free_mem); --- libc/intl/localealias.c.jj 2002-09-01 15:33:18.000000000 +0200 +++ libc/intl/localealias.c 2002-10-26 00:11:00.000000000 +0200 @@ -117,10 +117,14 @@ struct alias_map }; -static char *string_space; +#ifndef _LIBC +# define libc_freeres_ptr(decl) decl +#endif + +libc_freeres_ptr (static char *string_space); static size_t string_space_act; static size_t string_space_max; -static struct alias_map *map; +libc_freeres_ptr (static struct alias_map *map); static size_t nmap; static size_t maxmap; @@ -371,19 +375,6 @@ extend_alias_table () } -#ifdef _LIBC -static void __attribute__ ((unused)) -free_mem (void) -{ - if (string_space != NULL) - free (string_space); - if (map != NULL) - free (map); -} -text_set_element (__libc_subfreeres, free_mem); -#endif - - static int alias_compare (map1, map2) const struct alias_map *map1; --- libc/malloc/set-freeres.c.jj 2002-08-03 11:09:31.000000000 +0200 +++ libc/malloc/set-freeres.c 2002-10-26 01:11:29.000000000 +0200 @@ -27,6 +27,8 @@ DEFINE_HOOK (__libc_subfreeres, (void)); +symbol_set_define (__libc_freeres_ptrs); + void __libc_freeres (void) { @@ -36,11 +38,17 @@ __libc_freeres (void) if (compare_and_swap (&already_called, 0, 1)) { + void * const *p; + #ifdef USE_IN_LIBIO _IO_cleanup (); #endif RUN_HOOK (__libc_subfreeres, ()); + + for (p = symbol_set_first_element (__libc_freeres_ptrs); + ! symbol_set_end_p (__libc_freeres_ptrs, p); ++p) + free (*p); } } libc_hidden_def (__libc_freeres) --- libc/misc/efgcvt.c.jj 2001-08-23 18:48:30.000000000 +0200 +++ libc/misc/efgcvt.c 2002-10-26 00:13:58.000000000 +0200 @@ -1,5 +1,5 @@ /* Compatibility functions for floating point formatting. - Copyright (C) 1995, 1996, 1997, 1999 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1999, 2002 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 @@ -57,7 +57,7 @@ static char FCVT_BUFFER[MAXDIG]; static char ECVT_BUFFER[MAXDIG]; -static char *FCVT_BUFPTR; +libc_freeres_ptr (static char *FCVT_BUFPTR); char * APPEND (FUNC_PREFIX, fcvt) (value, ndigit, decpt, sign) @@ -102,13 +102,3 @@ APPEND (FUNC_PREFIX, gcvt) (value, ndigi sprintf (buf, "%.*" FLOAT_FMT_FLAG "g", MIN (ndigit, NDIGIT_MAX), value); return buf; } - -/* Free all resources if necessary. */ -static void __attribute__ ((unused)) -free_mem (void) -{ - if (FCVT_BUFPTR != NULL) - free (FCVT_BUFPTR); -} - -text_set_element (__libc_subfreeres, free_mem); --- libc/misc/mntent.c.jj 2001-08-23 18:48:30.000000000 +0200 +++ libc/misc/mntent.c 2002-10-26 00:14:43.000000000 +0200 @@ -1,5 +1,5 @@ /* Utilities for reading/writing fstab, mtab, etc. - Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 2000, 2002 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 @@ -24,7 +24,7 @@ /* We don't want to allocate the static buffer all the time since it is not always used (in fact, rather infrequently). Accept the extra cost of a `malloc'. */ -static char *getmntent_buffer; +libc_freeres_ptr (static char *getmntent_buffer); /* This is the size of the buffer. This is really big. */ #define BUFFER_SIZE 4096 @@ -52,15 +52,3 @@ getmntent (FILE *stream) return __getmntent_r (stream, &m, getmntent_buffer, BUFFER_SIZE); } - - -/* Make sure the memory is freed if the programs ends while in - memory-debugging mode and something actually was allocated. */ -static void -__attribute__ ((unused)) -free_mem (void) -{ - free (getmntent_buffer); -} - -text_set_element (__libc_subfreeres, free_mem); --- libc/crypt/md5-crypt.c.jj 2002-01-30 18:00:15.000000000 +0100 +++ libc/crypt/md5-crypt.c 2002-10-26 00:17:12.000000000 +0200 @@ -1,5 +1,5 @@ /* One way encryption based on MD5 sum. - Copyright (C) 1996, 1997, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1996,1997,1999,2000,2001,2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -233,8 +233,10 @@ __md5_crypt_r (key, salt, buffer, buflen return buffer; } - -static char *buffer; +#ifndef _LIBC +# define libc_freeres_ptr(decl) decl +#endif +libc_freeres_ptr (static char *buffer); char * __md5_crypt (const char *key, const char *salt) @@ -261,10 +263,11 @@ __md5_crypt (const char *key, const char return __md5_crypt_r (key, salt, buffer, buflen); } - +#ifndef _LIBC static void __attribute__ ((__destructor__)) free_mem (void) { free (buffer); } +#endif --- libc/nss/getXXbyYY.c.jj 2001-08-23 18:48:43.000000000 +0200 +++ libc/nss/getXXbyYY.c 2002-10-26 00:17:58.000000000 +0200 @@ -86,7 +86,7 @@ extern int INTERNAL (REENTRANT_NAME) (AD __libc_lock_define_initialized (static, lock); /* This points to the static buffer used. */ -static char *buffer; +libc_freeres_ptr (static char *buffer); LOOKUP_TYPE * @@ -162,13 +162,3 @@ done: return result; } - - -/* Free all resources if necessary. */ -static void __attribute__ ((unused)) -free_mem (void) -{ - free (buffer); -} - -text_set_element (__libc_subfreeres, free_mem); --- libc/nss/getXXent.c.jj 2001-08-23 18:48:43.000000000 +0200 +++ libc/nss/getXXent.c 2002-10-26 00:18:37.000000000 +0200 @@ -63,7 +63,7 @@ extern int INTERNAL (REENTRANT_GETNAME) __libc_lock_define_initialized (static, lock); /* This points to the static buffer used. */ -static char *buffer; +libc_freeres_ptr (static char *buffer); LOOKUP_TYPE * @@ -87,13 +87,3 @@ GETFUNC_NAME (void) __set_errno (save); return result; } - - -/* Free all resources if necessary. */ -static void __attribute__ ((unused)) -free_mem (void) -{ - free (buffer); -} - -text_set_element (__libc_subfreeres, free_mem); --- libc/pwd/fgetpwent.c.jj 2001-08-23 18:49:01.000000000 +0200 +++ libc/pwd/fgetpwent.c 2002-10-26 00:19:34.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 1996, 1997, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1991,1996,1997,1999,2000,2002 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 @@ -26,7 +26,7 @@ /* We need to protect the dynamic buffer handling. */ __libc_lock_define_initialized (static, lock); -static char *buffer; +libc_freeres_ptr (static char *buffer); /* Read one entry from the given stream. */ struct passwd * @@ -83,13 +83,3 @@ fgetpwent (FILE *stream) return result; } - - -/* Free all resources if necessary. */ -static void __attribute__ ((unused)) -free_mem (void) -{ - free (buffer); -} - -text_set_element (__libc_subfreeres, free_mem); --- libc/resolv/res_hconf.c.jj 2002-09-24 13:00:09.000000000 +0200 +++ libc/resolv/res_hconf.c 2002-10-26 00:20:39.000000000 +0200 @@ -489,6 +489,7 @@ _res_hconf_init (void) /* List of known interfaces. */ +libc_freeres_ptr ( static struct netaddr { int addrtype; @@ -500,7 +501,7 @@ static struct netaddr u_int32_t mask; } ipv4; } u; -} *ifaddrs; +} *ifaddrs); /* We need to protect the dynamic buffer handling. */ __libc_lock_define_initialized (static, lock); @@ -657,13 +658,3 @@ _res_hconf_trim_domains (struct hostent for (i = 0; hp->h_aliases[i]; ++i) _res_hconf_trim_domain (hp->h_aliases[i]); } - - -/* Free all resources if necessary. */ -static void __attribute__ ((unused)) -free_mem (void) -{ - free (ifaddrs); -} - -text_set_element (__libc_subfreeres, free_mem); --- libc/shadow/fgetspent.c.jj 2001-08-23 18:49:01.000000000 +0200 +++ libc/shadow/fgetspent.c 2002-10-26 00:21:13.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1999, 2000, 2002 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 @@ -29,7 +29,7 @@ /* We need to protect the dynamic buffer handling. */ __libc_lock_define_initialized (static, lock); -static char *buffer; +libc_freeres_ptr (static char *buffer); /* Read one shadow entry from the given stream. */ struct spwd * @@ -86,13 +86,3 @@ fgetspent (FILE *stream) return result; } - - -/* Free all resources if necessary. */ -static void __attribute__ ((unused)) -free_mem (void) -{ - free (buffer); -} - -text_set_element (__libc_subfreeres, free_mem); --- libc/stdio-common/reg-printf.c.jj 2002-03-23 11:50:55.000000000 +0100 +++ libc/stdio-common/reg-printf.c 2002-10-26 00:31:44.000000000 +0200 @@ -21,10 +21,8 @@ #include /* Array of functions indexed by format character. */ -static printf_function *printf_funcs[UCHAR_MAX + 1]; -printf_arginfo_function *__printf_arginfo_table[UCHAR_MAX + 1] - attribute_hidden; - +libc_freeres_ptr (printf_arginfo_function **__printf_arginfo_table) + attribute_hidden; printf_function **__printf_function_table attribute_hidden; int __register_printf_function __P ((int, printf_function, @@ -43,9 +41,18 @@ __register_printf_function (spec, conver return -1; } - __printf_function_table = printf_funcs; + if (__printf_function_table == NULL) + { + __printf_arginfo_table = (printf_arginfo_function **) + malloc ((UCHAR_MAX + 1) * sizeof (void *) * 2); + if (__printf_arginfo_table == NULL) + return -1; + __printf_function_table = (printf_function **) + (__printf_arginfo_table + UCHAR_MAX + 1); + } + + __printf_function_table[spec] = converter; __printf_arginfo_table[spec] = arginfo; - printf_funcs[spec] = converter; return 0; } --- libc/stdio-common/printf-parse.h.jj 2002-03-23 11:50:55.000000000 +0100 +++ libc/stdio-common/printf-parse.h 2002-10-25 17:19:29.000000000 +0200 @@ -117,7 +117,7 @@ find_spec (const UCHAR_T *format, mbstat /* These are defined in reg-printf.c. */ -extern printf_arginfo_function *__printf_arginfo_table[] attribute_hidden; +extern printf_arginfo_function **__printf_arginfo_table attribute_hidden; extern printf_function **__printf_function_table attribute_hidden; @@ -354,7 +354,7 @@ parse_one_spec (const UCHAR_T *format, s /* Get the format specification. */ spec->info.spec = (wchar_t) *format++; - if (__printf_function_table != NULL + if (__builtin_expect (__printf_function_table != NULL, 0) && spec->info.spec <= UCHAR_MAX && __printf_arginfo_table[spec->info.spec] != NULL) /* We don't try to get the types for all arguments if the format --- libc/sysdeps/posix/ttyname.c.jj 2001-08-23 18:50:12.000000000 +0200 +++ libc/sysdeps/posix/ttyname.c 2002-10-26 00:24:43.000000000 +0200 @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 92, 93, 96, 97, 98, 2000 Free Software Foundation, Inc. +/* Copyright (C) 1991,92,93,96,97,98,2000,2002 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 @@ -32,7 +32,7 @@ static char *getttyname (int fd, dev_t m int save, int *dostat) internal_function; -static char *getttyname_name; +libc_freeres_ptr (static char *getttyname_name); static char * internal_function @@ -134,11 +134,3 @@ ttyname (fd) return name; } - - -static void -free_mem (void) -{ - free (getttyname_name); -} -text_set_element (__libc_subfreeres, free_mem); --- libc/sysdeps/unix/sysv/linux/getsysstats.c.jj 2002-09-24 13:00:11.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/getsysstats.c 2002-10-26 00:25:32.000000000 +0200 @@ -38,7 +38,7 @@ static const char path_proc[] = "/proc"; /* Actual mount point of /proc filesystem. */ -static char *mount_proc; +libc_freeres_ptr (static char *mount_proc); /* Determine the path to the /proc filesystem if available. */ static const char * @@ -319,11 +319,3 @@ __get_avphys_pages () return phys_pages_info ("MemFree: %ld kB"); } weak_alias (__get_avphys_pages, get_avphys_pages) - - -static void -free_mem (void) -{ - free (mount_proc); -} -text_set_element (__libc_subfreeres, free_mem); --- libc/sysdeps/unix/sysv/linux/ttyname.c.jj 2002-09-24 13:00:11.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/ttyname.c 2002-10-26 00:30:15.000000000 +0200 @@ -38,7 +38,7 @@ static char *getttyname (const char *dev internal_function; -static char *getttyname_name; +libc_freeres_ptr (static char *getttyname_name); static char * internal_function @@ -103,7 +103,7 @@ getttyname (const char *dev, dev_t mydev /* Static buffer in `ttyname'. */ -static char *ttyname_buf; +libc_freeres_ptr (static char *ttyname_buf); /* Return the pathname of the terminal FD is open on, or NULL on errors. @@ -186,12 +186,3 @@ ttyname (int fd) return name; } - - -static void -free_mem (void) -{ - free (ttyname_buf); - free (getttyname_name); -} -text_set_element (__libc_subfreeres, free_mem); --- libc/Makerules.jj 2002-10-17 13:34:18.000000000 +0200 +++ libc/Makerules 2002-10-26 01:56:52.000000000 +0200 @@ -447,7 +447,7 @@ $(build-shlib-helper) \ $(LDLIBS-$(@F:lib%.so=%).so) 2>&1 | \ sed -e '/^=========/,/^=========/!d;/^=========/d' \ -e 's/^.*\.hash[ ]*:.*$$/ .note.ABI-tag : { *(.note.ABI-tag) } &/' \ - > $@.lds + $(LDSEDCMD-$(@F:lib%.so=%).so) > $@.lds rm -f $@.new $(build-shlib-helper) -o $@ -T $@.lds \ $(csu-objpfx)abi-note.o $(build-shlib-objlist) @@ -548,6 +548,7 @@ ifeq ($(elf),yes) $(common-objpfx)libc_pic.os: $(common-objpfx)libc_pic.a $(LINK.o) -nostdlib -nostartfiles -r -o $@ \ $(LDFLAGS-c_pic.os) -Wl,-d -Wl,--whole-archive $^ +LDSEDCMD-c.so = -e 's/^.*\*(\.dynbss).*$$/& __start___libc_freeres_ptrs = .; *(__libc_freeres_ptrs) __stop___libc_freeres_ptrs = .;/' # Use our own special initializer and finalizer files for libc.so. $(common-objpfx)libc.so: $(elfobjdir)/soinit.os \ $(common-objpfx)libc_pic.os \ Jakub From drepper@redhat.com Fri Oct 25 22:43:00 2002 From: drepper@redhat.com (Ulrich Drepper) Date: Fri, 25 Oct 2002 22:43:00 -0000 Subject: next weeks program Message-ID: <3DBA2B25.1070305@redhat.com> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 I'll be out of town next week, starting tomorrow. I might be able to look at the mail but real work has to wait until Friday. - -- - --------------. ,-. 444 Castro Street Ulrich Drepper \ ,-----------------' \ Mountain View, CA 94041 USA Red Hat `--' drepper at redhat.com `--------------------------- -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.7 (GNU/Linux) iD8DBQE9uisl2ijCOnn/RHQRAjsHAJ9w3tBGCCd3/dUgX+8hty14dfUm0ACfXJyr iu60fNfsAt/QRBVPW5da/9o= =CvWD -----END PGP SIGNATURE----- From roland@redhat.com Mon Oct 28 21:37:00 2002 From: roland@redhat.com (Roland McGrath) Date: Mon, 28 Oct 2002 21:37:00 -0000 Subject: next weeks program In-Reply-To: Ulrich Drepper's message of Friday, 25 October 2002 22:41:57 -0700 <3DBA2B25.1070305@redhat.com> Message-ID: <200210260543.g9Q5hGw18003@magilla.sf.frob.com> > I'll be out of town next week, starting tomorrow. I might be able to > look at the mail but real work has to wait until Friday. Me too (same place). Don't expect to get any patches in before Friday. From davidm@napali.hpl.hp.com Mon Oct 28 22:27:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Mon, 28 Oct 2002 22:27:00 -0000 Subject: patch to make init_array work (2nd version) Message-ID: <15806.7806.501878.610194@napali.hpl.hp.com> My previous patch (adopted from HJ's work) was missing a change to dl-fini.c which broke the handling of .fini_array. The patch below is updated to fix that and "make check" now passes as expected (I must have made a mistake previously as I thought it worked with the previous patch already). If it looks OK, please apply. (Yes, I know both Uli and Roland are out this week, but I'll likely be out next week...). Thanks, --david 2002-10-28 David Mosberger * elf/dl-fini.c (_dl_fini): Invoke fini_array in _reverse_ order. Don't add l->l_addr to array entry values. 2002-03-12 H.J. Lu * csu/init.c (__libc_preinit_array): New. Define if HAVE_INITFINI_ARRAY is defined. (__libc_init_array): Likewise. (__libc_fini_array): Likewise. * elf/Makefile (tests): Add tst-array1, tst-array2 and tst-array3 if $(have-initfini-array) is yes. (tests-static): Add tst-array3 if $(have-initfini-array) is yes. (modules-names): Add tst-array2dep if $(have-initfini-array) is yes. ($(objpfx)tst-array1.out): New target. ($(objpfx)tst-array2): Likewise. ($(objpfx)tst-array2.out): Likewise. ($(objpfx)tst-array3.out): Likewise. * elf/tst-array1.c: New file. * elf/tst-array1.exp: Likewise. * elf/tst-array2.c: Likewise. * elf/tst-array2dep.c: Likewise. * elf/tst-array2.exp: Likewise. * elf/tst-array3.c: Likewise. * sysdeps/generic/libc-start.c (__libc_start_main): Process __libc_preinit_array, __libc_init_array and __libc_fini_array if HAVE_INITFINI_ARRAY is defined. Index: csu/init.c =================================================================== RCS file: /cvs/glibc/libc/csu/init.c,v retrieving revision 1.4 diff -u -r1.4 init.c --- csu/csu/init.c 6 Jul 2001 04:54:45 -0000 1.4 +++ csu/csu/init.c 29 Oct 2002 05:35:15 -0000 @@ -25,3 +25,43 @@ const int _IO_stdin_used = _G_IO_IO_FILE_VERSION; #endif + +#ifdef HAVE_INITFINI_ARRAY +extern void (*__preinit_array_start []) (void); +extern void (*__preinit_array_end []) (void); + +void +__libc_preinit_array (void) +{ + unsigned int size, i; + + size = __preinit_array_end - __preinit_array_start; + for (i = 0; i < size; i++) + __preinit_array_start [i] (); +} + +extern void (*__init_array_start []) (void); +extern void (*__init_array_end []) (void); + +void +__libc_init_array (void) +{ + unsigned int size, i; + + size = __init_array_end - __init_array_start; + for (i = 0; i < size; i++) + __init_array_start [i] (); +} + +extern void (*__fini_array_start []) (void); +extern void (*__fini_array_end []) (void); + +void +__libc_fini_array (void) +{ + int i; + + for (i = __fini_array_end - __fini_array_start - 1; i >= 0; i--) + __fini_array_start [i] (); +} +#endif Index: elf/Makefile =================================================================== RCS file: /cvs/glibc/libc/elf/Makefile,v retrieving revision 1.242 diff -u -r1.242 Makefile --- elf/elf/Makefile 24 Oct 2002 00:20:38 -0000 1.242 +++ elf/elf/Makefile 29 Oct 2002 05:35:15 -0000 @@ -117,6 +117,9 @@ endif tests = tst-tls1 tst-tls2 tst-tls9 +ifeq (yes,$(have-initfini-array)) +tests += tst-array1 tst-array2 tst-array3 +endif ifeq (yes,$(build-static)) tests-static = tst-tls1-static tst-tls2-static ifeq (yesyesyes,$(build-static)$(build-shared)$(elf)) @@ -156,6 +159,9 @@ tst-tlsmod5 tst-tlsmod6 \ circlemod1 circlemod1a circlemod2 circlemod2a \ circlemod3 circlemod3a +ifeq (yes,$(have-initfini-array)) +modules-names += tst-array2dep +endif modules-vis-yes = vismod1 vismod2 vismod3 modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4 modules-nodlopen-yes = nodlopenmod nodlopenmod2 @@ -543,3 +549,22 @@ $(objpfx)tst-tls9-static: $(common-objpfx)dlfcn/libdl.a $(objpfx)tst-tls9-static.out: $(objpfx)tst-tlsmod5.so $(objpfx)tst-tlsmod6.so endif + +$(objpfx)tst-array1.out: $(objpfx)tst-array1 + $(elf-objpfx)$(rtld-installed-name) \ + --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \ + $(objpfx)tst-array1 > $@ + cmp $@ tst-array1.exp > /dev/null + +$(objpfx)tst-array2: $(objpfx)tst-array2dep.so +$(objpfx)tst-array2.out: $(objpfx)tst-array2 + $(elf-objpfx)$(rtld-installed-name) \ + --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \ + $(objpfx)tst-array2 > $@ + cmp $@ tst-array2.exp > /dev/null + +$(objpfx)tst-array3.out: $(objpfx)tst-array3 + $(elf-objpfx)$(rtld-installed-name) \ + --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \ + $(objpfx)tst-array3 > $@ + cmp $@ tst-array1.exp > /dev/null Index: elf/dl-fini.c =================================================================== RCS file: /cvs/glibc/libc/elf/dl-fini.c,v retrieving revision 1.27 diff -u -r1.27 dl-fini.c --- elf/elf/dl-fini.c 1 Mar 2002 09:11:58 -0000 1.27 +++ elf/elf/dl-fini.c 29 Oct 2002 05:35:15 -0000 @@ -157,12 +157,11 @@ ElfW(Addr) *array = (ElfW(Addr) *) (l->l_addr + l->l_info[DT_FINI_ARRAY]->d_un.d_ptr); - unsigned int sz = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val - / sizeof (ElfW(Addr))); - unsigned int cnt; + int i = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val + / sizeof (ElfW(Addr))) - 1; - for (cnt = 0; cnt < sz; ++cnt) - ((fini_t) (l->l_addr + array[cnt])) (); + for (; i >= 0; --i) + ((fini_t) array[i]) (); } /* Next try the old-style destructor. */ Index: elf/tst-array1.c =================================================================== RCS file: elf/tst-array1.c diff -N elf/tst-array1.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ elf/elf/tst-array1.c 29 Oct 2002 05:35:15 -0000 @@ -0,0 +1,101 @@ +#include + +static void init (void) __attribute__ ((constructor)); + +static void +init (void) +{ + write (STDOUT_FILENO, "init\n", 5); +} + +static void fini (void) __attribute__ ((destructor)); + +static void +fini (void) +{ + write (STDOUT_FILENO, "fini\n", 5); +} + +static void +preinit_0 (void) +{ + write (STDOUT_FILENO, "preinit array 0\n", 16); +} + +static void +preinit_1 (void) +{ + write (STDOUT_FILENO, "preinit array 1\n", 16); +} + +static void +preinit_2 (void) +{ + write (STDOUT_FILENO, "preinit array 2\n", 16); +} + +void +(*preinit_array []) (void) __attribute__ ((section (".preinit_array"))) = +{ + &preinit_0, + &preinit_1, + &preinit_2 +}; + +static void +init_0 (void) +{ + write (STDOUT_FILENO, "init array 0\n", 13); +} + +static void +init_1 (void) +{ + write (STDOUT_FILENO, "init array 1\n", 13); +} + +static void +init_2 (void) +{ + write (STDOUT_FILENO, "init array 2\n", 13); +} + +void +(*init_array []) (void) __attribute__ ((section (".init_array"))) = +{ + &init_0, + &init_1, + &init_2 +}; + +static void +fini_0 (void) +{ + write (STDOUT_FILENO, "fini array 0\n", 13); +} + +static void +fini_1 (void) +{ + write (STDOUT_FILENO, "fini array 1\n", 13); +} + +static void +fini_2 (void) +{ + write (STDOUT_FILENO, "fini array 2\n", 13); +} + +void +(*fini_array []) (void) __attribute__ ((section (".fini_array"))) = +{ + &fini_0, + &fini_1, + &fini_2 +}; + +int +main (void) +{ + return 0; +} Index: elf/tst-array1.exp =================================================================== RCS file: elf/tst-array1.exp diff -N elf/tst-array1.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ elf/elf/tst-array1.exp 29 Oct 2002 05:35:15 -0000 @@ -0,0 +1,11 @@ +preinit array 0 +preinit array 1 +preinit array 2 +init +init array 0 +init array 1 +init array 2 +fini array 2 +fini array 1 +fini array 0 +fini Index: elf/tst-array2.c =================================================================== RCS file: elf/tst-array2.c diff -N elf/tst-array2.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ elf/elf/tst-array2.c 29 Oct 2002 05:35:15 -0000 @@ -0,0 +1 @@ +#include "tst-array1.c" Index: elf/tst-array2.exp =================================================================== RCS file: elf/tst-array2.exp diff -N elf/tst-array2.exp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ elf/elf/tst-array2.exp 29 Oct 2002 05:35:15 -0000 @@ -0,0 +1,19 @@ +preinit array 0 +preinit array 1 +preinit array 2 +DSO init +DSO init array 0 +DSO init array 1 +DSO init array 2 +init +init array 0 +init array 1 +init array 2 +fini array 2 +fini array 1 +fini array 0 +fini +DSO fini array 2 +DSO fini array 1 +DSO fini array 0 +DSO fini Index: elf/tst-array2dep.c =================================================================== RCS file: elf/tst-array2dep.c diff -N elf/tst-array2dep.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ elf/elf/tst-array2dep.c 29 Oct 2002 05:35:15 -0000 @@ -0,0 +1,69 @@ +#include + +static void init (void) __attribute__ ((constructor)); + +static void +init (void) +{ + write (STDOUT_FILENO, "DSO init\n", 9); +} + +static void fini (void) __attribute__ ((destructor)); + +static void +fini (void) +{ + write (STDOUT_FILENO, "DSO fini\n", 9); +} + +static void +init_0 (void) +{ + write (STDOUT_FILENO, "DSO init array 0\n", 17); +} + +static void +init_1 (void) +{ + write (STDOUT_FILENO, "DSO init array 1\n", 17); +} + +static void +init_2 (void) +{ + write (STDOUT_FILENO, "DSO init array 2\n", 17); +} + +void +(*init_array []) (void) __attribute__ ((section (".init_array"))) = +{ + &init_0, + &init_1, + &init_2 +}; + +static void +fini_0 (void) +{ + write (STDOUT_FILENO, "DSO fini array 0\n", 17); +} + +static void +fini_1 (void) +{ + write (STDOUT_FILENO, "DSO fini array 1\n", 17); +} + +static void +fini_2 (void) +{ + write (STDOUT_FILENO, "DSO fini array 2\n", 17); +} + +void +(*fini_array []) (void) __attribute__ ((section (".fini_array"))) = +{ + &fini_0, + &fini_1, + &fini_2 +}; Index: elf/tst-array3.c =================================================================== RCS file: elf/tst-array3.c diff -N elf/tst-array3.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ elf/elf/tst-array3.c 29 Oct 2002 05:35:15 -0000 @@ -0,0 +1 @@ +#include "tst-array1.c" Index: sysdeps/generic/libc-start.c =================================================================== RCS file: /cvs/glibc/libc/sysdeps/generic/libc-start.c,v retrieving revision 1.33 diff -u -r1.33 libc-start.c --- sysdeps/generic/sysdeps/generic/libc-start.c 25 Oct 2002 19:41:24 -0000 1.33 +++ sysdeps/generic/sysdeps/generic/libc-start.c 29 Oct 2002 05:35:16 -0000 @@ -36,6 +36,16 @@ ; #endif +#ifdef HAVE_INITFINI_ARRAY +# ifdef SHARED +extern void __libc_init_array (void) __attribute__ ((weak)); +extern void __libc_fini_array (void) __attribute__ ((weak)); +# else +extern void __libc_preinit_array (void); +extern void __libc_init_array (void); +extern void __libc_fini_array (void); +# endif +#endif extern int BP_SYM (__libc_start_main) (int (*main) (int, char **, char **), int argc, @@ -115,6 +125,17 @@ if (fini) __cxa_atexit ((void (*) (void *)) fini, NULL, NULL); +#ifdef HAVE_INITFINI_ARRAY +# ifdef SHARED + if (__libc_fini_array) +# endif + __cxa_atexit ((void (*) (void *)) __libc_fini_array, NULL, NULL); + +# ifndef SHARED + __libc_preinit_array (); +# endif +#endif + /* Call the initializer of the program, if any. */ #ifdef SHARED if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) @@ -122,6 +143,13 @@ #endif if (init) (*init) (); + +#ifdef HAVE_INITFINI_ARRAY +# ifdef SHARED + if (__libc_init_array) +# endif + __libc_init_array (); +#endif #ifdef SHARED if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) From hjl@lucon.org Mon Oct 28 22:34:00 2002 From: hjl@lucon.org (H. J. Lu) Date: Mon, 28 Oct 2002 22:34:00 -0000 Subject: patch to make init_array work (2nd version) In-Reply-To: <15806.7806.501878.610194@napali.hpl.hp.com>; from davidm@napali.hpl.hp.com on Mon, Oct 28, 2002 at 09:37:02PM -0800 References: <15806.7806.501878.610194@napali.hpl.hp.com> Message-ID: <20021028222748.A17290@lucon.org> On Mon, Oct 28, 2002 at 09:37:02PM -0800, David Mosberger wrote: > My previous patch (adopted from HJ's work) was missing a change to > dl-fini.c which broke the handling of .fini_array. The patch below is > updated to fix that and "make check" now passes as expected (I must > have made a mistake previously as I thought it worked with the > previous patch already). > > If it looks OK, please apply. (Yes, I know both Uli and Roland are > out this week, but I'll likely be out next week...). > I am sorry if I didn't send out my latest patch. David, could you please check out the one enclosed here. Thanks. H.J. -------------- next part -------------- 2002-03-12 H.J. Lu * config.h.in (HAVE_INITFINI_ARRAY): New. * config.make.in (have-initfini-array): New. * configure.in: Check .preinit_array/.init_array/.fini_array support in ld. * configure: Rebuild. * csu/init.c (__libc_preinit_array): New. Define if HAVE_INITFINI_ARRAY is defined. (__libc_init_array): Likewise. (__libc_fini_array): Likewise. * elf/Makefile (tests): Add tst-array1, tst-array2 and tst-array3 if $(have-initfini-array) is yes. (tests-static): Add tst-array3 if $(have-initfini-array) is yes. (modules-names): Add tst-array2dep if $(have-initfini-array) is yes. ($(objpfx)tst-array1.out): New target. ($(objpfx)tst-array2): Likewise. ($(objpfx)tst-array2.out): Likewise. ($(objpfx)tst-array3.out): Likewise. * elf/dl-fini.c (_dl_fini): Fix calling the fini array. * elf/dl-init.c (_dl_init): Fix calling the preinit array. * elf/tst-array1.c: New file. * elf/tst-array1.exp: Likewise. * elf/tst-array2.c: Likewise. * elf/tst-array2dep.c: Likewise. * elf/tst-array2.exp: Likewise. * elf/tst-array3.c: Likewise. * sysdeps/generic/libc-start.c (__libc_start_main): Process __libc_preinit_array, __libc_init_array and __libc_fini_array if HAVE_INITFINI_ARRAY is defined. --- libc/config.h.in.array Mon Mar 11 23:26:51 2002 +++ libc/config.h.in Tue Mar 12 10:47:15 2002 @@ -96,6 +96,10 @@ certain registers (CR0, MQ, CTR, LR) in asm statements. */ #undef BROKEN_PPC_ASM_CR0 +/* Define if the linker supports .preinit_array/.init_array/.fini_array + sections. */ +#undef HAVE_INITFINI_ARRAY + /* Define if the linker supports the -z combreloc option. */ #undef HAVE_Z_COMBRELOC --- libc/config.make.in.array Tue Mar 12 10:24:37 2002 +++ libc/config.make.in Tue Mar 12 17:15:31 2002 @@ -36,6 +36,7 @@ sysincludes = @SYSINCLUDES@ all-warnings = @all_warnings@ elf = @elf@ +have-initfini-array = @libc_cv_initfinit_array@ have-protected = @libc_cv_asm_protected_directive@ have-z-nodelete = @libc_cv_z_nodelete@ have-z-nodlopen = @libc_cv_z_nodlopen@ --- libc/configure.in.array Tue Mar 12 10:24:38 2002 +++ libc/configure.in Tue Mar 12 17:14:36 2002 @@ -1050,6 +1050,36 @@ EOF fi fi + AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support, + libc_cv_initfinit_array, [dnl + cat > conftest.c <&AC_FD_CC]) + then + libc_cv_initfinit_array=yes + else + libc_cv_initfinit_array=no + fi + rm -f conftest*]) + AC_SUBST(libc_cv_initfinit_array) + if test $libc_cv_initfinit_array = yes; then + AC_DEFINE(HAVE_INITFINI_ARRAY) + fi + AC_CACHE_CHECK(for -z nodelete option, libc_cv_z_nodelete, [dnl cat > conftest.c <= 0; i--) + __fini_array_start [i] (); +} +#endif --- libc/elf/Makefile.array Tue Mar 12 10:24:37 2002 +++ libc/elf/Makefile Tue Mar 12 17:17:17 2002 @@ -120,6 +120,10 @@ tests = loadtest restest1 preloadtest lo neededtest3 neededtest4 unload2 lateglobal initfirst global \ restest2 next dblload dblunload reldep5 reldep6 tst-tls1 tst-tls2 \ tst-tls3 tst-tls4 tst-tls5 tst-tls6 tst-tls7 tst-tls8 +ifeq (yes,$(have-initfini-array)) +tests += tst-array1 tst-array2 tst-array3 +tests-static += tst-array3 +endif test-srcs = tst-pathopt tests-vis-yes = vismain tests-nodelete-yes = nodelete @@ -138,6 +142,9 @@ modules-names = testobj1 testobj2 testob dblloadmod1 dblloadmod2 dblloadmod3 reldepmod5 reldepmod6 \ reldep6mod0 reldep6mod1 reldep6mod2 reldep6mod3 reldep6mod4 \ tst-tlsmod1 tst-tlsmod2 tst-tlsmod3 tst-tlsmod4 +ifeq (yes,$(have-initfini-array)) +modules-names += tst-array2dep +endif modules-vis-yes = vismod1 vismod2 vismod3 modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4 modules-nodlopen-yes = nodlopenmod nodlopenmod2 @@ -466,3 +473,20 @@ $(objpfx)tst-tls7.out: $(objpfx)tst-tlsm $(objpfx)tst-tls8: $(libdl) $(objpfx)tst-tls8.out: $(objpfx)tst-tlsmod3.so $(objpfx)tst-tlsmod4.so + +$(objpfx)tst-array1.out: $(objpfx)tst-array1 + $(elf-objpfx)$(rtld-installed-name) \ + --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \ + $(objpfx)tst-array1 > $@ + cmp $@ tst-array1.exp > /dev/null + +$(objpfx)tst-array2: $(objpfx)tst-array2dep.so +$(objpfx)tst-array2.out: $(objpfx)tst-array2 + $(elf-objpfx)$(rtld-installed-name) \ + --library-path $(rpath-link)$(patsubst %,:%,$(sysdep-library-path)) \ + $(objpfx)tst-array2 > $@ + cmp $@ tst-array2.exp > /dev/null + +$(objpfx)tst-array3.out: $(objpfx)tst-array3 + $(objpfx)tst-array3 > $@ + cmp $@ tst-array1.exp > /dev/null --- libc/elf/dl-fini.c.array Fri Mar 1 22:57:50 2002 +++ libc/elf/dl-fini.c Tue Mar 12 12:21:27 2002 @@ -157,12 +157,11 @@ _dl_fini (void) ElfW(Addr) *array = (ElfW(Addr) *) (l->l_addr + l->l_info[DT_FINI_ARRAY]->d_un.d_ptr); - unsigned int sz = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val - / sizeof (ElfW(Addr))); - unsigned int cnt; + int cnt = (l->l_info[DT_FINI_ARRAYSZ]->d_un.d_val + / sizeof (ElfW(Addr))) - 1; - for (cnt = 0; cnt < sz; ++cnt) - ((fini_t) (l->l_addr + array[cnt])) (); + for (; cnt >= 0; --cnt) + ((fini_t) array[cnt]) (); } /* Next try the old-style destructor. */ --- libc/elf/dl-init.c.array Fri Mar 1 22:57:50 2002 +++ libc/elf/dl-init.c Tue Mar 12 12:00:47 2002 @@ -101,7 +101,8 @@ _dl_init (struct link_map *main_map, int /* Don't do anything if there is no preinit array. */ if (__builtin_expect (preinit_array != NULL, 0) - && (i = preinit_array->d_un.d_val / sizeof (ElfW(Addr))) > 0) + && (i = main_map->l_info[DT_PREINIT_ARRAYSZ]->d_un.d_val + / sizeof (ElfW(Addr))) > 0) { ElfW(Addr) *addrs; unsigned int cnt; @@ -111,7 +112,7 @@ _dl_init (struct link_map *main_map, int main_map->l_name[0] ? main_map->l_name : rtld_progname); - addrs = (ElfW(Addr) *) (main_map->l_info[DT_PREINIT_ARRAY]->d_un.d_ptr + addrs = (ElfW(Addr) *) (preinit_array->d_un.d_ptr + main_map->l_addr); for (cnt = 0; cnt < i; ++cnt) ((init_t) addrs[cnt]) (argc, argv, env); --- libc/elf/tst-array1.c.array Tue Mar 12 13:46:09 2002 +++ libc/elf/tst-array1.c Tue Mar 12 15:14:39 2002 @@ -0,0 +1,101 @@ +#include + +static void init (void) __attribute__ ((constructor)); + +static void +init (void) +{ + write (STDOUT_FILENO, "init\n", 5); +} + +static void fini (void) __attribute__ ((destructor)); + +static void +fini (void) +{ + write (STDOUT_FILENO, "fini\n", 5); +} + +static void +preinit_0 (void) +{ + write (STDOUT_FILENO, "preinit array 0\n", 16); +} + +static void +preinit_1 (void) +{ + write (STDOUT_FILENO, "preinit array 1\n", 16); +} + +static void +preinit_2 (void) +{ + write (STDOUT_FILENO, "preinit array 2\n", 16); +} + +void +(*preinit_array []) (void) __attribute__ ((section (".preinit_array"))) = +{ + &preinit_0, + &preinit_1, + &preinit_2 +}; + +static void +init_0 (void) +{ + write (STDOUT_FILENO, "init array 0\n", 13); +} + +static void +init_1 (void) +{ + write (STDOUT_FILENO, "init array 1\n", 13); +} + +static void +init_2 (void) +{ + write (STDOUT_FILENO, "init array 2\n", 13); +} + +void +(*init_array []) (void) __attribute__ ((section (".init_array"))) = +{ + &init_0, + &init_1, + &init_2 +}; + +static void +fini_0 (void) +{ + write (STDOUT_FILENO, "fini array 0\n", 13); +} + +static void +fini_1 (void) +{ + write (STDOUT_FILENO, "fini array 1\n", 13); +} + +static void +fini_2 (void) +{ + write (STDOUT_FILENO, "fini array 2\n", 13); +} + +void +(*fini_array []) (void) __attribute__ ((section (".fini_array"))) = +{ + &fini_0, + &fini_1, + &fini_2 +}; + +int +main (void) +{ + return 0; +} --- libc/elf/tst-array1.exp.array Tue Mar 12 14:50:24 2002 +++ libc/elf/tst-array1.exp Tue Mar 12 15:15:01 2002 @@ -0,0 +1,11 @@ +preinit array 0 +preinit array 1 +preinit array 2 +init +init array 0 +init array 1 +init array 2 +fini array 2 +fini array 1 +fini array 0 +fini --- libc/elf/tst-array2.c.array Tue Mar 12 15:01:13 2002 +++ libc/elf/tst-array2.c Tue Mar 12 15:23:44 2002 @@ -0,0 +1 @@ +#include "tst-array1.c" --- libc/elf/tst-array2.exp.array Tue Mar 12 15:01:19 2002 +++ libc/elf/tst-array2.exp Tue Mar 12 15:16:45 2002 @@ -0,0 +1,19 @@ +preinit array 0 +preinit array 1 +preinit array 2 +DSO init +DSO init array 0 +DSO init array 1 +DSO init array 2 +init +init array 0 +init array 1 +init array 2 +fini array 2 +fini array 1 +fini array 0 +fini +DSO fini array 2 +DSO fini array 1 +DSO fini array 0 +DSO fini --- libc/elf/tst-array2dep.c.array Tue Mar 12 15:05:39 2002 +++ libc/elf/tst-array2dep.c Tue Mar 12 15:16:20 2002 @@ -0,0 +1,69 @@ +#include + +static void init (void) __attribute__ ((constructor)); + +static void +init (void) +{ + write (STDOUT_FILENO, "DSO init\n", 9); +} + +static void fini (void) __attribute__ ((destructor)); + +static void +fini (void) +{ + write (STDOUT_FILENO, "DSO fini\n", 9); +} + +static void +init_0 (void) +{ + write (STDOUT_FILENO, "DSO init array 0\n", 17); +} + +static void +init_1 (void) +{ + write (STDOUT_FILENO, "DSO init array 1\n", 17); +} + +static void +init_2 (void) +{ + write (STDOUT_FILENO, "DSO init array 2\n", 17); +} + +void +(*init_array []) (void) __attribute__ ((section (".init_array"))) = +{ + &init_0, + &init_1, + &init_2 +}; + +static void +fini_0 (void) +{ + write (STDOUT_FILENO, "DSO fini array 0\n", 17); +} + +static void +fini_1 (void) +{ + write (STDOUT_FILENO, "DSO fini array 1\n", 17); +} + +static void +fini_2 (void) +{ + write (STDOUT_FILENO, "DSO fini array 2\n", 17); +} + +void +(*fini_array []) (void) __attribute__ ((section (".fini_array"))) = +{ + &fini_0, + &fini_1, + &fini_2 +}; --- libc/elf/tst-array3.c.array Tue Mar 12 15:25:15 2002 +++ libc/elf/tst-array3.c Tue Mar 12 15:25:05 2002 @@ -0,0 +1 @@ +#include "tst-array1.c" --- libc/sysdeps/generic/libc-start.c.array Mon Feb 4 13:45:13 2002 +++ libc/sysdeps/generic/libc-start.c Tue Mar 12 14:30:57 2002 @@ -33,6 +33,16 @@ extern void *__libc_stack_end; extern void __pthread_initialize_minimal (void) __attribute__ ((weak)); #endif +#ifdef HAVE_INITFINI_ARRAY +# ifdef SHARED +extern void __libc_init_array (void) __attribute__ ((weak)); +extern void __libc_fini_array (void) __attribute__ ((weak)); +# else +extern void __libc_preinit_array (void); +extern void __libc_init_array (void); +extern void __libc_fini_array (void); +# endif +#endif extern int BP_SYM (__libc_start_main) (int (*main) (int, char **, char **), int argc, @@ -113,6 +123,17 @@ BP_SYM (__libc_start_main) (int (*main) if (fini) __cxa_atexit ((void (*) (void *)) fini, NULL, NULL); +#ifdef HAVE_INITFINI_ARRAY +# ifdef SHARED + if (__libc_fini_array) +# endif + __cxa_atexit ((void (*) (void *)) __libc_fini_array, NULL, NULL); + +# ifndef SHARED + __libc_preinit_array (); +# endif +#endif + /* Call the initializer of the program, if any. */ #ifdef SHARED if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) @@ -121,6 +142,13 @@ BP_SYM (__libc_start_main) (int (*main) if (init) (*init) (); +#ifdef HAVE_INITFINI_ARRAY +# ifdef SHARED + if (__libc_init_array) +# endif + __libc_init_array (); +#endif + #ifdef SHARED if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0)) _dl_debug_printf ("\ntransferring control: %s\n\n", argv[0]); From davidm@napali.hpl.hp.com Tue Oct 29 07:41:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Tue, 29 Oct 2002 07:41:00 -0000 Subject: patch to make init_array work (2nd version) In-Reply-To: <20021028222748.A17290@lucon.org> References: <15806.7806.501878.610194@napali.hpl.hp.com> <20021028222748.A17290@lucon.org> Message-ID: <15806.11228.791882.880867@napali.hpl.hp.com> >>>>> On Mon, 28 Oct 2002 22:27:48 -0800, "H. J. Lu" said: HJ> I am sorry if I didn't send out my latest patch. David, could HJ> you please check out the one enclosed here. Your patch was fine, but it didn't apply cleanly on top of the current libc tree. During the merge, I somehow lost your changes to dl-fini.c. When adding those back, I renamed "cnt" to "i" (cnt didn't seem quite like the right name), hence the new ChangeLog entry. --david From jakub@redhat.com Tue Oct 29 23:22:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Tue, 29 Oct 2002 23:22:00 -0000 Subject: [PATCH] Fix compatibility sys_siglist and sys_sigabbrev Message-ID: <20021029164139.T3451@sunsite.ms.mff.cuni.cz> Hi! Since gcc started using .data.rel.ro.local and similar sections, sys_siglist@GLIBC_2.0 and sys_sigabbrev@GLIBC_2.0 are very broken - they point to some random object in .data section which happens to follow (in my build that is proc_file_chain_lock). The following patch should fix it (and as a bonus arm special siglist version can go away, since ASM_TYPE_DIRECTIVE_PREFIX configury takes care of it. 2002-10-29 Jakub Jelinek * sysdeps/gnu/siglist.c (PTR_SIZE_STR): Remove. (__old_sys_siglist, __old_sys_sigabbrev): Use strong_alias and declare_symbol. * sysdeps/mach/hurd/siglist.h (OLD_SIGLIST_SIZE_STR): Remove. (OLD_SIGLIST_SIZE): Define. * sysdeps/unix/sysv/linux/siglist.h (OLD_SIGLIST_SIZE_STR): Remove. (OLD_SIGLIST_SIZE): Define. * sysdeps/unix/sysv/linux/arm/siglist.c: Remove. --- libc/sysdeps/gnu/siglist.c.jj 2002-08-05 08:44:20.000000000 +0200 +++ libc/sysdeps/gnu/siglist.c 2002-10-29 15:30:52.000000000 +0100 @@ -21,20 +21,7 @@ #include #include #include - #include -#if __WORDSIZE == 32 -#define PTR_SIZE_STR "4" -#elif __WORDSIZE == 64 -#define PTR_SIZE_STR "8" -#else -#error unexpected wordsize __WORDSIZE -#endif - - -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -asm (".data\n\t.globl __old_sys_siglist\n__old_sys_siglist:"); -#endif const char *const __new_sys_siglist[NSIG] = { @@ -45,10 +32,8 @@ const char *const __new_sys_siglist[NSIG strong_alias (__new_sys_siglist, _sys_siglist_internal) #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -asm (".type __old_sys_siglist,@object\n\t.size __old_sys_siglist," - OLD_SIGLIST_SIZE_STR "*" PTR_SIZE_STR); - -asm (".data\n\t.globl __old_sys_sigabbrev\n__old_sys_sigabbrev:"); +strong_alias (_sys_siglist_internal, __old_sys_siglist) +declare_symbol (__old_sys_siglist, object, OLD_SIGLIST_SIZE * __WORDSIZE / 8) #endif const char *const __new_sys_sigabbrev[NSIG] = @@ -57,13 +42,11 @@ const char *const __new_sys_sigabbrev[NS #include #undef init_sig }; +strong_alias (__new_sys_sigabbrev, _sys_sigabbrev_internal) #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -asm (".type __old_sys_sigabbrev,@object\n\t.size __old_sys_sigabbrev," - OLD_SIGLIST_SIZE_STR "*" PTR_SIZE_STR); - -extern const char *const *__old_sys_siglist; -extern const char *const *__old_sys_sigabbrev; +strong_alias (_sys_sigabbrev_internal, __old_sys_sigabbrev) +declare_symbol (__old_sys_sigabbrev, object, OLD_SIGLIST_SIZE * __WORDSIZE / 8) strong_alias (__old_sys_siglist, _old_sys_siglist) compat_symbol (libc, __old_sys_siglist, _sys_siglist, GLIBC_2_0); --- libc/sysdeps/mach/hurd/siglist.h.jj 2001-08-23 18:50:05.000000000 +0200 +++ libc/sysdeps/mach/hurd/siglist.h 2002-10-29 15:26:35.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 1999 Free Software Foundation, Inc. +/* Copyright (C) 1999, 2002 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 @@ -20,4 +20,4 @@ #include_next /* Get the canonical list. */ -#define OLD_SIGLIST_SIZE_STR "33" /* For GLIBC_2.0 binary compatibility. */ +#define OLD_SIGLIST_SIZE 33 /* For GLIBC_2.0 binary compatibility. */ --- libc/sysdeps/unix/sysv/linux/arm/siglist.c.jj 2002-08-05 08:44:24.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/arm/siglist.c 2002-10-29 15:39:23.000000000 +0100 @@ -1,67 +0,0 @@ -/* Copyright (C) 1997, 1998, 2000, 2002 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 SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -asm (".data; .globl __old_sys_siglist; __old_sys_siglist:"); -#endif - -const char *const __new_sys_siglist[NSIG] = -{ -#define init_sig(sig, abbrev, desc) [sig] desc, -#include "siglist.h" -#undef init_sig -}; -strong_alias (__new_sys_siglist, _sys_siglist_internal) - -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -asm (".type __old_sys_siglist,%object;.size __old_sys_siglist," - OLD_SIGLIST_SIZE_STR "*" PTR_SIZE_STR); - -asm (".data; .globl __old_sys_sigabbrev; __old_sys_sigabbrev:"); -#endif - -const char *const __new_sys_sigabbrev[NSIG] = -{ -#define init_sig(sig, abbrev, desc) [sig] abbrev, -#include "siglist.h" -#undef init_sig -}; - -#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) -asm (".type __old_sys_sigabbrev,%object;.size __old_sys_sigabbrev," - OLD_SIGLIST_SIZE_STR "*" PTR_SIZE_STR); - -extern const char *const *__old_sys_siglist; -extern const char *const *__old_sys_sigabbrev; - -strong_alias (__old_sys_siglist, _old_sys_siglist) -compat_symbol (libc, __old_sys_siglist, _sys_siglist, GLIBC_2_0); -compat_symbol (libc, _old_sys_siglist, sys_siglist, GLIBC_2_0); -compat_symbol (libc, __old_sys_sigabbrev, sys_sigabbrev, GLIBC_2_0); -#endif - -strong_alias (__new_sys_siglist, _new_sys_siglist) -versioned_symbol (libc, __new_sys_siglist, _sys_siglist, GLIBC_2_1); -versioned_symbol (libc, _new_sys_siglist, sys_siglist, GLIBC_2_1); -versioned_symbol (libc, __new_sys_sigabbrev, sys_sigabbrev, GLIBC_2_1); --- libc/sysdeps/unix/sysv/linux/siglist.h.jj 2001-08-23 18:50:44.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/siglist.h 2002-10-29 15:27:02.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1998, 1999, 2002 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 @@ -20,4 +20,4 @@ #include_next /* Get the canonical list. */ -#define OLD_SIGLIST_SIZE_STR "32" /* For GLIBC_2.0 binary compatibility. */ +#define OLD_SIGLIST_SIZE 32 /* For GLIBC_2.0 binary compatibility. */ Jakub From davidm@napali.hpl.hp.com Wed Oct 30 07:00:00 2002 From: davidm@napali.hpl.hp.com (David Mosberger) Date: Wed, 30 Oct 2002 07:00:00 -0000 Subject: [PATCH] move __gmon_start__ call out of .init section Message-ID: <200210300722.g9U7MCXs000818@napali.hpl.hp.com> The patch below changes the ia64 initfini.c such that the call to __gmon_start__ is done via the .init_array section (if available). The idea here is to keep the .init/.fini empty (apart from prologue/epilogue) so as to ensure that the unwind info is always correct. Note: this patch should be applied _after_ HJ's init_array fixes as otherwise gmon startup would fail for profiled binaries. Thanks, --david 2002-10-29 David Mosberger * sysdeps/ia64/elf/initfini.c [HAVE_INITFINI_ARRAY] (gmon_initializer): New function. (.init prologue): If HAVE_INITFINI_ARRAY is true, don't call __gmon_start__ here. Call it from gmon_initializer() instead. Index: sysdeps/ia64/elf/initfini.c =================================================================== RCS file: /cvs/glibc/libc/sysdeps/ia64/elf/initfini.c,v retrieving revision 1.3 diff -u -r1.3 initfini.c --- sysdeps/ia64/elf/sysdeps/ia64/elf/initfini.c 25 Aug 2002 00:34:23 -0000 1.3 +++ sysdeps/ia64/elf/sysdeps/ia64/elf/initfini.c 30 Oct 2002 04:37:13 -0000 @@ -27,81 +27,110 @@ * crtn.s puts the corresponding function epilogues in the .init and .fini sections. */ -__asm__ ("\n\ -\n\ -#include \"defs.h\"\n\ -\n\ -/*@HEADER_ENDS*/\n\ -\n\ -/*@_init_PROLOG_BEGINS*/\n\ - .section .init\n\ - .align 16\n\ - .global _init#\n\ - .proc _init#\n\ -_init:\n\ - alloc r34 = ar.pfs, 0, 3, 0, 0\n\ - mov r32 = r12\n\ - mov r33 = b0\n\ - adds r12 = -16, r12\n\ - addl r14 = @ltoff(@fptr(__gmon_start__#)), gp\n\ - ;;\n\ - ld8 r15 = [r14]\n\ - ;;\n\ - cmp.eq p6, p7 = 0, r15\n\ - (p6) br.cond.dptk .L5\n\ -\n\ -/* we could use r35 to save gp, but we use the stack since that's what\n\ - * all the other init routines will do --davidm 00/04/05 */\n\ - st8 [r12] = gp, -16\n\ - br.call.sptk.many b0 = __gmon_start__# ;;\n\ - adds r12 = 16, r12\n\ - ;;\n\ - ld8 gp = [r12]\n\ - ;;\n\ -.L5:\n\ - .align 16\n\ - .endp _init#\n\ -\n\ -/*@_init_PROLOG_ENDS*/\n\ -\n\ -/*@_init_EPILOG_BEGINS*/\n\ - .section .init\n\ - .regstk 0,2,0,0\n\ - mov r12 = r32\n\ - mov ar.pfs = r34\n\ - mov b0 = r33\n\ - br.ret.sptk.many b0\n\ - .endp _init#\n\ -/*@_init_EPILOG_ENDS*/\n\ -\n\ -/*@_fini_PROLOG_BEGINS*/\n\ - .section .fini\n\ - .align 16\n\ - .global _fini#\n\ - .proc _fini#\n\ -_fini:\n\ - alloc r34 = ar.pfs, 0, 3, 0, 0\n\ - mov r32 = r12\n\ - mov r33 = b0\n\ - adds r12 = -16, r12\n\ - ;;\n\ - .align 16\n\ - .endp _fini#\n\ -\n\ -/*@_fini_PROLOG_ENDS*/\n\ - br.call.sptk.many b0 = i_am_not_a_leaf# ;;\n\ - ;;\n\ -\n\ -/*@_fini_EPILOG_BEGINS*/\n\ - .section .fini\n\ - mov r12 = r32\n\ - mov ar.pfs = r34\n\ - mov b0 = r33\n\ - br.ret.sptk.many b0\n\ - .endp _fini#\n\ -\n\ -/*@_fini_EPILOG_ENDS*/\n\ -\n\ -/*@TRAILER_BEGINS*/\n\ - .weak __gmon_start__#\n\ -"); +__asm__ ("\n\n" +"#include \"defs.h\"\n" +"\n" +"/*@HEADER_ENDS*/\n" +"\n" +"/*@_init_PROLOG_BEGINS*/\n"); + +#ifdef HAVE_INITFINI_ARRAY + +/* If we have working .init_array support, we want to keep the .init + section empty (apart from the mandatory prologue/epilogue. This + ensures that the default unwind conventions (return-pointer in b0, + frame state in ar.pfs, etc.) will do the Right Thing. To ensure + an empty .init section, we register gmon_initializer() via the + .init_array. + + --davidm 02/10/29 */ + +static void +gmon_initializer (void) +{ + extern void weak_function __gmon_start__ (void); + + if (__gmon_start__) + (*__gmon_start__)(); +} + +__asm__ (".section .init_array, \"aw\"\n" + "\tdata8 @fptr(gmon_initializer)\n"); + +#endif + +__asm__ (".section .init\n" +" .align 16\n" +" .global _init#\n" +" .proc _init#\n" +"_init:\n" +" alloc r34 = ar.pfs, 0, 3, 0, 0\n" +" mov r32 = r12\n" +" mov r33 = b0\n" +" adds r12 = -16, r12\n" +#ifdef HAVE_INITFINI_ARRAY + " ;;\n" /* see gmon_initializer() below */ +#else +" .weak __gmon_start__#\n" +" addl r14 = @ltoff(@fptr(__gmon_start__#)), gp\n" +" ;;\n" +" ld8 r15 = [r14]\n" +" ;;\n" +" cmp.eq p6, p7 = 0, r15\n" +" (p6) br.cond.dptk .L5\n" +"\n" +"/* we could use r35 to save gp, but we use the stack since that's what\n" +" * all the other init routines will do --davidm 00/04/05 */\n" +" st8 [r12] = gp, -16\n" +" br.call.sptk.many b0 = __gmon_start__# ;;\n" +" adds r12 = 16, r12\n" +" ;;\n" +" ld8 gp = [r12]\n" +" ;;\n" +".L5:\n" +#endif +" .align 16\n" +" .endp _init#\n" +"\n" +"/*@_init_PROLOG_ENDS*/\n" +"\n" +"/*@_init_EPILOG_BEGINS*/\n" +" .section .init\n" +" .regstk 0,2,0,0\n" +" mov r12 = r32\n" +" mov ar.pfs = r34\n" +" mov b0 = r33\n" +" br.ret.sptk.many b0\n" +" .endp _init#\n" +"/*@_init_EPILOG_ENDS*/\n" +"\n" +"/*@_fini_PROLOG_BEGINS*/\n" +" .section .fini\n" +" .align 16\n" +" .global _fini#\n" +" .proc _fini#\n" +"_fini:\n" +" alloc r34 = ar.pfs, 0, 3, 0, 0\n" +" mov r32 = r12\n" +" mov r33 = b0\n" +" adds r12 = -16, r12\n" +" ;;\n" +" .align 16\n" +" .endp _fini#\n" +"\n" +"/*@_fini_PROLOG_ENDS*/\n" +" br.call.sptk.many b0 = i_am_not_a_leaf# ;;\n" +" ;;\n" +"\n" +"/*@_fini_EPILOG_BEGINS*/\n" +" .section .fini\n" +" mov r12 = r32\n" +" mov ar.pfs = r34\n" +" mov b0 = r33\n" +" br.ret.sptk.many b0\n" +" .endp _fini#\n" +"\n" +"/*@_fini_EPILOG_ENDS*/\n" +"\n" +"/*@TRAILER_BEGINS*/\n" +); From jakub@redhat.com Wed Oct 30 07:56:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 30 Oct 2002 07:56:00 -0000 Subject: Regex memory management Message-ID: <20021030155931.W3451@sunsite.ms.mff.cuni.cz> Hi! I wonder whether it wouldn't be a win to switch to using obstacks for regex (one created by regcomp and destroyed in regfree, one created at start of regexec and destroyed when it is done searching). Looking at typical regex malloc/free patterns (just read bug-regex2.mtrace or bug-regex14.mtrace), it is something like ~ 40 mallocs followed by ~15 free calls (regcomp), then a couple of (~ 12 mallocs followed by ~ 7 frees of these; during first regexec) and then always a one or more mallocs followed by one or more frees for each remaining regexec. >From this, I think it could be a win to have 2 different obstacks, one permanent, inited at regcomp start, freed in regfree, the other would be temporary, inited at regcomp start and freed at regcomp end and inited at regexec start, freed at regexec end. The obstack_chunk_alloc routine would have to either longjmp to regcomp/regexec cleanup handler, or when glibc starts to use try/finally it could throw exception. The temporary allocation obstacks might even use alloca for the initial (say 2K) buffer - the only user of big malloc chunk seems to be build_trtable. Attached is just a patch which changes big temporary allocations in build_trtable from set of 5 malloc calls to 2 alloca calls and adds some ENOMEM handling. group_nodes_into_DFAstates can still leak if malloc returns NULL and I haven't checked other routines. 2002-10-30 Jakub Jelinek * posix/regexec.c (build_trtable): Alloca or malloc dests_node and dests_ch arrays together. Alloca or malloc dest_states, dest_states_word and dest_states_nl arrays together. Free memory on error exit. --- libc/posix/regexec.c.jj 2002-10-21 19:14:52.000000000 +0200 +++ libc/posix/regexec.c 2002-10-30 15:41:50.000000000 +0100 @@ -2469,8 +2469,10 @@ build_trtable (preg, state, fl_search) reg_errcode_t err; re_dfa_t *dfa = (re_dfa_t *) preg->buffer; int i, j, k, ch; + int dests_node_malloced = 0, dest_states_malloced = 0; int ndests; /* Number of the destination states from `state'. */ - re_dfastate_t **trtable, **dest_states, **dest_states_word, **dest_states_nl; + re_dfastate_t **trtable; + re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl; re_node_set follows, *dests_node; bitset *dests_ch; bitset acceptable; @@ -2479,34 +2481,76 @@ build_trtable (preg, state, fl_search) from `state'. `dests_node[i]' represents the nodes which i-th destination state contains, and `dests_ch[i]' represents the characters which i-th destination state accepts. */ - dests_node = re_malloc (re_node_set, SBC_MAX); - dests_ch = re_malloc (bitset, SBC_MAX); +#ifdef _LIBC + if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX)) + dests_node = (re_node_set *) + alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX); + else +#endif + { + dests_node = (re_node_set *) + malloc ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX); + if (BE (dests_node == NULL, 0)) + return NULL; + dests_node_malloced = 1; + } + dests_ch = (bitset *) (dests_node + SBC_MAX); /* Initialize transiton table. */ trtable = (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX); - if (BE (dests_node == NULL || dests_ch == NULL || trtable == NULL, 0)) - return NULL; + if (BE (trtable == NULL, 0)) + { + if (dests_node_malloced) + free (dests_node); + return NULL; + } /* At first, group all nodes belonging to `state' into several destinations. */ ndests = group_nodes_into_DFAstates (preg, state, dests_node, dests_ch); if (BE (ndests <= 0, 0)) { - re_free (dests_node); - re_free (dests_ch); + if (dests_node_malloced) + free (dests_node); /* Return NULL in case of an error, trtable otherwise. */ - return (ndests < 0) ? NULL : trtable; + if (ndests == 0) + return trtable; + free (trtable); + return NULL; } - dest_states = re_malloc (re_dfastate_t *, ndests); - dest_states_word = re_malloc (re_dfastate_t *, ndests); - dest_states_nl = re_malloc (re_dfastate_t *, ndests); - bitset_empty (acceptable); - err = re_node_set_alloc (&follows, ndests + 1); - if (BE (dest_states == NULL || dest_states_word == NULL - || dest_states_nl == NULL || err != REG_NOERROR, 0)) - return NULL; + if (BE (err != REG_NOERROR, 0)) + goto out_free; + +#ifdef _LIBC + if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset)) * SBC_MAX + + ndests * 3 * sizeof (re_dfastate_t *))) + dest_states = (re_dfastate_t **) + alloca (ndests * 3 * sizeof (re_dfastate_t *)); + else +#endif + { + dest_states = (re_dfastate_t **) + malloc (ndests * 3 * sizeof (re_dfastate_t *)); + if (BE (dest_states == NULL, 0)) + { +out_free: + if (dest_states_malloced) + free (dest_states); + re_node_set_free (&follows); + for (i = 0; i < ndests; ++i) + re_node_set_free (dests_node + i); + free (trtable); + if (dests_node_malloced) + free (dests_node); + return NULL; + } + dest_states_malloced = 1; + } + dest_states_word = dest_states + ndests; + dest_states_nl = dest_states_word + ndests; + bitset_empty (acceptable); /* Then build the states for all destinations. */ for (i = 0; i < ndests; ++i) @@ -2521,7 +2565,7 @@ build_trtable (preg, state, fl_search) { err = re_node_set_merge (&follows, dfa->eclosures + next_node); if (BE (err != REG_NOERROR, 0)) - return NULL; + goto out_free; } } /* If search flag is set, merge the initial state. */ @@ -2541,12 +2585,12 @@ build_trtable (preg, state, fl_search) err = re_node_set_merge (&follows, dfa->init_state->entrance_nodes); if (BE (err != REG_NOERROR, 0)) - return NULL; + goto out_free; } } dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0); if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0)) - return NULL; + goto out_free; /* If the new state has context constraint, build appropriate states for these contexts. */ if (dest_states[i]->has_constraint) @@ -2554,11 +2598,11 @@ build_trtable (preg, state, fl_search) dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows, CONTEXT_WORD); if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0)) - return NULL; + goto out_free; dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows, CONTEXT_NEWLINE); if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0)) - return NULL; + goto out_free; } else { @@ -2615,16 +2659,15 @@ build_trtable (preg, state, fl_search) } } - re_free (dest_states_nl); - re_free (dest_states_word); - re_free (dest_states); + if (dest_states_malloced) + free (dest_states); re_node_set_free (&follows); for (i = 0; i < ndests; ++i) re_node_set_free (dests_node + i); - re_free (dests_ch); - re_free (dests_node); + if (dests_node_malloced) + free (dests_node); return trtable; } Jakub From jakub@redhat.com Wed Oct 30 08:08:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 30 Oct 2002 08:08:00 -0000 Subject: [PATCH] Tiny bi-arch bits/syscall.h change Message-ID: <20021030165633.X3451@sunsite.ms.mff.cuni.cz> Hi! I noticed bits/syscall.h on x86-64 has all defines in __WORDSIZE == 64, ie. defines no 32-bit syscall. Fixed thusly. 32bit-predefine is not needed on other arches, since asm stubs use #if defined basearch && defined 64bitarch resp. #if defined basearch && !defined 64bitarch. 2002-10-30 Jakub Jelinek * sysdeps/unix/sysv/linux/Makefile (syscall-%.h): Add -D for each 32bit-predefine when creating .new32 list and -U for each 32bit-predefine when creating .new64 list. --- libc/sysdeps/unix/sysv/linux/x86_64/Makefile.jj 2002-10-16 23:22:16.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/x86_64/Makefile 2002-10-30 16:42:02.000000000 +0100 @@ -1,3 +1,4 @@ +32bit-predefine = __i386__ 64bit-predefine = __x86_64__ ifeq ($(subdir),misc) --- libc/sysdeps/unix/sysv/linux/Makefile.jj 2002-10-16 09:12:53.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/Makefile 2002-10-30 16:42:27.000000000 +0100 @@ -25,7 +25,7 @@ sysdep_headers += sys/mount.h sys/acct.h install-others += $(inst_includedir)/bits/syscall.h # Generate the list of SYS_* macros for the system calls (__NR_* macros). -# For bi-arch platforms, the CPU/Makefile defines 64bit-predefine and +# For bi-arch platforms, the CPU/Makefile defines {32,64}bit-predefine and # we generate a file that uses . $(objpfx)syscall-%.h $(objpfx)syscall-%.d: ../sysdeps/unix/sysv/linux/sys/syscall.h rm -f $(@:.h=.d)-t @@ -37,11 +37,13 @@ $(objpfx)syscall-%.h $(objpfx)syscall-%. echo '#endif'; \ echo ''; \ SUNPRO_DEPENDENCIES='$(@:.h=.d)-t $@' \ - $(CC) -E -x c $(sysincludes) $< $(addprefix -U,$(64bit-predefine)) -D_LIBC -dM | \ + $(CC) -E -x c $(sysincludes) $< $(addprefix -U,$(64bit-predefine)) \ + $(addprefix -D,$(32bit-predefine)) -D_LIBC -dM | \ sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \ LC_ALL=C sort > $(@:.d=.h).new32; \ SUNPRO_DEPENDENCIES='$(@:.h=.d)-t $@' \ - $(CC) -E -x c $(sysincludes) $< $(addprefix -D,$(64bit-predefine)) -D_LIBC -dM | \ + $(CC) -E -x c $(sysincludes) $< $(addprefix -U,$(64bit-predefine)) \ + $(addprefix -D,$(64bit-predefine)) -D_LIBC -dM | \ sed -n 's@^#define __NR_\([^ ]*\) .*$$@#define SYS_\1 __NR_\1@p' | \ LC_ALL=C sort > $(@:.d=.h).new64; \ if cmp -s $(@:.d=.h).new32 $(@:.d=.h).new64; then \ Jakub From jakub@redhat.com Wed Oct 30 08:45:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 30 Oct 2002 08:45:00 -0000 Subject: [PATCH] Avoid .text duplication in obstack.c Message-ID: <20021030170756.Y3451@sunsite.ms.mff.cuni.cz> Hi! It is not much, but anyway. 2002-10-30 Jakub Jelinek * malloc/obstack.c (obstack_free): Change into strong_alias instead of duplicating the whole function in libc. --- libc/malloc/obstack.c.jj 2002-08-05 08:44:17.000000000 +0200 +++ libc/malloc/obstack.c 2002-10-30 17:15:24.000000000 +0100 @@ -418,6 +418,10 @@ _obstack_free (h, obj) /* This function is used from ANSI code. */ +#ifdef _LIBC +strong_alias (_obstack_free, obstack_free) +#else + void obstack_free (h, obj) struct obstack *h; @@ -449,6 +453,7 @@ obstack_free (h, obj) /* obj is not in any of the chunks! */ abort (); } +#endif int _obstack_memory_used (h) Jakub From jakub@redhat.com Wed Oct 30 10:26:00 2002 From: jakub@redhat.com (Jakub Jelinek) Date: Wed, 30 Oct 2002 10:26:00 -0000 Subject: [PATCH] Optimize other free_mem handlers, some more .bss shrinking Message-ID: <20021030174455.Z3451@sunsite.ms.mff.cuni.cz> Hi! This patch is on top of the 2002-10-26 one, frees some more space from .bss and moves the remaining free_mem functions (together > ~ 2K on IA-32) to separate section. I'm afraid there is not much that can be done about inet_nsap_ntoa, since that function apparently is not assumed to ever fail, so we cannot use malloc which might fail. I've at least calculated properly the maximum size of the buffer. Still something might be done about utmp_file.c. Another saving in PF_W|PF_R segment can be had after fixing gcc (see the patch I posted yesterday). 2002-10-30 Jakub Jelinek * include/libc-symbols.h (__libc_freeres_fn_section, libc_freeres_fn): Define. * elf/dl-close.c (free_mem): Use libc_freeres_fn macro, remove text_set_element. * elf/dl-libc.c (free_mem): Likewise. * iconv/gconv_conf.c (free_mem): Likewise. * iconv/gconv_db.c (free_mem): Likewise. * iconv/gconv_dl.c (free_mem): Likewise. * iconv/gconv_cache.c (free_mem): Likewise. * intl/finddomain.c (free_mem): Likewise. * intl/dcigettext.c (free_mem): Likewise. * locale/setlocale.c (free_mem): Likewise. * misc/fstab.c (fstab_free): Likewise. * nss/nsswitch.c (free_mem): Likewise. * posix/regcomp.c (free_mem): Likewise. * resolv/gai_misc.c (free_res): Likewise. * stdlib/fmtmsg.c (free_mem): Likewise. * sunrpc/clnt_perr.c (free_mem): Likewise. * sysdeps/generic/setenv.c (free_mem): Likewise. * sysdeps/unix/sysv/linux/shm_open.c (freeit): Likewise. * sysdeps/pthread/aio_misc.c (free_res): Likewise. * time/tzset.c (free_mem): Likewise. * locale/loadarchive.c (_nl_archive_subfreeres): Add __libc_freeres_fn_section. * malloc/mtrace.c (release_libc_mem): Add __libc_freeres_fn_section. * malloc/set-freeres.c (__libc_freeres): Add __libc_freeres_fn_section. * login/getutent.c: Include stdlib.h instead of stddef.h. (buffer): Change into pointer to utmp, add libc_freeres_ptr. (__getutent): Allocate buffer the first time it is run. * login/getutid.c: Include stdlib.h instead of stddef.h. (buffer): Change into pointer to utmp, add libc_freeres_ptr. (__getutid): Allocate buffer the first time it is run. * login/getutline.c: Include stdlib.h instead of stddef.h. (buffer): Change into pointer to utmp, add libc_freeres_ptr. (__getutline): Allocate buffer the first time it is run. * malloc/mtrace.c (malloc_trace_buffer): Change into char *. (mtrace): Allocate malloc_trace_buffer. * resolv/nsap_addr.c (inet_nsap_ntoa): Decrease size of tmpbuf. * resolv/ns_print.c (ns_sprintrrf): Decrease size of t. * string/strerror.c: Include libintl.h and errno.h. (buf): New variable. (strerror): Only allocate buffer if actually needed (unknown error). * time/tzfile.c (transitions): Add libc_freeres_ptr. (freeres): Remove. --- libc/elf/dl-close.c.jj 2002-10-24 21:23:40.000000000 +0200 +++ libc/elf/dl-close.c 2002-10-29 12:14:17.000000000 +0100 @@ -424,8 +424,7 @@ free_slotinfo (struct dtv_slotinfo_list #endif -static void -free_mem (void) +libc_freeres_fn (free_mem) { if (__builtin_expect (GL(dl_global_scope_alloc), 0) != 0 && GL(dl_main_searchlist)->r_nlist == GL(dl_initial_searchlist).r_nlist) @@ -453,4 +452,3 @@ free_mem (void) GL(dl_tls_dtv_slotinfo_list)->next = NULL; #endif } -text_set_element (__libc_subfreeres, free_mem); --- libc/elf/dl-libc.c.jj 2002-04-14 22:11:33.000000000 +0200 +++ libc/elf/dl-libc.c 2002-10-29 12:14:40.000000000 +0100 @@ -123,8 +123,7 @@ __libc_dlclose (void *__map) } -static void -free_mem (void) +libc_freeres_fn (free_mem) { struct link_map *l; struct r_search_path_elem *d; @@ -154,4 +153,3 @@ free_mem (void) } } } -text_set_element (__libc_subfreeres, free_mem); --- libc/iconv/gconv_conf.c.jj 2002-03-23 11:50:26.000000000 +0100 +++ libc/iconv/gconv_conf.c 2002-10-29 12:17:42.000000000 +0100 @@ -597,11 +597,8 @@ __gconv_read_conf (void) /* Free all resources if necessary. */ -static void __attribute__ ((unused)) -free_mem (void) +libc_freeres_fn (free_mem) { if (__gconv_path_elem != NULL && __gconv_path_elem != &empty_path_elem) free ((void *) __gconv_path_elem); } - -text_set_element (__libc_subfreeres, free_mem); --- libc/iconv/gconv_db.c.jj 2002-08-05 08:44:15.000000000 +0200 +++ libc/iconv/gconv_db.c 2002-10-29 12:18:06.000000000 +0100 @@ -778,8 +778,7 @@ free_modules_db (struct gconv_module *no /* Free all resources if necessary. */ -static void __attribute__ ((unused)) -free_mem (void) +libc_freeres_fn (free_mem) { if (__gconv_alias_db != NULL) __tdestroy (__gconv_alias_db, free); @@ -790,5 +789,3 @@ free_mem (void) if (known_derivations != NULL) __tdestroy (known_derivations, free_derivation); } - -text_set_element (__libc_subfreeres, free_mem); --- libc/iconv/gconv_dl.c.jj 2001-08-04 20:20:57.000000000 +0200 +++ libc/iconv/gconv_dl.c 2002-10-29 12:18:27.000000000 +0100 @@ -203,12 +203,10 @@ do_release_all (void *nodep) free (obj); } -static void __attribute__ ((unused)) -free_mem (void) +libc_freeres_fn (free_mem) { __tdestroy (loaded, do_release_all); } -text_set_element (__libc_subfreeres, free_mem); #ifdef DEBUG --- libc/iconv/gconv_cache.c.jj 2002-08-27 23:19:41.000000000 +0200 +++ libc/iconv/gconv_cache.c 2002-10-29 12:18:52.000000000 +0100 @@ -445,8 +445,7 @@ __gconv_release_cache (struct __gconv_st /* Free all resources if necessary. */ -static void __attribute__ ((unused)) -free_mem (void) +libc_freeres_fn (free_mem) { if (cache_malloced) free (gconv_cache); @@ -455,5 +454,3 @@ free_mem (void) __munmap (gconv_cache, cache_size); #endif } - -text_set_element (__libc_subfreeres, free_mem); --- libc/include/libc-symbols.h.jj 2002-10-25 23:49:37.000000000 +0200 +++ libc/include/libc-symbols.h 2002-10-29 12:24:26.000000000 +0100 @@ -265,6 +265,8 @@ # define libc_freeres_ptr(decl) \ __make_section_unallocated ("__libc_freeres_ptrs, \"aw\", @nobits") \ decl __attribute__ ((section ("__libc_freeres_ptrs" __sec_comment))) +# define __libc_freeres_fn_section \ + __attribute__ ((section ("__libc_freeres_fn"))) # else /* Not ELF: a.out */ # ifdef HAVE_XCOFF /* XCOFF does not support .stabs. @@ -278,12 +280,18 @@ ".stabs \"" __SYMBOL_PREFIX #symbol "\",1,0,0,0\n"); # endif /* XCOFF */ # define libc_freeres_ptr(decl) decl +# define __libc_freeres_fn_section # endif #else /* We will never be heard; they will all die horribly. */ # define link_warning(symbol, msg) # define libc_freeres_ptr(decl) decl +# define __libc_freeres_fn_section #endif +#define libc_freeres_fn(name) \ + static void name (void) __attribute_used__ __libc_freeres_fn_section; \ + text_set_element (__libc_subfreeres, name); \ + static void name (void) /* A canned warning for sysdeps/stub functions. */ #define stub_warning(name) \ --- libc/intl/finddomain.c.jj 2002-07-29 15:14:51.000000000 +0200 +++ libc/intl/finddomain.c 2002-10-29 12:20:06.000000000 +0100 @@ -168,8 +168,7 @@ _nl_find_domain (dirname, locale, domain #ifdef _LIBC -static void __attribute__ ((unused)) -free_mem (void) +libc_freeres_fn (free_mem) { struct loaded_l10nfile *runp = _nl_loaded_domains; @@ -183,6 +182,4 @@ free_mem (void) free (here); } } - -text_set_element (__libc_subfreeres, free_mem); #endif --- libc/intl/dcigettext.c.jj 2002-09-24 13:00:06.000000000 +0200 +++ libc/intl/dcigettext.c 2002-10-29 12:20:29.000000000 +0100 @@ -1124,8 +1124,7 @@ mempcpy (dest, src, n) #ifdef _LIBC /* If we want to free all resources we have to do some work at program's end. */ -static void __attribute__ ((unused)) -free_mem (void) +libc_freeres_fn (free_mem) { void *old; @@ -1155,6 +1154,4 @@ free_mem (void) free (old); } } - -text_set_element (__libc_subfreeres, free_mem); #endif --- libc/locale/setlocale.c.jj 2002-09-01 09:34:28.000000000 +0200 +++ libc/locale/setlocale.c 2002-10-29 12:20:55.000000000 +0100 @@ -463,8 +463,7 @@ free_category (int category, } } -static void __attribute__ ((unused)) -free_mem (void) +libc_freeres_fn (free_mem) { #ifdef NL_CURRENT_INDIRECT /* We don't use the loop because we want to have individual weak @@ -494,4 +493,3 @@ free_mem (void) not called _nl_unload_locale on them above. */ _nl_archive_subfreeres (); } -text_set_element (__libc_subfreeres, free_mem); --- libc/locale/loadarchive.c.jj 2002-09-01 15:33:18.000000000 +0200 +++ libc/locale/loadarchive.c 2002-10-29 12:25:28.000000000 +0100 @@ -493,7 +493,7 @@ _nl_load_locale_from_archive (int catego return lia->data[category]; } -void +void __libc_freeres_fn_section _nl_archive_subfreeres (void) { struct locale_in_archive *lia; --- libc/login/getutent.c.jj 2001-08-23 18:48:16.000000000 +0200 +++ libc/login/getutent.c 2002-10-29 16:24:04.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1998, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1998, 2001, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -17,12 +17,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include /* For NULL. */ +#include #include /* Local buffer to store the result. */ -static struct utmp buffer; +libc_freeres_ptr (static struct utmp *buffer); struct utmp * @@ -30,7 +30,14 @@ __getutent (void) { struct utmp *result; - if (__getutent_r (&buffer, &result) < 0) + if (buffer == NULL) + { + buffer = (struct utmp *) malloc (sizeof (struct utmp)); + if (buffer == NULL) + return NULL; + } + + if (__getutent_r (buffer, &result) < 0) return NULL; return result; --- libc/login/getutid.c.jj 2001-08-23 18:48:16.000000000 +0200 +++ libc/login/getutid.c 2002-10-29 16:24:20.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1998, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1998, 2001, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -17,20 +17,25 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include /* For NULL. */ +#include #include /* Local buffer to store the result. */ -static struct utmp buffer; - +libc_freeres_ptr (static struct utmp *buffer); struct utmp * __getutid (const struct utmp *id) { struct utmp *result; - if (__getutid_r (id, &buffer, &result) < 0) + if (buffer == NULL) + { + buffer = (struct utmp *) malloc (sizeof (struct utmp)); + if (buffer == NULL) + return NULL; + } + if (__getutid_r (id, buffer, &result) < 0) return NULL; return result; --- libc/login/getutline.c.jj 2001-08-23 18:48:16.000000000 +0200 +++ libc/login/getutline.c 2002-10-29 16:40:18.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 1996, 1997, 1998, 2001 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1998, 2001, 2002 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. @@ -17,12 +17,12 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include /* For NULL. */ +#include #include /* Local buffer to store the result. */ -static struct utmp buffer; +libc_freeres_ptr (static struct utmp *buffer); struct utmp * @@ -30,7 +30,13 @@ __getutline (const struct utmp *line) { struct utmp *result; - if (__getutline_r (line, &buffer, &result) < 0) + if (buffer == NULL) + { + buffer = (struct utmp *) malloc (sizeof (struct utmp)); + if (buffer == NULL) + return NULL; + } + if (__getutline_r (line, buffer, &result) < 0) return NULL; return result; --- libc/malloc/mtrace.c.jj 2002-08-05 08:44:17.000000000 +0200 +++ libc/malloc/mtrace.c 2002-10-29 14:36:40.000000000 +0100 @@ -50,7 +50,7 @@ static FILE *mallstream; static const char mallenv[]= "MALLOC_TRACE"; -static char malloc_trace_buffer[TRACE_BUFFER_SIZE]; +static char *malloc_trace_buffer; __libc_lock_define_initialized (static, lock); @@ -237,7 +237,7 @@ tr_reallochook (ptr, size, caller) /* This function gets called to make sure all memory the library allocates get freed and so does not irritate the user when studying the mtrace output. */ -static void +static void __libc_freeres_fn_section release_libc_mem (void) { /* Only call the free function if we still are running in mtrace mode. */ @@ -274,6 +274,10 @@ mtrace () #endif if (mallfile != NULL || mallwatch != NULL) { + char *mtb = malloc (TRACE_BUFFER_SIZE); + if (mtb == NULL) + return; + mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "w"); if (mallstream != NULL) { @@ -285,6 +289,7 @@ mtrace () __fcntl (fileno (mallstream), F_SETFD, flags); } /* Be sure it doesn't malloc its buffer! */ + malloc_trace_buffer = mtb; setvbuf (mallstream, malloc_trace_buffer, _IOFBF, TRACE_BUFFER_SIZE); fprintf (mallstream, "= Start\n"); tr_old_free_hook = __free_hook; @@ -303,6 +308,8 @@ mtrace () } #endif } + else + free (mtb); } } --- libc/malloc/set-freeres.c.jj 2002-10-26 02:36:52.000000000 +0200 +++ libc/malloc/set-freeres.c 2002-10-29 12:27:17.000000000 +0100 @@ -29,7 +29,7 @@ DEFINE_HOOK (__libc_subfreeres, (void)); symbol_set_define (__libc_freeres_ptrs); -void +void __libc_freeres_fn_section __libc_freeres (void) { /* This function might be called from different places. So better --- libc/misc/fstab.c.jj 2001-08-23 18:48:30.000000000 +0200 +++ libc/misc/fstab.c 2002-10-29 12:29:59.000000000 +0100 @@ -180,9 +180,7 @@ fstab_convert (struct fstab_state *state /* Make sure the memory is freed if the programs ends while in memory-debugging mode and something actually was allocated. */ -static void -__attribute__ ((unused)) -fstab_free (void) +libc_freeres_fn (fstab_free) { char *buffer; @@ -190,5 +188,3 @@ fstab_free (void) if (buffer != NULL) free ((void *) buffer); } - -text_set_element (__libc_subfreeres, fstab_free); --- libc/nss/nsswitch.c.jj 2002-08-03 11:09:32.000000000 +0200 +++ libc/nss/nsswitch.c 2002-10-29 12:31:35.000000000 +0100 @@ -697,8 +697,7 @@ nss_new_service (name_database *database /* Free all resources if necessary. */ -static void __attribute__ ((unused)) -free_mem (void) +libc_freeres_fn (free_mem) { name_database *top = service_table; name_database_entry *entry; @@ -745,5 +744,3 @@ free_mem (void) free (top); } - -text_set_element (__libc_subfreeres, free_mem); --- libc/posix/regcomp.c.jj 2002-10-25 12:34:18.000000000 +0200 +++ libc/posix/regcomp.c 2002-10-29 12:33:06.000000000 +0100 @@ -696,12 +696,10 @@ re_comp (s) } #ifdef _LIBC -static void __attribute__ ((unused)) -free_mem (void) +libc_freeres_fn (free_mem) { __regfree (&re_comp_buf); } -text_set_element (__libc_subfreeres, free_mem); #endif #endif /* _REGEX_RE_COMP */ --- libc/resolv/gai_misc.c.jj 2001-08-23 18:49:01.000000000 +0200 +++ libc/resolv/gai_misc.c 2002-10-29 12:33:37.000000000 +0100 @@ -410,9 +410,7 @@ handle_requests (void *arg) /* Free allocated resources. */ -static void -__attribute__ ((unused)) -free_res (void) +libc_freeres_fn (free_res) { size_t row; @@ -421,4 +419,3 @@ free_res (void) free (pool); } -text_set_element (__libc_subfreeres, free_res); --- libc/resolv/nsap_addr.c.jj 2000-07-27 15:59:40.000000000 +0200 +++ libc/resolv/nsap_addr.c 2002-10-29 14:27:32.000000000 +0100 @@ -70,7 +70,7 @@ char * inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii) { int nib; int i; - static char tmpbuf[255*3]; + static char tmpbuf[255*2 + 128]; char *start; if (ascii) --- libc/resolv/ns_print.c.jj 2000-07-27 15:59:40.000000000 +0200 +++ libc/resolv/ns_print.c 2002-10-29 14:30:06.000000000 +0100 @@ -309,7 +309,9 @@ ns_sprintrrf(const u_char *msg, size_t m break; case ns_t_nsap: { - char t[255*3]; + /* 2*255 for hex digits, 128 for '.' and '\0', 2 for + 0x if inet_nsap_ntoa starts using it. */ + char t[255*2 + 128 + 2]; (void) inet_nsap_ntoa(rdlen, rdata, t); T(addstr(t, strlen(t), &buf, &buflen)); --- libc/stdlib/fmtmsg.c.jj 2002-08-28 12:58:10.000000000 +0200 +++ libc/stdlib/fmtmsg.c 2002-10-29 12:34:07.000000000 +0100 @@ -390,8 +390,7 @@ addseverity (int severity, const char *s } -static void __attribute__ ((unused)) -free_mem (void) +libc_freeres_fn (free_mem) { struct severity_info *runp = severity_list; @@ -407,4 +406,3 @@ free_mem (void) else runp = runp->next; } -text_set_element (__libc_subfreeres, free_mem); --- libc/string/strerror.c.jj 2001-08-21 22:30:38.000000000 +0200 +++ libc/string/strerror.c 2002-10-29 14:55:05.000000000 +0100 @@ -1,4 +1,4 @@ -/* Copyright (C) 1991, 93, 94, 95, 96, 98 Free Software Foundation, Inc. +/* Copyright (C) 1991, 93, 94, 95, 96, 98, 2002 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 @@ -16,16 +16,30 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include #include #include +#include /* Return a string describing the errno code in ERRNUM. The storage is good only until the next call to strerror. Writing to the storage causes undefined behavior. */ +libc_freeres_ptr (static char *buf); + char * strerror (errnum) int errnum; { - static char buf[1024]; - return __strerror_r (errnum, buf, sizeof buf); + char *ret = __strerror_r (errnum, NULL, 0); + int saved_errno; + + if (__builtin_expect (ret != NULL, 1)) + return ret; + saved_errno = errno; + if (buf == NULL) + buf = malloc (1024); + __set_errno (saved_errno); + if (buf == NULL) + return _("Unknown error"); + return __strerror_r (errnum, buf, 1024); } --- libc/sunrpc/clnt_perr.c.jj 2002-08-06 10:15:16.000000000 +0200 +++ libc/sunrpc/clnt_perr.c 2002-10-29 12:35:44.000000000 +0100 @@ -413,9 +413,8 @@ auth_errmsg (enum auth_stat stat) } -static void __attribute__ ((unused)) -free_mem (void) +libc_freeres_fn (free_mem) { + /* Not libc_freeres_ptr, since buf is a macro. */ free (buf); } -text_set_element (__libc_subfreeres, free_mem); --- libc/sysdeps/generic/setenv.c.jj 2001-08-23 18:49:35.000000000 +0200 +++ libc/sysdeps/generic/setenv.c 2002-10-29 12:44:26.000000000 +0100 @@ -323,8 +323,7 @@ clearenv () return 0; } #ifdef _LIBC -static void -free_mem (void) +libc_freeres_fn (free_mem) { /* Remove all traces. */ clearenv (); @@ -333,8 +332,6 @@ free_mem (void) __tdestroy (known_values, free); known_values = NULL; } -text_set_element (__libc_subfreeres, free_mem); - # undef setenv # undef unsetenv --- libc/sysdeps/unix/sysv/linux/shm_open.c.jj 2002-09-09 13:08:14.000000000 +0200 +++ libc/sysdeps/unix/sysv/linux/shm_open.c 2002-10-29 12:45:13.000000000 +0100 @@ -226,14 +226,10 @@ shm_unlink (const char *name) } -static void __attribute__ ((unused)) -freeit (void) +/* Make sure the table is freed if we want to free everything before + exiting. */ +libc_freeres_fn (freeit) { if (mountpoint.dir != defaultdir) free (mountpoint.dir); } - - -/* Make sure the table is freed if we want to free everything before - exiting. */ -text_set_element (__libc_subfreeres, freeit); --- libc/sysdeps/pthread/aio_misc.c.jj 2001-08-23 18:50:16.000000000 +0200 +++ libc/sysdeps/pthread/aio_misc.c 2002-10-29 12:45:41.000000000 +0100 @@ -665,9 +665,7 @@ handle_fildes_io (void *arg) /* Free allocated resources. */ -static void -__attribute__ ((unused)) -free_res (void) +libc_freeres_fn (free_res) { size_t row; @@ -676,7 +674,6 @@ free_res (void) free (pool); } -text_set_element (__libc_subfreeres, free_res); /* Add newrequest to the runlist. The __abs_prio flag of newrequest must --- libc/time/tzfile.c.jj 2001-08-23 18:51:42.000000000 +0200 +++ libc/time/tzfile.c 2002-10-29 12:46:49.000000000 +0100 @@ -49,7 +49,7 @@ static struct ttinfo *find_transition (t static void compute_tzname_max (size_t) internal_function; static size_t num_transitions; -static time_t *transitions; +libc_freeres_ptr (static time_t *transitions); static unsigned char *type_idxs; static size_t num_types; static struct ttinfo *types; @@ -553,14 +553,3 @@ compute_tzname_max (size_t chars) } while (++p < &zone_names[chars]); } - -/* This function is only called when we are checking for memory leaks. */ -static void -freeres (void) -{ - if (transitions != NULL) - free ((void *) transitions); -} - -/* Make sure all allocated data is freed before exiting. */ -text_set_element (__libc_subfreeres, freeres); --- libc/time/tzset.c.jj 2002-03-23 11:52:56.000000000 +0100 +++ libc/time/tzset.c 2002-10-29 12:47:12.000000000 +0100 @@ -624,8 +624,7 @@ __tz_convert (const time_t *timer, int u } -static void -free_mem (void) +libc_freeres_fn (free_mem) { while (tzstring_list != NULL) { @@ -637,4 +636,3 @@ free_mem (void) free (old_tz); old_tz = NULL; } -text_set_element (__libc_subfreeres, free_mem); Jakub From aj@suse.de Thu Oct 31 11:50:00 2002 From: aj@suse.de (Andreas Jaeger) Date: Thu, 31 Oct 2002 11:50:00 -0000 Subject: [PATCH] Tiny bi-arch bits/syscall.h change In-Reply-To: <20021030165633.X3451@sunsite.ms.mff.cuni.cz> (Jakub Jelinek's message of "Wed, 30 Oct 2002 16:56:33 +0100") References: <20021030165633.X3451@sunsite.ms.mff.cuni.cz> Message-ID: Jakub Jelinek writes: > Hi! > > I noticed bits/syscall.h on x86-64 has all defines in __WORDSIZE > == 64, ie. defines no 32-bit syscall. > Fixed thusly. 32bit-predefine is not needed > on other arches, since asm stubs use #if defined basearch && defined 64bitarch > resp. #if defined basearch && !defined 64bitarch. > > 2002-10-30 Jakub Jelinek > > * sysdeps/unix/sysv/linux/Makefile (syscall-%.h): Add -D for each > 32bit-predefine when creating .new32 list and -U for each > 32bit-predefine when creating .new64 list. > > --- libc/sysdeps/unix/sysv/linux/x86_64/Makefile.jj 2002-10-16 23:22:16.000000000 +0200 > +++ libc/sysdeps/unix/sysv/linux/x86_64/Makefile 2002-10-30 16:42:02.000000000 +0100 > @@ -1,3 +1,4 @@ > +32bit-predefine = __i386__ > 64bit-predefine = __x86_64__ Thanks, committed with ChangeLog mentioning the above change, Andreas -- Andreas Jaeger SuSE Labs aj@suse.de private aj@arthur.inka.de http://www.suse.de/~aj From jes@trained-monkey.org Thu Oct 31 11:57:00 2002 From: jes@trained-monkey.org (Jes Sorensen) Date: Thu, 31 Oct 2002 11:57:00 -0000 Subject: 2.2.x mips signal crash Message-ID: <200210311950.g9VJoST18983@trained-monkey.org> Hi We are chasing a problem on Linux/mips with glibc-2.2.x, which I am not sure whether is a kernel bug or a libc bug. We haven't been able to reproduce it under Linux/x86 or Linux/ia64 so far though. Basically what seems to be happening is the following, a task is spawned from fork(), the child sends some signals to the parent after which it exits. The parent exits before the signals arrives and a signal is delivered some time after reaching exit(). As the signal handler is using printf() we get an explosion since the file descriptor seems to be gone (munmap()). My question is as follows: Is one required to wait for signal delivery in the parent before exiting or unregister the signal handlers? or is it a genuine bug? Any suggestions? Thanks, Jes The backtrace I get looks like this: Program received signal SIGSEGV, Segmentation fault. _wordcopy_fwd_aligned (dstp=715816944, srcp=2147439180, len=8) at ../sysdeps/generic/wordcopy.c:110 110 ((op_t *) dstp)[4] = a1; (gdb) bt #0 _wordcopy_fwd_aligned (dstp=715816944, srcp=2147439180, len=8) at ../sysdeps/generic/wordcopy.c:110 #1 0x0043416c in __mempcpy (dstpp=0x2aaa7ff0, srcpp=0x7fff524c, len=22) at ../sysdeps/generic/mempcpy.c:57 #2 0x004309e4 in _IO_new_file_xsputn (f=0x10001070, data=0x7fff524c, n=22) at fileops.c:941 #3 0x00419b20 in buffered_vfprintf (s=0x10001070, format=0x7fff524c "", args=0x8) at vfprintf.c:2104 #4 0x0041362c in _IO_vfprintf (s=0x10001070, format=0x475584 "pid=%d usr2handler\n", ap=0x7fff792c) at vfprintf.c:1272 #5 0x00400aa0 in printf (format=0x7fff524c "") at printf.c:33 #6 0x00400528 in usr2handler () #7 #8 0x00409ee4 in munmap () #9 0x00431d98 in _IO_setb (f=0x10001070, b=0x100010b7 "", eb=0x100010b8 "\020", a=Cannot access memory at address 0x0 ) at genops.c:388 #10 0x00432308 in _IO_default_setbuf (fp=Cannot access memory at address 0x0 ) at genops.c:548 #11 0x0042f690 in _IO_new_file_setbuf (fp=Cannot access memory at address 0x0 ) at fileops.c:417 #12 0x00432fac in _IO_unbuffer_write () at genops.c:904 #13 0x00433038 in _IO_cleanup () at genops.c:924 #14 0x00401490 in exit (status=Cannot access memory at address 0x0 ) at exit.c:74 #15 0x00400c94 in __libc_start_main (main=Cannot access memory at address 0x0 ) at ../sysdeps/generic/libc-start.c:129 From hjl@lucon.org Thu Oct 31 18:44:00 2002 From: hjl@lucon.org (H. J. Lu) Date: Thu, 31 Oct 2002 18:44:00 -0000 Subject: 2.2.x mips signal crash In-Reply-To: <200210311950.g9VJoST18983@trained-monkey.org>; from jes@trained-monkey.org on Thu, Oct 31, 2002 at 02:50:28PM -0500 References: <200210311950.g9VJoST18983@trained-monkey.org> Message-ID: <20021031115701.A20971@lucon.org> On Thu, Oct 31, 2002 at 02:50:28PM -0500, Jes Sorensen wrote: > Hi > > We are chasing a problem on Linux/mips with glibc-2.2.x, which I am not > sure whether is a kernel bug or a libc bug. We haven't been able to > reproduce it under Linux/x86 or Linux/ia64 so far though. > > Basically what seems to be happening is the following, a task is > spawned from fork(), the child sends some signals to the parent after > which it exits. > > The parent exits before the signals arrives and a signal is delivered > some time after reaching exit(). As the signal handler is using > printf() we get an explosion since the file descriptor seems to be > gone (munmap()). > > My question is as follows: Is one required to wait for signal delivery > in the parent before exiting or unregister the signal handlers? or is > it a genuine bug? > > Any suggestions? > A testcase? H.J.