scripts/build/libc/glibc-eglibc.sh-common
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Mon Feb 21 23:39:46 2011 +0100 (2011-02-21)
changeset 2312 8b9938edd3d8
parent 2289 165eff2a1e10
child 2313 6336f985e2c0
permissions -rw-r--r--
libc/glibc: add fortify option

By default, recent versions of glibc and eglibc will build some
functions that take format strings (eg. printf, syslog...) with
run-time checks against some format string attacks. This is
called a fortified build.

Unfortunately, this fails somehow while building the instrumented
version of syslog, with some kind of circular dependency...

Disable fortified builds by default, and hide the enabling option
behind EXPERIMENTAL for daring users...

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
     1 # This file contains the functions common to glibc and eglibc
     2 
     3 # Build and install headers and start files
     4 do_libc_start_files() {
     5     local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}"
     6 
     7     CT_DoStep INFO "Installing C library headers & start files"
     8 
     9     mkdir -p "${CT_BUILD_DIR}/build-libc-startfiles"
    10     cd "${CT_BUILD_DIR}/build-libc-startfiles"
    11 
    12     CT_DoLog EXTRA "Configuring C library"
    13 
    14     case "${CT_LIBC}" in
    15         eglibc)
    16             if [ "${CT_EGLIBC_CUSTOM_CONFIG}" = "y" ]; then
    17                 CT_DoExecLog ALL cp "${CT_CONFIG_DIR}/eglibc.config" option-groups.config
    18             fi
    19             ;;
    20     esac
    21 
    22     cross_cc=$(CT_Which "${CT_TARGET}-gcc")
    23     cross_cxx=$(CT_Which "${CT_TARGET}-g++")
    24     cross_ar=$(CT_Which "${CT_TARGET}-ar")
    25     cross_ranlib=$(CT_Which "${CT_TARGET}-ranlib")
    26 
    27     CT_DoLog DEBUG "Using gcc for target: '${cross_cc}'"
    28     CT_DoLog DEBUG "Using g++ for target: '${cross_cxx}'"
    29     CT_DoLog DEBUG "Using ar for target: '${cross_ar}'"
    30     CT_DoLog DEBUG "Using ranlib for target: '${cross_ranlib}'"
    31 
    32     touch config.cache
    33     if [ "${CT_LIBC_GLIBC_FORCE_UNWIND}" = "y" ]; then
    34         echo "libc_cv_forced_unwind=yes" >>config.cache
    35         echo "libc_cv_c_cleanup=yes" >>config.cache
    36     fi
    37 
    38     # Pre-seed the configparms file with values from the config option
    39     printf "${CT_LIBC_GLIBC_CONFIGPARMS}\n" > configparms
    40 
    41     BUILD_CC="${CT_BUILD}-gcc"                          \
    42     CC=${cross_cc}                                      \
    43     CXX=${cross_cxx}                                    \
    44     AR=${cross_ar}                                      \
    45     RANLIB=${cross_ranlib}                              \
    46     CT_DoExecLog CFG                                    \
    47     "${src_dir}/configure"                              \
    48         --prefix=/usr                                   \
    49         --with-headers="${CT_HEADERS_DIR}"              \
    50         --build="${CT_BUILD}"                           \
    51         --host="${CT_TARGET}"                           \
    52         --cache-file="$(pwd)/config.cache"              \
    53         --disable-profile                               \
    54         --without-gd                                    \
    55         --without-cvs                                   \
    56         --enable-add-ons
    57 
    58     CT_DoLog EXTRA "Installing C library headers"
    59 
    60     # use the 'install-headers' makefile target to install the
    61     # headers
    62     CT_DoExecLog ALL make ${JOBSFLAGS}              \
    63                      install_root=${CT_SYSROOT_DIR} \
    64                      install-bootstrap-headers=yes  \
    65                      install-headers
    66 
    67     # For glibc, a few headers need to be manually installed
    68     if [ "${CT_LIBC}" = "glibc" ]; then
    69         # Two headers -- stubs.h and features.h -- aren't installed by install-headers,
    70         # so do them by hand.  We can tolerate an empty stubs.h for the moment.
    71         # See e.g. http://gcc.gnu.org/ml/gcc/2002-01/msg00900.html
    72         mkdir -p "${CT_HEADERS_DIR}/gnu"
    73         CT_DoExecLog ALL touch "${CT_HEADERS_DIR}/gnu/stubs.h"
    74         CT_DoExecLog ALL cp -v "${CT_SRC_DIR}/glibc-${CT_LIBC_VERSION}/include/features.h"  \
    75                                "${CT_HEADERS_DIR}/features.h"
    76 
    77         # Building the bootstrap gcc requires either setting inhibit_libc, or
    78         # having a copy of stdio_lim.h... see
    79         # http://sources.redhat.com/ml/libc-alpha/2003-11/msg00045.html
    80         CT_DoExecLog ALL cp -v bits/stdio_lim.h "${CT_HEADERS_DIR}/bits/stdio_lim.h"
    81 
    82         # Following error building gcc-4.0.0's gcj:
    83         #  error: bits/syscall.h: No such file or directory
    84         # solved by following copy; see http://sourceware.org/ml/crossgcc/2005-05/msg00168.html
    85         # but it breaks arm, see http://sourceware.org/ml/crossgcc/2006-01/msg00091.html
    86         [ "${CT_ARCH}" != "arm" ] && CT_DoExecLog ALL cp -v misc/syscall-list.h "${CT_HEADERS_DIR}/bits/syscall.h" || true
    87     fi
    88 
    89     CT_DoLog EXTRA "Installing C library start files"
    90 
    91     # there are a few object files needed to link shared libraries,
    92     # which we build and install by hand
    93     CT_DoExecLog ALL mkdir -p "${CT_SYSROOT_DIR}/usr/lib"
    94     CT_DoExecLog ALL make ${JOBSFLAGS} csu/subdir_lib
    95     CT_DoExecLog ALL cp csu/crt1.o csu/crti.o csu/crtn.o \
    96                         "${CT_SYSROOT_DIR}/usr/lib"
    97 
    98     # Finally, 'libgcc_s.so' requires a 'libc.so' to link against.
    99     # However, since we will never actually execute its code,
   100     # it doesn't matter what it contains.  So, treating '/dev/null'
   101     # as a C source file, we produce a dummy 'libc.so' in one step
   102     CT_DoExecLog ALL "${cross_cc}" -nostdlib        \
   103                                    -nostartfiles    \
   104                                    -shared          \
   105                                    -x c /dev/null   \
   106                                    -o "${CT_SYSROOT_DIR}/usr/lib/libc.so"
   107 
   108     CT_EndStep
   109 }
   110 
   111 # This function builds and install the full C library
   112 do_libc() {
   113     local src_dir="${CT_SRC_DIR}/${CT_LIBC}-${CT_LIBC_VERSION}"
   114     local extra_cc_args
   115     local -a extra_config
   116     local -a extra_make_args
   117     local glibc_cflags
   118 
   119     CT_DoStep INFO "Installing C library"
   120 
   121     mkdir -p "${CT_BUILD_DIR}/build-libc"
   122     cd "${CT_BUILD_DIR}/build-libc"
   123 
   124     CT_DoLog EXTRA "Configuring C library"
   125 
   126     case "${CT_LIBC}" in
   127         eglibc)
   128             if [ "${CT_EGLIBC_CUSTOM_CONFIG}" = "y" ]; then
   129                 CT_DoExecLog ALL cp "${CT_CONFIG_DIR}/eglibc.config" option-groups.config
   130             fi
   131             if [ "${CT_EGLIBC_OPT_SIZE}" = "y" ]; then
   132                 OPTIMIZE=-Os
   133             else
   134                 OPTIMIZE=-O2
   135             fi
   136             ;;
   137         glibc)
   138             # glibc can't be built without -O2 (reference needed!)
   139             OPTIMIZE=-O2
   140             # Also, if those two are missing, iconv build breaks
   141             extra_config+=( --disable-debug --disable-sanity-checks )
   142             ;;
   143     esac
   144 
   145     # Add some default glibc config options if not given by user.
   146     # We don't need to be conditional on wether the user did set different
   147     # values, as they CT_LIBC_GLIBC_EXTRA_CONFIG is passed after extra_config
   148 
   149     extra_config+=("$(do_libc_min_kernel_config)")
   150 
   151     case "${CT_THREADS}" in
   152         nptl)           extra_config+=("--with-__thread" "--with-tls");;
   153         linuxthreads)   extra_config+=("--with-__thread" "--without-tls" "--without-nptl");;
   154         none)           extra_config+=("--without-__thread" "--without-nptl")
   155                         case "${CT_LIBC_GLIBC_EXTRA_CONFIG}" in
   156                             *-tls*) ;;
   157                             *) extra_config+=("--without-tls");;
   158                         esac
   159                         ;;
   160     esac
   161 
   162     case "${CT_SHARED_LIBS}" in
   163         y) extra_config+=("--enable-shared");;
   164         *) extra_config+=("--disable-shared");;
   165     esac
   166 
   167     case "${CT_ARCH_FLOAT_HW},${CT_ARCH_FLOAT_SW}" in
   168         y,) extra_config+=("--with-fp");;
   169         ,y) extra_config+=("--without-fp");;
   170     esac
   171 
   172     if [ "${CT_LIBC_DISABLE_VERSIONING}" = "y" ]; then
   173         extra_config+=("--disable-versioning")
   174     fi
   175 
   176     if [ "${CT_LIBC_OLDEST_ABI}" != "" ]; then
   177         extra_config+=("--enable-oldest-abi=${CT_LIBC_OLDEST_ABI}")
   178     fi
   179 
   180     case "$(do_libc_add_ons_list ,)" in
   181         "") ;;
   182         *)  extra_config+=("--enable-add-ons=$(do_libc_add_ons_list ,)");;
   183     esac
   184 
   185     extra_cc_args="${extra_cc_args} ${CT_ARCH_ENDIAN_OPT}"
   186 
   187     touch config.cache
   188     if [ "${CT_LIBC_GLIBC_FORCE_UNWIND}" = "y" ]; then
   189         echo "libc_cv_forced_unwind=yes" >>config.cache
   190         echo "libc_cv_c_cleanup=yes" >>config.cache
   191     fi
   192 
   193     # Pre-seed the configparms file with values from the config option
   194     printf "${CT_LIBC_GLIBC_CONFIGPARMS}\n" > configparms
   195 
   196     cross_cc=$(CT_Which "${CT_TARGET}-gcc")    
   197 
   198     CT_DoLog DEBUG "Using gcc for target:     '${cross_cc}'"
   199     CT_DoLog DEBUG "Configuring with addons : '$(do_libc_add_ons_list ,)'"
   200     CT_DoLog DEBUG "Extra config args passed: '${extra_config[*]}'"
   201     CT_DoLog DEBUG "Extra CC args passed    : '${extra_cc_args}'"
   202 
   203     glibc_cflags="${CT_TARGET_CFLAGS} ${CT_LIBC_GLIBC_EXTRA_CFLAGS} ${OPTIMIZE}"
   204     case "${CT_LIBC_ENABLE_FORTIFIED_BUILD}" in
   205         y)  ;;
   206         *)  glibc_cflags+=" -U_FORTIFY_SOURCE";;
   207     esac
   208 
   209     # ./configure is mislead by our tools override wrapper for bash
   210     # so just tell it where the real bash is _on_the_target_!
   211     # Notes:
   212     # - ${ac_cv_path_BASH_SHELL} is only used to set BASH_SHELL
   213     # - ${BASH_SHELL}            is only used to set BASH
   214     # - ${BASH}                  is only used to set the shebang
   215     #                            in two scripts to run on the target
   216     # So we can safely bypass bash detection at compile time.
   217     # Should this change in a future eglibc release, we'd better
   218     # directly mangle the generated scripts _after_ they get built,
   219     # or even after they get installed... eglibc is such a sucker...
   220     echo "ac_cv_path_BASH_SHELL=/bin/bash" >>config.cache
   221 
   222     # Configure with --prefix the way we want it on the target...
   223     # There are a whole lot of settings here.  You'll probably want
   224     # to read up on what they all mean, and customize a bit, possibly by setting GLIBC_EXTRA_CONFIG
   225     # Compare these options with the ones used when installing the glibc headers above - they're different.
   226     # Adding "--without-gd" option to avoid error "memusagestat.c:36:16: gd.h: No such file or directory"
   227     # See also http://sources.redhat.com/ml/libc-alpha/2000-07/msg00024.html.
   228     # Set BUILD_CC, or we won't be able to build datafiles
   229 
   230     BUILD_CC="${CT_BUILD}-gcc"                                      \
   231     CFLAGS="${glibc_cflags}"                                        \
   232     CC="${CT_TARGET}-gcc ${CT_LIBC_EXTRA_CC_ARGS} ${extra_cc_args}" \
   233     AR=${CT_TARGET}-ar                                              \
   234     RANLIB=${CT_TARGET}-ranlib                                      \
   235     CT_DoExecLog CFG                                                \
   236     "${src_dir}/configure"                                          \
   237         --prefix=/usr                                               \
   238         --build=${CT_BUILD}                                         \
   239         --host=${CT_TARGET}                                         \
   240         --cache-file="$(pwd)/config.cache"                          \
   241         --without-cvs                                               \
   242         --disable-profile                                           \
   243         --without-gd                                                \
   244         --with-headers="${CT_HEADERS_DIR}"                          \
   245         "${extra_config[@]}"                                        \
   246         ${CT_LIBC_GLIBC_EXTRA_CONFIG}
   247     
   248     # build hacks
   249     case "${CT_ARCH},${CT_ARCH_CPU}" in
   250         powerpc,8??)
   251             # http://sourceware.org/ml/crossgcc/2008-10/msg00068.html
   252             CT_DoLog DEBUG "Activating support for memset on broken ppc-8xx (CPU15 erratum)"
   253             extra_make_args+=( ASFLAGS="-DBROKEN_PPC_8xx_CPU15" )
   254             ;;
   255     esac
   256 
   257     CT_DoLog EXTRA "Building C library"
   258     CT_DoExecLog ALL make ${JOBSFLAGS}                      \
   259                           "${extra_make_args[@]}"           \
   260                           all
   261 
   262     CT_DoLog EXTRA "Installing C library"
   263     CT_DoExecLog ALL make ${JOBSFLAGS}                      \
   264                           "${extra_make_args[@]}"           \
   265                           install_root="${CT_SYSROOT_DIR}"  \
   266                           install
   267 
   268     CT_EndStep
   269 }
   270 
   271 # This function finishes the C library install
   272 # This is a no-op
   273 do_libc_finish() {
   274     :
   275 }
   276 
   277 # Build up the addons list, separated with $1
   278 do_libc_add_ons_list() {
   279     local sep="$1"
   280     local addons_list="$( echo "${CT_LIBC_ADDONS_LIST}"         \
   281                           |sed -r -e "s/[[:space:],]/${sep}/g;" \
   282                         )"
   283     case "${CT_THREADS}" in
   284         none)   ;;
   285         *)      addons_list="${addons_list}${sep}${CT_THREADS}";;
   286     esac
   287     [ "${CT_LIBC_GLIBC_USE_PORTS}" = "y" ] && addons_list="${addons_list}${sep}ports"
   288     # Remove duplicate, leading and trailing separators
   289     echo "${addons_list}" |sed -r -e "s/${sep}+/${sep}/g; s/^${sep}//; s/${sep}\$//;"
   290 }
   291 
   292 # Compute up the minimum supported Linux kernel version
   293 do_libc_min_kernel_config() {
   294     local min_kernel_config
   295 
   296     case "${CT_LIBC_GLIBC_EXTRA_CONFIG}" in
   297         *--enable-kernel*) ;;
   298         *)  if [ "${CT_LIBC_GLIBC_KERNEL_VERSION_AS_HEADERS}" = "y" ]; then
   299                 # We can't rely on the kernel version from the configuration,
   300                 # because it might not be available if the user uses pre-installed
   301                 # headers. On the other hand, both method will have the kernel
   302                 # version installed in "usr/include/linux/version.h" in the sysroot.
   303                 # Parse that instead of having two code-paths.
   304                 version_code_file="${CT_SYSROOT_DIR}/usr/include/linux/version.h"
   305                 if [ ! -f "${version_code_file}" -o ! -r "${version_code_file}" ]; then
   306                     CT_Abort "Linux version is unavailable in installed headers files"
   307                 fi
   308                 version_code="$( grep -E LINUX_VERSION_CODE "${version_code_file}"  \
   309                                  |cut -d ' ' -f 3                                   \
   310                                )"
   311                 version=$(((version_code>>16)&0xFF))
   312                 patchlevel=$(((version_code>>8)&0xFF))
   313                 sublevel=$((version_code&0xFF))
   314                 min_kernel_config="${version}.${patchlevel}.${sublevel}"
   315             elif [ "${CT_LIBC_GLIBC_KERNEL_VERSION_CHOSEN}" = "y" ]; then
   316                 # Trim the fourth part of the linux version, keeping only the first three numbers
   317                 min_kernel_config="$( echo "${CT_LIBC_GLIBC_MIN_KERNEL_VERSION}"            \
   318                                       |sed -r -e 's/^([^.]+\.[^.]+\.[^.]+)(|\.[^.]+)$/\1/;' \
   319                                     )"
   320             fi
   321             echo "--enable-kernel=${min_kernel_config}"
   322             ;;
   323     esac
   324 }