Merge pull request #123989 from Mic92/static-pie
glibc: allow to build position-independent static executable
This commit is contained in:
commit
5551a78578
@ -20,15 +20,25 @@ if [ -z "${NIX_BINTOOLS_WRAPPER_FLAGS_SET_@suffixSalt@:-}" ]; then
|
||||
source @out@/nix-support/add-flags.sh
|
||||
fi
|
||||
|
||||
setDynamicLinker=1
|
||||
|
||||
# Optionally filter out paths not refering to the store.
|
||||
expandResponseParams "$@"
|
||||
|
||||
# NIX_LINK_TYPE is set if ld has been called through our cc wrapper. We take
|
||||
# advantage of this to avoid both recalculating it, and also repeating other
|
||||
# processing cc wrapper has already done.
|
||||
if [[ -n "${NIX_LINK_TYPE_@suffixSalt@:-}" ]]; then
|
||||
linkType=$NIX_LINK_TYPE_@suffixSalt@
|
||||
else
|
||||
linkType=$(checkLinkType "$@")
|
||||
fi
|
||||
|
||||
if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "${NIX_STORE:-}"
|
||||
&& ( -z "$NIX_IGNORE_LD_THROUGH_GCC_@suffixSalt@" || -z "${NIX_LDFLAGS_SET_@suffixSalt@:-}" ) ]]; then
|
||||
&& ( -z "$NIX_IGNORE_LD_THROUGH_GCC_@suffixSalt@" || -z "${NIX_LINK_TYPE_@suffixSalt@:-}" ) ]]; then
|
||||
rest=()
|
||||
nParams=${#params[@]}
|
||||
declare -i n=0
|
||||
|
||||
while (( "$n" < "$nParams" )); do
|
||||
p=${params[n]}
|
||||
p2=${params[n+1]:-} # handle `p` being last one
|
||||
@ -48,11 +58,6 @@ if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "${NIX_STORE:-}"
|
||||
# Our ld is not built with sysroot support (Can we fix that?)
|
||||
:
|
||||
else
|
||||
if [[ "$p" = -static || "$p" = -static-pie ]]; then
|
||||
# Using a dynamic linker for static binaries can lead to crashes.
|
||||
# This was observed for rust binaries.
|
||||
setDynamicLinker=0
|
||||
fi
|
||||
rest+=("$p")
|
||||
fi
|
||||
n+=1
|
||||
@ -61,22 +66,24 @@ if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "${NIX_STORE:-}"
|
||||
params=(${rest+"${rest[@]}"})
|
||||
fi
|
||||
|
||||
|
||||
source @out@/nix-support/add-hardening.sh
|
||||
|
||||
extraAfter=()
|
||||
extraBefore=(${hardeningLDFlags[@]+"${hardeningLDFlags[@]}"})
|
||||
|
||||
if [ -z "${NIX_LDFLAGS_SET_@suffixSalt@:-}" ]; then
|
||||
extraAfter+=($NIX_LDFLAGS_@suffixSalt@)
|
||||
extraBefore+=($NIX_LDFLAGS_BEFORE_@suffixSalt@)
|
||||
if [ -z "${NIX_LINK_TYPE_@suffixSalt@:-}" ]; then
|
||||
extraAfter+=($(filterRpathFlags "$linkType" $NIX_LDFLAGS_@suffixSalt@))
|
||||
extraBefore+=($(filterRpathFlags "$linkType" $NIX_LDFLAGS_BEFORE_@suffixSalt@))
|
||||
|
||||
# By adding dynamic linker to extraBefore we allow the users set their
|
||||
# own dynamic linker as NIX_LD_FLAGS will override earlier set flags
|
||||
if [[ "$setDynamicLinker" = 1 && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then
|
||||
if [[ "$linkType" == dynamic && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then
|
||||
extraBefore+=("-dynamic-linker" "$NIX_DYNAMIC_LINKER_@suffixSalt@")
|
||||
fi
|
||||
fi
|
||||
|
||||
extraAfter+=($NIX_LDFLAGS_AFTER_@suffixSalt@)
|
||||
extraAfter+=($(filterRpathFlags "$linkType" $NIX_LDFLAGS_AFTER_@suffixSalt@))
|
||||
|
||||
# These flags *must not* be pulled up to -Wl, flags, so they can't go in
|
||||
# add-flags.sh. They must always be set, so must not be disabled by
|
||||
@ -173,7 +180,7 @@ do
|
||||
prev="$p"
|
||||
done
|
||||
|
||||
if [[ "$link32" = "1" && "$setDynamicLinker" = 1 && -e "@out@/nix-support/dynamic-linker-m32" ]]; then
|
||||
if [[ "$link32" == "1" && "$linkType" == dynamic && -e "@out@/nix-support/dynamic-linker-m32" ]]; then
|
||||
# We have an alternate 32-bit linker and we're producing a 32-bit ELF, let's
|
||||
# use it.
|
||||
extraAfter+=(
|
||||
@ -183,7 +190,7 @@ if [[ "$link32" = "1" && "$setDynamicLinker" = 1 && -e "@out@/nix-support/dynami
|
||||
fi
|
||||
|
||||
# Add all used dynamic libraries to the rpath.
|
||||
if [ "$NIX_DONT_SET_RPATH_@suffixSalt@" != 1 ]; then
|
||||
if [[ "$NIX_DONT_SET_RPATH_@suffixSalt@" != 1 && "$linkType" != static-pie ]]; then
|
||||
# For each directory in the library search path (-L...),
|
||||
# see if it contains a dynamic library used by a -l... flag. If
|
||||
# so, add the directory to the rpath.
|
||||
|
@ -29,9 +29,10 @@ cc1=0
|
||||
cxxInclude=1
|
||||
cxxLibrary=1
|
||||
cInclude=1
|
||||
setDynamicLinker=1
|
||||
|
||||
expandResponseParams "$@"
|
||||
linkType=$(checkLinkType "$@")
|
||||
|
||||
declare -i n=0
|
||||
nParams=${#params[@]}
|
||||
while (( "$n" < "$nParams" )); do
|
||||
@ -60,8 +61,6 @@ while (( "$n" < "$nParams" )); do
|
||||
cxxInclude=0
|
||||
elif [ "$p" = -nostdinc++ ]; then
|
||||
cxxInclude=0
|
||||
elif [[ "$p" = -static || "$p" = -static-pie ]]; then
|
||||
setDynamicLinker=0
|
||||
elif [[ "$p" != -?* ]]; then
|
||||
# A dash alone signifies standard input; it is not a flag
|
||||
nonFlagArgs=1
|
||||
@ -151,24 +150,24 @@ if [ "$dontLink" != 1 ]; then
|
||||
|
||||
# Add the flags that should only be passed to the compiler when
|
||||
# linking.
|
||||
extraAfter+=($NIX_CFLAGS_LINK_@suffixSalt@)
|
||||
extraAfter+=($(filterRpathFlags "$linkType" $NIX_CFLAGS_LINK_@suffixSalt@))
|
||||
|
||||
# Add the flags that should be passed to the linker (and prevent
|
||||
# `ld-wrapper' from adding NIX_LDFLAGS_@suffixSalt@ again).
|
||||
for i in $NIX_LDFLAGS_BEFORE_@suffixSalt@; do
|
||||
for i in $(filterRpathFlags "$linkType" $NIX_LDFLAGS_BEFORE_@suffixSalt@); do
|
||||
extraBefore+=("-Wl,$i")
|
||||
done
|
||||
if [[ "$setDynamicLinker" = 1 && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then
|
||||
if [[ "$linkType" == dynamic && -n "$NIX_DYNAMIC_LINKER_@suffixSalt@" ]]; then
|
||||
extraBefore+=("-Wl,-dynamic-linker=$NIX_DYNAMIC_LINKER_@suffixSalt@")
|
||||
fi
|
||||
for i in $NIX_LDFLAGS_@suffixSalt@; do
|
||||
for i in $(filterRpathFlags "$linkType" $NIX_LDFLAGS_@suffixSalt@); do
|
||||
if [ "${i:0:3}" = -L/ ]; then
|
||||
extraAfter+=("$i")
|
||||
else
|
||||
extraAfter+=("-Wl,$i")
|
||||
fi
|
||||
done
|
||||
export NIX_LDFLAGS_SET_@suffixSalt@=1
|
||||
export NIX_LINK_TYPE_@suffixSalt@=$linkType
|
||||
fi
|
||||
|
||||
# As a very special hack, if the arguments are just `-v', then don't
|
||||
|
@ -129,3 +129,38 @@ expandResponseParams() {
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
checkLinkType() {
|
||||
local arg mode
|
||||
type="dynamic"
|
||||
for arg in "$@"; do
|
||||
if [[ "$arg" = -static ]]; then
|
||||
type="static"
|
||||
elif [[ "$arg" = -static-pie ]]; then
|
||||
type="static-pie"
|
||||
fi
|
||||
done
|
||||
echo "$type"
|
||||
}
|
||||
|
||||
# When building static-pie executables we cannot have rpath
|
||||
# set. At least glibc requires rpath to be empty
|
||||
filterRpathFlags() {
|
||||
local linkType=$1 ret="" i
|
||||
shift
|
||||
|
||||
if [[ "$linkType" == "static-pie" ]]; then
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
i="$1"; shift 1
|
||||
if [[ "$i" == -rpath ]]; then
|
||||
# also skip its argument
|
||||
shift
|
||||
else
|
||||
ret+="$i "
|
||||
fi
|
||||
done
|
||||
else
|
||||
ret=$@
|
||||
fi
|
||||
echo $ret
|
||||
}
|
||||
|
@ -153,6 +153,8 @@ stdenv.mkDerivation ({
|
||||
"--enable-add-ons"
|
||||
"--sysconfdir=/etc"
|
||||
"--enable-stackguard-randomization"
|
||||
"--enable-static-pie"
|
||||
"--enable-bind-now"
|
||||
(lib.withFeatureAs withLinuxHeaders "headers" "${linuxHeaders}/include")
|
||||
(lib.enableFeature profilingLibraries "profile")
|
||||
] ++ lib.optionals withLinuxHeaders [
|
||||
|
@ -35,8 +35,7 @@ in stdenv.mkDerivation {
|
||||
printf "checking whether compiler builds valid static C binaries... " >&2
|
||||
$CC ${staticLibc} -static -o cc-static ${./cc-main.c}
|
||||
./cc-static
|
||||
# our glibc does not have pie enabled yet.
|
||||
${lib.optionalString (stdenv.hostPlatform.isMusl && stdenv.cc.isGNU) ''
|
||||
${lib.optionalString (stdenv.cc.isGNU && lib.versionAtLeast (lib.getVersion stdenv.cc.name) "8.0.0") ''
|
||||
printf "checking whether compiler builds valid static pie C binaries... " >&2
|
||||
$CC ${staticLibc} -static-pie -o cc-static-pie ${./cc-main.c}
|
||||
./cc-static-pie
|
||||
|
Loading…
Reference in New Issue
Block a user