| 1 | #! /bin/sh |
| 2 | # Wrapper around gcc to tweak the output in various ways when running |
| 3 | # the testsuite. |
| 4 | |
| 5 | # Copyright (C) 2010-2017 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/sh $srcdir/gdb/contrib/cc-with-tweaks.sh ARGS gcc" \ |
| 31 | # CXX_FOR_TARGET="/bin/sh $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 |
| 46 | # -p create .dwp files (Fission), you need to also use gcc option -gsplit-dwarf |
| 47 | # If nothing is given, no changes are made |
| 48 | |
| 49 | myname=cc-with-tweaks.sh |
| 50 | |
| 51 | if [ -z "$GDB" ] |
| 52 | then |
| 53 | if [ -f ./gdb ] |
| 54 | then |
| 55 | GDB="./gdb -data-directory data-directory" |
| 56 | elif [ -f ../gdb ] |
| 57 | then |
| 58 | GDB="../gdb -data-directory ../data-directory" |
| 59 | elif [ -f ../../gdb ] |
| 60 | then |
| 61 | GDB="../../gdb -data-directory ../../data-directory" |
| 62 | else |
| 63 | echo "$myname: unable to find usable gdb" >&2 |
| 64 | exit 1 |
| 65 | fi |
| 66 | fi |
| 67 | |
| 68 | OBJCOPY=${OBJCOPY:-objcopy} |
| 69 | READELF=${READELF:-readelf} |
| 70 | |
| 71 | DWZ=${DWZ:-dwz} |
| 72 | DWP=${DWP:-dwp} |
| 73 | |
| 74 | have_link=unknown |
| 75 | next_is_output_file=no |
| 76 | output_file=a.out |
| 77 | |
| 78 | want_index=false |
| 79 | want_dwz=false |
| 80 | want_multi=false |
| 81 | want_dwp=false |
| 82 | want_objcopy_compress=false |
| 83 | |
| 84 | while [ $# -gt 0 ]; do |
| 85 | case "$1" in |
| 86 | -Z) want_objcopy_compress=true ;; |
| 87 | -z) want_dwz=true ;; |
| 88 | -i) want_index=true ;; |
| 89 | -m) want_multi=true ;; |
| 90 | -p) want_dwp=true ;; |
| 91 | *) break ;; |
| 92 | esac |
| 93 | shift |
| 94 | done |
| 95 | |
| 96 | for arg in "$@" |
| 97 | do |
| 98 | if [ "$next_is_output_file" = "yes" ] |
| 99 | then |
| 100 | output_file="$arg" |
| 101 | next_is_output_file=no |
| 102 | continue |
| 103 | fi |
| 104 | |
| 105 | # Poor man's gcc argument parser. |
| 106 | # We don't need to handle all arguments, we just need to know if we're |
| 107 | # doing a link and what the output file is. |
| 108 | # It's not perfect, but it seems to work well enough for the task at hand. |
| 109 | case "$arg" in |
| 110 | "-c") have_link=no ;; |
| 111 | "-E") have_link=no ;; |
| 112 | "-S") have_link=no ;; |
| 113 | "-o") next_is_output_file=yes ;; |
| 114 | esac |
| 115 | done |
| 116 | |
| 117 | if [ "$next_is_output_file" = "yes" ] |
| 118 | then |
| 119 | echo "$myname: Unable to find output file" >&2 |
| 120 | exit 1 |
| 121 | fi |
| 122 | |
| 123 | if [ "$have_link" = "no" ] |
| 124 | then |
| 125 | "$@" |
| 126 | exit $? |
| 127 | fi |
| 128 | |
| 129 | index_file="${output_file}.gdb-index" |
| 130 | if [ "$want_index" = true ] && [ -f "$index_file" ] |
| 131 | then |
| 132 | echo "$myname: Index file $index_file exists, won't clobber." >&2 |
| 133 | exit 1 |
| 134 | fi |
| 135 | |
| 136 | output_dir="${output_file%/*}" |
| 137 | [ "$output_dir" = "$output_file" ] && output_dir="." |
| 138 | |
| 139 | "$@" |
| 140 | rc=$? |
| 141 | [ $rc != 0 ] && exit $rc |
| 142 | if [ ! -f "$output_file" ] |
| 143 | then |
| 144 | echo "$myname: Internal error: $output_file missing." >&2 |
| 145 | exit 1 |
| 146 | fi |
| 147 | |
| 148 | if [ "$want_objcopy_compress" = true ]; then |
| 149 | $OBJCOPY --compress-debug-sections "$output_file" |
| 150 | rc=$? |
| 151 | [ $rc != 0 ] && exit $rc |
| 152 | fi |
| 153 | |
| 154 | if [ "$want_index" = true ]; then |
| 155 | $GDB --batch-silent -nx -ex "set auto-load no" -ex "file $output_file" -ex "save gdb-index $output_dir" |
| 156 | rc=$? |
| 157 | [ $rc != 0 ] && exit $rc |
| 158 | |
| 159 | # GDB might not always create an index. Cope. |
| 160 | if [ -f "$index_file" ] |
| 161 | then |
| 162 | $OBJCOPY --add-section .gdb_index="$index_file" \ |
| 163 | --set-section-flags .gdb_index=readonly \ |
| 164 | "$output_file" "$output_file" |
| 165 | rc=$? |
| 166 | else |
| 167 | rc=0 |
| 168 | fi |
| 169 | [ $rc != 0 ] && exit $rc |
| 170 | fi |
| 171 | |
| 172 | if [ "$want_dwz" = true ]; then |
| 173 | $DWZ "$output_file" > /dev/null 2>&1 |
| 174 | elif [ "$want_multi" = true ]; then |
| 175 | cp $output_file ${output_file}.alt |
| 176 | $DWZ -m ${output_file}.dwz "$output_file" ${output_file}.alt > /dev/null 2>&1 |
| 177 | fi |
| 178 | |
| 179 | if [ "$want_dwp" = true ]; then |
| 180 | dwo_files=$($READELF -wi "${output_file}" | grep _dwo_name | \ |
| 181 | sed -e 's/^.*: //' | sort | uniq) |
| 182 | rc=0 |
| 183 | if [ -n "$dwo_files" ]; then |
| 184 | $DWP -o "${output_file}.dwp" ${dwo_files} > /dev/null |
| 185 | rc=$? |
| 186 | [ $rc != 0 ] && exit $rc |
| 187 | rm -f ${dwo_files} |
| 188 | fi |
| 189 | fi |
| 190 | |
| 191 | rm -f "$index_file" |
| 192 | exit $rc |