1 |
commit: 84206c6200eb003314cf4f2d640bf73f04654012 |
2 |
Author: Mike Gilbert <floppym <AT> gentoo <DOT> org> |
3 |
AuthorDate: Mon Oct 25 15:30:08 2021 +0000 |
4 |
Commit: Mike Gilbert <floppym <AT> gentoo <DOT> org> |
5 |
CommitDate: Sun Oct 31 18:15:27 2021 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=84206c62 |
7 |
|
8 |
estrip: rework hard link logic in save_elf_debug |
9 |
|
10 |
GDB loads debug files based on the file name given in the .gnu_debuglink |
11 |
section, prepended with /usr/lib/debug/${dirname}, where dirname is the |
12 |
absolute path to the parent directory of the binary being executed. |
13 |
|
14 |
For each unique inode as input, we need a link to the debug file with |
15 |
the GNU debuglink as its basename. A link to the debug file should exist |
16 |
for each directory in which the input inode exists. |
17 |
|
18 |
The debug link names should be based on the .gnu_debuglink value instead |
19 |
of the name of the file we are processing as input. |
20 |
|
21 |
The .gnu_debuglink value is based on the name of the first link |
22 |
processed for each inode. We save this value as a symlink, and then read |
23 |
it back as we process subsequent links. |
24 |
|
25 |
For example, given the following input: |
26 |
|
27 |
INODE PATH |
28 |
1 /usr/bin/git |
29 |
1 /usr/libexec/git-core/git-add |
30 |
2 /usr/bin/git-shell |
31 |
2 /usr/libexec/git-core/git-shell |
32 |
|
33 |
We generate the following inodes for the debug files: |
34 |
|
35 |
INODE DEBUGLINK |
36 |
3 git.debug |
37 |
4 git-shell.debug |
38 |
|
39 |
We should generate the following links: |
40 |
|
41 |
INODE PATH |
42 |
3 /usr/lib/debug/usr/bin/git.debug |
43 |
3 /usr/lib/debug/usr/libexec/git-core/git.debug |
44 |
4 /usr/bin/debug/usr/bin/git-shell.debug |
45 |
4 /usr/bin/debug/usr/libexec/git-core/git-shell.debug |
46 |
|
47 |
The previous code would have generated this broken output: |
48 |
|
49 |
INODE PATH |
50 |
3 /usr/lib/debug/usr/bin/git.debug |
51 |
3 /usr/lib/debug/usr/libexec/git-core/git-add.debug (*) |
52 |
4 /usr/bin/debug/usr/bin/git-shell.debug |
53 |
4 /usr/bin/debug/usr/libexec/git-core/git-shell.debug |
54 |
|
55 |
(*) This link has the wrong name. |
56 |
|
57 |
Bug: https://bugs.gentoo.org/820107 |
58 |
Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org> |
59 |
|
60 |
bin/estrip | 60 +++++++++++++++++++++++++++++++++++++++--------------------- |
61 |
1 file changed, 39 insertions(+), 21 deletions(-) |
62 |
|
63 |
diff --git a/bin/estrip b/bin/estrip |
64 |
index abe523fff..e33977091 100755 |
65 |
--- a/bin/estrip |
66 |
+++ b/bin/estrip |
67 |
@@ -189,7 +189,7 @@ save_elf_sources() { |
68 |
"${x}") |
69 |
} |
70 |
|
71 |
-# Usage: save_elf_debug <elf> [splitdebug file] |
72 |
+# Usage: save_elf_debug <src> <inode_debug> [splitdebug] |
73 |
save_elf_debug() { |
74 |
${FEATURES_splitdebug} || return 0 |
75 |
${PORTAGE_RESTRICT_splitdebug} && return 0 |
76 |
@@ -198,49 +198,67 @@ save_elf_debug() { |
77 |
# ${EPREFIX}/usr/lib/debug/${EPREFIX} (note that ${EPREFIX} occurs |
78 |
# twice in this path) in order for gdb's debug-file-directory |
79 |
# lookup to work correctly. |
80 |
- local x=$1 |
81 |
- local inode_debug=$2 |
82 |
- local splitdebug=$3 |
83 |
- local d_noslash=${D%/} |
84 |
- local y=${ED%/}/usr/lib/debug/${x:${#d_noslash}}.debug |
85 |
+ local src=$1 # File from which we extract symbols. |
86 |
+ local inode_debug=$2 # Temp path for hard link tracking |
87 |
+ local splitdebug=$3 # Existing debug file optionally created by eu-strip in parent function |
88 |
|
89 |
- # dont save debug info twice |
90 |
- [[ ${x} == *".debug" ]] && return 0 |
91 |
+ # Source paths |
92 |
+ local src_basename=${src##*/} |
93 |
+ local src_dirname=${src%/*} |
94 |
|
95 |
- mkdir -p "${y%/*}" |
96 |
+ # Destination paths |
97 |
+ local dst_dirname=${ED%/}/usr/lib/debug/${src_dirname#${D%/}/} |
98 |
+ local dst_basename dst |
99 |
|
100 |
- if [ -f "${inode_debug}" ] ; then |
101 |
- ln "${inode_debug}" "${y}" || die "ln failed unexpectedly" |
102 |
+ # dont save debug info twice |
103 |
+ [[ ${src} == *".debug" ]] && return 0 |
104 |
+ |
105 |
+ mkdir -p "${dst_dirname}" || die |
106 |
+ |
107 |
+ if [[ -L ${inode_debug} ]] ; then |
108 |
+ # We already created a debug file for this inode. |
109 |
+ # Read back the file name, and create another hard link if necessary. |
110 |
+ dst_basename=$(readlink "${inode_debug}") || die |
111 |
+ dst_basename=${dst_basename##*/} |
112 |
+ dst=${dst_dirname}/${dst_basename} |
113 |
+ if [[ ! -e ${dst} ]]; then |
114 |
+ ln -L "${inode_debug}" "${dst}" || die |
115 |
+ fi |
116 |
else |
117 |
+ dst_basename=${src_basename}.debug |
118 |
+ dst=${dst_dirname}/${dst_basename} |
119 |
if [[ -n ${splitdebug} ]] ; then |
120 |
- mv "${splitdebug}" "${y}" |
121 |
+ mv "${splitdebug}" "${dst}" |
122 |
else |
123 |
local objcopy_flags="--only-keep-debug" |
124 |
${FEATURES_compressdebug} && objcopy_flags+=" --compress-debug-sections" |
125 |
- ${OBJCOPY} ${objcopy_flags} "${x}" "${y}" |
126 |
- ${OBJCOPY} --add-gnu-debuglink="${y}" "${x}" |
127 |
+ ${OBJCOPY} ${objcopy_flags} "${src}" "${dst}" && |
128 |
+ ${OBJCOPY} --add-gnu-debuglink="${dst}" "${src}" |
129 |
fi |
130 |
# Only do the following if the debug file was |
131 |
# successfully created (see bug #446774). |
132 |
- if [ $? -eq 0 ] ; then |
133 |
+ if [[ $? -eq 0 ]] ; then |
134 |
local args="a-x,o-w" |
135 |
- [[ -g ${x} || -u ${x} ]] && args+=",go-r" |
136 |
- chmod ${args} "${y}" |
137 |
- ln "${y}" "${inode_debug}" || die "ln failed unexpectedly" |
138 |
+ [[ -g ${src} || -u ${src} ]] && args+=",go-r" |
139 |
+ chmod ${args} "${dst}" |
140 |
+ # symlink so we can read the name back. |
141 |
+ ln -s "${dst}" "${inode_debug}" || die |
142 |
fi |
143 |
fi |
144 |
|
145 |
# if we don't already have build-id from debugedit, look it up |
146 |
if [[ -z ${buildid} ]] ; then |
147 |
# convert the readelf output to something useful |
148 |
- buildid=$(${READELF} -n "${x}" 2>/dev/null | awk '/Build ID:/{ print $NF; exit }') |
149 |
+ buildid=$(${READELF} -n "${src}" 2>/dev/null | awk '/Build ID:/{ print $NF; exit }') |
150 |
fi |
151 |
if [[ -n ${buildid} ]] ; then |
152 |
local buildid_dir="${ED%/}/usr/lib/debug/.build-id/${buildid:0:2}" |
153 |
local buildid_file="${buildid_dir}/${buildid:2}" |
154 |
+ local src_buildid_rel="../../../../../${src#${ED%/}/}" |
155 |
+ local dst_buildid_rel="../../${dst#${ED%/}/usr/lib/debug/}" |
156 |
mkdir -p "${buildid_dir}" |
157 |
- [ -L "${buildid_file}".debug ] || ln -s "../../${x:$((${#d_noslash} + 1))}.debug" "${buildid_file}.debug" |
158 |
- [ -L "${buildid_file}" ] || ln -s "/${x:$((${#d_noslash} + 1))}" "${buildid_file}" |
159 |
+ [[ -L "${buildid_file}".debug ]] || ln -s "${dst_buildid_rel}" "${buildid_file}.debug" |
160 |
+ [[ -L "${buildid_file}" ]] || ln -s "${src_buildid_rel}" "${buildid_file}" |
161 |
fi |
162 |
} |