sys-devel/llvm: ppc64 stable wrt bug #705530
[gentoo.git] / eclass / toolchain-glibc.eclass
1 # Copyright 1999-2018 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3
4 # @ECLASS: toolchain-glibc.eclass
5 # @MAINTAINER:
6 # <toolchain@gentoo.org>
7 # @SUPPORTED_EAPIS: 0 1 2 3 4 5 6
8 # @BLURB: Common code for sys-libs/glibc ebuilds
9 # @DESCRIPTION:
10 # This eclass contains the common phase functions migrated from
11 # sys-libs/glibc eblits.
12
13 if [[ -z ${_TOOLCHAIN_GLIBC_ECLASS} ]]; then
14
15 inherit eutils versionator toolchain-funcs flag-o-matic gnuconfig \
16         multilib systemd unpacker multiprocessing prefix
17
18 case ${EAPI:-0} in
19         0|1|2|3) EXPORT_FUNCTIONS pkg_setup src_unpack src_compile src_test \
20                 src_install pkg_preinst pkg_postinst;;
21         2|3) EXPORT_FUNCTIONS pkg_setup src_unpack src_prepare src_configure \
22                 src_compile src_test src_install pkg_preinst pkg_postinst;;
23         4|5) EXPORT_FUNCTIONS pkg_pretend pkg_setup src_unpack src_prepare \
24                 src_configure src_compile src_test src_install \
25                 pkg_preinst pkg_postinst;;
26         6) EXPORT_FUNCTIONS pkg_pretend;;
27         *) die "Unsupported EAPI=${EAPI}";;
28 esac
29
30 # == common ==
31
32 alt_prefix() {
33         is_crosscompile && echo /usr/${CTARGET}
34 }
35
36 if [[ ${EAPI:-0} == [012] ]] ; then
37         : ${ED:=${D}}
38         : ${EROOT:=${ROOT}}
39 fi
40 # This indirection is for binpkgs. #523332
41 _nonfatal() { nonfatal "$@" ; }
42 if [[ ${EAPI:-0} == [0123] ]] ; then
43         nonfatal() { "$@" ; }
44         _nonfatal() { "$@" ; }
45 fi
46
47 # We need to be able to set alternative headers for
48 # compiling for non-native platform
49 # Will also become useful for testing kernel-headers without screwing up
50 # the whole system.
51 # note: intentionally undocumented.
52 alt_headers() {
53         echo ${ALT_HEADERS:=$(alt_prefix)/usr/include}
54 }
55 alt_build_headers() {
56         if [[ -z ${ALT_BUILD_HEADERS} ]] ; then
57                 ALT_BUILD_HEADERS="${EPREFIX}$(alt_headers)"
58                 if tc-is-cross-compiler ; then
59                         ALT_BUILD_HEADERS=${SYSROOT}$(alt_headers)
60                         if [[ ! -e ${ALT_BUILD_HEADERS}/linux/version.h ]] ; then
61                                 local header_path=$(echo '#include <linux/version.h>' | $(tc-getCPP ${CTARGET}) ${CFLAGS} 2>&1 | grep -o '[^"]*linux/version.h')
62                                 ALT_BUILD_HEADERS=${header_path%/linux/version.h}
63                         fi
64                 fi
65         fi
66         echo "${ALT_BUILD_HEADERS}"
67 }
68
69 alt_libdir() {
70         echo $(alt_prefix)/$(get_libdir)
71 }
72 alt_usrlibdir() {
73         echo $(alt_prefix)/usr/$(get_libdir)
74 }
75
76 builddir() {
77         echo "${WORKDIR}/build-${ABI}-${CTARGET}-$1"
78 }
79
80 setup_target_flags() {
81         # This largely mucks with compiler flags.  None of which should matter
82         # when building up just the headers.
83         just_headers && return 0
84
85         case $(tc-arch) in
86                 x86)
87                         # -march needed for #185404 #199334
88                         # TODO: When creating the first glibc cross-compile, this test will
89                         # always fail as it does a full link which in turn requires glibc.
90                         # Probably also applies when changing multilib profile settings (e.g.
91                         # enabling x86 when the profile was amd64-only previously).
92                         # We could change main to _start and pass -nostdlib here so that we
93                         # only test the gcc code compilation.  Or we could do a compile and
94                         # then look for the symbol via scanelf.
95                         if ! glibc_compile_test "" 'void f(int i, void *p) {if (__sync_fetch_and_add(&i, 1)) f(i, p);}\nint main(){return 0;}\n' 2>/dev/null ; then
96                                 local t=${CTARGET_OPT:-${CTARGET}}
97                                 t=${t%%-*}
98                                 filter-flags '-march=*'
99                                 export CFLAGS="-march=${t} ${CFLAGS}"
100                                 einfo "Auto adding -march=${t} to CFLAGS #185404"
101                         fi
102                 ;;
103                 amd64)
104                         # -march needed for #185404 #199334
105                         # Note: This test only matters when the x86 ABI is enabled, so we could
106                         # optimize a bit and elide it.
107                         # TODO: See cross-compile issues listed above for x86.
108                         if ! glibc_compile_test "${CFLAGS_x86}" 'void f(int i, void *p) {if (__sync_fetch_and_add(&i, 1)) f(i, p);}\nint main(){return 0;}\n' 2>/dev/null ; then
109                                 local t=${CTARGET_OPT:-${CTARGET}}
110                                 t=${t%%-*}
111                                 # Normally the target is x86_64-xxx, so turn that into the -march that
112                                 # gcc actually accepts. #528708
113                                 [[ ${t} == "x86_64" ]] && t="x86-64"
114                                 filter-flags '-march=*'
115                                 # ugly, ugly, ugly.  ugly.
116                                 CFLAGS_x86=$(CFLAGS=${CFLAGS_x86} filter-flags '-march=*'; echo "${CFLAGS}")
117                                 export CFLAGS_x86="${CFLAGS_x86} -march=${t}"
118                                 einfo "Auto adding -march=${t} to CFLAGS_x86 #185404"
119                         fi
120                 ;;
121                 mips)
122                         # The mips abi cannot support the GNU style hashes. #233233
123                         filter-ldflags -Wl,--hash-style=gnu -Wl,--hash-style=both
124                 ;;
125                 sparc)
126                         # Both sparc and sparc64 can use -fcall-used-g6.  -g7 is bad, though.
127                         filter-flags "-fcall-used-g7"
128                         append-flags "-fcall-used-g6"
129
130                         # If the CHOST is the basic one (e.g. not sparcv9-xxx already),
131                         # try to pick a better one so glibc can use cpu-specific .S files.
132                         # We key off the CFLAGS to get a good value.  Also need to handle
133                         # version skew.
134                         # We can't force users to set their CHOST to their exact machine
135                         # as many of these are not recognized by config.sub/gcc and such :(.
136                         # Note: If the mcpu values don't scale, we might try probing CPP defines.
137                         # Note: Should we factor in -Wa,-AvXXX flags too ?  Or -mvis/etc... ?
138
139                         local cpu
140                         case ${CTARGET} in
141                         sparc64-*)
142                                 case $(get-flag mcpu) in
143                                 niagara[234])
144                                         if version_is_at_least 2.8 ; then
145                                                 cpu="sparc64v2"
146                                         elif version_is_at_least 2.4 ; then
147                                                 cpu="sparc64v"
148                                         elif version_is_at_least 2.2.3 ; then
149                                                 cpu="sparc64b"
150                                         fi
151                                         ;;
152                                 niagara)
153                                         if version_is_at_least 2.4 ; then
154                                                 cpu="sparc64v"
155                                         elif version_is_at_least 2.2.3 ; then
156                                                 cpu="sparc64b"
157                                         fi
158                                         ;;
159                                 ultrasparc3)
160                                         cpu="sparc64b"
161                                         ;;
162                                 *)
163                                         # We need to force at least v9a because the base build doesn't
164                                         # work with just v9.
165                                         # https://sourceware.org/bugzilla/show_bug.cgi?id=19477
166                                         [[ -z ${cpu} ]] && append-flags "-Wa,-xarch=v9a"
167                                         ;;
168                                 esac
169                                 ;;
170                         sparc-*)
171                                 case $(get-flag mcpu) in
172                                 niagara[234])
173                                         if version_is_at_least 2.8 ; then
174                                                 cpu="sparcv9v2"
175                                         elif version_is_at_least 2.4 ; then
176                                                 cpu="sparcv9v"
177                                         elif version_is_at_least 2.2.3 ; then
178                                                 cpu="sparcv9b"
179                                         else
180                                                 cpu="sparcv9"
181                                         fi
182                                         ;;
183                                 niagara)
184                                         if version_is_at_least 2.4 ; then
185                                                 cpu="sparcv9v"
186                                         elif version_is_at_least 2.2.3 ; then
187                                                 cpu="sparcv9b"
188                                         else
189                                                 cpu="sparcv9"
190                                         fi
191                                         ;;
192                                 ultrasparc3)
193                                         cpu="sparcv9b"
194                                         ;;
195                                 v9|ultrasparc)
196                                         cpu="sparcv9"
197                                         ;;
198                                 v8|supersparc|hypersparc|leon|leon3)
199                                         cpu="sparcv8"
200                                         ;;
201                                 esac
202                         ;;
203                         esac
204                         [[ -n ${cpu} ]] && CTARGET_OPT="${cpu}-${CTARGET#*-}"
205                 ;;
206         esac
207 }
208
209 setup_flags() {
210         # Make sure host make.conf doesn't pollute us
211         if is_crosscompile || tc-is-cross-compiler ; then
212                 CHOST=${CTARGET} strip-unsupported-flags
213         fi
214
215         # Store our CFLAGS because it's changed depending on which CTARGET
216         # we are building when pulling glibc on a multilib profile
217         CFLAGS_BASE=${CFLAGS_BASE-${CFLAGS}}
218         CFLAGS=${CFLAGS_BASE}
219         CXXFLAGS_BASE=${CXXFLAGS_BASE-${CXXFLAGS}}
220         CXXFLAGS=${CXXFLAGS_BASE}
221         ASFLAGS_BASE=${ASFLAGS_BASE-${ASFLAGS}}
222         ASFLAGS=${ASFLAGS_BASE}
223
224         # Over-zealous CFLAGS can often cause problems.  What may work for one
225         # person may not work for another.  To avoid a large influx of bugs
226         # relating to failed builds, we strip most CFLAGS out to ensure as few
227         # problems as possible.
228         strip-flags
229         strip-unsupported-flags
230         filter-flags -m32 -m64 -mabi=*
231         filter-ldflags -Wl,-rpath=*
232
233         # Bug 492892.
234         filter-flags -frecord-gcc-switches
235
236         unset CBUILD_OPT CTARGET_OPT
237         if use multilib ; then
238                 CTARGET_OPT=$(get_abi_CTARGET)
239                 [[ -z ${CTARGET_OPT} ]] && CTARGET_OPT=$(get_abi_CHOST)
240         fi
241
242         setup_target_flags
243
244         if [[ -n ${CTARGET_OPT} && ${CBUILD} == ${CHOST} ]] && ! is_crosscompile; then
245                 CBUILD_OPT=${CTARGET_OPT}
246         fi
247
248         # Lock glibc at -O2 -- linuxthreads needs it and we want to be
249         # conservative here.  -fno-strict-aliasing is to work around #155906
250         filter-flags -O?
251         append-flags -O2 -fno-strict-aliasing
252
253         # Can't build glibc itself with fortify code.  Newer versions add
254         # this flag for us, so no need to do it manually.
255         version_is_at_least 2.16 ${PV} || append-cppflags -U_FORTIFY_SOURCE
256
257         # building glibc <2.25 with SSP is fraught with difficulty, especially
258         # due to __stack_chk_fail_local which would mean significant changes
259         # to the glibc build process. See bug #94325 #293721
260         # Note we have to handle both user-given CFLAGS and gcc defaults via
261         # spec rules here.  We can't simply add -fno-stack-protector as it gets
262         # added before user flags, and we can't just filter-flags because
263         # _filter_hardened doesn't support globs.
264         filter-flags -fstack-protector*
265         if ! version_is_at_least 2.25 ; then
266                 tc-enables-ssp && append-flags $(test-flags -fno-stack-protector)
267         fi
268
269         if [[ $(gcc-major-version) -lt 6 ]]; then
270                 # Starting with gcc-6 (and fully upstreamed pie patches) we control
271                 # default enabled/disabled pie via use flags. So nothing to do
272                 # here. #618160
273
274                 if use hardened && tc-enables-pie ; then
275                         # Force PIC macro definition for all compilations since they're all
276                         # either -fPIC or -fPIE with the default-PIE compiler.
277                         append-cppflags -DPIC
278                 else
279                         # Don't build -fPIE without the default-PIE compiler and the
280                         # hardened-pie patch
281                         filter-flags -fPIE
282                 fi
283         fi
284 }
285
286 want_nptl() {
287         [[ -z ${LT_VER} ]] && return 0
288         want_tls || return 1
289         use nptl || return 1
290
291         # Older versions of glibc had incomplete arch support for nptl.
292         # But if you're building those now, you can handle USE=nptl yourself.
293         return 0
294 }
295
296 want_linuxthreads() {
297         [[ -z ${LT_VER} ]] && return 1
298         use linuxthreads
299 }
300
301 want_tls() {
302         # Archs that can use TLS (Thread Local Storage)
303         case $(tc-arch) in
304                 x86)
305                         # requires i486 or better #106556
306                         [[ ${CTARGET} == i[4567]86* ]] && return 0
307                         return 1
308                 ;;
309         esac
310
311         return 0
312 }
313
314 want__thread() {
315         want_tls || return 1
316
317         # For some reason --with-tls --with__thread is causing segfaults on sparc32.
318         [[ ${PROFILE_ARCH} == "sparc" ]] && return 1
319
320         [[ -n ${WANT__THREAD} ]] && return ${WANT__THREAD}
321
322         # only test gcc -- can't test linking yet
323         tc-has-tls -c ${CTARGET}
324         WANT__THREAD=$?
325
326         return ${WANT__THREAD}
327 }
328
329 use_multiarch() {
330         # Make sure binutils is new enough to support indirect functions #336792
331         # This funky sed supports gold and bfd linkers.
332         local bver nver
333         bver=$($(tc-getLD ${CTARGET}) -v | sed -n -r '1{s:[^0-9]*::;s:^([0-9.]*).*:\1:;p}')
334         case $(tc-arch ${CTARGET}) in
335         amd64|x86) nver="2.20" ;;
336         arm)       nver="2.22" ;;
337         hppa)      nver="2.23" ;;
338         ppc|ppc64) nver="2.20" ;;
339         # ifunc was added in 2.23, but glibc also needs machinemode which is in 2.24.
340         s390)      nver="2.24" ;;
341         sparc)     nver="2.21" ;;
342         *)         return 1 ;;
343         esac
344         version_is_at_least ${nver} ${bver}
345 }
346
347 # Setup toolchain variables that had historically
348 # been defined in the profiles for these archs.
349 setup_env() {
350         # silly users
351         unset LD_RUN_PATH
352         unset LD_ASSUME_KERNEL
353
354         if is_crosscompile || tc-is-cross-compiler ; then
355                 multilib_env ${CTARGET_OPT:-${CTARGET}}
356
357                 if ! use multilib ; then
358                         MULTILIB_ABIS=${DEFAULT_ABI}
359                 else
360                         MULTILIB_ABIS=${MULTILIB_ABIS:-${DEFAULT_ABI}}
361                 fi
362
363                 # If the user has CFLAGS_<CTARGET> in their make.conf, use that,
364                 # and fall back on CFLAGS.
365                 local VAR=CFLAGS_${CTARGET//[-.]/_}
366                 CFLAGS=${!VAR-${CFLAGS}}
367                 einfo " $(printf '%15s' 'Manual CFLAGS:')   ${CFLAGS}"
368         fi
369
370         setup_flags
371
372         export ABI=${ABI:-${DEFAULT_ABI:-default}}
373
374         if just_headers ; then
375                 # Avoid mixing host's CC and target's CFLAGS_${ABI}:
376                 # At this bootstrap stage we have only binutils for
377                 # target but not compiler yet.
378                 einfo "Skip CC ABI injection. We can't use (cross-)compiler yet."
379                 return 0
380         fi
381
382         local VAR=CFLAGS_${ABI}
383         # We need to export CFLAGS with abi information in them because glibc's
384         # configure script checks CFLAGS for some targets (like mips).  Keep
385         # around the original clean value to avoid appending multiple ABIs on
386         # top of each other.
387         : ${__GLIBC_CC:=$(tc-getCC ${CTARGET_OPT:-${CTARGET}})}
388         export __GLIBC_CC CC="${__GLIBC_CC} ${!VAR}"
389         einfo " $(printf '%15s' 'Manual CC:')   ${CC}"
390 }
391
392 foreach_abi() {
393         setup_env
394
395         local ret=0
396         local abilist=""
397         if use multilib ; then
398                 abilist=$(get_install_abis)
399         else
400                 abilist=${DEFAULT_ABI}
401         fi
402         local -x ABI
403         for ABI in ${abilist:-default} ; do
404                 setup_env
405                 einfo "Running $1 for ABI ${ABI}"
406                 $1
407                 : $(( ret |= $? ))
408         done
409         return ${ret}
410 }
411
412 just_headers() {
413         is_crosscompile && use headers-only
414 }
415
416 glibc_banner() {
417         local b="Gentoo ${PVR}"
418         [[ -n ${SNAP_VER} ]] && b+=" snapshot ${SNAP_VER}"
419         [[ -n ${PATCH_VER} ]] && ! use vanilla && b+=" p${PATCH_VER}"
420         echo "${b}"
421 }
422
423 # == phases ==
424
425 glibc_compile_test() {
426         local ret save_cflags=${CFLAGS}
427         CFLAGS+=" $1"
428         shift
429
430         pushd "${T}" >/dev/null
431
432         rm -f glibc-test*
433         printf '%b' "$*" > glibc-test.c
434
435         _nonfatal emake -s glibc-test
436         ret=$?
437
438         popd >/dev/null
439
440         CFLAGS=${save_cflags}
441         return ${ret}
442 }
443
444 glibc_run_test() {
445         local ret
446
447         if [[ ${EMERGE_FROM} == "binary" ]] ; then
448                 # ignore build failures when installing a binary package #324685
449                 glibc_compile_test "" "$@" 2>/dev/null || return 0
450         else
451                 if ! glibc_compile_test "" "$@" ; then
452                         ewarn "Simple build failed ... assuming this is desired #324685"
453                         return 0
454                 fi
455         fi
456
457         pushd "${T}" >/dev/null
458
459         ./glibc-test
460         ret=$?
461         rm -f glibc-test*
462
463         popd >/dev/null
464
465         return ${ret}
466 }
467
468 check_devpts() {
469         # Make sure devpts is mounted correctly for use w/out setuid pt_chown.
470
471         # If merely building the binary package, then there's nothing to verify.
472         [[ ${MERGE_TYPE} == "buildonly" ]] && return
473
474         # Only sanity check when installing the native glibc.
475         [[ ${ROOT} != "/" ]] && return
476
477         # Older versions always installed setuid, so no need to check.
478         in_iuse suid || return
479
480         # If they're opting in to the old suid code, then no need to check.
481         use suid && return
482
483         if awk '$3 == "devpts" && $4 ~ /[, ]gid=5[, ]/ { exit 1 }' /proc/mounts ; then
484                 eerror "In order to use glibc with USE=-suid, you must make sure that"
485                 eerror "you have devpts mounted at /dev/pts with the gid=5 option."
486                 eerror "Openrc should do this for you, so you should check /etc/fstab"
487                 eerror "and make sure you do not have any invalid settings there."
488                 # Do not die on older kernels as devpts did not export these settings #489520.
489                 if version_is_at_least 2.6.25 $(uname -r) ; then
490                         die "mount & fix your /dev/pts settings"
491                 fi
492         fi
493 }
494
495 toolchain-glibc_pkg_pretend() {
496         if [[ ${EAPI:-0} == 6 ]]; then
497                 eerror "We're moving code back to the ebuilds to get away from the ancient EAPI cruft."
498                 eerror "From EAPI=6 on you'll have to define the phases in the glibc ebuilds."
499                 die "Silly overlay authors..."
500         fi
501
502         # For older EAPIs, this is run in pkg_preinst.
503         if [[ ${EAPI:-0} != [0123] ]] ; then
504                 check_devpts
505         fi
506
507         # Prevent native builds from downgrading.
508         if [[ ${MERGE_TYPE} != "buildonly" ]] && \
509            [[ ${ROOT} == "/" ]] && \
510            [[ ${CBUILD} == ${CHOST} ]] && \
511            [[ ${CHOST} == ${CTARGET} ]] ; then
512                 # The high rev # is to allow people to downgrade between -r# versions.
513                 # We want to block 2.20->2.19, but 2.20-r3->2.20-r2 should be fine.
514                 # Hopefully we never actually use a r# this high.
515                 if has_version ">${CATEGORY}/${P}-r10000" ; then
516                         eerror "Sanity check to keep you from breaking your system:"
517                         eerror " Downgrading glibc is not supported and a sure way to destruction"
518                         [[ ${I_ALLOW_TO_BREAK_MY_SYSTEM} = yes ]] || die "Aborting to save your system."
519                 fi
520
521                 if ! glibc_run_test '#include <pwd.h>\nint main(){return getpwuid(0)==0;}\n'
522                 then
523                         eerror "Your patched vendor kernel is broken.  You need to get an"
524                         eerror "update from whoever is providing the kernel to you."
525                         eerror "https://sourceware.org/bugzilla/show_bug.cgi?id=5227"
526                         eerror "http://bugs.gentoo.org/262698"
527                         die "keeping your system alive, say thank you"
528                 fi
529
530                 if ! glibc_run_test '#include <unistd.h>\n#include <sys/syscall.h>\nint main(){return syscall(1000)!=-1;}\n'
531                 then
532                         eerror "Your old kernel is broken.  You need to update it to"
533                         eerror "a newer version as syscall(<bignum>) will break."
534                         eerror "http://bugs.gentoo.org/279260"
535                         die "keeping your system alive, say thank you"
536                 fi
537         fi
538
539         # users have had a chance to phase themselves, time to give em the boot
540         if [[ -e ${EROOT}/etc/locale.gen ]] && [[ -e ${EROOT}/etc/locales.build ]] ; then
541                 eerror "You still haven't deleted ${EROOT}/etc/locales.build."
542                 eerror "Do so now after making sure ${EROOT}/etc/locale.gen is kosher."
543                 die "lazy upgrader detected"
544         fi
545
546         if [[ ${CTARGET} == i386-* ]] ; then
547                 eerror "i386 CHOSTs are no longer supported."
548                 eerror "Chances are you don't actually want/need i386."
549                 eerror "Please read http://www.gentoo.org/doc/en/change-chost.xml"
550                 die "please fix your CHOST"
551         fi
552
553         if [[ -e /proc/xen ]] && [[ $(tc-arch) == "x86" ]] && ! is-flag -mno-tls-direct-seg-refs ; then
554                 ewarn "You are using Xen but don't have -mno-tls-direct-seg-refs in your CFLAGS."
555                 ewarn "This will result in a 50% performance penalty when running with a 32bit"
556                 ewarn "hypervisor, which is probably not what you want."
557         fi
558
559         # Make sure host system is up to date #394453
560         if has_version '<sys-libs/glibc-2.13' && \
561            [[ -n $(scanelf -qys__guard -F'#s%F' "${EROOT}"/lib*/l*-*.so) ]]
562         then
563                 ebegin "Scanning system for __guard to see if you need to rebuild first ..."
564                 local files=$(
565                         scanelf -qys__guard -F'#s%F' \
566                                 "${EROOT}"/*bin/ \
567                                 "${EROOT}"/lib* \
568                                 "${EROOT}"/usr/*bin/ \
569                                 "${EROOT}"/usr/lib* | \
570                                 egrep -v \
571                                         -e "^${EROOT}/lib.*/(libc|ld)-2.*.so$" \
572                                         -e "^${EROOT}/sbin/(ldconfig|sln)$"
573                 )
574                 [[ -z ${files} ]]
575                 if ! eend $? ; then
576                         eerror "Your system still has old SSP __guard symbols.  You need to"
577                         eerror "rebuild all the packages that provide these files first:"
578                         eerror "${files}"
579                         die "old __guard detected"
580                 fi
581         fi
582 }
583
584 toolchain-glibc_pkg_setup() {
585         [[ ${EAPI:-0} == [0123] ]] && toolchain-glibc_pkg_pretend
586 }
587
588 # The following Kernel version handling functions are mostly copied from portage
589 # source. It's better not to use linux-info.eclass here since a) it adds too
590 # much magic, see bug 326693 for some of the arguments, and b) some of the
591 # functions are just not provided.
592
593 tc_glibc_get_KV() {
594         uname -r
595         return $?
596 }
597
598 tc_glibc_KV_major() {
599         [[ -z $1 ]] && return 1
600         local KV=$@
601         echo "${KV%%.*}"
602 }
603
604 tc_glibc_KV_minor() {
605         [[ -z $1 ]] && return 1
606         local KV=$@
607         KV=${KV#*.}
608         echo "${KV%%.*}"
609 }
610
611 tc_glibc_KV_micro() {
612         [[ -z $1 ]] && return 1
613         local KV=$@
614         KV=${KV#*.*.}
615         echo "${KV%%[^[:digit:]]*}"
616 }
617
618 tc_glibc_KV_to_int() {
619         [[ -z $1 ]] && return 1
620         local KV_MAJOR=$(tc_glibc_KV_major "$1")
621         local KV_MINOR=$(tc_glibc_KV_minor "$1")
622         local KV_MICRO=$(tc_glibc_KV_micro "$1")
623         local KV_int=$(( KV_MAJOR * 65536 + KV_MINOR * 256 + KV_MICRO ))
624
625         # We make version 2.2.0 the minimum version we will handle as
626         # a sanity check ... if its less, we fail ...
627         if [[ ${KV_int} -ge 131584 ]] ; then
628                 echo "${KV_int}"
629                 return 0
630         fi
631         return 1
632 }
633
634 tc_glibc_int_to_KV() {
635         local version=$1 major minor micro
636         major=$((version / 65536))
637         minor=$(((version % 65536) / 256))
638         micro=$((version % 256))
639         echo ${major}.${minor}.${micro}
640 }
641
642 eend_KV() {
643         [[ $(tc_glibc_KV_to_int $1) -ge $(tc_glibc_KV_to_int $2) ]]
644         eend $?
645 }
646
647 get_kheader_version() {
648         printf '#include <linux/version.h>\nLINUX_VERSION_CODE\n' | \
649         $(tc-getCPP ${CTARGET}) -I "$(alt_build_headers)" - | \
650         tail -n 1
651 }
652
653 check_nptl_support() {
654         # don't care about the compiler here as we aren't using it
655         just_headers && return
656
657         local run_kv build_kv want_kv
658         run_kv=$(tc_glibc_get_KV)
659         build_kv=$(tc_glibc_int_to_KV $(get_kheader_version))
660         want_kv=${NPTL_KERN_VER}
661
662         ebegin "Checking gcc for __thread support"
663         if ! eend $(want__thread ; echo $?) ; then
664                 echo
665                 eerror "Could not find a gcc that supports the __thread directive!"
666                 eerror "Please update your binutils/gcc and try again."
667                 die "No __thread support in gcc!"
668         fi
669
670         if ! is_crosscompile && ! tc-is-cross-compiler ; then
671                 # Building fails on an non-supporting kernel
672                 ebegin "Checking kernel version (${run_kv} >= ${want_kv})"
673                 if ! eend_KV ${run_kv} ${want_kv} ; then
674                         echo
675                         eerror "You need a kernel of at least ${want_kv} for NPTL support!"
676                         die "Kernel version too low!"
677                 fi
678         fi
679
680         ebegin "Checking linux-headers version (${build_kv} >= ${want_kv})"
681         if ! eend_KV ${build_kv} ${want_kv} ; then
682                 echo
683                 eerror "You need linux-headers of at least ${want_kv} for NPTL support!"
684                 die "linux-headers version too low!"
685         fi
686 }
687
688 unpack_pkg() {
689         local a=${PN}
690         [[ -n ${SNAP_VER} ]] && a="${a}-${RELEASE_VER}"
691         [[ -n $1 ]] && a="${a}-$1"
692         if [[ -n ${SNAP_VER} ]] ; then
693                 a="${a}-${SNAP_VER}"
694         else
695                 if [[ -n $2 ]] ; then
696                         a="${a}-$2"
697                 else
698                         a="${a}-${RELEASE_VER}"
699                 fi
700         fi
701         if has ${a}.tar.xz ${A} ; then
702                 unpacker ${a}.tar.xz
703         else
704                 unpack ${a}.tar.bz2
705         fi
706         [[ -n $1 ]] && { mv ${a} $1 || die ; }
707 }
708
709 toolchain-glibc_do_src_unpack() {
710         # Check NPTL support _before_ we unpack things to save some time
711         want_nptl && check_nptl_support
712
713         unpack_pkg
714
715         cd "${S}"
716         touch locale/C-translit.h #185476 #218003
717         [[ -n ${LT_VER}     ]] && unpack_pkg linuxthreads ${LT_VER}
718         [[ -n ${PORTS_VER}  ]] && unpack_pkg ports ${PORTS_VER}
719         [[ -n ${LIBIDN_VER} ]] && unpack_pkg libidn
720
721         if [[ -n ${PATCH_VER} ]] ; then
722                 cd "${WORKDIR}"
723                 unpack glibc-${RELEASE_VER}-patches-${PATCH_VER}.tar.bz2
724                 # pull out all the addons
725                 local d
726                 for d in extra/*/configure ; do
727                         d=${d%/configure}
728                         [[ -d ${S}/${d} ]] && die "${d} already exists in \${S}"
729                         mv "${d}" "${S}" || die "moving ${d} failed"
730                 done
731         fi
732 }
733
734 toolchain-glibc_src_unpack() {
735         setup_env
736
737         toolchain-glibc_do_src_unpack
738         [[ ${EAPI:-0} == [01] ]] && cd "${S}" && toolchain-glibc_src_prepare
739 }
740
741 toolchain-glibc_src_prepare() {
742         # tag, glibc is it
743         if ! version_is_at_least 2.17 ; then
744                 [[ -e csu/Banner ]] && die "need new banner location"
745                 glibc_banner > csu/Banner
746         fi
747         if [[ -n ${PATCH_VER} ]] && ! use vanilla ; then
748                 EPATCH_MULTI_MSG="Applying Gentoo Glibc Patchset ${RELEASE_VER}-${PATCH_VER} ..." \
749                 EPATCH_EXCLUDE=${GLIBC_PATCH_EXCLUDE} \
750                 EPATCH_SUFFIX="patch" \
751                 ARCH=$(tc-arch) \
752                 epatch "${WORKDIR}"/patches
753         fi
754
755         if just_headers ; then
756                 if [[ -e ports/sysdeps/mips/preconfigure ]] ; then
757                         # mips peeps like to screw with us.  if building headers,
758                         # we don't have a real compiler, so we can't let them
759                         # insert -mabi on us.
760                         sed -i '/CPPFLAGS=.*-mabi/s|.*|:|' ports/sysdeps/mips/preconfigure || die
761                         find ports/sysdeps/mips/ -name Makefile -exec sed -i '/^CC.*-mabi=/s:-mabi=.*:-D_MIPS_SZPTR=32:' {} +
762                 fi
763         fi
764
765         epatch_user
766
767         gnuconfig_update
768
769         # Glibc is stupid sometimes, and doesn't realize that with a
770         # static C-Only gcc, -lgcc_eh doesn't exist.
771         # https://sourceware.org/ml/libc-alpha/2003-09/msg00100.html
772         # https://sourceware.org/ml/libc-alpha/2005-02/msg00042.html
773         # But! Finally fixed in recent versions:
774         # https://sourceware.org/ml/libc-alpha/2012-05/msg01865.html
775         if ! version_is_at_least 2.16 ; then
776                 echo 'int main(){}' > "${T}"/gcc_eh_test.c
777                 if ! $(tc-getCC ${CTARGET}) ${CFLAGS} ${LDFLAGS} "${T}"/gcc_eh_test.c -lgcc_eh 2>/dev/null ; then
778                         sed -i -e 's:-lgcc_eh::' Makeconfig || die "sed gcc_eh"
779                 fi
780         fi
781
782         cd "${WORKDIR}"
783         find . -type f '(' -size 0 -o -name "*.orig" ')' -delete
784         find . -name configure -exec touch {} +
785
786         eprefixify extra/locale/locale-gen
787
788         # Fix permissions on some of the scripts.
789         chmod u+x "${S}"/scripts/*.sh
790 }
791 dump_toolchain_settings() {
792         echo
793
794         einfo "$*"
795
796         local v
797         for v in ABI CBUILD CHOST CTARGET CBUILD_OPT CTARGET_OPT CC LD {AS,C,CPP,CXX,LD}FLAGS ; do
798                 einfo " $(printf '%15s' ${v}:)   ${!v}"
799         done
800
801         # The glibc configure script doesn't properly use LDFLAGS all the time.
802         export CC="$(tc-getCC ${CTARGET}) ${LDFLAGS}"
803         einfo " $(printf '%15s' 'Manual CC:')   ${CC}"
804         echo
805 }
806
807 glibc_do_configure() {
808         # Glibc does not work with gold (for various reasons) #269274.
809         tc-ld-disable-gold
810
811         dump_toolchain_settings "Configuring glibc for $1"
812
813         local myconf=()
814
815         # set addons
816         pushd "${S}" > /dev/null
817         local addons=$(echo */configure | sed \
818                 -e 's:/configure::g' \
819                 -e 's:\(linuxthreads\|nptl\|rtkaio\|glibc-compat\)\( \|$\)::g' \
820                 -e 's: \+$::' \
821                 -e 's! !,!g' \
822                 -e 's!^!,!' \
823                 -e '/^,\*$/d')
824         [[ -d ports ]] && addons+=",ports"
825         popd > /dev/null
826
827         if has_version '<sys-libs/glibc-2.13' ; then
828                 myconf+=( --enable-old-ssp-compat )
829         fi
830
831         if version_is_at_least 2.25 ; then
832                 case ${CTARGET} in
833                         m68k*)
834                                 # setjmp() is not compatible with stack protection:
835                                 # https://sourceware.org/PR24202
836                                 myconf+=( --enable-stack-protector=no )
837                                 ;;
838                         mips*)
839                                 # dlopen() detects stack smash on mips n32 ABI.
840                                 # Cause is unknown: https://bugs.gentoo.org/640130
841                                 myconf+=( --enable-stack-protector=no )
842                                 ;;
843                         powerpc-*)
844                                 # Currently gcc on powerpc32 generates invalid code for
845                                 # __builtin_return_address(0) calls. Normally programs
846                                 # don't do that but malloc hooks in glibc do:
847                                 # https://gcc.gnu.org/PR81996
848                                 # https://bugs.gentoo.org/629054
849                                 myconf+=( --enable-stack-protector=no )
850                                 ;;
851                         *)
852                                 myconf+=( --enable-stack-protector=all )
853                                 ;;
854                 esac
855         fi
856
857         # Keep a whitelist of targets supporing IFUNC. glibc's ./configure
858         # is not robust enough to detect proper support:
859         #    https://bugs.gentoo.org/641216
860         #    https://sourceware.org/PR22634#c0
861         case $(tc-arch ${CTARGET}) in
862                 # Keep whitelist of targets where autodetection mostly works.
863                 amd64|x86|sparc|ppc|ppc64|arm|arm64|s390) ;;
864                 # Blacklist everywhere else
865                 *) myconf+=( libc_cv_ld_gnu_indirect_function=no ) ;;
866         esac
867
868         if version_is_at_least 2.25 ; then
869                 myconf+=( --enable-stackguard-randomization )
870         else
871                 myconf+=( $(use_enable hardened stackguard-randomization) )
872         fi
873
874         [[ $(tc-is-softfloat) == "yes" ]] && myconf+=( --without-fp )
875
876         if [[ $1 == "linuxthreads" ]] ; then
877                 if want_tls ; then
878                         myconf+=( --with-tls )
879
880                         if ! want__thread || use glibc-compat20 || [[ ${LT_KER_VER} == 2.[02].* ]] ; then
881                                 myconf+=( --without-__thread )
882                         else
883                                 myconf+=( --with-__thread )
884                         fi
885                 else
886                         myconf+=( --without-tls --without-__thread )
887                 fi
888
889                 myconf+=( --disable-sanity-checks )
890                 addons="linuxthreads${addons}"
891                 myconf+=( --enable-kernel=${LT_KER_VER} )
892         elif [[ $1 == "nptl" ]] ; then
893                 # Newer versions require nptl, so there is no addon for it.
894                 version_is_at_least 2.20 || addons="nptl${addons}"
895                 myconf+=( --enable-kernel=${NPTL_KERN_VER} )
896         else
897                 die "invalid pthread option"
898         fi
899         myconf+=( --enable-add-ons="${addons#,}" )
900
901         # Since SELinux support is only required for nscd, only enable it if:
902         # 1. USE selinux
903         # 2. only for the primary ABI on multilib systems
904         # 3. Not a crosscompile
905         if ! is_crosscompile && use selinux ; then
906                 if use multilib ; then
907                         if is_final_abi ; then
908                                 myconf+=( --with-selinux )
909                         else
910                                 myconf+=( --without-selinux )
911                         fi
912                 else
913                         myconf+=( --with-selinux )
914                 fi
915         else
916                 myconf+=( --without-selinux )
917         fi
918
919         # Force a few tests where we always know the answer but
920         # configure is incapable of finding it.
921         if is_crosscompile ; then
922                 export \
923                         libc_cv_c_cleanup=yes \
924                         libc_cv_forced_unwind=yes
925         fi
926
927         myconf+=(
928                 --without-cvs
929                 --disable-werror
930                 --enable-bind-now
931                 --build=${CBUILD_OPT:-${CBUILD}}
932                 --host=${CTARGET_OPT:-${CTARGET}}
933                 $(use_enable profile)
934                 $(use_with gd)
935                 --with-headers=$(alt_build_headers)
936                 --prefix="${EPREFIX}/usr"
937                 --sysconfdir="${EPREFIX}/etc"
938                 --localstatedir="${EPREFIX}/var"
939                 --libdir='$(prefix)'/$(get_libdir)
940                 --mandir='$(prefix)'/share/man
941                 --infodir='$(prefix)'/share/info
942                 --libexecdir='$(libdir)'/misc/glibc
943                 --with-bugurl=http://bugs.gentoo.org/
944                 --with-pkgversion="$(glibc_banner)"
945                 $(use_multiarch || echo --disable-multi-arch)
946                 $(in_iuse rpc && use_enable rpc obsolete-rpc || echo --enable-obsolete-rpc)
947                 $(in_iuse systemtap && use_enable systemtap)
948                 $(in_iuse nscd && use_enable nscd)
949                 ${EXTRA_ECONF}
950         )
951
952         # We rely on sys-libs/timezone-data for timezone tools normally.
953         if version_is_at_least 2.23 ; then
954                 myconf+=( $(use_enable vanilla timezone-tools) )
955         fi
956
957         # These libs don't have configure flags.
958         ac_cv_lib_audit_audit_log_user_avc_message=$(in_iuse audit && usex audit || echo no)
959         ac_cv_lib_cap_cap_init=$(in_iuse caps && usex caps || echo no)
960
961         # There is no configure option for this and we need to export it
962         # since the glibc build will re-run configure on itself
963         export libc_cv_rootsbindir="${EPREFIX}/sbin"
964         export libc_cv_slibdir="${EPREFIX}/$(get_libdir)"
965
966         # We take care of patching our binutils to use both hash styles,
967         # and many people like to force gnu hash style only, so disable
968         # this overriding check.  #347761
969         export libc_cv_hashstyle=no
970
971         # Overtime, generating info pages can be painful.  So disable this for
972         # versions older than the latest stable to avoid the issue (this ver
973         # should be updated from time to time).  #464394 #465816
974         if ! version_is_at_least 2.17 ; then
975                 export ac_cv_prog_MAKEINFO=:
976         fi
977
978         local builddir=$(builddir "$1")
979         mkdir -p "${builddir}"
980         cd "${builddir}"
981         set -- "${S}"/configure "${myconf[@]}"
982         echo "$@"
983         "$@" || die "failed to configure glibc"
984
985         # ia64 static cross-compilers are a pita in so much that they
986         # can't produce static ELFs (as the libgcc.a is broken).  so
987         # disable building of the programs for those targets if it
988         # doesn't work.
989         # XXX: We could turn this into a compiler test, but ia64 is
990         # the only one that matters, so this should be fine for now.
991         if is_crosscompile && [[ ${CTARGET} == ia64* ]] ; then
992                 sed -i '1i+link-static = touch $@' config.make
993         fi
994
995         # If we're trying to migrate between ABI sets, we need
996         # to lie and use a local copy of gcc.  Like if the system
997         # is built with MULTILIB_ABIS="amd64 x86" but we want to
998         # add x32 to it, gcc/glibc don't yet support x32.
999         if [[ -n ${GCC_BOOTSTRAP_VER} ]] && use multilib ; then
1000                 echo 'main(){}' > "${T}"/test.c
1001                 if ! $(tc-getCC ${CTARGET}) ${CFLAGS} ${LDFLAGS} "${T}"/test.c -Wl,-emain -lgcc 2>/dev/null ; then
1002                         sed -i -e '/^CC = /s:$: -B$(objdir)/../'"gcc-${GCC_BOOTSTRAP_VER}/${ABI}:" config.make || die
1003                         mkdir -p sunrpc
1004                         cp $(which rpcgen) sunrpc/cross-rpcgen || die
1005                         touch -t 202001010101 sunrpc/cross-rpcgen || die
1006                 fi
1007         fi
1008 }
1009
1010 toolchain-glibc_headers_configure() {
1011         export ABI=default
1012
1013         local builddir=$(builddir "headers")
1014         mkdir -p "${builddir}"
1015         cd "${builddir}"
1016
1017         # if we don't have a compiler yet, we can't really test it now ...
1018         # hopefully they don't affect header generation, so let's hope for
1019         # the best here ...
1020         local v vars=(
1021                 ac_cv_header_cpuid_h=yes
1022                 libc_cv_{386,390,alpha,arm,hppa,ia64,mips,{powerpc,sparc}{,32,64},sh,x86_64}_tls=yes
1023                 libc_cv_asm_cfi_directives=yes
1024                 libc_cv_broken_visibility_attribute=no
1025                 libc_cv_c_cleanup=yes
1026                 libc_cv_forced_unwind=yes
1027                 libc_cv_gcc___thread=yes
1028                 libc_cv_mlong_double_128=yes
1029                 libc_cv_mlong_double_128ibm=yes
1030                 libc_cv_ppc_machine=yes
1031                 libc_cv_ppc_rel16=yes
1032                 libc_cv_predef_fortify_source=no
1033                 libc_cv_visibility_attribute=yes
1034                 libc_cv_z_combreloc=yes
1035                 libc_cv_z_execstack=yes
1036                 libc_cv_z_initfirst=yes
1037                 libc_cv_z_nodelete=yes
1038                 libc_cv_z_nodlopen=yes
1039                 libc_cv_z_relro=yes
1040                 libc_mips_abi=${ABI}
1041                 libc_mips_float=$([[ $(tc-is-softfloat) == "yes" ]] && echo soft || echo hard)
1042                 # These libs don't have configure flags.
1043                 ac_cv_lib_audit_audit_log_user_avc_message=no
1044                 ac_cv_lib_cap_cap_init=no
1045         )
1046         if ! version_is_at_least 2.25 ; then
1047                 vars+=(
1048                         libc_cv_predef_stack_protector=no
1049                 )
1050         fi
1051         einfo "Forcing cached settings:"
1052         for v in "${vars[@]}" ; do
1053                 einfo " ${v}"
1054                 export ${v}
1055         done
1056
1057         # Blow away some random CC settings that screw things up. #550192
1058         if [[ -d ${S}/sysdeps/mips ]]; then
1059                 pushd "${S}"/sysdeps/mips >/dev/null
1060                 sed -i -e '/^CC +=/s:=.*:= -D_MIPS_SZPTR=32:' mips32/Makefile mips64/n32/Makefile || die
1061                 sed -i -e '/^CC +=/s:=.*:= -D_MIPS_SZPTR=64:' mips64/n64/Makefile || die
1062                 if version_is_at_least 2.21 ; then
1063                         # Force the mips ABI to the default.  This is OK because the set of
1064                         # installed headers in this phase is the same between the 3 ABIs.
1065                         # If this ever changes, this hack will break, but that's unlikely
1066                         # as glibc discourages that behavior.
1067                         # https://crbug.com/647033
1068                         sed -i -e 's:abiflag=.*:abiflag=_ABIO32:' preconfigure || die
1069                 fi
1070                 popd >/dev/null
1071         fi
1072
1073         local myconf=()
1074         myconf+=(
1075                 --disable-sanity-checks
1076                 --enable-hacker-mode
1077                 --without-cvs
1078                 --disable-werror
1079                 --enable-bind-now
1080                 --build=${CBUILD_OPT:-${CBUILD}}
1081                 --host=${CTARGET_OPT:-${CTARGET}}
1082                 --with-headers=$(alt_build_headers)
1083                 --prefix="${EPREFIX}/usr"
1084                 ${EXTRA_ECONF}
1085         )
1086
1087         local addons
1088         [[ -d ${S}/ports ]] && addons+=",ports"
1089         # Newer versions require nptl, so there is no addon for it.
1090         version_is_at_least 2.20 || addons+=",nptl"
1091         myconf+=( --enable-add-ons="${addons#,}" )
1092
1093         # Nothing is compiled here which would affect the headers for the target.
1094         # So forcing CC/CFLAGS is sane.
1095         set -- "${S}"/configure "${myconf[@]}"
1096         echo "$@"
1097         CC="$(tc-getBUILD_CC)" \
1098         CFLAGS="-O1 -pipe" \
1099         CPPFLAGS="-U_FORTIFY_SOURCE" \
1100         LDFLAGS="" \
1101         "$@" || die "failed to configure glibc"
1102 }
1103
1104 toolchain-glibc_do_src_configure() {
1105         if just_headers ; then
1106                 toolchain-glibc_headers_configure
1107         else
1108                 want_linuxthreads && glibc_do_configure linuxthreads
1109                 want_nptl && glibc_do_configure nptl
1110         fi
1111 }
1112
1113 toolchain-glibc_src_configure() {
1114         foreach_abi toolchain-glibc_do_src_configure
1115 }
1116
1117 toolchain-glibc_do_src_compile() {
1118         local t
1119         for t in linuxthreads nptl ; do
1120                 if want_${t} ; then
1121                         [[ ${EAPI:-0} == [01] ]] && glibc_do_configure ${t}
1122                         emake -C "$(builddir ${t})" || die "make ${t} for ${ABI} failed"
1123                 fi
1124         done
1125 }
1126
1127 toolchain-glibc_src_compile() {
1128         if just_headers ; then
1129                 [[ ${EAPI:-0} == [01] ]] && toolchain-glibc_headers_configure
1130                 return
1131         fi
1132
1133         foreach_abi toolchain-glibc_do_src_compile
1134 }
1135
1136 glibc_src_test() {
1137         cd "$(builddir $1)"
1138         nonfatal emake -j1 check && return 0
1139         einfo "make check failed - re-running with --keep-going to get the rest of the results"
1140         nonfatal emake -j1 -k check
1141         ewarn "make check failed for ${ABI}-${CTARGET}-$1"
1142         return 1
1143 }
1144
1145 toolchain-glibc_do_src_test() {
1146         local ret=0 t
1147         for t in linuxthreads nptl ; do
1148                 if want_${t} ; then
1149                         glibc_src_test ${t}
1150                         : $(( ret |= $? ))
1151                 fi
1152         done
1153         return ${ret}
1154 }
1155
1156 toolchain-glibc_src_test() {
1157         # Give tests more time to complete.
1158         export TIMEOUTFACTOR=5
1159
1160         foreach_abi toolchain-glibc_do_src_test || die "tests failed"
1161 }
1162
1163 toolchain-glibc_do_src_install() {
1164         local builddir=$(builddir $(want_linuxthreads && echo linuxthreads || echo nptl))
1165         cd "${builddir}"
1166
1167         emake install_root="${D}$(alt_prefix)" install || die
1168
1169         if want_linuxthreads && want_nptl ; then
1170                 einfo "Installing NPTL to $(alt_libdir)/tls/..."
1171                 cd "$(builddir nptl)"
1172                 dodir $(alt_libdir)/tls $(alt_usrlibdir)/nptl
1173
1174                 local l src_lib
1175                 for l in libc libm librt libpthread libthread_db ; do
1176                         # take care of shared lib first ...
1177                         l=${l}.so
1178                         if [[ -e ${l} ]] ; then
1179                                 src_lib=${l}
1180                         else
1181                                 src_lib=$(eval echo */${l})
1182                         fi
1183                         cp -a ${src_lib} "${ED}"$(alt_libdir)/tls/${l} || die "copying nptl ${l}"
1184                         fperms a+rx $(alt_libdir)/tls/${l}
1185                         dosym ${l} $(alt_libdir)/tls/$(scanelf -qSF'%S#F' ${src_lib})
1186
1187                         # then grab the linker script or the symlink ...
1188                         if [[ -L ${ED}$(alt_usrlibdir)/${l} ]] ; then
1189                                 dosym $(alt_libdir)/tls/${l} $(alt_usrlibdir)/nptl/${l}
1190                         else
1191                                 sed \
1192                                         -e "s:/${l}:/tls/${l}:g" \
1193                                         -e "s:/${l/%.so/_nonshared.a}:/nptl/${l/%.so/_nonshared.a}:g" \
1194                                         "${ED}"$(alt_usrlibdir)/${l} > "${ED}"$(alt_usrlibdir)/nptl/${l}
1195                         fi
1196
1197                         # then grab the static lib ...
1198                         src_lib=${src_lib/%.so/.a}
1199                         [[ ! -e ${src_lib} ]] && src_lib=${src_lib/%.a/_pic.a}
1200                         cp -a ${src_lib} "${ED}"$(alt_usrlibdir)/nptl/ || die "copying nptl ${src_lib}"
1201                         src_lib=${src_lib/%.a/_nonshared.a}
1202                         if [[ -e ${src_lib} ]] ; then
1203                                 cp -a ${src_lib} "${ED}"$(alt_usrlibdir)/nptl/ || die "copying nptl ${src_lib}"
1204                         fi
1205                 done
1206
1207                 # use the nptl linker instead of the linuxthreads one as the linuxthreads
1208                 # one may lack TLS support and that can be really bad for business
1209                 cp -a elf/ld.so "${ED}"$(alt_libdir)/$(scanelf -qSF'%S#F' elf/ld.so) || die "copying nptl interp"
1210         fi
1211
1212         # Normally real_pv is ${PV}. Live ebuilds are exception, there we need
1213         # to infer upstream version:
1214         # '#define VERSION "2.26.90"' -> '2.26.90'
1215         local upstream_pv=$(sed -n -r 's/#define VERSION "(.*)"/\1/p' "${S}"/version.h)
1216         # Newer versions get fancy with libm linkage to include vectorized support.
1217         # While we don't really need a ldscript here, portage QA checks get upset.
1218         if [[ -e ${ED}$(alt_usrlibdir)/libm-${upstream_pv}.a ]] ; then
1219                 dosym ../../$(get_libdir)/libm-${upstream_pv}.so $(alt_usrlibdir)/libm-${upstream_pv}.so
1220         fi
1221
1222         # We'll take care of the cache ourselves
1223         rm -f "${ED}"/etc/ld.so.cache
1224
1225         # Everything past this point just needs to be done once ...
1226         is_final_abi || return 0
1227
1228         # Make sure the non-native interp can be found on multilib systems even
1229         # if the main library set isn't installed into the right place.  Maybe
1230         # we should query the active gcc for info instead of hardcoding it ?
1231         local i ldso_abi ldso_name
1232         local ldso_abi_list=(
1233                 # x86
1234                 amd64   /lib64/ld-linux-x86-64.so.2
1235                 x32     /libx32/ld-linux-x32.so.2
1236                 x86     /lib/ld-linux.so.2
1237                 # mips
1238                 o32     /lib/ld.so.1
1239                 n32     /lib32/ld.so.1
1240                 n64     /lib64/ld.so.1
1241                 # powerpc
1242                 ppc     /lib/ld.so.1
1243                 ppc64   /lib64/ld64.so.1
1244                 # s390
1245                 s390    /lib/ld.so.1
1246                 s390x   /lib/ld64.so.1
1247                 # sparc
1248                 sparc32 /lib/ld-linux.so.2
1249                 sparc64 /lib64/ld-linux.so.2
1250         )
1251         case $(tc-endian) in
1252         little)
1253                 ldso_abi_list+=(
1254                         # arm
1255                         arm64   /lib/ld-linux-aarch64.so.1
1256                 )
1257                 ;;
1258         big)
1259                 ldso_abi_list+=(
1260                         # arm
1261                         arm64   /lib/ld-linux-aarch64_be.so.1
1262                 )
1263                 ;;
1264         esac
1265         if [[ ${SYMLINK_LIB} == "yes" ]] && [[ ! -e ${ED}/$(alt_prefix)/lib ]] ; then
1266                 dosym $(get_abi_LIBDIR ${DEFAULT_ABI}) $(alt_prefix)/lib
1267         fi
1268         for (( i = 0; i < ${#ldso_abi_list[@]}; i += 2 )) ; do
1269                 ldso_abi=${ldso_abi_list[i]}
1270                 has ${ldso_abi} $(get_install_abis) || continue
1271
1272                 ldso_name="$(alt_prefix)${ldso_abi_list[i+1]}"
1273                 if [[ ! -L ${ED}/${ldso_name} && ! -e ${ED}/${ldso_name} ]] ; then
1274                         dosym ../$(get_abi_LIBDIR ${ldso_abi})/${ldso_name##*/} ${ldso_name}
1275                 fi
1276         done
1277
1278         # With devpts under Linux mounted properly, we do not need the pt_chown
1279         # binary to be setuid.  This is because the default owners/perms will be
1280         # exactly what we want.
1281         if in_iuse suid && ! use suid ; then
1282                 find "${ED}" -name pt_chown -exec chmod -s {} +
1283         fi
1284
1285         #################################################################
1286         # EVERYTHING AFTER THIS POINT IS FOR NATIVE GLIBC INSTALLS ONLY #
1287         # Make sure we install some symlink hacks so that when we build
1288         # a 2nd stage cross-compiler, gcc finds the target system
1289         # headers correctly.  See gcc/doc/gccinstall.info
1290         if is_crosscompile ; then
1291                 # We need to make sure that /lib and /usr/lib always exists.
1292                 # gcc likes to use relative paths to get to its multilibs like
1293                 # /usr/lib/../lib64/.  So while we don't install any files into
1294                 # /usr/lib/, we do need it to exist.
1295                 cd "${ED}"$(alt_libdir)/..
1296                 [[ -e lib ]] || mkdir lib
1297                 cd "${ED}"$(alt_usrlibdir)/..
1298                 [[ -e lib ]] || mkdir lib
1299
1300                 dosym usr/include $(alt_prefix)/sys-include
1301                 return 0
1302         fi
1303
1304         # Files for Debian-style locale updating
1305         dodir /usr/share/i18n
1306         sed \
1307                 -e "/^#/d" \
1308                 -e "/SUPPORTED-LOCALES=/d" \
1309                 -e "s: \\\\::g" -e "s:/: :g" \
1310                 "${S}"/localedata/SUPPORTED > "${ED}"/usr/share/i18n/SUPPORTED \
1311                 || die "generating /usr/share/i18n/SUPPORTED failed"
1312         cd "${WORKDIR}"/extra/locale
1313         dosbin locale-gen || die
1314         doman *.[0-8]
1315         insinto /etc
1316         doins locale.gen || die
1317
1318         # Make sure all the ABI's can find the locales and so we only
1319         # have to generate one set
1320         local a
1321         keepdir /usr/$(get_libdir)/locale
1322         for a in $(get_install_abis) ; do
1323                 if [[ ! -e ${ED}/usr/$(get_abi_LIBDIR ${a})/locale ]] ; then
1324                         dosym /usr/$(get_libdir)/locale /usr/$(get_abi_LIBDIR ${a})/locale
1325                 fi
1326         done
1327
1328         cd "${S}"
1329
1330         # Install misc network config files
1331         insinto /etc
1332         doins nscd/nscd.conf posix/gai.conf nss/nsswitch.conf || die
1333         doins "${WORKDIR}"/extra/etc/*.conf || die
1334
1335         if ! in_iuse nscd || use nscd ; then
1336                 doinitd "$(prefixify_ro "${WORKDIR}"/extra/etc/nscd)" || die
1337
1338                 local nscd_args=(
1339                         -e "s:@PIDFILE@:$(strings "${ED}"/usr/sbin/nscd | grep nscd.pid):"
1340                 )
1341                 version_is_at_least 2.16 || nscd_args+=( -e 's: --foreground : :' )
1342                 sed -i "${nscd_args[@]}" "${ED}"/etc/init.d/nscd
1343
1344                 # Newer versions of glibc include the nscd.service themselves.
1345                 # TODO: Drop the $FILESDIR copy once 2.19 goes stable.
1346                 if version_is_at_least 2.19 ; then
1347                         systemd_dounit nscd/nscd.service || die
1348                         systemd_newtmpfilesd nscd/nscd.tmpfiles nscd.conf || die
1349                 else
1350                         systemd_dounit "${FILESDIR}"/nscd.service || die
1351                         systemd_newtmpfilesd "${FILESDIR}"/nscd.tmpfilesd nscd.conf || die
1352                 fi
1353         else
1354                 # Do this since extra/etc/*.conf above might have nscd.conf.
1355                 rm -f "${ED}"/etc/nscd.conf
1356         fi
1357
1358         echo 'LDPATH="include ld.so.conf.d/*.conf"' > "${T}"/00glibc
1359         doenvd "${T}"/00glibc || die
1360
1361         for d in BUGS ChangeLog* CONFORMANCE FAQ NEWS NOTES PROJECTS README* ; do
1362                 [[ -s ${d} ]] && dodoc ${d}
1363         done
1364
1365         # Prevent overwriting of the /etc/localtime symlink.  We'll handle the
1366         # creation of the "factory" symlink in pkg_postinst().
1367         rm -f "${ED}"/etc/localtime
1368 }
1369
1370 toolchain-glibc_headers_install() {
1371         local builddir=$(builddir "headers")
1372         cd "${builddir}"
1373         emake install_root="${D}$(alt_prefix)" install-headers || die
1374         if ! version_is_at_least 2.16 ; then
1375                 insinto $(alt_headers)/bits
1376                 doins bits/stdio_lim.h || die
1377         fi
1378         insinto $(alt_headers)/gnu
1379         doins "${S}"/include/gnu/stubs.h || die "doins include gnu"
1380         # Make sure we install the sys-include symlink so that when
1381         # we build a 2nd stage cross-compiler, gcc finds the target
1382         # system headers correctly.  See gcc/doc/gccinstall.info
1383         dosym usr/include $(alt_prefix)/sys-include
1384 }
1385
1386 toolchain-glibc_src_install() {
1387         if just_headers ; then
1388                 export ABI=default
1389                 toolchain-glibc_headers_install
1390                 return
1391         fi
1392
1393         foreach_abi toolchain-glibc_do_src_install
1394 }
1395
1396 # Simple test to make sure our new glibc isn't completely broken.
1397 # Make sure we don't test with statically built binaries since
1398 # they will fail.  Also, skip if this glibc is a cross compiler.
1399 #
1400 # If coreutils is built with USE=multicall, some of these files
1401 # will just be wrapper scripts, not actual ELFs we can test.
1402 glibc_sanity_check() {
1403         cd / #228809
1404
1405         # We enter ${ED} so to avoid trouble if the path contains
1406         # special characters; for instance if the path contains the
1407         # colon character (:), then the linker will try to split it
1408         # and look for the libraries in an unexpected place. This can
1409         # lead to unsafe code execution if the generated prefix is
1410         # within a world-writable directory.
1411         # (e.g. /var/tmp/portage:${HOSTNAME})
1412         pushd "${ED}"/$(get_libdir) >/dev/null
1413
1414         local x striptest
1415         for x in cal date env free ls true uname uptime ; do
1416                 x=$(type -p ${x})
1417                 [[ -z ${x} || ${x} != ${EPREFIX}/* ]] && continue
1418                 striptest=$(LC_ALL="C" file -L ${x} 2>/dev/null) || continue
1419                 case ${striptest} in
1420                 *"statically linked"*) continue;;
1421                 *"ASCII text"*) continue;;
1422                 esac
1423                 # We need to clear the locale settings as the upgrade might want
1424                 # incompatible locale data.  This test is not for verifying that.
1425                 LC_ALL=C \
1426                 ./ld-*.so --library-path . ${x} > /dev/null \
1427                         || die "simple run test (${x}) failed"
1428         done
1429
1430         popd >/dev/null
1431 }
1432
1433 toolchain-glibc_pkg_preinst() {
1434         # nothing to do if just installing headers
1435         just_headers && return
1436
1437         # prepare /etc/ld.so.conf.d/ for files
1438         mkdir -p "${EROOT}"/etc/ld.so.conf.d
1439
1440         # Default /etc/hosts.conf:multi to on for systems with small dbs.
1441         if [[ $(wc -l < "${EROOT}"/etc/hosts) -lt 1000 ]] ; then
1442                 sed -i '/^multi off/s:off:on:' "${ED}"/etc/host.conf
1443                 elog "Defaulting /etc/host.conf:multi to on"
1444         fi
1445
1446         [[ ${ROOT} != "/" ]] && return 0
1447         [[ -d ${ED}/$(get_libdir) ]] || return 0
1448         [[ -z ${BOOTSTRAP_RAP} ]] && glibc_sanity_check
1449
1450         # For newer EAPIs, this was run in pkg_pretend.
1451         if [[ ${EAPI:-0} == [0123] ]] ; then
1452                 check_devpts
1453         fi
1454 }
1455
1456 toolchain-glibc_pkg_postinst() {
1457         # nothing to do if just installing headers
1458         just_headers && return
1459
1460         if ! tc-is-cross-compiler && [[ -x ${EROOT}/usr/sbin/iconvconfig ]] ; then
1461                 # Generate fastloading iconv module configuration file.
1462                 "${EROOT}"/usr/sbin/iconvconfig --prefix="${ROOT}"
1463         fi
1464
1465         if ! is_crosscompile && [[ ${ROOT} == "/" ]] ; then
1466                 # Reload init ... if in a chroot or a diff init package, ignore
1467                 # errors from this step #253697
1468                 /sbin/telinit U 2>/dev/null
1469
1470                 # if the host locales.gen contains no entries, we'll install everything
1471                 local locale_list="${EROOT}etc/locale.gen"
1472                 if [[ -z $(locale-gen --list --config "${locale_list}") ]] ; then
1473                         ewarn "Generating all locales; edit /etc/locale.gen to save time/space"
1474                         locale_list="${EROOT}usr/share/i18n/SUPPORTED"
1475                 fi
1476                 locale-gen -j $(makeopts_jobs) --config "${locale_list}"
1477         fi
1478 }
1479
1480 _TOOLCHAIN_GLIBC_ECLASS=1
1481 fi