Hard-code ld.so paths for all architectures

This supports multiple ld.so files in a cleaner way.  Also
forward-port multiple libc.so.6 file handling in
wrap-find-debuginfo.sh from downstream.  This also incorporates
the “nm --format=posix“ change from #2115831 downstream.

Related: RHEL-35602

Fedora 40 commit: 4ccb7475fc
This commit is contained in:
Arjun Shankar 2024-06-07 15:39:01 +02:00
parent b5be881eef
commit ab55eeb40c
2 changed files with 83 additions and 74 deletions

View File

@ -230,6 +230,36 @@ Source11: parse-SUPPORTED.py
# Include in the source RPM for reference.
Source12: ChangeLog.old
# ABI-specific program interpreter name. Used for debuginfo
# extraction (wrap-find-debuginfo.sh) and smoke testing ($run_ldso below).
%ifarch %{ix86}
%global glibc_ldso /lib/ld-linux.so.2
%endif
%ifarch aarch64
%global glibc_ldso /lib/ld-linux-aarch64.so.1
%endif
%ifarch ppc
%global glibc_ldso /lib/ld.so.1
%endif
%ifarch ppc64
%global glibc_ldso /lib64/ld64.so.1
%endif
%ifarch ppc64le
%global glibc_ldso /lib64/ld64.so.2
%endif
%ifarch riscv64
%global glibc_ldso /lib/ld-linux-riscv64-lp64d.so.1
%endif
%ifarch s390
%global glibc_ldso /lib/ld.so.1
%endif
%ifarch s390x
%global glibc_ldso /lib/ld64.so.1
%endif
%ifarch x86_64 x86_64_v2 x86_64_v3 x86_64_v4
%global glibc_ldso /lib64/ld-linux-x86-64.so.2
%endif
######################################################################
# Activate the wrapper script for debuginfo generation, by rewriting
# the definition of __debug_install_post.
@ -241,7 +271,7 @@ local original = rpm.expand("%{macrobody:__debug_install_post}")
-- Avoid embedded newlines that confuse the macro definition.
original = original:match("^%s*(.-)%s*$"):gsub("\\\n", "")
rpm.define("__debug_install_post bash " .. wrapper
.. " " .. sysroot .. " " .. original)
.. " " .. sysroot .. " %{glibc_ldso} " .. original)
}
# sysroot package support. These contain arch-specific packages, so
@ -1361,7 +1391,7 @@ build build-%{target}-32 \
# Default set of compiler options.
build build-%{target} \
CC="gcc $glibc_flags_cc $glibc_flags_cc_main" \
CXX="gcc $glibc_flags_cc $glibc_flags_cc_main" \
CXX="g++ $glibc_flags_cc $glibc_flags_cc_main" \
CFLAGS="$glibc_flags_cflags" \
%ifarch x86_64
--enable-cet \
@ -2202,19 +2232,7 @@ echo ====================PLT RELOCS LIBC.SO==============
readelf -Wr %{glibc_sysroot}/%{_lib}/libc-*.so | sed -n -e "$PLTCMD"
echo ====================PLT RELOCS END==================
# Obtain a way to run the dynamic loader. Avoid matching the symbolic
# link and then pick the first loader (although there should be only
# one). Use -maxdepth 2 to avoid descending into the /sys-root/
# sub-tree. See wrap-find-debuginfo.sh.
%ifarch x86_64
# Hardcode the patch to avoid picking up the 32-bit dynamic linker from
# glibc32; both 32-bit and 64-bit dynamic linkers will be present.
ldso_path="%{glibc_sysroot}/lib64/ld-linux-x86-64.so.2"
%else
ldso_path="$(find %{glibc_sysroot}/ -maxdepth 2 -regextype posix-extended \
-regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f | LC_ALL=C sort | head -n1)"
%endif
run_ldso="$ldso_path --library-path %{glibc_sysroot}/%{_lib}"
run_ldso="%{glibc_sysroot}/%{glibc_ldso} --library-path %{glibc_sysroot}/%{_lib}"
# Show the auxiliary vector as seen by the new library
# (even if we do not perform the valgrind test).

View File

@ -18,7 +18,13 @@ set -ex
workdir="$(mktemp -d -t find_debuginfo.XXXXXX)"
ldso_tmp="$workdir/ld.so"
libc_tmp="$workdir/libc.so"
libc_tmp_dir="$workdir/"
# Return the path where a libc should be saved temporarily. This path is
# based on its original path received in $1.
libc_tmp_path() {
echo "$libc_tmp_dir"`dirname "$1"`"/libc.so"
}
# Prefer a separately installed debugedit over the RPM-integrated one.
if command -v debugedit >/dev/null ; then
@ -34,64 +40,65 @@ trap cleanup 0
sysroot_path="$1"
shift
# Resolve symbolic link, so that the activities below only alter the
# file it points to.
ldso_path="$(readlink -f "$sysroot_path/$1")"
shift
script_path="$1"
shift
# See ldso_path setting in glibc.spec.
ldso_path=
for ldso_candidate in `find "$sysroot_path" -maxdepth 2 \
-regextype posix-extended -regex '.*/ld(-.*|64|)\.so\.[0-9]+$' -type f` ; do
if test -z "$ldso_path" ; then
ldso_path="$ldso_candidate"
elif [ -f "$sysroot_path/lib64/ld-linux-x86-64.so.2" ] && [ -f "$sysroot_path/lib/ld-linux.so.2" ]; then
# x86_64 with 32-bit libc built for glibc32 as well. Finding
# multiple dynamic linkers is expected, not a bug; ensure the
# 64-bit one is used.
ldso_path="$sysroot_path/lib64/ld-linux-x86-64.so.2"
else
echo "error: multiple ld.so candidates: $ldso_path, $ldso_candidate"
exit 1
fi
done
# libc.so.6 always uses this name, so it is simpler to locate.
libc_path=
for libc_candidate in `find "$sysroot_path" -maxdepth 2 -name libc.so.6`; do
if test -z "$libc_path" ; then
libc_path="$libc_candidate"
elif [ -f "$sysroot_path/lib64/ld-linux-x86-64.so.2" ] && [ -f "$sysroot_path/lib/ld-linux.so.2" ]; then
# x86_64 with 32-bit libc built for glibc32 as well. The test
# here uses ld.so paths, not libc paths, to ensure it doesn't
# apply on any other architecture.
libc_path="$sysroot_path/lib64/libc.so.6"
else
echo "error: multiple libc.so.6 candidates: $libc_path, $libc_candidate"
exit 1
fi
done
# This can result in multiple paths, hence the loop below.
libc_path=`find "$sysroot_path" -name libc.so.6`
# Preserve the original files.
cp "$ldso_path" "$ldso_tmp"
cp "$libc_path" "$libc_tmp"
for lib in $libc_path ; do
libtmp=`libc_tmp_path $lib`
mkdir -p `dirname "$libtmp"`
cp "$lib" "$libtmp"
done
# Run the debuginfo extraction.
"$script_path" "$@"
# libc.so.6: Extract the .gnu_debuglink section
objcopy -j.gnu_debuglink --set-section-flags .gnu_debuglink=alloc \
-O binary "$libc_path" "$libc_tmp.debuglink"
for lib in $libc_path ; do
libtmp=`libc_tmp_path "$lib"`
# libc.so.6: Extract the .gnu_debuglink section
objcopy -j.gnu_debuglink --set-section-flags .gnu_debuglink=alloc \
-O binary "$lib" "$libtmp.debuglink"
# Restore the original files.
cp "$libtmp" "$lib"
# Restore the original files.
# Reduce the size of libc notes. Primarily for annobin.
objcopy --merge-notes "$lib"
# libc.so.6: Restore the .gnu_debuglink section
objcopy --add-section .gnu_debuglink="$libtmp.debuglink" "$lib"
# libc.so.6: Reduce to valuable symbols. Eliminate file symbols,
# annobin symbols, and symbols used by the glibc build to implement
# hidden aliases (__EI_*). We would also like to remove __GI_*
# symbols, but even listing them explicitly (as in -K __GI_strlen)
# still causes strip to remove them, so there is no filtering of
# __GI_* here. (Debuginfo is gone after this, so no need to optimize
# it.)
strip -w \
-K '*' \
-K '!*.c' \
-K '!*.os' \
-K '!.annobin_*' \
-K '!__EI_*' \
-K '!__PRETTY_FUNCTION__*' \
"$lib"
done
# Restore the original ld.so.
cp "$ldso_tmp" "$ldso_path"
cp "$libc_tmp" "$libc_path"
# Reduce the size of notes. Primarily for annobin.
objcopy --merge-notes "$ldso_path"
objcopy --merge-notes "$libc_path"
# libc.so.6: Restore the .gnu_debuglink section
objcopy --add-section .gnu_debuglink="$libc_tmp.debuglink" "$libc_path"
# ld.so does not have separated debuginfo and so the debuginfo file
# generated by find-debuginfo is redundant. Therefore, remove it.
@ -108,22 +115,6 @@ for ldso_debug_candidate in `find "$sysroot_path" -maxdepth 2 \
done
rm -f "$ldso_debug"
# libc.so.6: Reduce to valuable symbols. Eliminate file symbols,
# annobin symbols, and symbols used by the glibc build to implement
# hidden aliases (__EI_*). We would also like to remove __GI_*
# symbols, but even listing them explicitly (as in -K __GI_strlen)
# still causes strip to remove them, so there is no filtering of
# __GI_* here. (Debuginfo is gone after this, so no need to optimize
# it.)
strip -w \
-K '*' \
-K '!*.c' \
-K '!*.os' \
-K '!.annobin_*' \
-K '!__EI_*' \
-K '!__PRETTY_FUNCTION__*' \
"$libc_path"
# ld.so: Rewrite the source file paths to match the extracted
# locations. First compute the arguments for invoking debugedit.
# See find-debuginfo.sh.
@ -147,7 +138,7 @@ done
debug_base_name=${last_arg:-$RPM_BUILD_ROOT}
$debugedit -b "$debug_base_name" -d "$debug_dest_name" -n $ldso_path
# Remove the .annobin* symbols (and only them).
if nm --format=just-symbols "$ldso_path" \
if nm --format=posix "$ldso_path" | cut -d' ' -f1 \
| grep '^\.annobin' > "$ldso_tmp.annobin-symbols"; then
objcopy --strip-symbols="$ldso_tmp.annobin-symbols" "$ldso_path"
fi