/
niceSOFT
/
debugedit
Обзор
Документация
Войти
/
niceSOFT
/
debugedit
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
debugedit-5.3
tests/debugedit.at
977 строк
29 KB
Mark Wielaard
debugedit: Support files with more than 65280 ELF sections
10 мар 2026, 14:07
10 мар 2026, 14:07
edc0a3d
Код
Авторство
О чём код?
# debugedit.at: Tests for the debugedit tool # # Copyright (C) 2019, 2024, 2025 Mark J. Wielaard <mark@klomp.org> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see see <http://www.gnu.org/licenses/>. # Tests for the tools/debugedit program. AT_BANNER([debugedit]) # Show which debugedit binary we are testing. AT_TESTED([debugedit]) # Helper to create some test binaries. # Optional fist parameter can specify additional gcc parameters. # e.g. -gdwarf-4 or -gdwarf-5 for explicit DWARF version. # -g3 is always given. Second parameter can be a compression flag # like $GZ_ZLIB_FLAG (if it exists), when not given $GZ_NONE_FLAG # is used. m4_define([DEBUGEDIT_SETUP],[[ # Create some test binaries. Create and build them in different subdirs # to make sure they produce different relative/absolute paths. export HOME=${PWD} mkdir subdir_foo cp "${abs_srcdir}"/data/SOURCES/foo.c subdir_foo mkdir subdir_bar cp "${abs_srcdir}"/data/SOURCES/bar.c subdir_bar mkdir subdir_headers cp "${abs_srcdir}"/data/SOURCES/foobar.h subdir_headers cp "${abs_srcdir}"/data/SOURCES/baz.c . # Check second param, if given use compression if test -z "$2"; then GZ_FLAG=$GZ_NONE_FLAG else GZ_FLAG=$2 fi # First three object files (foo.o subdir_bar/bar.o and baz.o) $CC $CFLAGS -g3 $GZ_FLAG -Isubdir_headers $1 -c subdir_foo/foo.c cd subdir_bar $CC $CFLAGS -g3 $GZ_FLAG -I../subdir_headers $1 -c bar.c cd .. $CC $CFLAGS -g3 $GZ_FLAG -I$(pwd)/subdir_headers $1 -c $(pwd)/baz.c # Then a partially linked object file (somewhat like a kernel module). # This will still have relocations between the debug sections. $LD $LDFLAGS -r -o foobarbaz.part.o foo.o subdir_bar/bar.o baz.o # Create an executable. Relocations between debug sections will # have been resolved. $CC $CFLAGS -g3 $GZ_FLAG $1 -o foobarbaz.exe foo.o subdir_bar/bar.o baz.o ]]) m4_define([DEBUGEDIT_SETUP_LARGE],[[ # Create some a large test binaries (65280+ sections). export HOME=${PWD} cp "${abs_srcdir}"/data/SOURCES/large.c . $CXX $CXXFLAGS -g -c large.c ]]) # === # Check debugedit --help doesn't crash and burn. # === AT_SETUP([debugedit help]) AT_KEYWORDS([debuginfo] [debugedit]) AT_CHECK([debugedit --help],[0],[ignore],[ignore]) AT_CLEANUP # === # Check debugedit usage. # === AT_SETUP([debugedit usage]) AT_KEYWORDS([debuginfo] [debugedit]) AT_CHECK([debugedit --usage],[0],[ignore],[]) AT_CHECK([debugedit],[1],[],[ignore]) AT_CHECK([debugedit . ..],[1],[],[ignore]) AT_CLEANUP # === # Make sure that an executable still runs after debugedit munged it. # === AT_SETUP([debugedit executable]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP AT_CHECK([[./foobarbaz.exe]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.exe]]) AT_CHECK([[./foobarbaz.exe]]) AT_CLEANUP AT_SETUP([debugedit executable (compressed)]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test -z "$GZ_ZLIB_FLAG"]) AT_SKIP_IF([test "$READELF_VERSION_OK" = "no"]) DEBUGEDIT_SETUP([], [$GZ_ZLIB_FLAG]) AT_CHECK([[./foobarbaz.exe]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.exe]]) AT_CHECK([[./foobarbaz.exe]]) AT_CLEANUP # === # debugedit should at least replace the .debug_str directory paths # in the objects. # === AT_SETUP([debugedit .debug_str objects DWARF4]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP([-gdwarf-4]) # Capture strings that start with the testdir (pwd) directory path # (and replace that textually with /foo/bar/baz) ($READELF -zp.debug_str foo.o; \ $READELF -zp.debug_str subdir_bar/bar.o; \ $READELF -zp.debug_str baz.o) \ | cut -c13- \ | grep ^$(pwd) | sort \ | sed -e "s@$(pwd)@/foo/bar/baz@" > expout # Make sure there is at least some output expout_lines=$(wc --lines expout | cut -f1 -d\ ) if test $expout_lines -lt 3; then echo "Expecting at least 3 debug strings starting with ${testdir}" >> expout fi # Check the replaced strings are all there. AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foo.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./subdir_bar/bar.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./baz.o]]) AT_CHECK([[ ($READELF -zp.debug_str foo.o; \ $READELF -zp.debug_str subdir_bar/bar.o; \ $READELF -zp.debug_str baz.o) \ | cut -c13- \ | grep ^/foo/bar/baz | sort ]],[0],[expout]) AT_CLEANUP # === # debugedit should at least replace the .debug_str/line_str directory paths # in the objects. # === AT_SETUP([debugedit .debug_str/line_str objects DWARF5]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test "$GDWARF_5_FLAG" = "no"]) DEBUGEDIT_SETUP([-gdwarf-5]) # Capture strings that start with the testdir (pwd) directory path # (and replace that textually with /foo/bar/baz) ($READELF -zp.debug_str -zp.debug_line_str foo.o; \ $READELF -zp.debug_str -zp.debug_line_str subdir_bar/bar.o; \ $READELF -zp.debug_str -zp.debug_line_str baz.o) \ | cut -c13- \ | grep ^$(pwd) | sort | uniq \ | sed -e "s@$(pwd)@/foo/bar/baz@" > expout # Make sure there is at least some output expout_lines=$(wc --lines expout | cut -f1 -d\ ) if test $expout_lines -lt 3; then echo "Expecting at least 3 debug strings starting with ${testdir}" >> expout fi # Check the replaced strings are all there. AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foo.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./subdir_bar/bar.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./baz.o]]) AT_CHECK([[ ($READELF -zp.debug_str -zp.debug_line_str foo.o; \ $READELF -zp.debug_str -zp.debug_line_str subdir_bar/bar.o; \ $READELF -zp.debug_str -zp.debug_line_str baz.o) \ | cut -c13- \ | grep ^/foo/bar/baz | sort | uniq ]],[0],[expout],[ignore]) AT_CLEANUP # === # debugedit should at least replace the .debug_str directory paths # also in partially linked files. # === AT_SETUP([debugedit .debug_str partial DWARF4]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP([-gdwarf-4]) # Capture strings that start with the testdir (pwd) directory path # (and replace that textually with /foo/bar/baz) # Note that partially linked files, might have multiple duplicate # strings, but debugedit will merge them. So use sort -u. $READELF -zp.debug_str ./foobarbaz.part.o | cut -c13- \ | grep ^$(pwd) | sort -u \ | sed -e "s@$(pwd)@/foo/bar/baz@" > expout # Make sure there is at least some output expout_lines=$(wc --lines expout | cut -f1 -d\ ) if test $expout_lines -lt 3; then echo "Expecting at least 3 debug strings starting with ${testdir}" >> expout fi # Check the replaced strings are all there. AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.part.o]]) AT_CHECK([[ $READELF -zp.debug_str ./foobarbaz.part.o | cut -c13- \ | grep ^/foo/bar/baz | sort ]],[0],[expout]) AT_CLEANUP # === # debugedit should at least replace the .debug_str/line_str directory paths # also in partially linked files. # === AT_SETUP([debugedit .debug_str/line_str partial DWARF5]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test "$GDWARF_5_FLAG" = "no"]) DEBUGEDIT_SETUP([-gdwarf-5]) # Capture strings that start with the testdir (pwd) directory path # (and replace that textually with /foo/bar/baz) # Note that partially linked files, might have multiple duplicate # strings, but debugedit will merge them. So use sort -u. $READELF -zp.debug_str -zp.debug_line_str ./foobarbaz.part.o | cut -c13- \ | grep ^$(pwd) | sort -u | uniq \ | sed -e "s@$(pwd)@/foo/bar/baz@" > expout # Make sure there is at least some output expout_lines=$(wc --lines expout | cut -f1 -d\ ) if test $expout_lines -lt 3; then echo "Expecting at least 3 debug strings starting with ${testdir}" >> expout fi # Check the replaced strings are all there. AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.part.o]]) AT_CHECK([[ $READELF -zp.debug_str -zp.debug_line_str ./foobarbaz.part.o | cut -c13- \ | grep ^/foo/bar/baz | sort | uniq ]],[0],[expout],[ignore]) AT_CLEANUP # === # debugedit should at least replace the .debug_str directory paths # and in the executable. # === AT_SETUP([debugedit .debug_str exe DWARF4]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP([-gdwarf-4]) # Capture strings that start with the testdir (pwd) directory path # (and replace that textually with /foo/bar/baz) $READELF -zp.debug_str foobarbaz.exe | cut -c13- \ | grep ^$(pwd) | sort \ | sed -e "s@$(pwd)@/foo/bar/baz@" > expout # Make sure there is at least some output # The linker will have merged unique strings, so no need for sort -u. expout_lines=$(wc --lines expout | cut -f1 -d\ ) if test $expout_lines -lt 3; then echo "Expecting at least 3 debug strings starting with ${testdir}" >> expout fi # Check the replaced strings are all there. AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.exe]]) AT_CHECK([[ $READELF -zp.debug_str foobarbaz.exe | cut -c13- \ | grep ^/foo/bar/baz | sort ]],[0],[expout]) AT_CLEANUP # === # debugedit should at least replace the .debug_str/line_str directory paths # and in the executable. # === AT_SETUP([debugedit .debug_str/line_str exe DWARF5]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test "$GDWARF_5_FLAG" = "no"]) DEBUGEDIT_SETUP([-gdwarf-5]) # Capture strings that start with the testdir (pwd) directory path # (and replace that textually with /foo/bar/baz) $READELF -zp.debug_str -zp.debug_line_str foobarbaz.exe | cut -c13- \ | grep ^$(pwd) | sort | uniq \ | sed -e "s@$(pwd)@/foo/bar/baz@" > expout # Make sure there is at least some output # The linker will have merged unique strings, so no need for sort -u. expout_lines=$(wc --lines expout | cut -f1 -d\ ) if test $expout_lines -lt 3; then echo "Expecting at least 3 debug strings starting with ${testdir}" >> expout fi # Check the replaced strings are all there. AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.exe]]) AT_CHECK([[ $READELF -zp.debug_str -zp.debug_line_str foobarbaz.exe | cut -c13- \ | grep ^/foo/bar/baz | sort | uniq ]],[0],[expout],[ignore]) AT_CLEANUP # For .debug_info we expect the following DW_AT_name and DW_AT_comp_dir # strings for the DW_TAG_compile_unit: # - foo.o # DW_AT_name: subdir_foo/foo.c # DW_AT_comp_dir: /foo/baz/baz # - bar.o # DW_AT_name: bar.c # DW_AT_comp_dir: /foo/bar/baz/subdir_bar # - baz.o # DW_AT_name: /foo/bar/baz/baz.c # DW_AT_comp_dir: /foo/baz/baz # # Older gcc (before 7) don't emit the DW_AT_comp_dir for baz.o. # But because it is similar to the comp_dir of foo.o, just sort -u. # === # Make sure DW_AT_name and DW_AT_comp_dir strings are replaced # in objects. # === AT_SETUP([debugedit .debug_info objects]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP AT_DATA([expout], [/foo/bar/baz /foo/bar/baz/baz.c /foo/bar/baz/subdir_bar ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foo.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./subdir_bar/bar.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./baz.o]]) AT_CHECK([[ ($READELF --debug-dump=info foo.o; \ $READELF --debug-dump=info subdir_bar/bar.o; \ $READELF --debug-dump=info baz.o) \ | grep -E 'DW_AT_(name|comp_dir)' \ | rev | cut -d: -f1 | rev | cut -c2- | grep ^/foo/bar/baz | sort -u ]],[0],[expout],[ignore]) AT_CLEANUP AT_SETUP([debugedit .debug_info objects (compressed)]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test -z "$GZ_ZLIB_FLAG"]) AT_SKIP_IF([test "$READELF_VERSION_OK" = "no"]) DEBUGEDIT_SETUP([], [$GZ_ZLIB_FLAG]) AT_DATA([expout], [/foo/bar/baz /foo/bar/baz/baz.c /foo/bar/baz/subdir_bar ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foo.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./subdir_bar/bar.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./baz.o]]) AT_CHECK([[ ($READELF --debug-dump=info foo.o; \ $READELF --debug-dump=info subdir_bar/bar.o; \ $READELF --debug-dump=info baz.o) \ | grep -E 'DW_AT_(name|comp_dir)' \ | rev | cut -d: -f1 | rev | cut -c2- | grep ^/foo/bar/baz | sort -u ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure DW_AT_name and DW_AT_comp_dir strings are replaced # in partial linked object. # === AT_SETUP([debugedit .debug_info partial]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP AT_DATA([expout], [/foo/bar/baz /foo/bar/baz/baz.c /foo/bar/baz/subdir_bar ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.part.o]]) AT_CHECK([[ $READELF --debug-dump=info ./foobarbaz.part.o \ | grep -E 'DW_AT_(name|comp_dir)' \ | rev | cut -d: -f1 | rev | cut -c2- | grep ^/foo/bar/baz | sort -u ]],[0],[expout],[ignore]) AT_CLEANUP AT_SETUP([debugedit .debug_info partial (compressed)]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test -z "$GZ_ZLIB_FLAG"]) AT_SKIP_IF([test "$READELF_VERSION_OK" = "no"]) DEBUGEDIT_SETUP([], [$GZ_ZLIB_FLAG]) AT_DATA([expout], [/foo/bar/baz /foo/bar/baz/baz.c /foo/bar/baz/subdir_bar ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.part.o]]) AT_CHECK([[ $READELF --debug-dump=info ./foobarbaz.part.o \ | grep -E 'DW_AT_(name|comp_dir)' \ | rev | cut -d: -f1 | rev | cut -c2- | grep ^/foo/bar/baz | sort -u ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure DW_AT_name and DW_AT_comp_dir strings are replaced # in executable. # === AT_SETUP([debugedit .debug_info exe]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP AT_DATA([expout], [/foo/bar/baz /foo/bar/baz/baz.c /foo/bar/baz/subdir_bar ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.exe]]) AT_CHECK([[ $READELF --debug-dump=info ./foobarbaz.exe | grep -E 'DW_AT_(name|comp_dir)' \ | rev | cut -d: -f1 | rev | cut -c2- | grep ^/foo/bar/baz | sort -u ]],[0],[expout],[ignore]) AT_CLEANUP AT_SETUP([debugedit .debug_info exe (compressed)]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test -z "$GZ_ZLIB_FLAG"]) AT_SKIP_IF([test "$READELF_VERSION_OK" = "no"]) DEBUGEDIT_SETUP([], [$GZ_ZLIB_FLAG]) AT_DATA([expout], [/foo/bar/baz /foo/bar/baz/baz.c /foo/bar/baz/subdir_bar ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.exe]]) AT_CHECK([[ $READELF --debug-dump=info ./foobarbaz.exe | grep -E 'DW_AT_(name|comp_dir)' \ | rev | cut -d: -f1 | rev | cut -c2- | grep ^/foo/bar/baz | sort -u ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure -fdebug-types-section has updated strings in objects. # Currently only works with DWARF4 # === AT_SETUP([debugedit .debug_types objects]) AT_KEYWORDS([debugtypes] [debugedit]) DEBUGEDIT_SETUP([-fdebug-types-section -gdwarf-4]) AT_SKIP_IF([! $READELF -S ./foo.o ./subdir_bar/bar.o ./baz.o | grep -F -q '.debug_types']) AT_DATA([expout], [st1 stf stringp1 stringp_foo st1 stb stringp1 stringp_bar st1 stringp1 stringp_baz stz ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foo.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./subdir_bar/bar.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./baz.o]]) AT_CHECK([[ for i in ./foo.o ./subdir_bar/bar.o ./baz.o;do \ $READELF --debug-dump=info $i \ | awk '/Abbrev Number:.*DW_TAG_type_unit/{p=1}{if(p)print}/^$/{p=0}' \ | sed -n 's/^.*> *DW_AT_name *:.* \(stringp[^ ]*\|st.\)$/\1/p' \ | sort; done ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure -fdebug-types-section has updated strings in partial linked object. # Currently only works with DWARF4 # === AT_SETUP([debugedit .debug_types partial]) AT_KEYWORDS([debugtypes] [debugedit]) DEBUGEDIT_SETUP([-fdebug-types-section -gdwarf-4]) AT_SKIP_IF([! $READELF -S ./foobarbaz.part.o | grep -F -q '.debug_types']) AT_DATA([expout], [st1 stb stf stringp1 stringp_bar stringp_baz stringp_foo stz ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.part.o]]) AT_CHECK([[ $READELF --debug-dump=info ./foobarbaz.part.o \ | awk '/Abbrev Number:.*DW_TAG_type_unit/{p=1}{if(p)print}/^$/{p=0}' \ | sed -n 's/^.*> *DW_AT_name *:.* \(stringp[^ ]*\|st.\)$/\1/p' \ | sort ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure -fdebug-types-section has updated strings in executable. # DWARF4 # === AT_SETUP([debugedit .debug_types exe DWARF4]) AT_KEYWORDS([debugtypes] [debugedit]) DEBUGEDIT_SETUP([-fdebug-types-section -gdwarf-4]) AT_SKIP_IF([! $READELF -S ./foobarbaz.exe | grep -F -q '.debug_types']) AT_DATA([expout], [st1 stb stf stringp1 stringp_bar stringp_baz stringp_foo stz ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.exe]]) AT_CHECK([[ $READELF --debug-dump=info ./foobarbaz.exe \ | awk '/Abbrev Number:.*DW_TAG_type_unit/{p=1}{if(p)print}/^$/{p=0}' \ | sed -n 's/^.*> *DW_AT_name *:.* \(stringp[^ ]*\|st.\)$/\1/p' \ | sort ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure -fdebug-types-section has updated strings in executable. # DWARF5 # === AT_SETUP([debugedit .debug_types exe DWARF5]) AT_KEYWORDS([debugtypes] [debugedit]) DEBUGEDIT_SETUP([-fdebug-types-section -gdwarf-5]) AT_SKIP_IF([test "$GDWARF_5_FLAG" = "no"]) AT_SKIP_IF([! $READELF --debug-dump=info ./foobarbaz.exe | grep -F -q 'DW_TAG_type_unit']) AT_DATA([expout], [st1 stb stf stringp1 stringp_bar stringp_baz stringp_foo stz ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.exe]]) AT_CHECK([[ $READELF --debug-dump=info ./foobarbaz.exe \ | awk '/Abbrev Number:.*DW_TAG_type_unit/{p=1}{if(p)print}/^$/{p=0}' \ | sed -n 's/^.*> *DW_AT_name *:.* \(stringp[^ ]*\|st.\)$/\1/p' \ | sort ]],[0],[expout],[ignore]) AT_CLEANUP # foo.o and bar.o are build with relative paths and so will use the # comp_dir (from .debug_info). But bar.o is build from sources with # an absolute path, so the .debug_line Directory Table should contain # /foo/bar/baz and /foo/bar/baz/subdir_headers. # === # Make sure .debug_line Directory Table entries are replaced # in objects. # === AT_SETUP([debugedit .debug_line objects DWARF4]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP([-gdwarf-4]) ($READELF --debug-dump=line foo.o; \ $READELF --debug-dump=line subdir_bar/bar.o; \ $READELF --debug-dump=line baz.o) \ | grep -E -A5 "The (Directory|File Name) Table" \ | grep "^ [[1234]]" \ | sed -e "s@$(pwd)@/foo/bar/baz@" | tee expout AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foo.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./subdir_bar/bar.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./baz.o]]) AT_CHECK([[ ($READELF --debug-dump=line foo.o; \ $READELF --debug-dump=line subdir_bar/bar.o; \ $READELF --debug-dump=line baz.o) \ | grep -E -A5 "The (Directory|File Name) Table" | grep "^ [1234]" ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure .debug_line Directory Table entries are replaced # in objects. # === AT_SETUP([debugedit .debug_line objects DWARF5]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test "$GDWARF_5_FLAG" = "no"]) AT_SKIP_IF([test "$DWARF_5_DEBUGLINE" = "no"]) DEBUGEDIT_SETUP([-gdwarf-5]) ($READELF --debug-dump=line foo.o; \ $READELF --debug-dump=line subdir_bar/bar.o; \ $READELF --debug-dump=line baz.o) \ | grep -E -A5 "The (Directory|File Name) Table" \ | grep "^ [[01234]]" | cut -f3 -d: \ | sed -e "s@$(pwd)@/foo/bar/baz@" | tee expout AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foo.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./subdir_bar/bar.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./baz.o]]) AT_CHECK([[ ($READELF --debug-dump=line foo.o; \ $READELF --debug-dump=line subdir_bar/bar.o; \ $READELF --debug-dump=line baz.o) \ | grep -E -A5 "The (Directory|File Name) Table" \ | grep "^ [01234]" | cut -f3 -d: ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure .debug_line Directory Table entries are replaced # in partial linked object. # === AT_SETUP([debugedit .debug_line partial DWARF4]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP([-gdwarf-4]) $READELF --debug-dump=line ./foobarbaz.part.o \ | grep -E -A5 "The (Directory|File Name) Table" \ | grep "^ [[1234]]" \ | sed -e "s@$(pwd)@/foo/bar/baz@" | tee expout AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.part.o]]) AT_CHECK([[ $READELF --debug-dump=line ./foobarbaz.part.o \ | grep -E -A5 "The (Directory|File Name) Table" \ | grep "^ [1234]" ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure .debug_line Directory Table entries are replaced # in partial linked object. # === AT_SETUP([debugedit .debug_line partial DWARF5]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test "$GDWARF_5_FLAG" = "no"]) AT_SKIP_IF([test "$DWARF_5_DEBUGLINE" = "no"]) DEBUGEDIT_SETUP([-gdwarf-5]) $READELF --debug-dump=line ./foobarbaz.part.o \ | grep -E -A5 "The (Directory|File Name) Table" \ | grep "^ [[01234]]" | cut -f3 -d: \ | sed -e "s@$(pwd)@/foo/bar/baz@" | tee expout AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.part.o]]) AT_CHECK([[ $READELF --debug-dump=line ./foobarbaz.part.o \ | grep -E -A5 "The (Directory|File Name) Table" \ | grep "^ [01234]" | cut -f3 -d: ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure .debug_line Directory Table entries are replaced # in executable. # === AT_SETUP([debugedit .debug_line exe DWARF4]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP([-gdwarf-4]) $READELF --debug-dump=line ./foobarbaz.exe \ | grep -E -A5 "The (Directory|File Name) Table" \ | grep "^ [[1234]]" \ | sed -e "s@$(pwd)@/foo/bar/baz@" | tee expout AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.exe]]) AT_CHECK([[ $READELF --debug-dump=line ./foobarbaz.exe \ | grep -E -A5 "The (Directory|File Name) Table" \ | grep "^ [1234]" ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure .debug_line Directory Table entries are replaced # in executable. # === AT_SETUP([debugedit .debug_line exe DWARF5]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test "$GDWARF_5_FLAG" = "no"]) AT_SKIP_IF([test "$DWARF_5_DEBUGLINE" = "no"]) DEBUGEDIT_SETUP([-gdwarf-5]) $READELF --debug-dump=line ./foobarbaz.exe \ | grep -E -A5 "The (Directory|File Name) Table" \ | grep "^ [[01234]]" | cut -f3 -d: \ | sed -e "s@$(pwd)@/foo/bar/baz@" | tee expout AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.exe]]) AT_CHECK([[ $READELF --debug-dump=line ./foobarbaz.exe \ | grep -E -A5 "The (Directory|File Name) Table" \ | grep "^ [01234]" | cut -f3 -d: ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure .debug_macro strings are still there # in objects. # === AT_SETUP([debugedit .debug_macro objects]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP([$DEBUG_MACRO_FLAG]) # We expect 3 for each compile unit. AT_DATA([expout], [NUMBER 42 NUMBER 42 NUMBER 42 ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foo.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./subdir_bar/bar.o]]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./baz.o]]) AT_CHECK([[ ($READELF --debug-dump=macro foo.o; \ $READELF --debug-dump=macro subdir_bar/bar.o; \ $READELF --debug-dump=macro baz.o) \ | grep NUMBER | rev | cut -d: -f1 | rev | cut -c2- ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure .debug_macro strings are still there # in partial linked object. # === AT_SETUP([debugedit .debug_macro partial]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP([$DEBUG_MACRO_FLAG]) # We expect 3 for each compile unit. AT_DATA([expout], [NUMBER 42 NUMBER 42 NUMBER 42 ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.part.o]]) AT_CHECK([[ $READELF --debug-dump=macro ./foobarbaz.part.o \ | grep NUMBER | rev | cut -d: -f1 | rev | cut -c2- ]],[0],[expout],[ignore]) AT_CLEANUP # === # Make sure .debug_macro strings are still there # in executable. # === AT_SETUP([debugedit .debug_macro exe]) AT_KEYWORDS([debuginfo] [debugedit]) DEBUGEDIT_SETUP([$DEBUG_MACRO_FLAG]) # We expect 3 for each compile unit. AT_DATA([expout], [NUMBER 42 NUMBER 42 NUMBER 42 ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.exe]]) AT_CHECK([[ $READELF --debug-dump=macro ./foobarbaz.exe \ | grep NUMBER | rev | cut -d: -f1 | rev | cut -c2- ]],[0],[expout],[ignore]) AT_CLEANUP AT_SETUP([debugedit .debug_macro exe (compressed)]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test -z "$GZ_ZLIB_FLAG"]) AT_SKIP_IF([test "$READELF_VERSION_OK" = "no"]) DEBUGEDIT_SETUP([$DEBUG_MACRO_FLAG], [$GZ_ZLIB_FLAG]) # We expect 3 for each compile unit. AT_DATA([expout], [NUMBER 42 NUMBER 42 NUMBER 42 ]) AT_CHECK([[debugedit -b $(pwd) -d /foo/bar/baz ./foobarbaz.exe]]) AT_CHECK([[ $READELF --debug-dump=macro ./foobarbaz.exe \ | grep NUMBER | rev | cut -d: -f1 | rev | cut -c2- ]],[0],[expout],[ignore]) AT_CLEANUP # === # source list mode dwarf-4 # === AT_SETUP([debugedit --list-file DWARF4]) AT_KEYWORDS([debuginfo] [debugedit]) echo "int main () { }" > main.c $CC $CFLAGS -gdwarf-4 -o main main.c AT_CHECK([[debugedit -l sources.list main]]) AT_CHECK([[grep -q main.c sources.list]]) cat sources.list AT_CLEANUP # === # source list mode dwarf-5 # === AT_SETUP([debugedit --list-file DWARF5]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test "$GDWARF_5_FLAG" = "no"]) echo "int main () { }" > main.c $CC $CFLAGS -gdwarf-5 -o main main.c AT_CHECK([[debugedit -l sources.list main]]) AT_CHECK([[grep -q main.c sources.list]]) AT_CLEANUP # === # source list with compression dwarf-4 # === AT_SETUP([debugedit --list-file compressed DWARF4]) AT_KEYWORDS([debuginfo] [debugedit]) echo "int main () { }" > main.c $CC $CFLAGS $GZ_ZLIB_FLAG -gdwarf-4 -o main main.c AT_CHECK([[debugedit -l sources.list main]]) AT_CHECK([[grep -q main.c sources.list]]) AT_CLEANUP # === # source list with compression dwarf-5 # === AT_SETUP([debugedit --list-file compressed DWARF5]) AT_KEYWORDS([debuginfo] [debugedit]) AT_SKIP_IF([test "$GDWARF_5_FLAG" = "no"]) echo "int main () { }" > main.c $CC $CFLAGS $GZ_ZLIB_FLAG -gdwarf-5 -o main main.c AT_CHECK([[debugedit -l sources.list main]]) AT_CHECK([[grep -q main.c sources.list]]) AT_CLEANUP # === # build-id recomputation # === AT_SETUP([debugedit build-id recompute]) AT_KEYWORDS([debuginfo] [debugedit] [build-id]) # compile a test program and extract its linker-assigned build-id echo "int main () { }" > main.c $CC $CFLAGS -Wl,--build-id -o main main.c AT_CHECK([[$READELF -n main | grep -o "Build.ID:.*" | awk '{print $3}']], [0], [stdout], [ignore]) bid="`cat stdout`" AT_CHECK([[expr "$bid" : '[0-9a-f]*']], [0], [ignore]) # run debugedit to recompute build-id AT_CHECK([[debugedit -i -s deadbeef main]], [0], [stdout]) bid2a="`cat stdout`" AT_CHECK([[expr "$bid2a" : '[0-9a-f]*']], [0], [ignore]) AT_CHECK([[test "$bid" != "$bid2a"]]) # check that debugedit's stdout matches readelf -n note AT_CHECK([[$READELF -n main | grep -o "Build.ID:.*" | awk '{print $3}']], [0], [stdout], [ignore]) bid2b="`cat stdout`" AT_CHECK([[expr "$bid2b" : '[0-9a-f]*']], [0], [ignore]) AT_CHECK([[test "$bid2a" = "$bid2b"]]) # run debugedit to recompute build-id, check for idempotence AT_CHECK([[debugedit -i -s deadbeef main]], [0], [stdout]) bid2c="`cat stdout`" AT_CHECK([[expr "$bid2c" : '[0-9a-f]*']], [0], [ignore]) AT_CHECK([[test "$bid2a" = "$bid2c"]]) # check that debugedit -i with different -s seed results in different valid build-id AT_CHECK([[debugedit -i -s zoofoo main]], [0], [stdout]) bid3="`cat stdout`" AT_CHECK([[expr "$bid3" : '[0-9a-f]*']], [0], [ignore]) AT_CHECK([[test "$bid3" != "$bid2a"]]) AT_CLEANUP # Preserving time stamps AT_SETUP([debugedit preserve timestamps]) AT_KEYWORDS([debugedit] [timestamp]) # compile a test program and record the timestamps echo "int main () { }" > main.c $CC $CFLAGS -g -o main main.c AT_CHECK([[stat -c "%x %y" main]], [0], [stdout], []) mv stdout expout # process it with debugedit, using -p AT_CHECK([[debugedit -p -b $(pwd) -d /foo/bar/baz ./main]]) # check timestamps were preserved AT_CHECK([[stat -c "%x %y" main]], [0], [expout], []) AT_CLEANUP # debugedit should handle Elf files with > 65280 sections AT_SETUP([debugedit large file]) AT_KEYWORDS([debugedit] [large]) DEBUGEDIT_SETUP_LARGE # The debuginfo contains the current working directory AT_CHECK([[ $READELF --debug-dump=info ./large.o | grep $(pwd) ]],[0],[ignore],[ignore]) AT_CHECK([[debugedit -b $(pwd) -d /foo ./large.o]]) # Now it should not contain $(pwd) AT_CHECK([[ $READELF --debug-dump=info ./large.o | grep $(pwd) ]],[1],[ignore],[ignore]) # Make sure it does contain /foo instead. AT_DATA([expout], [/foo ]) AT_CHECK([[ $READELF --debug-dump=info ./large.o | grep -E 'DW_AT_(name|comp_dir)' \ | rev | cut -d: -f1 | rev | cut -c2- | grep ^/foo | sort -u ]],[0],[expout],[ignore]) AT_CLEANUP