]> git.pld-linux.org Git - packages/rpm.git/blame - rpm-new-debuginfo.patch
build-id aware debuginfo finding (but bashizms (TODO))
[packages/rpm.git] / rpm-new-debuginfo.patch
CommitLineData
0af33fd8
AM
1--- rpm-4.5/macros.in.org 2009-03-23 09:25:24.383581794 +0100
2+++ rpm-4.5/macros.in 2009-03-23 09:25:19.403234944 +0100
3@@ -183,7 +183,7 @@
4 # Path to script that creates debug symbols in a /usr/lib/debug
5 # shadow tree.
6 %__debug_install_post \
7- %{_rpmhome}/find-debuginfo.sh %{_builddir}/%{?buildsubdir}\
8+ %{_rpmhome}/find-debuginfo.sh %{?_missing_build_ids_terminate_build:--strict-build-id} %{?_find_debuginfo_opts} "%{_builddir}/%{?buildsubdir}"\
9 %{nil}
10
11 # Template for debug information sub-package.
12--- rpm-4.5/scripts/find-debuginfo.sh.org 2009-03-23 09:17:40.543353186 +0100
13+++ rpm-4.5/scripts/find-debuginfo.sh 2007-09-06 09:36:38.000000000 +0200
14@@ -1,57 +1,336 @@
15-#!/bin/sh
16+#!/bin/bash
17 #find-debuginfo.sh - automagically generate debug info and file list
18 #for inclusion in an rpm spec file.
19+#
20+# Usage: find-debuginfo.sh [--strict-build-id] [-g]
21+# [-o debugfiles.list]
22+# [[-l filelist]... [-p 'pattern'] -o debuginfo.list]
23+# [builddir]
24+#
25+# The -g flag says to use strip -g instead of full strip on DSOs.
26+# The --strict-build-id flag says to exit with failure status if
27+# any ELF binary processed fails to contain a build-id note.
28+#
29+# A single -o switch before any -l or -p switches simply renames
30+# the primary output file from debugfiles.list to something else.
31+# A -o switch that follows a -p switch or some -l switches produces
32+# an additional output file with the debuginfo for the files in
33+# the -l filelist file, or whose names match the -p pattern.
34+# The -p argument is an egrep-style regexp matching the a file name,
35+# and must not use anchors (^ or $).
36+#
37+# All file names in switches are relative to builddir (. if not given).
38+#
39+
40+# With -g arg, pass it to strip on libraries.
41+strip_g=false
42+
43+# Barf on missing build IDs.
44+strict=false
45+
46+BUILDDIR=.
47+out=debugfiles.list
48+nout=0
49+while [ $# -gt 0 ]; do
50+ case "$1" in
51+ --strict-build-id)
52+ strict=true
53+ ;;
54+ -g)
55+ strip_g=true
56+ ;;
57+ -o)
58+ if [ -z "${lists[$nout]}" -a -z "${ptns[$nout]}" ]; then
59+ out=$2
60+ else
61+ outs[$nout]=$2
62+ ((nout++))
63+ fi
64+ shift
65+ ;;
66+ -l)
67+ lists[$nout]="${lists[$nout]} $2"
68+ shift
69+ ;;
70+ -p)
71+ ptns[$nout]=$2
72+ shift
73+ ;;
74+ *)
75+ BUILDDIR=$1
76+ shift
77+ break
78+ ;;
79+ esac
80+ shift
81+done
82
83-if [ -z "$1" ] ; then BUILDDIR="."
84-else BUILDDIR=$1
85-fi
86+i=0
87+while ((i < nout)); do
88+ outs[$i]="$BUILDDIR/${outs[$i]}"
89+ l=''
90+ for f in ${lists[$i]}; do
91+ l="$l $BUILDDIR/$f"
92+ done
93+ lists[$i]=$l
94+ ((++i))
95+done
96
97-LISTFILE=$BUILDDIR/debugfiles.list
98-SOURCEFILE=$BUILDDIR/debugsources.list
99+LISTFILE="$BUILDDIR/$out"
100+SOURCEFILE="$BUILDDIR/debugsources.list"
101+LINKSFILE="$BUILDDIR/debuglinks.list"
102+
103+> "$SOURCEFILE"
104+> "$LISTFILE"
105+> "$LINKSFILE"
106
107 debugdir="${RPM_BUILD_ROOT}/usr/lib/debug"
108
109-echo -n > $SOURCEFILE
110-
111 strip_to_debug()
112 {
113- eu-strip --remove-comment -f "$1" "$2" || :
114+ local g=
115+ $strip_g && case "$(file -bi "$2")" in
116+ application/x-sharedlib,*) g=-g ;;
117+ esac
118+ eu-strip --remove-comment $g -f "$1" "$2" || exit
119+}
120+
121+# Make a relative symlink to $1 called $3$2
122+shopt -s extglob
123+link_relative()
124+{
125+ local t="$1" f="$2" pfx="$3"
126+ local fn="${f#/}" tn="${t#/}"
127+ local fd td d
128+
129+ while fd="${fn%%/*}"; td="${tn%%/*}"; [ "$fd" = "$td" ]; do
130+ fn="${fn#*/}"
131+ tn="${tn#*/}"
132+ done
133+
134+ d="${fn%/*}"
135+ if [ "$d" != "$fn" ]; then
136+ d="${d//+([!\/])/..}"
137+ tn="${d}/${tn}"
138+ fi
139+
140+ mkdir -p "$(dirname "$pfx$f")" && ln -snf "$tn" "$pfx$f"
141 }
142
143+# Make a symlink in /usr/lib/debug/$2 to $1
144+debug_link()
145+{
146+ local l="/usr/lib/debug$2"
147+ local t="$1"
148+ echo >> "$LINKSFILE" "$l $t"
149+ link_relative "$t" "$l" "$RPM_BUILD_ROOT"
150+}
151+
152+# Make a build-id symlink for id $1 with suffix $3 to file $2.
153+make_id_link()
154+{
155+ local id="$1" file="$2"
156+ local idfile=".build-id/${id:0:2}/${id:2}"
157+ [ $# -eq 3 ] && idfile="${idfile}$3"
158+ local root_idfile="$RPM_BUILD_ROOT/usr/lib/debug/$idfile"
159+
160+ if [ ! -L "$root_idfile" ]; then
161+ debug_link "$file" "/$idfile"
162+ return
163+ fi
164+
165+ [ $# -eq 3 ] && return 0
166+
167+ local other=$(readlink -m "$root_idfile")
168+ other=${other#$RPM_BUILD_ROOT}
169+ if cmp -s "$root_idfile" "$RPM_BUILD_ROOT$file" ||
170+ eu-elfcmp -q "$root_idfile" "$RPM_BUILD_ROOT$file" 2> /dev/null; then
171+ # Two copies. Maybe one has to be setuid or something.
172+ echo >&2 "*** WARNING: identical binaries are copied, not linked:"
173+ echo >&2 " $file"
174+ echo >&2 " and $other"
175+ else
176+ # This is pathological, break the build.
177+ echo >&2 "*** ERROR: same build ID in nonidentical files!"
178+ echo >&2 " $file"
179+ echo >&2 " and $other"
180+ exit 2
181+ fi
182+}
183+
184+get_debugfn()
185+{
186+ dn=$(dirname "${1#$RPM_BUILD_ROOT}")
187+ bn=$(basename "$1" .debug).debug
188+
189+ debugdn=${debugdir}${dn}
190+ debugfn=${debugdn}/${bn}
191+}
192+
193+set -o pipefail
194+
195+strict_error=ERROR
196+$strict || strict_error=WARNING
197+
198 # Strip ELF binaries
199-for f in `find $RPM_BUILD_ROOT ! -path "${debugdir}/*.debug" -type f \( -perm -0100 -or -perm -0010 -or -perm -0001 \) -exec file {} \; | \
200- sed -n -e 's/^\(.*\):[ ]*.*ELF.*, not stripped/\1/p'`
201+find "$RPM_BUILD_ROOT" ! -path "${debugdir}/*.debug" -type f \
202+ \( -perm -0100 -or -perm -0010 -or -perm -0001 \) \
203+ -print |
204+file -N -f - | sed -n -e 's/^\(.*\):[ ]*.*ELF.*, not stripped/\1/p' |
205+xargs --no-run-if-empty stat -c '%h %D_%i %n' |
206+while read nlinks inum f; do
207+ get_debugfn "$f"
208+ [ -f "${debugfn}" ] && continue
209+
210+ # If this file has multiple links, keep track and make
211+ # the corresponding .debug files all links to one file too.
212+ if [ $nlinks -gt 1 ]; then
213+ eval linked=\$linked_$inum
214+ if [ -n "$linked" ]; then
215+ link=$debugfn
216+ get_debugfn "$linked"
217+ echo "hard linked $link to $debugfn"
218+ ln -nf "$debugfn" "$link"
219+ continue
220+ else
221+ eval linked_$inum=\$f
222+ echo "file $f has $[$nlinks - 1] other hard links"
223+ fi
224+ fi
225+
226+ echo "extracting debug info from $f"
227+ id=$(/usr/lib/rpm/debugedit -b "$RPM_BUILD_DIR" -d /usr/src/debug \
228+ -i -l "$SOURCEFILE" "$f") || exit
229+ if [ -z "$id" ]; then
230+ echo >&2 "*** ${strict_error}: No build ID note found in $f"
231+ $strict && exit 2
232+ fi
233+
234+ # A binary already copied into /usr/lib/debug doesn't get stripped,
235+ # just has its file names collected and adjusted.
236+ case "$dn" in
237+ /usr/lib/debug/*)
238+ [ -z "$id" ] || make_id_link "$id" "$dn/$(basename $f)"
239+ continue ;;
240+ esac
241+
242+ mkdir -p "${debugdn}"
243+ if test -w "$f"; then
244+ strip_to_debug "${debugfn}" "$f"
245+ else
246+ chmod u+w "$f"
247+ strip_to_debug "${debugfn}" "$f"
248+ chmod u-w "$f"
249+ fi
250+
251+ if [ -n "$id" ]; then
252+ make_id_link "$id" "$dn/$(basename $f)"
253+ make_id_link "$id" "/usr/lib/debug$dn/$bn" .debug
254+ fi
255+done || exit
256+
257+# For each symlink whose target has a .debug file,
258+# make a .debug symlink to that file.
259+find $RPM_BUILD_ROOT ! -path "${debugdir}/*" -type l -print |
260+while read f
261 do
262- dn=$(dirname $f | sed -n -e "s#^$RPM_BUILD_ROOT##p")
263- bn=$(basename $f .debug).debug
264-
265- debugdn="${debugdir}${dn}"
266- debugfn="${debugdn}/${bn}"
267- [ -f "${debugfn}" ] && continue
268-
269- echo extracting debug info from $f
270- /usr/lib/rpm/4.5/debugedit -b "$RPM_BUILD_DIR" -d /usr/src/debug -l "$SOURCEFILE" "$f"
271-
272- # A binary already copied into /usr/lib/debug doesn't get stripped,
273- # just has its file names collected and adjusted.
274- case "$dn" in
275- /usr/lib/debug/*) continue ;;
276- esac
277-
278- mkdir -p "${debugdn}"
279- if test -w "$f"; then
280- strip_to_debug "${debugfn}" "$f"
281- else
282- chmod u+w "$f"
283- strip_to_debug "${debugfn}" "$f"
284- chmod u-w "$f"
285- fi
286+ t=$(readlink -m "$f").debug
287+ f=${f#$RPM_BUILD_ROOT}
288+ t=${t#$RPM_BUILD_ROOT}
289+ if [ -f "$debugdir$t" ]; then
290+ echo "symlinked /usr/lib/debug$t to /usr/lib/debug${f}.debug"
291+ debug_link "/usr/lib/debug$t" "${f}.debug"
292+ fi
293 done
294
295-mkdir -p ${RPM_BUILD_ROOT}/usr/src/debug
296-cat $SOURCEFILE | (cd $RPM_BUILD_DIR; LANG=C sort -z -u | cpio -pd0mL ${RPM_BUILD_ROOT}/usr/src/debug)
297-# stupid cpio creates new directories in mode 0700, fixup
298-find ${RPM_BUILD_ROOT}/usr/src/debug -type d -print0 | xargs -0 chmod a+rx
299+if [ -s "$SOURCEFILE" ]; then
300+ mkdir -p "${RPM_BUILD_ROOT}/usr/src/debug"
301+ LC_ALL=C sort -z -u "$SOURCEFILE" | egrep -v -z '(<internal>|<built-in>)$' |
302+ (cd "$RPM_BUILD_DIR"; cpio -pd0mL "${RPM_BUILD_ROOT}/usr/src/debug")
303+ # stupid cpio creates new directories in mode 0700, fixup
304+ find "${RPM_BUILD_ROOT}/usr/src/debug" -type d -print0 |
305+ xargs --no-run-if-empty -0 chmod a+rx
306+fi
307+
308+if [ -d "${RPM_BUILD_ROOT}/usr/lib" -o -d "${RPM_BUILD_ROOT}/usr/src" ]; then
309+ ((nout > 0)) ||
310+ test ! -d "${RPM_BUILD_ROOT}/usr/lib" ||
311+ (cd "${RPM_BUILD_ROOT}/usr/lib"; find debug -type d) |
312+ sed 's,^,%dir /usr/lib/,' >> "$LISTFILE"
313+
314+ (cd "${RPM_BUILD_ROOT}/usr"
315+ test ! -d lib/debug || find lib/debug ! -type d
316+ test ! -d src/debug || find src/debug -mindepth 1 -maxdepth 1
317+ ) | sed 's,^,/usr/,' >> "$LISTFILE"
318+fi
319+
320+# Append to $1 only the lines from stdin not already in the file.
321+append_uniq()
322+{
323+ fgrep -f "$1" -x -v >> "$1"
324+}
325
326-find ${RPM_BUILD_ROOT}/usr/lib/debug -type f | sed -n -e "s#^$RPM_BUILD_ROOT##p" > $LISTFILE
327-find ${RPM_BUILD_ROOT}/usr/src/debug -mindepth 1 -maxdepth 1 | sed -n -e "s#^$RPM_BUILD_ROOT##p" >> $LISTFILE
328+# Helper to generate list of corresponding .debug files from a file list.
329+filelist_debugfiles()
330+{
331+ local extra="$1"
332+ shift
333+ sed 's/^%[a-z0-9_][a-z0-9_]*([^)]*) *//
334+s/^%[a-z0-9_][a-z0-9_]* *//
335+/^$/d
336+'"$extra" "$@"
337+}
338+
339+# Write an output debuginfo file list based on given input file lists.
340+filtered_list()
341+{
342+ local out="$1"
343+ shift
344+ test $# -gt 0 || return
345+ fgrep -f <(filelist_debugfiles 's,^.*$,/usr/lib/debug&.debug,' "$@") \
346+ -x $LISTFILE >> $out
347+ sed -n -f <(filelist_debugfiles 's/[\\.*+#]/\\&/g
348+h
349+s,^.*$,s# &$##p,p
350+g
351+s,^.*$,s# /usr/lib/debug&.debug$##p,p
352+' "$@") "$LINKSFILE" | append_uniq "$out"
353+}
354+
355+# Write an output debuginfo file list based on an egrep-style regexp.
356+pattern_list()
357+{
358+ local out="$1" ptn="$2"
359+ test -n "$ptn" || return
360+ egrep -x -e "$ptn" "$LISTFILE" >> "$out"
361+ sed -n -r "\#^$ptn #s/ .*\$//p" "$LINKSFILE" | append_uniq "$out"
362+}
363+
364+#
365+# When given multiple -o switches, split up the output as directed.
366+#
367+i=0
368+while ((i < nout)); do
369+ > ${outs[$i]}
370+ filtered_list ${outs[$i]} ${lists[$i]}
371+ pattern_list ${outs[$i]} "${ptns[$i]}"
372+ fgrep -vx -f ${outs[$i]} "$LISTFILE" > "${LISTFILE}.new"
373+ mv "${LISTFILE}.new" "$LISTFILE"
374+ ((++i))
375+done
376+if ((nout > 0)); then
377+ # Now add the right %dir lines to each output list.
378+ (cd "${RPM_BUILD_ROOT}"; find usr/lib/debug -type d) |
379+ sed 's#^.*$#\\@^/&/@{h;s@^.*$@%dir /&@p;g;}#' |
380+ LC_ALL=C sort -ur > "${LISTFILE}.dirs.sed"
381+ i=0
382+ while ((i < nout)); do
383+ sed -n -f "${LISTFILE}.dirs.sed" "${outs[$i]}" | sort -u > "${outs[$i]}.new"
384+ cat "${outs[$i]}" >> "${outs[$i]}.new"
385+ mv -f "${outs[$i]}.new" "${outs[$i]}"
386+ ((++i))
387+ done
388+ sed -n -f "${LISTFILE}.dirs.sed" "${LISTFILE}" | sort -u > "${LISTFILE}.new"
389+ cat "$LISTFILE" >> "${LISTFILE}.new"
390+ mv "${LISTFILE}.new" "$LISTFILE"
391+fi
This page took 0.083107 seconds and 4 git commands to generate.