aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Gilbert <floppym@gentoo.org>2021-10-25 11:30:08 -0400
committerMike Gilbert <floppym@gentoo.org>2021-10-31 14:15:27 -0400
commit84206c6200eb003314cf4f2d640bf73f04654012 (patch)
treee1bc20168b1a8cab8b3694bc00a699d59f86b0ed
parent.github: test against Python 3.10 final (diff)
downloadportage-84206c6200eb003314cf4f2d640bf73f04654012.tar.gz
portage-84206c6200eb003314cf4f2d640bf73f04654012.tar.bz2
portage-84206c6200eb003314cf4f2d640bf73f04654012.zip
estrip: rework hard link logic in save_elf_debug
GDB loads debug files based on the file name given in the .gnu_debuglink section, prepended with /usr/lib/debug/${dirname}, where dirname is the absolute path to the parent directory of the binary being executed. For each unique inode as input, we need a link to the debug file with the GNU debuglink as its basename. A link to the debug file should exist for each directory in which the input inode exists. The debug link names should be based on the .gnu_debuglink value instead of the name of the file we are processing as input. The .gnu_debuglink value is based on the name of the first link processed for each inode. We save this value as a symlink, and then read it back as we process subsequent links. For example, given the following input: INODE PATH 1 /usr/bin/git 1 /usr/libexec/git-core/git-add 2 /usr/bin/git-shell 2 /usr/libexec/git-core/git-shell We generate the following inodes for the debug files: INODE DEBUGLINK 3 git.debug 4 git-shell.debug We should generate the following links: INODE PATH 3 /usr/lib/debug/usr/bin/git.debug 3 /usr/lib/debug/usr/libexec/git-core/git.debug 4 /usr/bin/debug/usr/bin/git-shell.debug 4 /usr/bin/debug/usr/libexec/git-core/git-shell.debug The previous code would have generated this broken output: INODE PATH 3 /usr/lib/debug/usr/bin/git.debug 3 /usr/lib/debug/usr/libexec/git-core/git-add.debug (*) 4 /usr/bin/debug/usr/bin/git-shell.debug 4 /usr/bin/debug/usr/libexec/git-core/git-shell.debug (*) This link has the wrong name. Bug: https://bugs.gentoo.org/820107 Signed-off-by: Mike Gilbert <floppym@gentoo.org>
-rwxr-xr-xbin/estrip60
1 files changed, 39 insertions, 21 deletions
diff --git a/bin/estrip b/bin/estrip
index abe523fff..e33977091 100755
--- a/bin/estrip
+++ b/bin/estrip
@@ -189,7 +189,7 @@ save_elf_sources() {
"${x}")
}
-# Usage: save_elf_debug <elf> [splitdebug file]
+# Usage: save_elf_debug <src> <inode_debug> [splitdebug]
save_elf_debug() {
${FEATURES_splitdebug} || return 0
${PORTAGE_RESTRICT_splitdebug} && return 0
@@ -198,49 +198,67 @@ save_elf_debug() {
# ${EPREFIX}/usr/lib/debug/${EPREFIX} (note that ${EPREFIX} occurs
# twice in this path) in order for gdb's debug-file-directory
# lookup to work correctly.
- local x=$1
- local inode_debug=$2
- local splitdebug=$3
- local d_noslash=${D%/}
- local y=${ED%/}/usr/lib/debug/${x:${#d_noslash}}.debug
+ local src=$1 # File from which we extract symbols.
+ local inode_debug=$2 # Temp path for hard link tracking
+ local splitdebug=$3 # Existing debug file optionally created by eu-strip in parent function
- # dont save debug info twice
- [[ ${x} == *".debug" ]] && return 0
+ # Source paths
+ local src_basename=${src##*/}
+ local src_dirname=${src%/*}
- mkdir -p "${y%/*}"
+ # Destination paths
+ local dst_dirname=${ED%/}/usr/lib/debug/${src_dirname#${D%/}/}
+ local dst_basename dst
- if [ -f "${inode_debug}" ] ; then
- ln "${inode_debug}" "${y}" || die "ln failed unexpectedly"
+ # dont save debug info twice
+ [[ ${src} == *".debug" ]] && return 0
+
+ mkdir -p "${dst_dirname}" || die
+
+ if [[ -L ${inode_debug} ]] ; then
+ # We already created a debug file for this inode.
+ # Read back the file name, and create another hard link if necessary.
+ dst_basename=$(readlink "${inode_debug}") || die
+ dst_basename=${dst_basename##*/}
+ dst=${dst_dirname}/${dst_basename}
+ if [[ ! -e ${dst} ]]; then
+ ln -L "${inode_debug}" "${dst}" || die
+ fi
else
+ dst_basename=${src_basename}.debug
+ dst=${dst_dirname}/${dst_basename}
if [[ -n ${splitdebug} ]] ; then
- mv "${splitdebug}" "${y}"
+ mv "${splitdebug}" "${dst}"
else
local objcopy_flags="--only-keep-debug"
${FEATURES_compressdebug} && objcopy_flags+=" --compress-debug-sections"
- ${OBJCOPY} ${objcopy_flags} "${x}" "${y}"
- ${OBJCOPY} --add-gnu-debuglink="${y}" "${x}"
+ ${OBJCOPY} ${objcopy_flags} "${src}" "${dst}" &&
+ ${OBJCOPY} --add-gnu-debuglink="${dst}" "${src}"
fi
# Only do the following if the debug file was
# successfully created (see bug #446774).
- if [ $? -eq 0 ] ; then
+ if [[ $? -eq 0 ]] ; then
local args="a-x,o-w"
- [[ -g ${x} || -u ${x} ]] && args+=",go-r"
- chmod ${args} "${y}"
- ln "${y}" "${inode_debug}" || die "ln failed unexpectedly"
+ [[ -g ${src} || -u ${src} ]] && args+=",go-r"
+ chmod ${args} "${dst}"
+ # symlink so we can read the name back.
+ ln -s "${dst}" "${inode_debug}" || die
fi
fi
# if we don't already have build-id from debugedit, look it up
if [[ -z ${buildid} ]] ; then
# convert the readelf output to something useful
- buildid=$(${READELF} -n "${x}" 2>/dev/null | awk '/Build ID:/{ print $NF; exit }')
+ buildid=$(${READELF} -n "${src}" 2>/dev/null | awk '/Build ID:/{ print $NF; exit }')
fi
if [[ -n ${buildid} ]] ; then
local buildid_dir="${ED%/}/usr/lib/debug/.build-id/${buildid:0:2}"
local buildid_file="${buildid_dir}/${buildid:2}"
+ local src_buildid_rel="../../../../../${src#${ED%/}/}"
+ local dst_buildid_rel="../../${dst#${ED%/}/usr/lib/debug/}"
mkdir -p "${buildid_dir}"
- [ -L "${buildid_file}".debug ] || ln -s "../../${x:$((${#d_noslash} + 1))}.debug" "${buildid_file}.debug"
- [ -L "${buildid_file}" ] || ln -s "/${x:$((${#d_noslash} + 1))}" "${buildid_file}"
+ [[ -L "${buildid_file}".debug ]] || ln -s "${dst_buildid_rel}" "${buildid_file}.debug"
+ [[ -L "${buildid_file}" ]] || ln -s "${src_buildid_rel}" "${buildid_file}"
fi
}