cc-with-tweaks.sh revision 1.9
1#!/usr/bin/env bash 2# Wrapper around gcc to tweak the output in various ways when running 3# the testsuite. 4 5# Copyright (C) 2010-2020 Free Software Foundation, Inc. 6# This program is free software; you can redistribute it and/or modify 7# it under the terms of the GNU General Public License as published by 8# the Free Software Foundation; either version 3 of the License, or 9# (at your option) any later version. 10# 11# This program is distributed in the hope that it will be useful, 12# but WITHOUT ANY WARRANTY; without even the implied warranty of 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14# GNU General Public License for more details. 15# 16# You should have received a copy of the GNU General Public License 17# along with this program. If not, see <http://www.gnu.org/licenses/>. 18 19# This program requires gdb and objcopy in addition to gcc. 20# The default values are gdb from the build tree and objcopy from $PATH. 21# They may be overridden by setting environment variables GDB and OBJCOPY 22# respectively. Note that GDB should contain the gdb binary as well as the 23# -data-directory flag, e.g., "foo/gdb -data-directory foo/data-directory". 24# We assume the current directory is either $obj/gdb or $obj/gdb/testsuite. 25# 26# Example usage: 27# 28# bash$ cd $objdir/gdb/testsuite 29# bash$ runtest \ 30# CC_FOR_TARGET="/bin/bash $srcdir/gdb/contrib/cc-with-tweaks.sh ARGS gcc" \ 31# CXX_FOR_TARGET="/bin/bash $srcdir/gdb/contrib/cc-with-tweaks.sh ARGS g++" 32# 33# For documentation on Fission and dwp files: 34# http://gcc.gnu.org/wiki/DebugFission 35# http://gcc.gnu.org/wiki/DebugFissionDWP 36# For documentation on index files: info -f gdb.info -n "Index Files" 37# For information about 'dwz', see the announcement: 38# http://gcc.gnu.org/ml/gcc/2012-04/msg00686.html 39# (More documentation is to come.) 40 41# ARGS determine what is done. They can be: 42# -Z invoke objcopy --compress-debug-sections 43# -z compress using dwz 44# -m compress using dwz -m 45# -i make an index (.gdb_index) 46# -n make a dwarf5 index (.debug_names) 47# -p create .dwp files (Fission), you need to also use gcc option -gsplit-dwarf 48# If nothing is given, no changes are made 49 50myname=cc-with-tweaks.sh 51mydir=`dirname "$0"` 52 53if [ -z "$GDB" ] 54then 55 if [ -f ./gdb ] 56 then 57 GDB="./gdb -data-directory data-directory" 58 elif [ -f ../gdb ] 59 then 60 GDB="../gdb -data-directory ../data-directory" 61 elif [ -f ../../gdb ] 62 then 63 GDB="../../gdb -data-directory ../../data-directory" 64 else 65 echo "$myname: unable to find usable gdb" >&2 66 exit 1 67 fi 68fi 69 70OBJCOPY=${OBJCOPY:-objcopy} 71READELF=${READELF:-readelf} 72 73DWZ=${DWZ:-dwz} 74DWP=${DWP:-dwp} 75 76have_link=unknown 77next_is_output_file=no 78output_file=a.out 79 80want_index=false 81index_options="" 82want_dwz=false 83want_multi=false 84want_dwp=false 85want_objcopy_compress=false 86 87while [ $# -gt 0 ]; do 88 case "$1" in 89 -Z) want_objcopy_compress=true ;; 90 -z) want_dwz=true ;; 91 -i) want_index=true ;; 92 -n) want_index=true; index_options=-dwarf-5;; 93 -m) want_multi=true ;; 94 -p) want_dwp=true ;; 95 *) break ;; 96 esac 97 shift 98done 99 100if [ "$want_index" = true ] 101then 102 if [ -z "$GDB_ADD_INDEX" ] 103 then 104 if [ -f $mydir/gdb-add-index.sh ] 105 then 106 GDB_ADD_INDEX="$mydir/gdb-add-index.sh" 107 else 108 echo "$myname: unable to find usable contrib/gdb-add-index.sh" >&2 109 exit 1 110 fi 111 fi 112fi 113 114for arg in "$@" 115do 116 if [ "$next_is_output_file" = "yes" ] 117 then 118 output_file="$arg" 119 next_is_output_file=no 120 continue 121 fi 122 123 # Poor man's gcc argument parser. 124 # We don't need to handle all arguments, we just need to know if we're 125 # doing a link and what the output file is. 126 # It's not perfect, but it seems to work well enough for the task at hand. 127 case "$arg" in 128 "-c") have_link=no ;; 129 "-E") have_link=no ;; 130 "-S") have_link=no ;; 131 "-o") next_is_output_file=yes ;; 132 esac 133done 134 135if [ "$next_is_output_file" = "yes" ] 136then 137 echo "$myname: Unable to find output file" >&2 138 exit 1 139fi 140 141if [ "$have_link" = "no" ] 142then 143 "$@" 144 exit $? 145fi 146 147output_dir="${output_file%/*}" 148[ "$output_dir" = "$output_file" ] && output_dir="." 149 150"$@" 151rc=$? 152[ $rc != 0 ] && exit $rc 153if [ ! -f "$output_file" ] 154then 155 echo "$myname: Internal error: $output_file missing." >&2 156 exit 1 157fi 158 159get_tmpdir () 160{ 161 tmpdir=$(dirname "$output_file")/.tmp 162 mkdir -p "$tmpdir" 163} 164 165if [ "$want_objcopy_compress" = true ]; then 166 $OBJCOPY --compress-debug-sections "$output_file" 167 rc=$? 168 [ $rc != 0 ] && exit $rc 169fi 170 171if [ "$want_index" = true ]; then 172 get_tmpdir 173 mv "$output_file" "$tmpdir" 174 tmpfile="$tmpdir/$(basename $output_file)" 175 # Filter out these messages which would stop dejagnu testcase run: 176 # echo "$myname: No index was created for $file" 1>&2 177 # echo "$myname: [Was there no debuginfo? Was there already an index?]" 1>&2 178 GDB=$GDB $GDB_ADD_INDEX $index_options "$tmpfile" 2>&1 \ 179 | grep -v "^${GDB_ADD_INDEX##*/}: " >&2 180 rc=${PIPESTATUS[0]} 181 mv "$tmpfile" "$output_file" 182 [ $rc != 0 ] && exit $rc 183fi 184 185if [ "$want_dwz" = true ]; then 186 # Validate dwz's result by checking if the executable was modified. 187 cp "$output_file" "${output_file}.copy" 188 $DWZ "$output_file" > /dev/null 189 cmp "$output_file" "$output_file.copy" > /dev/null 190 cmp_rc=$? 191 rm -f "${output_file}.copy" 192 193 case $cmp_rc in 194 0) 195 echo "$myname: dwz did not modify ${output_file}." 196 exit 1 197 ;; 198 1) 199 # File was modified, great. 200 ;; 201 *) 202 # Other cmp error, it presumably has already printed something on 203 # stderr. 204 exit 1 205 ;; 206 esac 207elif [ "$want_multi" = true ]; then 208 get_tmpdir 209 dwz_file=$tmpdir/$(basename "$output_file").dwz 210 # Remove the dwz output file if it exists, so we don't mistake it for a 211 # new file in case dwz fails. 212 rm -f "$dwz_file" 213 214 cp $output_file ${output_file}.alt 215 $DWZ -m "$dwz_file" "$output_file" ${output_file}.alt > /dev/null 216 rm -f ${output_file}.alt 217 218 # Validate dwz's work by checking if the expected output file exists. 219 if [ ! -f "$dwz_file" ]; then 220 echo "$myname: dwz file $dwz_file missing." 221 exit 1 222 fi 223fi 224 225if [ "$want_dwp" = true ]; then 226 dwo_files=$($READELF -wi "${output_file}" | grep _dwo_name | \ 227 sed -e 's/^.*: //' | sort | uniq) 228 rc=0 229 if [ -n "$dwo_files" ]; then 230 $DWP -o "${output_file}.dwp" ${dwo_files} > /dev/null 231 rc=$? 232 [ $rc != 0 ] && exit $rc 233 rm -f ${dwo_files} 234 fi 235fi 236 237exit $rc 238