Push out misc fixes and include new hardened/hppa work.
authorMike Frysinger <vapier@gentoo.org>
Tue, 13 Mar 2007 06:09:44 +0000 (06:09 +0000)
committerMike Frysinger <vapier@gentoo.org>
Tue, 13 Mar 2007 06:09:44 +0000 (06:09 +0000)
Package-Manager: portage-2.1.2.2

sys-libs/glibc/ChangeLog
sys-libs/glibc/Manifest
sys-libs/glibc/files/2.5/glibc-2.5-gentoo-stack_chk_fail.c [new file with mode: 0644]
sys-libs/glibc/files/2.5/glibc-2.5-hardened-configure-picdefault.patch [new file with mode: 0644]
sys-libs/glibc/files/2.5/glibc-2.5-hardened-inittls-nosysenter.patch [new file with mode: 0644]
sys-libs/glibc/files/2.5/glibc-2.5-hardened-pie.patch [new file with mode: 0644]
sys-libs/glibc/files/digest-glibc-2.5-r1 [new file with mode: 0644]
sys-libs/glibc/glibc-2.5-r1.ebuild [new file with mode: 0644]

index 4cc44f520eba531356273c4949c06592412e2806..33d27fe7619b9b04e671da748b62c8d959caf7cb 100644 (file)
@@ -1,6 +1,15 @@
 # ChangeLog for sys-libs/glibc
 # Copyright 1999-2007 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/ChangeLog,v 1.505 2007/02/25 19:52:18 kumba Exp $
+# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/ChangeLog,v 1.506 2007/03/13 06:09:44 vapier Exp $
+
+*glibc-2.5-r1 (13 Mar 2007)
+
+  13 Mar 2007; Mike Frysinger <vapier@gentoo.org>
+  +files/2.5/glibc-2.5-gentoo-stack_chk_fail.c,
+  +files/2.5/glibc-2.5-hardened-configure-picdefault.patch,
+  +files/2.5/glibc-2.5-hardened-inittls-nosysenter.patch,
+  +files/2.5/glibc-2.5-hardened-pie.patch, +glibc-2.5-r1.ebuild:
+  Push out misc fixes and include new hardened/hppa work.
 
   25 Feb 2007; Joshua Kinard <kumba@gentoo.org> glibc-2.5.ebuild:
   Add ~mips to glibc-2.5 for testing under the 2007.1-dev profile.
index e3ebbed697e3b127f8fe1002dc682415fe53cd0f..b576784ad7497c1c20a929f581e6d3c52c46200a 100644 (file)
@@ -389,6 +389,22 @@ AUX 2.4/ssp_simple.c 914 RMD160 d9510f3b13f2fad4e2386c64644b592ef18efc7f SHA1 07
 MD5 573124b48c3117a5acdac52496fdec32 files/2.4/ssp_simple.c 914
 RMD160 d9510f3b13f2fad4e2386c64644b592ef18efc7f files/2.4/ssp_simple.c 914
 SHA256 57d6a3d25b24f13758637bc0b15dd9d0305a4178a5fe55b0bb14a1d2e49fd7c8 files/2.4/ssp_simple.c 914
+AUX 2.5/glibc-2.5-gentoo-stack_chk_fail.c 9058 RMD160 c98d7007857aeeea00e708e7989800dad9b07ae3 SHA1 ff92b7b6cb4a364dbe81c5110da79d1ad56a72ba SHA256 067fba2a36d2630d50198c44395ef208cdf080508f1b716bd3d079f7b964e2df
+MD5 24dfc0b6f2725063612ea5e4e346b6f3 files/2.5/glibc-2.5-gentoo-stack_chk_fail.c 9058
+RMD160 c98d7007857aeeea00e708e7989800dad9b07ae3 files/2.5/glibc-2.5-gentoo-stack_chk_fail.c 9058
+SHA256 067fba2a36d2630d50198c44395ef208cdf080508f1b716bd3d079f7b964e2df files/2.5/glibc-2.5-gentoo-stack_chk_fail.c 9058
+AUX 2.5/glibc-2.5-hardened-configure-picdefault.patch 794 RMD160 7ab81bac4b9625043b1e7edea6fb5707696c144d SHA1 25a0b018eb44f3c9818876a12e9ec817e305d80b SHA256 0c0359f567e4ad2d3184618bf6ac7e6102b703eab6227c7e9a4ff4dcdeed2c91
+MD5 a16cdc2083bdc31ad63f60045e2cc3ef files/2.5/glibc-2.5-hardened-configure-picdefault.patch 794
+RMD160 7ab81bac4b9625043b1e7edea6fb5707696c144d files/2.5/glibc-2.5-hardened-configure-picdefault.patch 794
+SHA256 0c0359f567e4ad2d3184618bf6ac7e6102b703eab6227c7e9a4ff4dcdeed2c91 files/2.5/glibc-2.5-hardened-configure-picdefault.patch 794
+AUX 2.5/glibc-2.5-hardened-inittls-nosysenter.patch 9407 RMD160 352112bf4f2d8d58471f22f623784350baf0bc86 SHA1 ae244e9923c0a0e8be4121d593897530c0bf08e8 SHA256 2a912e82445815ae32744d990c59d8758ec74e482b856bd274c292848b9af1fd
+MD5 310d9d273a19090287c44a38aba92753 files/2.5/glibc-2.5-hardened-inittls-nosysenter.patch 9407
+RMD160 352112bf4f2d8d58471f22f623784350baf0bc86 files/2.5/glibc-2.5-hardened-inittls-nosysenter.patch 9407
+SHA256 2a912e82445815ae32744d990c59d8758ec74e482b856bd274c292848b9af1fd files/2.5/glibc-2.5-hardened-inittls-nosysenter.patch 9407
+AUX 2.5/glibc-2.5-hardened-pie.patch 1548 RMD160 b33ce25195864ec4e8a63527f3f674aa5fb623da SHA1 0bb184451121d130be9e1888d081c556edcb88d3 SHA256 44e240987859e791095beddd2388fcea705195d1c86310fef4eea0097b9d2a00
+MD5 8d7eadd996eec8fa9939658404ee386d files/2.5/glibc-2.5-hardened-pie.patch 1548
+RMD160 b33ce25195864ec4e8a63527f3f674aa5fb623da files/2.5/glibc-2.5-hardened-pie.patch 1548
+SHA256 44e240987859e791095beddd2388fcea705195d1c86310fef4eea0097b9d2a00 files/2.5/glibc-2.5-hardened-pie.patch 1548
 AUX fix-sysctl_h.patch 376 RMD160 b5dd68158224b09ddc42986be02351c74f81e0a0 SHA1 5601fbea6961368bcc192aef78e96ee2c5310713 SHA256 3a589f63fd1f3f6c5a00c66a10943d3d64630aefb1eb5b37e7f2a856fcea234a
 MD5 e4393f4721a207750581d6265d5f7f40 files/fix-sysctl_h.patch 376
 RMD160 b5dd68158224b09ddc42986be02351c74f81e0a0 files/fix-sysctl_h.patch 376
@@ -445,6 +461,7 @@ DIST glibc-2.3.6.tar.bz2 14014977 RMD160 04b4f71cc3e89581e02ee2dbf5ab05f61e868bf
 DIST glibc-2.4-patches-1.19.tar.bz2 132880 RMD160 6df74db9b9e85220fba82658036ced5cdc16ae28 SHA1 b42dfd587fdf4df58c5f95853fc3dc4f8f51bee7 SHA256 9ec4cd3df3b8e7f294b3c93138d2f0fd7e8213b4981cfcc9cb58c25f934a23fa
 DIST glibc-2.4.tar.bz2 15202445 RMD160 ee2712a0e6fab8e086958c1f23221f8d07af3de1 SHA1 35c636e4b474cda0f06e361d5e9caec092fd73d3 SHA256 27aaaaa78b4ab5da76bb29385dc9be087ba7b855a9102eaaa78ce3ec5e2e7fcd
 DIST glibc-2.5-patches-1.3.2.tar.bz2 182152 RMD160 af497b417d05c0e8c26174d3db053f3192936ef6 SHA1 f1b5dff0659bd3dc02e44186948f9f05a6b6e9cc SHA256 20fa70f908011a5c9c0fade0e4489263550153722938a730669fad93c81865ff
+DIST glibc-2.5-patches-1.4.tar.bz2 527303 RMD160 08e219988bfa5aba2eea057f412a615d8531095b SHA1 6fbfeb1468f5a8f9dca73a1a6314de202d753e63 SHA256 5d0ab0634d4f9dd9016b86fda3ac469e9511267181ed7d9c409a6e9c392bc3e0
 DIST glibc-2.5.tar.bz2 15321839 RMD160 25a0a460c0db1e5b7c570e5087461696f2096fd2 SHA1 ec9a007c4875062099a4701ac9137fcdb5a71447 SHA256 9b2e12bb1eafb55ab2e5a868532b8e6ec39216c66c25b8998d7474bc4d4eb529
 DIST glibc-fedora-20041219T2331.tar.bz2 761998 RMD160 cfc859a7e0a904cfb340c832267d3377e850cf6e SHA1 31e10b882bb9288831e1a1b2ed0ddece7099ffbd SHA256 e36ffa84388ebb746cb80c37d6fd1acc9e45e07b85c30b0a2ad9f511fae59cec
 DIST glibc-infopages-2.3.5.tar.bz2 1273846 RMD160 14a587e5df98ad113fa1499d2a958efbb47c437a SHA1 bb974b6dacd02161532717a9d8f97248acd6da14 SHA256 79a602955e3cf4288fa9967240b397281594acab18c263d2ef864e7d71aa54e1
@@ -492,14 +509,18 @@ EBUILD glibc-2.4-r4.ebuild 39210 RMD160 fd782b08e862bd1889b9d6dc73386f6ff43ce676
 MD5 f7e1022963b4ac00d04110ef57c1a0eb glibc-2.4-r4.ebuild 39210
 RMD160 fd782b08e862bd1889b9d6dc73386f6ff43ce676 glibc-2.4-r4.ebuild 39210
 SHA256 d05fc7bf0c6cd701443f61328afb4e80ce6ff6d7d364de346cfdc297ffedc5df glibc-2.4-r4.ebuild 39210
-EBUILD glibc-2.5.ebuild 37912 RMD160 36a5ea1d569edfccc3f850235a3168b29debce0f SHA1 8a07038fa0e05905743497f93c0c18f3804dc503 SHA256 c361581400a2c5f6422a0d7545335ba7582c259428d4f76d52c0e8d213572bb1
-MD5 44797f3a8f221ce2730a770cc1973161 glibc-2.5.ebuild 37912
-RMD160 36a5ea1d569edfccc3f850235a3168b29debce0f glibc-2.5.ebuild 37912
-SHA256 c361581400a2c5f6422a0d7545335ba7582c259428d4f76d52c0e8d213572bb1 glibc-2.5.ebuild 37912
-MISC ChangeLog 99099 RMD160 00dd5b6474523bf1c9d9c10ef508c5aff45494ff SHA1 79aa024a9d080579a44aa293e724a191b03cea92 SHA256 28d3f4aeab543ee75b42a1474ab2b40c57917e08f076fe432225dc54d612d364
-MD5 82e748bdabd35a7dca824001b508a94d ChangeLog 99099
-RMD160 00dd5b6474523bf1c9d9c10ef508c5aff45494ff ChangeLog 99099
-SHA256 28d3f4aeab543ee75b42a1474ab2b40c57917e08f076fe432225dc54d612d364 ChangeLog 99099
+EBUILD glibc-2.5-r1.ebuild 38588 RMD160 3046649b70c8d26b0368f092d0738107ecd3a566 SHA1 9c300cba3668cdb85375eb9dc4138d7c444391a8 SHA256 69314824f6a15cade19964b4ee459ead466a30f26634ef08aba2f0317a735a49
+MD5 32a165a81983128fd6aa807a27f7b46a glibc-2.5-r1.ebuild 38588
+RMD160 3046649b70c8d26b0368f092d0738107ecd3a566 glibc-2.5-r1.ebuild 38588
+SHA256 69314824f6a15cade19964b4ee459ead466a30f26634ef08aba2f0317a735a49 glibc-2.5-r1.ebuild 38588
+EBUILD glibc-2.5.ebuild 37920 RMD160 f0ed4f2224d0788057479f08f46481b310a41c86 SHA1 07fea0d2d7b9d4fa25ea6f9729edd9cb3b68cf9d SHA256 95fbb9bfc9a1f964b51138413afc14eda068ce409784b78f19137fa157ca2d20
+MD5 1acffac4370ad139d4778d9f212a2f2e glibc-2.5.ebuild 37920
+RMD160 f0ed4f2224d0788057479f08f46481b310a41c86 glibc-2.5.ebuild 37920
+SHA256 95fbb9bfc9a1f964b51138413afc14eda068ce409784b78f19137fa157ca2d20 glibc-2.5.ebuild 37920
+MISC ChangeLog 99469 RMD160 8b6ef004e39f4a8b418f73241f41a7385127ec2f SHA1 1dd6c9b88dd21348292b25ceebe134127cd0e438 SHA256 a79e8110ba480ca84c602215bb76dcd4dc3b642bda8023eaa45948d43a54c0fd
+MD5 f45c057756832b7e4ce1c5898433d4d4 ChangeLog 99469
+RMD160 8b6ef004e39f4a8b418f73241f41a7385127ec2f ChangeLog 99469
+SHA256 a79e8110ba480ca84c602215bb76dcd4dc3b642bda8023eaa45948d43a54c0fd ChangeLog 99469
 MISC metadata.xml 162 RMD160 d002486a43522f2116b1d9d59828c484956d66e2 SHA1 d6b4923897f6ae673b4f93646f5b4ba61d5a2c3c SHA256 65a915d44de1f01d4b7f72d313b4192c38374a9835d24988c00c1e73dca5805a
 MD5 567094e03359ffc1c95af7356395228d metadata.xml 162
 RMD160 d002486a43522f2116b1d9d59828c484956d66e2 metadata.xml 162
@@ -528,10 +549,13 @@ SHA256 a49f96d87bda9dfbe73ac717c2a1dea7b4715c9c2e6031f404e3d7ee1209efea files/di
 MD5 5b7e320e8b8b1a96ace60aa95385c122 files/digest-glibc-2.5 1286
 RMD160 6302561abceb3a88449dfe74bd6f2e373f00dec3 files/digest-glibc-2.5 1286
 SHA256 c20b8f42085597085e3589fbfd2dc5351f0c63a5492a55f82b59a1481b2a28f3 files/digest-glibc-2.5 1286
+MD5 30fc9163b2a49cb4a083d02feace4918 files/digest-glibc-2.5-r1 1280
+RMD160 74d079011c9a8d9155cd5f51591ca3a04cb9df26 files/digest-glibc-2.5-r1 1280
+SHA256 b0af33330bd44dd7acd6f4aec9039d61b7fe9de005a8cf6edf63ee399cdeaa72 files/digest-glibc-2.5-r1 1280
 -----BEGIN PGP SIGNATURE-----
-Version: GnuPG v2.0.2 (GNU/Linux)
+Version: GnuPG v2.0.3 (GNU/Linux)
 
-iD8DBQFF5jjx8bi6rjpTunYRAtcQAKDY0fcNSqtKhPxsqCe8KFKD9OSXvwCeIjAa
-6K1BLA/E/YqHVwhtqj/E/tM=
-=qJWj
+iD8DBQFF9kA38bi6rjpTunYRAtOAAKDYEx+oUGLGfrzYnOVyx0wakG+WpgCgyg/9
+aCixONtpcBs31hFXbhXg25s=
+=CaGG
 -----END PGP SIGNATURE-----
diff --git a/sys-libs/glibc/files/2.5/glibc-2.5-gentoo-stack_chk_fail.c b/sys-libs/glibc/files/2.5/glibc-2.5-gentoo-stack_chk_fail.c
new file mode 100644 (file)
index 0000000..e304440
--- /dev/null
@@ -0,0 +1,311 @@
+/* Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Copyright (C) 2006 Gentoo Foundation Inc.
+ * License terms as above.
+ *
+ * Hardened Gentoo SSP handler
+ *
+ * An SSP failure handler that does not use functions from the rest of
+ * glibc; it uses the INTERNAL_SYSCALL methods directly.  This ensures
+ * no possibility of recursion into the handler.
+ *
+ * Direct all bug reports to http://bugs.gentoo.org/
+ *
+ * Re-written from the glibc-2.3 Hardened Gentoo SSP handler
+ * by Kevin F. Quinn - <kevquinn[@]gentoo.org>
+ *
+ * The following people contributed to the glibc-2.3 Hardened
+ * Gentoo SSP handler, from which this implementation draws much:
+ *
+ * Ned Ludd - <solar[@]gentoo.org>
+ * Alexander Gabert - <pappy[@]gentoo.org>
+ * The PaX Team - <pageexec[@]freemail.hu>
+ * Peter S. Mazinger - <ps.m[@]gmx.net>
+ * Yoann Vandoorselaere - <yoann[@]prelude-ids.org>
+ * Robert Connolly - <robert[@]linuxfromscratch.org>
+ * Cory Visi <cory[@]visi.name>
+ * Mike Frysinger <vapier[@]gentoo.org>
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <sys/types.h>
+
+#include <sysdep-cancel.h>
+#include <sys/syscall.h>
+#include <bp-checks.h>
+
+#include <kernel-features.h>
+
+#include <alloca.h>
+/* from sysdeps */
+#include <socketcall.h>
+/* for the stuff in bits/socket.h */
+#include <sys/socket.h>
+#include <sys/un.h>
+
+
+/* Sanity check on SYSCALL macro names - force compilation
+ * failure if the names used here do not exist
+ */
+#if !defined __NR_socketcall && !defined __NR_socket
+# error Cannot do syscall socket or socketcall
+#endif
+#if !defined __NR_socketcall && !defined __NR_connect
+# error Cannot do syscall connect or socketcall
+#endif
+#ifndef __NR_write
+# error Cannot do syscall write
+#endif
+#ifndef __NR_close
+# error Cannot do syscall close
+#endif
+#ifndef __NR_getpid
+# error Cannot do syscall getpid
+#endif
+#ifndef __NR_kill
+# error Cannot do syscall kill
+#endif
+#ifndef __NR_exit
+# error Cannot do syscall exit
+#endif
+#ifdef SSP_SMASH_DUMPS_CORE
+# if !defined _KERNEL_NSIG && !defined _NSIG
+#  error No _NSIG or _KERNEL_NSIG for rt_sigaction
+# endif
+# if !defined __NR_sigation && !defined __NR_rt_sigaction
+#  error Cannot do syscall sigaction or rt_sigaction
+# endif
+#endif
+
+
+
+/* Define DO_SOCKET/DO_CONNECT macros to deal with socketcall vs socket/connect */
+#ifdef __NR_socketcall
+
+# define DO_SOCKET(result,domain,type,protocol) \
+       {socketargs[0] = domain; \
+       socketargs[1] = type; \
+       socketargs[2] = protocol; \
+       socketargs[3] = 0; \
+       result = INLINE_SYSCALL(socketcall,2,SOCKOP_socket,socketargs);}
+
+# define DO_CONNECT(result,sockfd,serv_addr,addrlen) \
+       {socketargs[0] = sockfd; \
+       socketargs[1] = (unsigned long int)serv_addr; \
+       socketargs[2] = addrlen; \
+       socketargs[3] = 0; \
+       result = INLINE_SYSCALL(socketcall,2,SOCKOP_connect,socketargs);}
+
+#else
+
+# define DO_SOCKET(result,domain,type,protocol) \
+       {result = INLINE_SYSCALL(socket,3,domain,type,protocol);}
+
+# define DO_CONNECT(result,sockfd,serv_addr,addrlen) \
+       {result = INLINE_SYSCALL(connect,3,sockfd,serv_addr,addrlen);}
+
+#endif
+/* __NR_socketcall */
+
+
+#ifndef _PATH_LOG
+# define _PATH_LOG "/dev/log"
+#endif
+
+static const char path_log[]=_PATH_LOG;
+
+/* For building glibc with SSP switched on, define __progname to a
+ * constant if building for the run-time loader, to avoid pulling
+ * in more of libc.so into ld.so
+ */
+#ifdef IS_IN_rtld
+static char *__progname = "<rtld>";
+#else
+extern char *__progname;
+#endif
+
+
+/* Common handler code, used by stack_chk_fail and __stack_smash_handler
+ * Inlined to ensure no self-references to the handler within itself.
+ * Data static to avoid putting more than necessary on the stack,
+ * to aid core debugging.
+ */
+static inline void
+__attribute__ ((__noreturn__ , __always_inline__))
+__hardened_gentoo_stack_chk_fail (char func[], int damaged)
+{
+#define MESSAGE_BUFSIZ 256
+       static pid_t pid;
+       static int plen, i;
+       static char message[MESSAGE_BUFSIZ];
+       static const char msg_ssa[]=": stack smashing attack";
+       static const char msg_inf[]=" in function ";
+       static const char msg_ssd[]="*** stack smashing detected ***: ";
+       static const char msg_terminated[]=" - terminated\n";
+       static const char msg_report[]="Report to http://bugs.gentoo.org/\n";
+       static const char msg_unknown[]="<unknown>";
+#ifdef SSP_SMASH_DUMPS_CORE
+       static struct sigaction default_abort_act;
+#endif
+       static int log_socket, connect_result;
+       static struct sockaddr_un sock;
+#ifdef __NR_socketcall
+       static unsigned long int socketargs[4];
+#endif
+
+       /* Build socket address
+        */
+       sock.sun_family = AF_UNIX;
+       i=0;
+       while ((path_log[i] != '\0') && (i<(sizeof(sock.sun_path)-1)))
+         {
+               sock.sun_path[i]=path_log[i];
+               i++;
+         }
+       sock.sun_path[i]='\0';
+
+       /* Try SOCK_DGRAM connection to syslog */
+       connect_result=-1;
+       DO_SOCKET(log_socket,AF_UNIX,SOCK_DGRAM,0);
+       if (log_socket != -1)
+               DO_CONNECT(connect_result,log_socket,(&sock),(sizeof(sock)));
+       if (connect_result == -1)
+         {
+               if (log_socket != -1)
+                       INLINE_SYSCALL(close,1,log_socket);
+               /* Try SOCK_STREAM connection to syslog */
+               DO_SOCKET(log_socket,AF_UNIX,SOCK_STREAM,0);
+               if (log_socket != -1)
+                       DO_CONNECT(connect_result,log_socket,(&sock),(sizeof(sock)));
+         }
+
+       /* Build message.  Messages are generated both in the old style and new style,
+        * so that log watchers that are configured for the old-style message continue
+        * to work.
+        */
+#define strconcat(str) \
+               {i=0; while ((str[i] != '\0') && ((i+plen)<(MESSAGE_BUFSIZ-1))) \
+               {\
+                       message[plen+i]=str[i];\
+                       i++;\
+               }\
+               plen+=i;}
+
+       /* R.Henderson post-gcc-4 style message */
+       plen=0;
+       strconcat(msg_ssd);
+       if (__progname != (char *)0)
+               strconcat(__progname)
+       else
+               strconcat(msg_unknown);
+       strconcat(msg_terminated);
+
+       /* Write out error message to STDERR, to syslog if open */
+       INLINE_SYSCALL(write,3,STDERR_FILENO,message,plen);
+       if (connect_result != -1)
+               INLINE_SYSCALL(write,3,log_socket,message,plen);
+
+       /* Dr. Etoh pre-gcc-4 style message */
+       plen=0;
+       if (__progname != (char *)0)
+               strconcat(__progname)
+       else
+               strconcat(msg_unknown);
+       strconcat(msg_ssa);
+       strconcat(msg_inf);
+       if (func!=NULL)
+               strconcat(func)
+       else
+               strconcat(msg_unknown);
+       strconcat(msg_terminated);
+       /* Write out error message to STDERR, to syslog if open */
+       INLINE_SYSCALL(write,3,STDERR_FILENO,message,plen);
+       if (connect_result != -1)
+               INLINE_SYSCALL(write,3,log_socket,message,plen);
+
+       /* Direct reports to bugs.gentoo.org */
+       plen=0;
+       strconcat(msg_report);
+       message[plen++]='\0';
+
+       /* Write out error message to STDERR, to syslog if open */
+       INLINE_SYSCALL(write,3,STDERR_FILENO,message,plen);
+       if (connect_result != -1)
+               INLINE_SYSCALL(write,3,log_socket,message,plen);
+
+       if (log_socket != -1)
+               INLINE_SYSCALL(close,1,log_socket);
+
+       /* Suicide */
+       pid=INLINE_SYSCALL(getpid,0);
+#ifdef SSP_SMASH_DUMPS_CORE
+       /* Remove any user-supplied handler for SIGABRT, before using it */
+       default_abort_act.sa_handler = SIG_DFL;
+       default_abort_act.sa_sigaction = NULL;
+       __sigfillset(&default_abort_act.sa_mask);
+       default_abort_act.sa_flags = 0;
+       /* sigaction doesn't exist on amd64; however rt_sigaction seems to
+        * exist everywhere.  rt_sigaction has an extra parameter - the
+        * size of sigset_t.
+        */
+# ifdef __NR_sigation
+       if (INLINE_SYSCALL(sigaction,3,SIGABRT,&default_abort_act,NULL) == 0)
+# else
+       /* Although rt_sigaction expects sizeof(sigset_t) - it expects the size
+        * of the _kernel_ sigset_t which is not the same as the user sigset_t.
+        * Most arches have this as _NSIG bits - mips has _KERNEL_NSIG bits for
+        * some reason.
+        */
+#  ifdef _KERNEL_NSIG
+       if (INLINE_SYSCALL(rt_sigaction,4,SIGABRT,&default_abort_act,NULL,_KERNEL_NSIG/8) == 0)
+#  else
+       if (INLINE_SYSCALL(rt_sigaction,4,SIGABRT,&default_abort_act,NULL,_NSIG/8) == 0)
+#  endif
+# endif
+               INLINE_SYSCALL(kill,2,pid,SIGABRT);
+#endif
+       /* Note; actions cannot be added to SIGKILL */
+       INLINE_SYSCALL(kill,2,pid,SIGKILL);
+
+       /* In case the kill didn't work, exit anyway
+        * The loop prevents gcc thinking this routine returns
+        */
+       while (1) INLINE_SYSCALL(exit,0);
+}
+
+void
+__attribute__ ((__noreturn__))
+       __stack_chk_fail (void)
+{
+       __hardened_gentoo_stack_chk_fail(NULL,0);
+}
+
+#ifdef ENABLE_OLD_SSP_COMPAT
+void
+__attribute__ ((__noreturn__))
+__stack_smash_handler(char func[], int damaged)
+{
+       __hardened_gentoo_stack_chk_fail(func,damaged);
+}
+#endif
+
diff --git a/sys-libs/glibc/files/2.5/glibc-2.5-hardened-configure-picdefault.patch b/sys-libs/glibc/files/2.5/glibc-2.5-hardened-configure-picdefault.patch
new file mode 100644 (file)
index 0000000..253a61b
--- /dev/null
@@ -0,0 +1,29 @@
+Prevent default-fPIE from confusing configure into thinking
+PIC code is default.  This causes glibc to build both PIC and
+non-PIC code as normal, which on the hardened compiler generates
+PIC and PIE.
+
+Patch by Kevin F. Quinn <kevquinn@gentoo.org>
+
+--- configure.in
++++ configure.in
+@@ -2145,7 +2145,7 @@
+ # error PIC is default.
+ #endif
+ EOF
+-if eval "${CC-cc} -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then
++if eval "${CC-cc} -fno-PIE -S conftest.c 2>&AS_MESSAGE_LOG_FD 1>&AS_MESSAGE_LOG_FD"; then
+   pic_default=no
+ fi
+ rm -f conftest.*])
+--- configure
++++ configure
+@@ -7698,7 +7698,7 @@
+ # error PIC is default.
+ #endif
+ EOF
+-if eval "${CC-cc} -S conftest.c 2>&5 1>&5"; then
++if eval "${CC-cc} -fno-PIE -S conftest.c 2>&5 1>&5"; then
+   pic_default=no
+ fi
+ rm -f conftest.*
diff --git a/sys-libs/glibc/files/2.5/glibc-2.5-hardened-inittls-nosysenter.patch b/sys-libs/glibc/files/2.5/glibc-2.5-hardened-inittls-nosysenter.patch
new file mode 100644 (file)
index 0000000..420e6fd
--- /dev/null
@@ -0,0 +1,283 @@
+When building glibc PIE (which is not something upstream support),
+several modifications are necessary to the glibc build process.
+
+First, any syscalls in PIEs must be of the PIC variant, otherwise
+textrels ensue.  Then, any syscalls made before the initialisation
+of the TLS will fail on i386, as the sysenter variant on i386 uses
+the TLS, giving rise to a chicken-and-egg situation.  This patch
+defines a PIC syscall variant that doesn't use sysenter, even when the sysenter
+version is normally used, and uses the non-sysenter version for the brk
+syscall that is performed by the TLS initialisation.  Further, the TLS
+initialisation is moved in this case prior to the initialisation of
+dl_osversion, as that requires further syscalls.
+
+csu/libc-start.c: Move initial TLS initialization to before the
+initialisation of dl_osversion, when INTERNAL_SYSCALL_NOSYSENTER is defined
+
+csu/libc-tls.c: Use the no-sysenter version of sbrk when
+INTERNAL_SYSCALL_NOSYSENTER is defined.
+
+misc/sbrk.c: Define a no-sysenter version of sbrk, using the no-sysenter
+version of brk - if INTERNAL_SYSCALL_NOSYSENTER is defined.
+
+misc/brk.c: Define a no-sysenter version of brk if
+INTERNAL_SYSCALL_NOSYSENTER is defined.
+
+sysdeps/unix/sysv/linux/i386/sysdep.h: Define INTERNAL_SYSCALL_NOSYSENTER
+Make INTERNAL_SYSCALL always use the PIC variant, even if not SHARED.
+
+Patch by Kevin F. Quinn <kevquinn@gentoo.org>
+
+--- csu/libc-start.c.orig      2007-01-21 11:51:06.000000000 +0100
++++ csu/libc-start.c   2007-01-21 11:55:57.000000000 +0100
+@@ -28,6 +28,7 @@
+ extern int __libc_multiple_libcs;
+ #include <tls.h>
++#include <sysdep.h>
+ #ifndef SHARED
+ # include <dl-osinfo.h>
+ extern void __pthread_initialize_minimal (void)
+@@ -133,6 +134,14 @@
+ #  endif
+   _dl_aux_init (auxvec);
+ # endif
++# ifdef INTERNAL_SYSCALL_NOSYSENTER
++  /* Do the initial TLS initialization before _dl_osversion,
++     since the latter uses the uname syscall.  */
++#  if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
++  if (__pthread_initialize_minimal)
++#  endif
++    __pthread_initialize_minimal ();
++# endif
+ # ifdef DL_SYSDEP_OSCHECK
+   if (!__libc_multiple_libcs)
+     {
+@@ -142,15 +151,17 @@
+     }
+ # endif
++# ifndef INTERNAL_SYSCALL_NOSYSENTER
+   /* Initialize the thread library at least a bit since the libgcc
+      functions are using thread functions if these are available and
+      we need to setup errno.  If there is no thread library and we
+      handle TLS the function is defined in the libc to initialized the
+      TLS handling.  */
+-# if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
++#  if !(USE_TLS - 0) && !defined NONTLS_INIT_TP
+   if (__pthread_initialize_minimal)
+-# endif
++#  endif
+     __pthread_initialize_minimal ();
++# endif
+ #endif
+ # ifndef SHARED
+--- csu/libc-tls.c.orig        2007-01-21 11:37:02.000000000 +0100
++++ csu/libc-tls.c     2007-01-21 12:09:33.000000000 +0100
+@@ -23,6 +23,7 @@
+ #include <unistd.h>
+ #include <stdio.h>
+ #include <sys/param.h>
++#include <sysdep.h>
+ #ifdef SHARED
+@@ -30,6 +31,9 @@
+ #endif
+ #ifdef USE_TLS
++# ifdef INTERNAL_SYSCALL_NOSYSENTER
++extern void *__sbrk_nosysenter (intptr_t __delta);
++# endif
+ extern ElfW(Phdr) *_dl_phdr;
+ extern size_t _dl_phnum;
+@@ -142,14 +146,26 @@
+      The initialized value of _dl_tls_static_size is provided by dl-open.c
+      to request some surplus that permits dynamic loading of modules with
+-     IE-model TLS.  */
++     IE-model TLS.
++       
++       Where the normal sbrk would use a syscall that needs the TLS (i386)
++       use the special non-sysenter version instead.  */
+ # if TLS_TCB_AT_TP
+   tcb_offset = roundup (memsz + GL(dl_tls_static_size), tcbalign);
++#  ifdef INTERNAL_SYSCALL_NOSYSENTER
++  tlsblock = __sbrk_nosysenter (tcb_offset + tcbsize + max_align);
++#  else
+   tlsblock = __sbrk (tcb_offset + tcbsize + max_align);
++#  endif
+ # elif TLS_DTV_AT_TP
+   tcb_offset = roundup (tcbsize, align ?: 1);
++#  ifdef INTERNAL_SYSCALL_NOSYSENTER
++  tlsblock = __sbrk_nosysenter (tcb_offset + memsz + max_align
++                   + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
++#  else
+   tlsblock = __sbrk (tcb_offset + memsz + max_align
+                    + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
++#  endif
+   tlsblock += TLS_PRE_TCB_SIZE;
+ # else
+   /* In case a model with a different layout for the TCB and DTV
+--- misc/sbrk.c.orig   2007-01-21 11:38:27.000000000 +0100
++++ misc/sbrk.c        2007-01-21 12:07:29.000000000 +0100
+@@ -18,6 +18,7 @@
+ #include <unistd.h>
+ #include <errno.h>
++#include <sysdep.h>
+ /* Defined in brk.c.  */
+ extern void *__curbrk;
+@@ -29,6 +30,35 @@
+ /* Extend the process's data space by INCREMENT.
+    If INCREMENT is negative, shrink data space by - INCREMENT.
+    Return start of new space allocated, or -1 for errors.  */
++#ifdef INTERNAL_SYSCALL_NOSYSENTER
++/* This version is used by csu/libc-tls.c whem initialising the TLS
++   if the SYSENTER version requires the TLS (which it does on i386).
++   Obviously using the TLS before it is initialised is broken. */
++extern int __brk_nosysenter (void *addr);
++void *
++__sbrk_nosysenter (intptr_t increment)
++{
++  void *oldbrk;
++
++  /* If this is not part of the dynamic library or the library is used
++     via dynamic loading in a statically linked program update
++     __curbrk from the kernel's brk value.  That way two separate
++     instances of __brk and __sbrk can share the heap, returning
++     interleaved pieces of it.  */
++  if (__curbrk == NULL || __libc_multiple_libcs)
++    if (__brk_nosysenter (0) < 0)             /* Initialize the break.  */
++      return (void *) -1;
++
++  if (increment == 0)
++    return __curbrk;
++
++  oldbrk = __curbrk;
++  if (__brk_nosysenter (oldbrk + increment) < 0)
++    return (void *) -1;
++
++  return oldbrk;
++}
++#endif
+ void *
+ __sbrk (intptr_t increment)
+ {
+--- sysdeps/unix/sysv/linux/i386/brk.c.orig    2007-01-21 11:39:16.000000000 +0100
++++ sysdeps/unix/sysv/linux/i386/brk.c 2007-01-21 11:44:01.000000000 +0100
+@@ -31,6 +31,30 @@
+    linker.  */
+ weak_alias (__curbrk, ___brk_addr)
++#ifdef INTERNAL_SYSCALL_NOSYSENTER
++/* This version is used by csu/libc-tls.c whem initialising the TLS
++ * if the SYSENTER version requires the TLS (which it does on i386).
++ * Obviously using the TLS before it is initialised is broken. */
++int
++__brk_nosysenter (void *addr)
++{
++  void *__unbounded newbrk;
++
++  INTERNAL_SYSCALL_DECL (err);
++  newbrk = (void *__unbounded) INTERNAL_SYSCALL_NOSYSENTER (brk, err, 1,
++                                               __ptrvalue (addr));
++
++  __curbrk = newbrk;
++
++  if (newbrk < addr)
++    {
++      __set_errno (ENOMEM);
++      return -1;
++    }
++
++  return 0;
++}
++#endif
+ int
+ __brk (void *addr)
+ {
+--- sysdeps/unix/sysv/linux/i386/sysdep.h.orig 2007-01-21 13:08:00.000000000 +0100
++++ sysdeps/unix/sysv/linux/i386/sysdep.h      2007-01-21 13:19:10.000000000 +0100
+@@ -187,7 +187,7 @@
+ /* The original calling convention for system calls on Linux/i386 is
+    to use int $0x80.  */
+ #ifdef I386_USE_SYSENTER
+-# ifdef SHARED
++# if defined SHARED || defined __PIC__
+ #  define ENTER_KERNEL call *%gs:SYSINFO_OFFSET
+ # else
+ #  define ENTER_KERNEL call *_dl_sysinfo
+@@ -358,7 +358,7 @@
+    possible to use more than four parameters.  */
+ #undef INTERNAL_SYSCALL
+ #ifdef I386_USE_SYSENTER
+-# ifdef SHARED
++# if defined SHARED || defined __PIC__
+ #  define INTERNAL_SYSCALL(name, err, nr, args...) \
+   ({                                                                        \
+     register unsigned int resultvar;                                        \
+@@ -384,6 +384,18 @@
+     : "0" (name), "i" (offsetof (tcbhead_t, sysinfo))                       \
+       ASMFMT_##nr(args) : "memory", "cc");                                  \
+     (int) resultvar; })
++#  define INTERNAL_SYSCALL_NOSYSENTER(name, err, nr, args...) \
++  ({                                                                        \
++    register unsigned int resultvar;                                        \
++    EXTRAVAR_##nr                                                           \
++    asm volatile (                                                          \
++    LOADARGS_NOSYSENTER_##nr                                                \
++    "movl %1, %%eax\n\t"                                                    \
++    "int $0x80\n\t"                                                         \
++    RESTOREARGS_NOSYSENTER_##nr                                                     \
++    : "=a" (resultvar)                                                              \
++    : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc");                \
++    (int) resultvar; })
+ # else
+ #  define INTERNAL_SYSCALL(name, err, nr, args...) \
+   ({                                                                        \
+@@ -447,12 +459,20 @@
+ #define LOADARGS_0
+ #ifdef __PIC__
+-# if defined I386_USE_SYSENTER && defined SHARED
++# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ )
+ #  define LOADARGS_1 \
+     "bpushl .L__X'%k3, %k3\n\t"
+ #  define LOADARGS_5 \
+     "movl %%ebx, %4\n\t"                                                    \
+     "movl %3, %%ebx\n\t"
++#  define LOADARGS_NOSYSENTER_1 \
++    "bpushl .L__X'%k2, %k2\n\t"
++#  define LOADARGS_NOSYSENTER_2       LOADARGS_NOSYSENTER_1
++#  define LOADARGS_NOSYSENTER_3       LOADARGS_3
++#  define LOADARGS_NOSYSENTER_4       LOADARGS_3
++#  define LOADARGS_NOSYSENTER_5 \
++    "movl %%ebx, %3\n\t"                                                    \
++    "movl %2, %%ebx\n\t"
+ # else
+ #  define LOADARGS_1 \
+     "bpushl .L__X'%k2, %k2\n\t"
+@@ -474,11 +495,18 @@
+ #define RESTOREARGS_0
+ #ifdef __PIC__
+-# if defined I386_USE_SYSENTER && defined SHARED
++# if defined I386_USE_SYSENTER && ( defined SHARED || defined __PIC__ )
+ #  define RESTOREARGS_1 \
+     "bpopl .L__X'%k3, %k3\n\t"
+ #  define RESTOREARGS_5 \
+     "movl %4, %%ebx"
++#  define RESTOREARGS_NOSYSENTER_1 \
++    "bpopl .L__X'%k2, %k2\n\t"
++#  define RESTOREARGS_NOSYSENTER_2    RESTOREARGS_NOSYSENTER_1
++#  define RESTOREARGS_NOSYSENTER_3    RESTOREARGS_3
++#  define RESTOREARGS_NOSYSENTER_4    RESTOREARGS_3
++#  define RESTOREARGS_NOSYSENTER_5 \
++    "movl %3, %%ebx"
+ # else
+ #  define RESTOREARGS_1 \
+     "bpopl .L__X'%k2, %k2\n\t"
diff --git a/sys-libs/glibc/files/2.5/glibc-2.5-hardened-pie.patch b/sys-libs/glibc/files/2.5/glibc-2.5-hardened-pie.patch
new file mode 100644 (file)
index 0000000..280d6e1
--- /dev/null
@@ -0,0 +1,39 @@
+Change link commands for glibc executables to build PIEs
+
+Patch by Kevin F. Quinn <kevquinn@gentoo.org>
+
+--- Makeconfig
++++ Makeconfig
+@@ -415,10 +415,10 @@
+ # Command for linking programs with the C library.
+ ifndef +link
+-+link = $(CC) -nostdlib -nostartfiles -o $@ \
+++link = $(CC) -nostdlib -nostartfiles -fPIE -pie -o $@ \
+             $(sysdep-LDFLAGS) $(config-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \
+             $(combreloc-LDFLAGS) $(relro-LDFLAGS) \
+-            $(addprefix $(csu-objpfx),$(start-installed-name)) \
++            $(addprefix $(csu-objpfx),S$(start-installed-name)) \
+             $(+preinit) $(+prector) \
+             $(filter-out $(addprefix $(csu-objpfx),start.o \
+                                                    $(start-installed-name))\
+@@ -429,7 +429,7 @@
+ ifndef +link-static
+ +link-static = $(CC) -nostdlib -nostartfiles -static -o $@ \
+             $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F))  \
+-            $(addprefix $(csu-objpfx),$(static-start-installed-name)) \
++            $(addprefix $(csu-objpfx),S$(static-start-installed-name)) \
+             $(+preinit) $(+prector) \
+             $(filter-out $(addprefix $(csu-objpfx),start.o \
+                                                    $(start-installed-name))\
+@@ -528,8 +528,8 @@
+ ifeq ($(elf),yes)
+ +preinit = $(addprefix $(csu-objpfx),crti.o)
+ +postinit = $(addprefix $(csu-objpfx),crtn.o)
+-+prector = `$(CC) --print-file-name=crtbegin.o`
+-+postctor = `$(CC) --print-file-name=crtend.o`
+++prector = `$(CC) --print-file-name=crtbeginS.o`
+++postctor = `$(CC) --print-file-name=crtendS.o`
+ +interp = $(addprefix $(elf-objpfx),interp.os)
+ endif
+ csu-objpfx = $(common-objpfx)csu/
diff --git a/sys-libs/glibc/files/digest-glibc-2.5-r1 b/sys-libs/glibc/files/digest-glibc-2.5-r1
new file mode 100644 (file)
index 0000000..5aac065
--- /dev/null
@@ -0,0 +1,15 @@
+MD5 e52928305eee8be9bfc18201e8e1ce85 glibc-2.5-patches-1.4.tar.bz2 527303
+RMD160 08e219988bfa5aba2eea057f412a615d8531095b glibc-2.5-patches-1.4.tar.bz2 527303
+SHA256 5d0ab0634d4f9dd9016b86fda3ac469e9511267181ed7d9c409a6e9c392bc3e0 glibc-2.5-patches-1.4.tar.bz2 527303
+MD5 1fb29764a6a650a4d5b409dda227ac9f glibc-2.5.tar.bz2 15321839
+RMD160 25a0a460c0db1e5b7c570e5087461696f2096fd2 glibc-2.5.tar.bz2 15321839
+SHA256 9b2e12bb1eafb55ab2e5a868532b8e6ec39216c66c25b8998d7474bc4d4eb529 glibc-2.5.tar.bz2 15321839
+MD5 8787868ba8962d9b125997ec2f25ac01 glibc-libidn-2.5.tar.bz2 102330
+RMD160 e10e85e0ee7cdab2e5518a93978cb688ccabee88 glibc-libidn-2.5.tar.bz2 102330
+SHA256 de77e49e0beee6061d4c6e480f322566ba25d4e5e018c456a18ea4a8da5c0ede glibc-libidn-2.5.tar.bz2 102330
+MD5 870d76d46dcaba37c13d01dca47d1774 glibc-linuxthreads-2.5.tar.bz2 242445
+RMD160 788484d035d53ac39aac18f6e3409a912eea1cfa glibc-linuxthreads-2.5.tar.bz2 242445
+SHA256 ee27aeba6124a8b351c720eb898917f0f8874d9a384cc2f17aa111a3d679bd2c glibc-linuxthreads-2.5.tar.bz2 242445
+MD5 183f6d46e8fa5e4b2aff240ab1586c2e glibc-ports-2.5.tar.bz2 409372
+RMD160 e7e29df135a5f0f72760d10e5ad46de038e40725 glibc-ports-2.5.tar.bz2 409372
+SHA256 80c38a005325e7539012bd665fb8e06af9ee9bfc74efb236ebff121265bfd463 glibc-ports-2.5.tar.bz2 409372
diff --git a/sys-libs/glibc/glibc-2.5-r1.ebuild b/sys-libs/glibc/glibc-2.5-r1.ebuild
new file mode 100644 (file)
index 0000000..40703bd
--- /dev/null
@@ -0,0 +1,1248 @@
+# Copyright 1999-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/sys-libs/glibc/glibc-2.5-r1.ebuild,v 1.1 2007/03/13 06:09:44 vapier Exp $
+
+# Here's how the cross-compile logic breaks down ...
+#  CTARGET - machine that will target the binaries
+#  CHOST   - machine that will host the binaries
+#  CBUILD  - machine that will build the binaries
+# If CTARGET != CHOST, it means you want a libc for cross-compiling.
+# If CHOST != CBUILD, it means you want to cross-compile the libc.
+#  CBUILD = CHOST = CTARGET    - native build/install
+#  CBUILD != (CHOST = CTARGET) - cross-compile a native build
+#  (CBUILD = CHOST) != CTARGET - libc for cross-compiler
+#  CBUILD != CHOST != CTARGET  - cross-compile a libc for a cross-compiler
+# For install paths:
+#  CHOST = CTARGET  - install into /
+#  CHOST != CTARGET - install into /usr/CTARGET/
+
+KEYWORDS="-* ~alpha ~amd64 ~arm ~hppa ~ia64 ~mips ~ppc ~ppc64 ~sh ~sparc ~x86"
+
+BRANCH_UPDATE=""
+
+# Generated man pages
+GLIBC_MANPAGE_VERSION="none"
+
+# Generated stuff in manual subdir
+GLIBC_INFOPAGE_VERSION="none"
+
+# Gentoo patchset
+PATCH_VER="1.4"
+
+GENTOO_TOOLCHAIN_BASE_URI="mirror://gentoo"
+GENTOO_TOOLCHAIN_DEV_URI="http://dev.gentoo.org/~azarah/glibc/XXX http://dev.gentoo.org/~vapier/dist/XXX"
+
+### PUNT OUT TO ECLASS?? ###
+inherit eutils versionator libtool toolchain-funcs flag-o-matic gnuconfig multilib
+
+DESCRIPTION="GNU libc6 (also called glibc2) C library"
+HOMEPAGE="http://www.gnu.org/software/libc/libc.html"
+LICENSE="LGPL-2"
+
+IUSE="nls build nptl nptlonly hardened multilib selinux glibc-omitfp profile glibc-compat20"
+
+export CBUILD=${CBUILD:-${CHOST}}
+export CTARGET=${CTARGET:-${CHOST}}
+if [[ ${CTARGET} == ${CHOST} ]] ; then
+       if [[ ${CATEGORY/cross-} != ${CATEGORY} ]] ; then
+               export CTARGET=${CATEGORY/cross-}
+       fi
+fi
+if [[ ${CTARGET} == ${CHOST} ]] ; then
+       PROVIDE="virtual/libc"
+fi
+
+is_crosscompile() {
+       [[ ${CHOST} != ${CTARGET} ]]
+}
+just_headers() {
+       is_crosscompile && use crosscompile_opts_headers-only
+}
+
+GLIBC_RELEASE_VER=$(get_version_component_range 1-3)
+
+# Don't set this to :-, - allows BRANCH_UPDATE=""
+BRANCH_UPDATE=${BRANCH_UPDATE-$(get_version_component_range 4)}
+GLIBC_PORTS_VER=${GLIBC_RELEASE_VER}
+#GLIBC_PORTS_VER="20060925"
+GLIBC_LT_VER=${GLIBC_RELEASE_VER}
+#GLIBC_LT_VER="20060605"
+
+# (Recent snapshots fails with 2.6.5 and earlier with NPTL)
+NPTL_KERNEL_VERSION=${NPTL_KERNEL_VERSION:-"2.6.9"}
+LT_KERNEL_VERSION=${LT_KERNEL_VERSION:-"2.4.1"}
+
+### SRC_URI ###
+
+# This function handles the basics of setting the SRC_URI for a glibc ebuild.
+# To use, set SRC_URI with:
+#
+#      SRC_URI="$(get_glibc_src_uri)"
+#
+# Other than the variables normally set by portage, this function's behavior
+# can be altered by setting the following:
+#
+#      GENTOO_TOOLCHAIN_BASE_URI
+#                      This sets the base URI for all gentoo-specific patch files. Note
+#                      that this variable is only important for a brief period of time,
+#                      before your source files get picked up by mirrors. However, it is
+#                      still highly suggested that you keep files in this location
+#                      available.
+#
+#      BRANCH_UPDATE
+#                      If set, this variable signals that we should be using the main
+#                      release tarball (determined by ebuild version) and applying a
+#                      CVS branch update patch against it. The location of this branch
+#                      update patch is assumed to be in ${GENTOO_TOOLCHAIN_BASE_URI}.
+#                      Just like with SNAPSHOT, this variable is ignored if the ebuild
+#                      has a _pre suffix.
+#
+#      PATCH_VER
+#      PATCH_GLIBC_VER
+#                      This should be set to the version of the gentoo patch tarball.
+#                      The resulting filename of this tarball will be:
+#                      glibc-${PATCH_GLIBC_VER:-${GLIBC_RELEASE_VER}}-patches-${PATCH_VER}.tar.bz2
+#
+#      GLIBC_MANPAGE_VERSION
+#      GLIBC_INFOPAGE_VERSION
+#                      The version of glibc for which we will download pages. This will
+#                      default to ${GLIBC_RELEASE_VER}, but we may not want to pre-generate man pages
+#                      for prerelease test ebuilds for example. This allows you to
+#                      continue using pre-generated manpages from the last stable release.
+#                      If set to "none", this will prevent the downloading of manpages,
+#                      which is useful for individual library targets.
+#
+get_glibc_src_uri() {
+       GENTOO_TOOLCHAIN_BASE_URI=${GENTOO_TOOLCHAIN_BASE_URI:-"mirror://gentoo"}
+
+       GLIBC_SRC_URI="mirror://gnu/glibc/glibc-${GLIBC_RELEASE_VER}.tar.bz2
+                      mirror://gnu/glibc/glibc-ports-${GLIBC_PORTS_VER}.tar.bz2
+                      ftp://sources.redhat.com/pub/glibc/snapshots/glibc-ports-${GLIBC_PORTS_VER}.tar.bz2
+                      mirror://gnu/glibc/glibc-libidn-${GLIBC_RELEASE_VER}.tar.bz2"
+
+       if [[ -n ${BRANCH_UPDATE} ]] ; then
+               GLIBC_SRC_URI="${GLIBC_SRC_URI}
+                       ${GENTOO_TOOLCHAIN_BASE_URI}/glibc-${GLIBC_RELEASE_VER}-branch-update-${BRANCH_UPDATE}.patch.bz2
+                       ${GENTOO_TOOLCHAIN_DEV_URI//XXX/glibc-${GLIBC_RELEASE_VER}-branch-update-${BRANCH_UPDATE}.patch.bz2}"
+       fi
+
+       if [[ -n ${PATCH_VER} ]] ; then
+               GLIBC_SRC_URI="${GLIBC_SRC_URI}
+                       ${GENTOO_TOOLCHAIN_BASE_URI}/glibc-${PATCH_GLIBC_VER:-${GLIBC_RELEASE_VER}}-patches-${PATCH_VER}.tar.bz2
+                       ${GENTOO_TOOLCHAIN_DEV_URI//XXX/glibc-${PATCH_GLIBC_VER:-${GLIBC_RELEASE_VER}}-patches-${PATCH_VER}.tar.bz2}"
+       fi
+
+       if [[ ${GLIBC_MANPAGE_VERSION} != "none" ]] ; then
+               GLIBC_SRC_URI="${GLIBC_SRC_URI}
+                       ${GENTOO_TOOLCHAIN_BASE_URI}/glibc-manpages-${GLIBC_MANPAGE_VERSION:-${GLIBC_RELEASE_VER}}.tar.bz2
+                       ${GENTOO_TOOLCHAIN_DEV_URI//XXX/glibc-manpages-${GLIBC_MANPAGE_VERSION:-${GLIBC_RELEASE_VER}}.tar.bz2}"
+       fi
+
+       if [[ ${GLIBC_INFOPAGE_VERSION} != "none" ]] ; then
+               GLIBC_SRC_URI="${GLIBC_SRC_URI}
+                       ${GENTOO_TOOLCHAIN_BASE_URI}/glibc-infopages-${GLIBC_INFOPAGE_VERSION:-${GLIBC_RELEASE_VER}}.tar.bz2
+                       ${GENTOO_TOOLCHAIN_DEV_URI//XXX/glibc-infopages-${GLIBC_INFOPAGE_VERSION:-${GLIBC_RELEASE_VER}}.tar.bz2}"
+       fi
+
+       if [[ -n ${GLIBC_LT_VER} ]] ; then
+               GLIBC_SRC_URI="${GLIBC_SRC_URI}
+                       mirror://gnu/glibc/glibc-linuxthreads-${GLIBC_LT_VER}.tar.bz2
+                       ftp://sources.redhat.com/pub/glibc/snapshots/glibc-linuxthreads-${GLIBC_LT_VER}.tar.bz2"
+       fi
+
+       echo "${GLIBC_SRC_URI}"
+}
+
+SRC_URI=$(get_glibc_src_uri)
+S=${WORKDIR}/glibc-${GLIBC_RELEASE_VER}
+
+### EXPORTED FUNCTIONS ###
+unpack_addon() {
+       local addon=$1 ver=${2:-${GLIBC_RELEASE_VER}}
+       unpack glibc-${addon}-${ver}.tar.bz2
+       mv glibc-${addon}-${ver} ${addon} || die
+}
+toolchain-glibc_src_unpack() {
+       # Check NPTL support _before_ we unpack things to save some time
+       want_nptl && check_nptl_support
+
+       unpack glibc-${GLIBC_RELEASE_VER}.tar.bz2
+
+       cd "${S}"
+       [[ -n ${GLIBC_LT_VER} ]] && unpack glibc-linuxthreads-${GLIBC_LT_VER}.tar.bz2
+       unpack_addon libidn
+       unpack_addon ports ${GLIBC_PORTS_VER}
+
+       if [[ -n ${PATCH_VER} ]] ; then
+               cd "${WORKDIR}"
+               unpack glibc-${PATCH_GLIBC_VER:-${GLIBC_RELEASE_VER}}-patches-${PATCH_VER}.tar.bz2
+               # pull out all the addons
+               local d
+               for d in extra/*/configure ; do
+                       mv "${d%/configure}" "${S}" || die "moving ${d}"
+               done
+       fi
+
+       # XXX: We should do the branchupdate, before extracting the manpages and
+       # infopages else it does not help much (mtimes change if there is a change
+       # to them with branchupdate)
+       if [[ -n ${BRANCH_UPDATE} ]] ; then
+               cd "${S}"
+               epatch "${DISTDIR}"/glibc-${GLIBC_RELEASE_VER}-branch-update-${BRANCH_UPDATE}.patch.bz2
+
+               # Snapshot date patch
+               einfo "Patching version to display snapshot date ..."
+               sed -i -e "s:\(#define RELEASE\).*:\1 \"${BRANCH_UPDATE}\":" version.h
+       fi
+
+       if [[ ${GLIBC_MANPAGE_VERSION} != "none" ]] ; then
+               cd "${WORKDIR}"
+               unpack glibc-manpages-${GLIBC_MANPAGE_VERSION:-${GLIBC_RELEASE_VER}}.tar.bz2
+       fi
+
+       if [[ ${GLIBC_INFOPAGE_VERSION} != "none" ]] ; then
+               cd "${S}"
+               unpack glibc-infopages-${GLIBC_INFOPAGE_VERSION:-${GLIBC_RELEASE_VER}}.tar.bz2
+       fi
+
+       if [[ -n ${PATCH_VER} ]] ; then
+               cd "${S}"
+               EPATCH_MULTI_MSG="Applying Gentoo Glibc Patchset ${PATCH_GLIBC_VER:-${GLIBC_RELEASE_VER}}-${PATCH_VER} ..." \
+               EPATCH_EXCLUDE=${GLIBC_PATCH_EXCLUDE} \
+               EPATCH_SUFFIX="patch" \
+               ARCH=$(tc-arch) \
+               epatch "${WORKDIR}"/patches
+
+               # tag, glibc is it
+               [[ -e csu/Banner ]] && die "need new banner location"
+               echo "Gentoo patchset ${PATCH_VER}" > csu/Banner
+       fi
+
+       if use hardened ; then
+               cd "${S}"
+               einfo "Patching to get working PIE binaries on PIE (hardened) platforms"
+               epatch "${FILESDIR}"/2.5/glibc-2.5-hardened-pie.patch
+               epatch "${FILESDIR}"/2.5/glibc-2.5-hardened-configure-picdefault.patch
+               epatch "${FILESDIR}"/2.5/glibc-2.5-hardened-inittls-nosysenter.patch
+
+               einfo "Installing Hardened Gentoo SSP handler"
+               cp -f "${FILESDIR}"/2.5/glibc-2.4-gentoo-stack_chk_fail.c \
+                       debug/stack_chk_fail.c || die
+
+               if use debug ; then
+                       # When using Hardened Gentoo stack handler, have smashes dump core for
+                       # analysis - debug only, as core could be an information leak
+                       # (paranoia).
+                       sed -i \
+                               -e '/^CFLAGS-backtrace.c/ iCFLAGS-stack_chk_fail.c = -DSSP_SMASH_DUMPS_CORE' \
+                               debug/Makefile \
+                               || die "Failed to modify debug/Makefile for debug stack handler"
+               fi
+
+               # Build nscd with ssp-all
+               sed -i \
+                       -e 's:-fstack-protector$:-fstack-protector-all:' \
+                       nscd/Makefile \
+                       || die "Failed to ensure nscd builds with ssp-all"
+       fi
+
+       gnuconfig_update
+}
+
+toolchain-glibc_src_compile() {
+       echo
+       local v
+       for v in ABI CBUILD CHOST CTARGET CBUILD_OPT CTARGET_OPT CC CFLAGS ; do
+               einfo " $(printf '%15s' ${v}:)   ${!v}"
+       done
+       echo
+
+       if want_linuxthreads ; then
+               glibc_do_configure linuxthreads
+               einfo "Building GLIBC with linuxthreads..."
+               make PARALLELMFLAGS="${MAKEOPTS}" || die "make for ${ABI} failed"
+       fi
+       if want_nptl ; then
+               # ... and then do the optional nptl build
+               unset LD_ASSUME_KERNEL
+               glibc_do_configure nptl
+               einfo "Building GLIBC with NPTL..."
+               make PARALLELMFLAGS="${MAKEOPTS}" || die "make for ${ABI} failed"
+       fi
+}
+
+toolchain-glibc_headers_compile() {
+       local GBUILDDIR=${WORKDIR}/build-${ABI}-${CTARGET}-headers
+       mkdir -p "${GBUILDDIR}"
+       cd "${GBUILDDIR}"
+
+       # Pick out the correct location for build headers
+       local myconf="--disable-sanity-checks --enable-hacker-mode"
+       myconf="${myconf}
+               --enable-add-ons=nptl,ports
+               --without-cvs
+               --enable-bind-now
+               --build=${CBUILD_OPT:-${CBUILD}}
+               --host=${CTARGET_OPT:-${CTARGET}}
+               --with-headers=$(alt_build_headers)
+               --prefix=/usr
+               ${EXTRA_ECONF}"
+
+       einfo "Configuring GLIBC headers with: ${myconf// /\n\t\t}"
+       CC=gcc \
+       CFLAGS="-O1 -pipe" \
+       "${S}"/configure ${myconf} || die "failed to configure glibc"
+}
+
+toolchain-glibc_src_test() {
+       cd "${WORKDIR}"/build-${ABI}-${CTARGET}-$1 || die "cd build-${ABI}-${CTARGET}-$1"
+       unset LD_ASSUME_KERNEL
+       make check && return 0
+       einfo "make check failed - re-running with --ignore-errors to get the rest of the results"
+       make -k check
+       ewarn "make check failed for ${ABI}-${CTARGET}-$1"
+       return 1
+}
+
+toolchain-glibc_pkg_preinst() {
+       # PPC64+others may want to eventually be added to this logic if they
+       # decide to be multilib compatible and FHS compliant. note that this
+       # chunk of FHS compliance only applies to 64bit archs where 32bit
+       # compatibility is a major concern (not IA64, for example).
+
+       # amd64's 2005.0 is the first amd64 profile to not need this code.
+       # 2005.0 is setup properly, and this is executed as part of the
+       # 2004.3 -> 2005.0 upgrade script.
+       # It can be removed after 2004.3 has been purged from portage.
+       { use amd64 || use ppc64; } && [ "$(get_libdir)" == "lib64" ] && ! has_multilib_profile && fix_lib64_symlinks
+
+       # it appears that /lib/tls is sometimes not removed. See bug
+       # 69258 for more info.
+       if [[ -d ${ROOT}/$(alt_libdir)/tls ]] && ! { want_nptl && want_linuxthreads; }; then
+               addwrite "${ROOT}"/$(alt_libdir)/
+               ewarn "nptlonly or -nptl in USE, removing /${ROOT}$(alt_libdir)/tls..."
+               rm -r "${ROOT}"/$(alt_libdir)/tls || die
+       fi
+
+       # Shouldnt need to keep this updated
+       [[ -e ${ROOT}/etc/locale.gen ]] && rm -f "${D}"/etc/locale.gen
+}
+
+toolchain-glibc_src_install() {
+       # These should not be set, else the
+       # zoneinfo do not always get installed ...
+       unset LANGUAGE LANG LC_ALL
+
+       local GBUILDDIR
+       if want_linuxthreads ; then
+               GBUILDDIR=${WORKDIR}/build-${ABI}-${CTARGET}-linuxthreads
+       else
+               GBUILDDIR=${WORKDIR}/build-${ABI}-${CTARGET}-nptl
+       fi
+
+       local install_root=${D}
+       is_crosscompile && install_root="${install_root}/usr/${CTARGET}"
+       if want_linuxthreads ; then
+               cd "${WORKDIR}"/build-${ABI}-${CTARGET}-linuxthreads
+               einfo "Installing GLIBC ${ABI} with linuxthreads ..."
+               make PARALLELMFLAGS="${MAKEOPTS}" \
+                       install_root="${install_root}" \
+                       install || die
+       else # nptlonly
+               cd "${WORKDIR}"/build-${ABI}-${CTARGET}-nptl
+               einfo "Installing GLIBC ${ABI} with NPTL ..."
+               make PARALLELMFLAGS="${MAKEOPTS}" \
+                       install_root="${install_root}" \
+                       install || die
+       fi
+
+       if is_crosscompile ; then
+               # punt all the junk not needed by a cross-compiler
+               cd "${D}"/usr/${CTARGET} || die
+               rm -rf ./{,usr/}{bin,etc,sbin,share} ./{,usr/}*/{gconv,misc}
+       fi
+
+       if want_linuxthreads && want_nptl ; then
+               einfo "Installing NPTL to $(alt_libdir)/tls/..."
+               cd "${WORKDIR}"/build-${ABI}-${CTARGET}-nptl
+               dodir $(alt_libdir)/tls $(alt_usrlibdir)/nptl
+
+               local l src_lib
+               for l in libc libm librt libpthread libthread_db ; do
+                       # take care of shared lib first ...
+                       l=${l}.so
+                       if [[ -e ${l} ]] ; then
+                               src_lib=${l}
+                       else
+                               src_lib=$(eval echo */${l})
+                       fi
+                       cp -a ${src_lib} "${D}"$(alt_libdir)/tls/${l} || die "copying nptl ${l}"
+                       fperms a+rx $(alt_libdir)/tls/${l}
+                       dosym ${l} $(alt_libdir)/tls/$(scanelf -qSF'%S#F' ${src_lib})
+
+                       # then grab the linker script or the symlink ...
+                       if [[ -L ${D}$(alt_usrlibdir)/${l} ]] ; then
+                               dosym $(alt_libdir)/tls/${l} $(alt_usrlibdir)/nptl/${l}
+                       else
+                               sed \
+                                       -e "s:/${l}:/tls/${l}:g" \
+                                       -e "s:/${l/%.so/_nonshared.a}:/nptl/${l/%.so/_nonshared.a}:g" \
+                                       "${D}"$(alt_usrlibdir)/${l} > "${D}"$(alt_usrlibdir)/nptl/${l}
+                       fi
+
+                       # then grab the static lib ...
+                       src_lib=${src_lib/%.so/.a}
+                       [[ ! -e ${src_lib} ]] && src_lib=${src_lib/%.a/_pic.a}
+                       cp -a ${src_lib} "${D}"$(alt_usrlibdir)/nptl/ || die "copying nptl ${src_lib}"
+                       src_lib=${src_lib/%.a/_nonshared.a}
+                       if [[ -e ${src_lib} ]] ; then
+                               cp -a ${src_lib} "${D}"$(alt_usrlibdir)/nptl/ || die "copying nptl ${src_lib}"
+                       fi
+               done
+
+               # use the nptl linker instead of the linuxthreads one as the linuxthreads
+               # one may lack TLS support and that can be really bad for business
+               cp -a elf/ld.so "${D}"$(alt_libdir)/$(scanelf -qSF'%S#F' elf/ld.so) || die "copying nptl interp"
+       fi
+
+       # We'll take care of the cache ourselves
+       rm -f "${D}"/etc/ld.so.cache
+
+       # Some things want this, notably ash.
+       dosym libbsd-compat.a $(alt_usrlibdir)/libbsd.a
+
+       # Handle includes for different ABIs
+       prep_ml_includes $(alt_headers)
+
+       # When cross-compiling for a non-multilib setup, make sure we have
+       # lib and a proper symlink setup
+       if is_crosscompile && ! use multilib && ! has_multilib_profile && [[ $(get_libdir) != "lib" ]] ; then
+               cd "${D}"$(alt_libdir)/..
+               mv $(get_libdir) lib || die
+               ln -s lib $(get_libdir) || die
+               cd "${D}"$(alt_usrlibdir)/..
+               mv $(get_libdir) lib || die
+               ln -s lib $(get_libdir) || die
+       fi
+
+       #################################################################
+       # EVERYTHING AFTER THIS POINT IS FOR NATIVE GLIBC INSTALLS ONLY #
+       # Make sure we install some symlink hacks so that when we build
+       # a 2nd stage cross-compiler, gcc finds the target system
+       # headers correctly.  See gcc/doc/gccinstall.info
+       if is_crosscompile ; then
+               dosym usr/include /usr/${CTARGET}/sys-include
+               return 0
+       fi
+
+       # Everything past this point just needs to be done once ...
+       is_final_abi || return 0
+
+       # Make sure the non-native interp can be found on multilib systems
+       if has_multilib_profile ; then
+               case $(tc-arch) in
+                       amd64)
+                               [[ ! -e ${D}/lib ]] && dosym $(get_abi_LIBDIR amd64) /lib
+                               dosym ../$(get_abi_LIBDIR x86)/ld-linux.so.2 /lib/ld-linux.so.2
+                               ;;
+                       ppc64)
+                               [[ ! -e ${D}/lib ]] && dosym $(get_abi_LIBDIR ppc64) /lib
+                               dosym ../$(get_abi_LIBDIR ppc)/ld.so.1 /lib/ld.so.1
+                               ;;
+               esac
+       fi
+
+       # Files for Debian-style locale updating
+       dodir /usr/share/i18n
+       sed \
+               -e "/^#/d" \
+               -e "/SUPPORTED-LOCALES=/d" \
+               -e "s: \\\\::g" -e "s:/: :g" \
+               "${S}"/localedata/SUPPORTED > "${D}"/usr/share/i18n/SUPPORTED \
+               || die "generating /usr/share/i18n/SUPPORTED failed"
+       cd "${WORKDIR}"/extra/locale
+       dosbin locale-gen || die
+       doman *.[0-8]
+       insinto /etc
+       doins locale.gen || die
+
+       # Make sure all the ABI's can find the locales and so we only
+       # have to generate one set
+       local a
+       keepdir /usr/$(get_libdir)/locale
+       for a in $(get_install_abis) ; do
+               if [[ ! -e ${D}/usr/$(get_abi_LIBDIR ${a})/locale ]] ; then
+                       dosym /usr/$(get_libdir)/locale /usr/$(get_abi_LIBDIR ${a})/locale
+               fi
+       done
+
+       if ! has noinfo ${FEATURES} && [[ ${GLIBC_INFOPAGE_VERSION} != "none" ]] ; then
+               einfo "Installing info pages..."
+
+               make \
+                       -C "${GBUILDDIR}" \
+                       PARALLELMFLAGS="${MAKEOPTS}" \
+                       install_root="${install_root}" \
+                       info -i || die
+       fi
+
+       if [[ ${GLIBC_MANPAGE_VERSION} != "none" ]] ; then
+               einfo "Installing man pages..."
+
+               # Install linuxthreads man pages even if nptl is enabled
+               cd "${WORKDIR}"/man
+               doman *.3thr
+       fi
+
+       cd "${S}"
+
+       # Install misc network config files
+       insinto /etc
+       doins nscd/nscd.conf posix/gai.conf nss/nsswitch.conf || die
+       doins "${WORKDIR}"/extra/etc/*.conf || die
+       doinitd "${WORKDIR}"/extra/etc/nscd || die
+
+       dodoc BUGS ChangeLog* CONFORMANCE FAQ NEWS NOTES PROJECTS README*
+
+       # Prevent overwriting of the /etc/localtime symlink.  We'll handle the
+       # creation of the "factory" symlink in pkg_postinst().
+       rm -f "${D}"/etc/localtime
+
+       # simple test to make sure our new glibc isnt completely broken.
+       # for now, skip the multilib scenario.  also make sure we don't
+       # test with statically built binaries since they will fail.
+       [[ ${CBUILD} != ${CHOST} ]] && return 0
+       [[ $(get_libdir) != "lib" ]] && return 0
+       for x in date env ls true uname ; do
+               x=$(type -p ${x})
+               [[ -z ${x} ]] && continue
+               striptest=$(LC_ALL="C" file -L ${x} 2>/dev/null)
+               [[ -z ${striptest} ]] && continue
+               [[ ${striptest} == *"statically linked"* ]] && continue
+               "${D}"/$(get_libdir)/ld-*.so \
+                       --library-path "${D}"/$(get_libdir) \
+                       ${x} > /dev/null \
+                       || die "simple run test (${x}) failed"
+       done
+}
+
+toolchain-glibc_headers_install() {
+       local GBUILDDIR=${WORKDIR}/build-${ABI}-${CTARGET}-headers
+       cd "${GBUILDDIR}"
+       make install_root="${D}/usr/${CTARGET}" install-headers || die "install-headers failed"
+       # Copy over headers that are not part of install-headers ... these
+       # are pretty much taken verbatim from crosstool, see it for more details
+       insinto $(alt_headers)/bits
+       doins misc/syscall-list.h bits/stdio_lim.h || die "doins include bits"
+       insinto $(alt_headers)/gnu
+       doins "${S}"/include/gnu/stubs.h || die "doins include gnu"
+       # Make sure we install the sys-include symlink so that when 
+       # we build a 2nd stage cross-compiler, gcc finds the target 
+       # system headers correctly.  See gcc/doc/gccinstall.info
+       dosym usr/include /usr/${CTARGET}/sys-include
+}
+
+toolchain-glibc_pkg_postinst() {
+       # Mixing nptlonly and -nptlonly glibc can prove dangerous if libpthread
+       # isn't removed in unmerge which happens sometimes.  See bug #87671
+       if ! is_crosscompile && want_linuxthreads && [[ ${ROOT} == "/" ]] ; then
+               for libdir in $(get_all_libdirs) ; do
+                       for f in "${ROOT}"/${libdir}/libpthread-2.* "${ROOT}"/${libdir}/libpthread-0.6* ; do
+                               if [[ -f ${f} ]] ; then
+                                       rm -f ${f}
+                                       ldconfig
+                               fi
+                       done
+               done
+       fi
+
+       if ! tc-is-cross-compiler && [[ -x ${ROOT}/usr/sbin/iconvconfig ]] ; then
+               # Generate fastloading iconv module configuration file.
+               "${ROOT}"/usr/sbin/iconvconfig --prefix="${ROOT}"
+       fi
+
+       if [[ ! -e ${ROOT}/lib/ld.so.1 ]] && use ppc64 && ! has_multilib_profile ; then
+               ## SHOULDN'T THIS BE lib64??
+               ln -s ld64.so.1 "${ROOT}"/lib/ld.so.1
+       fi
+
+       if ! is_crosscompile && [[ ${ROOT} == "/" ]] ; then
+               # Reload init ...
+               /sbin/telinit U &> /dev/null
+
+               # if the host locales.gen contains no entries, we'll install everything
+               local locale_list="${ROOT}etc/locale.gen"
+               if [[ -z $(locale-gen --list --config "${locale_list}") ]] ; then
+                       ewarn "Generating all locales; edit /etc/locale.gen to save time/space"
+                       locale_list="${ROOT}usr/share/i18n/SUPPORTED"
+               fi
+               local x jobs
+               for x in ${MAKEOPTS} ; do [[ ${x} == -j* ]] && jobs=${x#-j} ; done
+               locale-gen -j ${jobs:-1} --config "${locale_list}"
+       fi
+
+       echo
+       einfo "Gentoo's glibc no longer includes mdns."
+       einfo "If you want mdns, emerge the sys-auth/nss-mdns package."
+       echo
+
+       if want_nptl && want_linuxthreads ; then
+               einfo "The default behavior of glibc on your system is to use NPTL.  If"
+               einfo "you want to use linuxthreads for a particular program, start it"
+               einfo "by executing 'LD_ASSUME_KERNEL=${LT_KERNEL_VERSION} <program> [<options>]'"
+               echo
+       fi
+}
+
+### SUPPORT FUNCTIONS ###
+# We need to be able to set alternative headers for
+# compiling for non-native platform
+# Will also become useful for testing kernel-headers without screwing up
+# the whole system.
+# note: intentionally undocumented.
+alt_headers() {
+       if [[ -z ${ALT_HEADERS} ]] ; then
+               if is_crosscompile ; then
+                       ALT_HEADERS="/usr/${CTARGET}/usr/include"
+               else
+                       ALT_HEADERS="/usr/include"
+               fi
+       fi
+       echo "${ALT_HEADERS}"
+}
+alt_build_headers() {
+       if [[ -z ${ALT_BUILD_HEADERS} ]] ; then
+               ALT_BUILD_HEADERS=$(alt_headers)
+               tc-is-cross-compiler && ALT_BUILD_HEADERS=${ROOT}$(alt_headers)
+       fi
+       echo "${ALT_BUILD_HEADERS}"
+}
+
+alt_libdir() {
+       if is_crosscompile ; then
+               echo /usr/${CTARGET}/$(get_libdir)
+       else
+               echo /$(get_libdir)
+       fi
+}
+
+alt_usrlibdir() {
+       if is_crosscompile ; then
+               echo /usr/${CTARGET}/usr/$(get_libdir)
+       else
+               echo /usr/$(get_libdir)
+       fi
+}
+
+setup_flags() {
+       # Make sure host make.conf doesn't pollute us
+       if is_crosscompile || tc-is-cross-compiler ; then
+               CHOST=${CTARGET} strip-unsupported-flags
+       fi
+
+       # Store our CFLAGS because it's changed depending on which CTARGET
+       # we are building when pulling glibc on a multilib profile
+       CFLAGS_BASE=${CFLAGS_BASE-${CFLAGS}}
+       CFLAGS=${CFLAGS_BASE}
+       CXXFLAGS_BASE=${CXXFLAGS_BASE-${CXXFLAGS}}
+       CXXFLAGS=${CXXFLAGS_BASE}
+       ASFLAGS_BASE=${ASFLAGS_BASE-${ASFLAGS}}
+       ASFLAGS=${ASFLAGS_BASE}
+
+       # Over-zealous CFLAGS can often cause problems.  What may work for one
+       # person may not work for another.  To avoid a large influx of bugs
+       # relating to failed builds, we strip most CFLAGS out to ensure as few
+       # problems as possible.
+       strip-flags
+       strip-unsupported-flags
+       filter-flags -m32 -m64 -mabi=*
+
+       unset CBUILD_OPT CTARGET_OPT
+       if has_multilib_profile ; then
+               CTARGET_OPT=$(get_abi_CTARGET)
+               [[ -z ${CTARGET_OPT} ]] && CTARGET_OPT=$(get_abi_CHOST)
+       fi
+
+       case $(tc-arch) in
+               amd64)
+                       # Punt this when amd64's 2004.3 is removed
+                       CFLAGS_x86="-m32"
+               ;;
+               ppc)
+                       append-flags "-freorder-blocks"
+               ;;
+               sparc)
+                       # Both sparc and sparc64 can use -fcall-used-g6.  -g7 is bad, though.
+                       filter-flags "-fcall-used-g7"
+                       append-flags "-fcall-used-g6"
+                       filter-flags "-mvis"
+
+                       if is_crosscompile || [[ ${PROFILE_ARCH} == "sparc64" ]] || { has_multilib_profile && ! tc-is-cross-compiler; } ; then
+                               case ${ABI} in
+                                       sparc64)
+                                               filter-flags -Wa,-xarch -Wa,-A
+
+                                               if is-flag "-mcpu=ultrasparc3"; then
+                                                       CTARGET_OPT="sparc64b-unknown-linux-gnu"
+                                                       append-flags "-Wa,-xarch=v9b"
+                                                       export ASFLAGS="${ASFLAGS} -Wa,-xarch=v9b"
+                                               else
+                                                       CTARGET_OPT="sparc64-unknown-linux-gnu"
+                                                       append-flags "-Wa,-xarch=v9a"
+                                                       export ASFLAGS="${ASFLAGS} -Wa,-xarch=v9a"
+                                               fi
+                                       ;;
+                                       *)
+                                               if is-flag "-mcpu=ultrasparc3"; then
+                                                       CTARGET_OPT="sparcv9b-unknown-linux-gnu"
+                                               else
+                                                       CTARGET_OPT="sparcv9-unknown-linux-gnu"
+                                               fi
+                                       ;;
+                               esac
+                       else
+                               if is-flag "-mcpu=ultrasparc3"; then
+                                       CTARGET_OPT="sparcv9b-unknown-linux-gnu"
+                               elif { is_crosscompile && want_nptl; } || is-flag "-mcpu=ultrasparc2" || is-flag "-mcpu=ultrasparc"; then
+                                       CTARGET_OPT="sparcv9-unknown-linux-gnu"
+                               fi
+                       fi
+               ;;
+       esac
+
+       if [[ -n ${CTARGET_OPT} && ${CBUILD} == ${CHOST} ]] && ! is_crosscompile; then
+               CBUILD_OPT=${CTARGET_OPT}
+       fi
+
+       # Lock glibc at -O2 -- linuxthreads needs it and we want to be
+       # conservative here.  -fno-strict-aliasing is to work around #155906
+       filter-flags -O?
+       append-flags -O2 -fno-strict-aliasing
+
+       # building glibc with SSP is fraught with difficulty, especially
+       # due to __stack_chk_fail_local which would mean significant changes
+       # to the glibc build process. See bug #94325
+       filter-flags -fstack-protector
+
+       # Don't let the compiler automatically build PIEs unless USE=hardened.
+       use hardened || filter-flags -fPIE
+}
+
+check_kheader_version() {
+       local version=$(
+               printf '#include <linux/version.h>\nLINUX_VERSION_CODE\n' | \
+               $(tc-getCPP ${CTARGET}) -I "$(alt_build_headers)" | \
+               tail -n 1
+       )
+       [[ ${version} -ge "$1" ]]
+}
+
+check_nptl_support() {
+       local min_kernel_version=$(KV_to_int "${NPTL_KERNEL_VERSION}")
+
+       echo
+
+       ebegin "Checking gcc for __thread support"
+       if ! eend $(want__thread ; echo $?) ; then
+               echo
+               eerror "Could not find a gcc that supports the __thread directive!"
+               eerror "Please update your binutils/gcc and try again."
+               die "No __thread support in gcc!"
+       fi
+
+       if ! is_crosscompile && ! tc-is-cross-compiler ; then
+               # Building fails on an non-supporting kernel
+               ebegin "Checking kernel version (>=${NPTL_KERNEL_VERSION})"
+               if ! eend $([[ $(get_KV) -ge ${min_kernel_version} ]] ; echo $?) ; then
+                       echo
+                       eerror "You need a kernel of at least version ${NPTL_KERNEL_VERSION}"
+                       eerror "for NPTL support!"
+                       die "Kernel version too low!"
+               fi
+       fi
+
+       # Building fails with too low linux-headers
+       ebegin "Checking linux-headers version (>=${NPTL_KERNEL_VERSION})"
+       if ! eend $(check_kheader_version "${min_kernel_version}" ; echo $?) ; then
+               echo
+               eerror "You need linux-headers of at least version ${NPTL_KERNEL_VERSION}"
+               eerror "for NPTL support!"
+               die "linux-headers version too low!"
+       fi
+
+       echo
+}
+
+want_nptl() {
+       want_tls || return 1
+       use nptl || return 1
+
+       # Only list the arches that cannot do NPTL
+       case $(tc-arch) in
+               m68k) return 1;;
+               sparc)
+                       # >= v9 is needed for nptl.
+                       [[ ${PROFILE_ARCH} == "sparc" ]] && return 1
+               ;;
+       esac
+
+       return 0
+}
+
+want_linuxthreads() {
+       ! use nptlonly && return 0
+       want_nptl || return 0
+       return 1
+}
+
+want_tls() {
+       # Archs that can use TLS (Thread Local Storage)
+       case $(tc-arch) in
+               sparc)
+                       # 2.3.6 should have tls support on sparc64
+                       # when using newer binutils
+                       case ${CTARGET/-*} in
+                               sparc64*) return 1 ;;
+                               *) return 0 ;;
+                       esac
+               ;;
+               x86)
+                       # requires i486 or better #106556
+                       [[ ${CTARGET} == i[4567]86* ]] && return 0
+                       return 1
+               ;;
+       esac
+
+       return 0
+}
+
+want__thread() {
+       want_tls || return 1
+
+       # For some reason --with-tls --with__thread is causing segfaults on sparc32.
+       [[ ${PROFILE_ARCH} == "sparc" ]] && return 1
+
+       [[ -n ${WANT__THREAD} ]] && return ${WANT__THREAD}
+
+       echo 'extern __thread int i;' > "${T}"/test-__thread.c
+       $(tc-getCC ${CTARGET}) -c "${T}"/test-__thread.c -o "${T}"/test-__thread.o &> /dev/null
+       WANT__THREAD=$?
+       rm -f "${T}"/test-__thread.[co]
+
+       return ${WANT__THREAD}
+}
+
+glibc_do_configure() {
+       local myconf
+
+       # set addons
+       pushd "${S}" > /dev/null
+       local ADDONS=$(echo */configure | sed \
+               -e 's:/configure::g' \
+               -e 's:\(linuxthreads\|nptl\|rtkaio\|glibc-compat\)\( \|$\)::g' \
+               -e 's: \+$::' \
+               -e 's! !,!g' \
+               -e 's!^!,!' \
+               -e '/^,\*$/d')
+       popd > /dev/null
+
+       use nls || myconf="${myconf} --disable-nls"
+       myconf="${myconf} $(use_enable hardened stackguard-randomization)"
+       if [[ $(<"${T}"/.ssp.compat) == "yes" ]] ; then
+               myconf="${myconf} --enable-old-ssp-compat"
+       else
+               myconf="${myconf} --disable-old-ssp-compat"
+       fi
+
+       use glibc-omitfp && myconf="${myconf} --enable-omitfp"
+
+       [[ ${CTARGET//_/-} == *-softfloat-* ]] && myconf="${myconf} --without-fp"
+
+       if [[ $1 == "linuxthreads" ]] ; then
+               if want_tls ; then
+                       myconf="${myconf} --with-tls"
+
+                       if ! want__thread || use glibc-compat20 || [[ ${LT_KERNEL_VERSION} == 2.[02].* ]] ; then
+                               myconf="${myconf} --without-__thread"
+                       else
+                               myconf="${myconf} --with-__thread"
+                       fi
+               else
+                       myconf="${myconf} --without-tls --without-__thread"
+               fi
+
+               myconf="${myconf} --disable-sanity-checks"
+               myconf="${myconf} --enable-add-ons=ports,linuxthreads${ADDONS}"
+               myconf="${myconf} --enable-kernel=${LT_KERNEL_VERSION}"
+       elif [[ $1 == "nptl" ]] ; then
+               myconf="${myconf} --with-tls --with-__thread"
+               myconf="${myconf} --enable-add-ons=ports,nptl${ADDONS}"
+               myconf="${myconf} --enable-kernel=${NPTL_KERNEL_VERSION}"
+       else
+               die "invalid pthread option"
+       fi
+
+       # Since SELinux support is only required for nscd, only enable it if:
+       # 1. USE selinux
+       # 2. ! USE build
+       # 3. only for the primary ABI on multilib systems
+       if use selinux && ! use build ; then
+               if use multilib || has_multilib_profile ; then
+                       if is_final_abi ; then
+                               myconf="${myconf} --with-selinux"
+                       else
+                               myconf="${myconf} --without-selinux"
+                       fi
+               else
+                       myconf="${myconf} --with-selinux"
+               fi
+       else
+               myconf="${myconf} --without-selinux"
+       fi
+
+       myconf="${myconf}
+               --without-cvs
+               --enable-bind-now
+               --build=${CBUILD_OPT:-${CBUILD}}
+               --host=${CTARGET_OPT:-${CTARGET}}
+               $(use_enable profile)
+               --without-gd
+               --with-headers=$(alt_build_headers)
+               --prefix=/usr
+               --libdir=/usr/$(get_libdir)
+               --mandir=/usr/share/man
+               --infodir=/usr/share/info
+               --libexecdir=/usr/$(get_libdir)/misc/glibc
+               ${EXTRA_ECONF}"
+
+       # There is no configure option for this and we need to export it
+       # since the glibc build will re-run configure on itself
+       export libc_cv_slibdir=/$(get_libdir)
+
+       has_version app-admin/eselect-compiler || export CC=$(tc-getCC ${CTARGET})
+
+       local GBUILDDIR=${WORKDIR}/build-${ABI}-${CTARGET}-$1
+       mkdir -p "${GBUILDDIR}"
+       cd "${GBUILDDIR}"
+       einfo "Configuring GLIBC for $1 with: ${myconf// /\n\t\t}"
+       "${S}"/configure ${myconf} || die "failed to configure glibc"
+}
+
+fix_lib64_symlinks() {
+       # the original Gentoo/AMD64 devs decided that since 64bit is the native
+       # bitdepth for AMD64, lib should be used for 64bit libraries. however,
+       # this ignores the FHS and breaks multilib horribly... especially
+       # since it wont even work without a lib64 symlink anyways. *rolls eyes*
+       # see bug 59710 for more information.
+       # Travis Tilley <lv@gentoo.org> (08 Aug 2004)
+       if [ -L ${ROOT}/lib64 ] ; then
+               ewarn "removing /lib64 symlink and moving lib to lib64..."
+               ewarn "dont hit ctrl-c until this is done"
+               addwrite ${ROOT}/
+               rm ${ROOT}/lib64
+               # now that lib64 is gone, nothing will run without calling ld.so
+               # directly. luckily the window of brokenness is almost non-existant
+               use amd64 && /lib/ld-linux-x86-64.so.2 /bin/mv ${ROOT}/lib ${ROOT}/lib64
+               use ppc64 && /lib/ld64.so.1 /bin/mv ${ROOT}/lib ${ROOT}/lib64
+               # all better :)
+               ldconfig
+               ln -s lib64 ${ROOT}/lib
+               einfo "done! :-)"
+               einfo "fixed broken lib64/lib symlink in ${ROOT}"
+       fi
+       if [ -L ${ROOT}/usr/lib64 ] ; then
+               addwrite ${ROOT}/usr
+               rm ${ROOT}/usr/lib64
+               mv ${ROOT}/usr/lib ${ROOT}/usr/lib64
+               ln -s lib64 ${ROOT}/usr/lib
+               einfo "fixed broken lib64/lib symlink in ${ROOT}/usr"
+       fi
+       if [ -L ${ROOT}/usr/X11R6/lib64 ] ; then
+               addwrite ${ROOT}/usr/X11R6
+               rm ${ROOT}/usr/X11R6/lib64
+               mv ${ROOT}/usr/X11R6/lib ${ROOT}/usr/X11R6/lib64
+               ln -s lib64 ${ROOT}/usr/X11R6/lib
+               einfo "fixed broken lib64/lib symlink in ${ROOT}/usr/X11R6"
+       fi
+}
+
+use_multilib() {
+       case ${CTARGET} in
+               sparc64*|mips64*|x86_64*|powerpc64*|s390x*)
+                       has_multilib_profile || use multilib ;;
+               *)  false ;;
+       esac
+}
+
+# Setup toolchain variables that would be defined in the profiles for these archs.
+setup_env() {
+       # These should not be set, else the zoneinfo do not always get installed ...
+       unset LANGUAGE LANG LC_ALL
+       # silly users
+       unset LD_RUN_PATH
+
+       if is_crosscompile || tc-is-cross-compiler ; then
+               multilib_env ${CTARGET}
+               if ! use multilib ; then
+                       MULTILIB_ABIS=${DEFAULT_ABI}
+               else
+                       MULTILIB_ABIS=${MULTILIB_ABIS:-${DEFAULT_ABI}}
+               fi
+
+               # If the user has CFLAGS_<CTARGET> in their make.conf, use that,
+               # and fall back on CFLAGS.
+               local VAR=CFLAGS_${CTARGET//[-.]/_}
+               CFLAGS=${!VAR-${CFLAGS}}
+       fi
+
+       setup_flags
+
+       export ABI=${ABI:-${DEFAULT_ABI:-default}}
+
+       if is_crosscompile || tc-is-cross-compiler ; then
+               local VAR=CFLAGS_${ABI}
+               # We need to export CFLAGS with abi information in them because
+               # glibc's configure script checks CFLAGS for some targets (like mips)
+               export CFLAGS="${!VAR} ${CFLAGS}"
+       fi
+}
+
+### /ECLASS PUNTAGE ###
+
+if is_crosscompile ; then
+       SLOT="${CTARGET}-2.2"
+else
+       SLOT="2.2"
+fi
+
+# we'll handle stripping ourself #46186
+RESTRICT="nostrip multilib-pkg-force"
+
+# General: We need a new-enough binutils for as-needed
+# arch: we need to make sure our binutils/gcc supports TLS
+DEPEND=">=sys-devel/gcc-3.4.4
+       arm? ( >=sys-devel/binutils-2.16.90 >=sys-devel/gcc-4.1.0 )
+       ppc? ( >=sys-devel/gcc-4.1.0 )
+       ppc64? ( >=sys-devel/gcc-4.1.0 )
+       nptl? ( || ( >=sys-kernel/mips-headers-${NPTL_KERNEL_VERSION} >=sys-kernel/linux-headers-${NPTL_KERNEL_VERSION} ) )
+       >=sys-devel/binutils-2.15.94
+       || ( >=sys-devel/gcc-config-1.3.12 app-admin/eselect-compiler )
+       >=app-misc/pax-utils-0.1.10
+       virtual/os-headers
+       nls? ( sys-devel/gettext )
+       selinux? ( !build? ( sys-libs/libselinux ) )"
+RDEPEND="nls? ( sys-devel/gettext )
+       selinux? ( !build? ( sys-libs/libselinux ) )"
+
+if [[ ${CATEGORY/cross-} != ${CATEGORY} ]] ; then
+       DEPEND="${DEPEND} ${CATEGORY}/gcc"
+
+       if [[ ${CATEGORY} == *-linux* ]] ; then
+               if [[ ${CATEGORY} == cross-mips* ]] ; then
+                       DEPEND="${DEPEND} >=${CATEGORY}/mips-headers-2.6.10"
+               else
+                       DEPEND="${DEPEND} ${CATEGORY}/linux-headers"
+               fi
+       fi
+else
+       DEPEND="${DEPEND} >=sys-libs/timezone-data-2007c"
+       RDEPEND="${RDEPEND} sys-libs/timezone-data"
+fi
+
+pkg_setup() {
+       # prevent native builds from downgrading ... maybe update to allow people
+       # to change between diff -r versions ? (2.3.6-r4 -> 2.3.6-r2)
+       if ! is_crosscompile && ! tc-is-cross-compiler ; then
+               if has_version '>'${CATEGORY}/${PF} ; then
+                       eerror "Sanity check to keep you from breaking your system:"
+                       eerror " Downgrading glibc is not supported and a sure way to destruction"
+                       die "aborting to save your system"
+               fi
+       fi
+
+       if [[ ${CTARGET} == i386-* ]] ; then
+               eerror "i386 CHOSTs are no longer supported."
+               eerror "Chances are you don't actually want/need i386."
+               eerror "Please read http://www.gentoo.org/doc/en/change-chost.xml"
+               die "please fix your CHOST"
+       fi
+
+       if use nptlonly && ! use nptl ; then
+               eerror "If you want nptlonly, add nptl to your USE too ;p"
+               die "nptlonly without nptl"
+       fi
+
+       if [[ -e /proc/xen ]] && [[ $(tc-arch) == "x86" ]] && ! is-flag -mno-tls-direct-seg-refs ; then
+               ewarn "You are using Xen but don't have -mno-tls-direct-seg-refs in your CFLAGS."
+               ewarn "This will result in a 50% performance penalty, which is probably not what you want."
+       fi
+
+       if ! type -p scanelf > /dev/null ; then
+               eerror "You do not have pax-utils installed."
+               die "install pax-utils"
+       fi
+}
+
+src_unpack() {
+       setup_env
+
+       toolchain-glibc_src_unpack
+
+       # Backwards SSP support
+       cd "${S}"
+# For now, we force everyone to have the extra symbols
+#      einfon "Scanning system for __guard to see if we need SSP compat ... "
+#      if [[ -n $(scanelf -qyls__guard -F'#s%F' | grep -v '^/lib.*/libc-2.*.so$') ]] ; then
+               echo "yes" > "${T}"/.ssp.compat
+#      else
+#              # ok, a quick scan didnt find it, so lets do a deep scan ...
+#              if [[ -n $(scanelf -qyRlps__guard -F'#s%F' | grep -v '^/lib.*/libc-2.*.so$') ]] ; then
+#                      echo "yes" > "${T}"/.ssp.compat
+#              else
+#                      echo "no" > "${T}"/.ssp.compat
+#              fi
+#      fi
+#      cat "${T}"/.ssp.compat
+
+       # Glibc is stupid sometimes, and doesn't realize that with a
+       # static C-Only gcc, -lgcc_eh doesn't exist.
+       # http://sources.redhat.com/ml/libc-alpha/2003-09/msg00100.html
+       # http://sourceware.org/ml/libc-alpha/2005-02/msg00042.html
+       echo 'int main(){}' > "${T}"/gcc_eh_test.c
+       if ! $(tc-getCC ${CTARGET}) "${T}"/gcc_eh_test.c -lgcc_eh 2>/dev/null ; then
+               sed -i -e 's:-lgcc_eh::' Makeconfig || die "sed gcc_eh"
+       fi
+
+       cd "${WORKDIR}"
+       find . -type f '(' -size 0 -o -name "*.orig" ')' -exec rm -f {} \;
+       find . -name configure -exec touch {} \;
+
+       # Fix permissions on some of the scripts
+       chmod u+x "${S}"/scripts/*.sh
+}
+
+src_compile() {
+       setup_env
+
+       if [[ -z ${OABI} ]] ; then
+               local abilist=""
+               if has_multilib_profile ; then
+                       abilist=$(get_install_abis)
+                       einfo "Building multilib glibc for ABIs: ${abilist}"
+               elif is_crosscompile || tc-is-cross-compiler ; then
+                       abilist=${DEFAULT_ABI}
+               fi
+               if [[ -n ${abilist} ]] ; then
+                       OABI=${ABI}
+                       for ABI in ${abilist} ; do
+                               export ABI
+                               src_compile
+                       done
+                       ABI=${OABI}
+                       unset OABI
+                       return 0
+               fi
+       fi
+
+       if just_headers ; then
+               toolchain-glibc_headers_compile
+       else
+               toolchain-glibc_src_compile
+       fi
+}
+
+src_test() {
+       local ret=0
+
+       setup_env
+
+       if [[ -z ${OABI} ]] && has_multilib_profile ; then
+               OABI=${ABI}
+               einfo "Testing multilib glibc for ABIs: $(get_install_abis)"
+               for ABI in $(get_install_abis) ; do
+                       export ABI
+                       einfo "   Testing ${ABI} glibc"
+                       src_test
+                       ((ret+=$?))
+               done
+               ABI=${OABI}
+               unset OABI
+               [[ ${ret} -ne 0 ]] \
+                       && die "tests failed" \
+                       || return 0
+       fi
+
+       want_linuxthreads && toolchain-glibc_src_test linuxthreads ; ((ret+=$?))
+       want_nptl && toolchain-glibc_src_test nptl ; ((ret+=$?))
+       return ${ret}
+}
+
+src_strip() {
+       # Now, strip everything but the thread libs #46186, as well as the dynamic
+       # linker, else we cannot set breakpoints in shared libraries due to bugs in
+       # gdb.  Also want to grab stuff in tls subdir.  whee.
+#when new portage supports this ...
+#      env \
+#              -uRESTRICT \
+#              CHOST=${CTARGET} \
+#              STRIP_MASK="/*/{,tls/}{ld-,lib{pthread,thread_db}}*" \
+#              prepallstrip
+       pushd "${D}" > /dev/null
+
+       if ! is_crosscompile ; then
+               mkdir -p "${T}"/strip-backup
+               for x in $(find "${D}" -maxdepth 3 \
+                          '(' -name 'ld-*' -o -name 'libpthread*' -o -name 'libthread_db*' ')' \
+                          -a '(' '!' -name '*.a' ')' -type f -printf '%P ')
+               do
+                       mkdir -p "${T}/strip-backup/${x%/*}"
+                       cp -a -- "${D}/${x}" "${T}/strip-backup/${x}" || die "backing up ${x}"
+               done
+       fi
+       env -uRESTRICT CHOST=${CTARGET} prepallstrip
+       if ! is_crosscompile ; then
+               cp -a -- "${T}"/strip-backup/* "${D}"/ || die "restoring non-stripped libs"
+       fi
+
+       popd > /dev/null
+}
+
+src_install() {
+       setup_env
+
+       if [[ -z ${OABI} ]] ; then
+               local abilist=""
+               if has_multilib_profile ; then
+                       abilist=$(get_install_abis)
+                       einfo "Installing multilib glibc for ABIs: ${abilist}"
+               elif is_crosscompile || tc-is-cross-compiler ; then
+                       abilist=${DEFAULT_ABI}
+               fi
+               if [[ -n ${abilist} ]] ; then
+                       OABI=${ABI}
+                       for ABI in ${abilist} ; do
+                               export ABI
+                               src_install
+                       done
+                       ABI=${OABI}
+                       unset OABI
+                       src_strip
+                       return 0
+               fi
+       fi
+
+       if just_headers ; then
+               toolchain-glibc_headers_install
+       else
+               toolchain-glibc_src_install
+       fi
+       [[ -z ${OABI} ]] && src_strip
+}
+
+pkg_preinst() {
+       toolchain-glibc_pkg_preinst
+}
+
+pkg_postinst() {
+       toolchain-glibc_pkg_postinst
+}