1 #!/bin/bash -e 2 3 # Copyright 2017 Google Inc. All rights reserved. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 # Script to handle the various ways soong may need to strip binaries 18 # Inputs: 19 # Environment: 20 # CLANG_BIN: path to the clang bin directory 21 # CROSS_COMPILE: prefix added to readelf, objcopy tools 22 # XZ: path to the xz binary 23 # Arguments: 24 # -i ${file}: input file (required) 25 # -o ${file}: output file (required) 26 # -d ${file}: deps file (required) 27 # -k symbols: Symbols to keep (optional) 28 # --add-gnu-debuglink 29 # --keep-mini-debug-info 30 # --keep-symbols 31 # --use-gnu-strip 32 # --remove-build-id 33 34 set -o pipefail 35 36 OPTSTRING=d:i:o:k:-: 37 38 usage() { 39 cat <<EOF 40 Usage: strip.sh [options] -k symbols -i in-file -o out-file -d deps-file 41 Options: 42 --add-gnu-debuglink Add a gnu-debuglink section to out-file 43 --keep-mini-debug-info Keep compressed debug info in out-file 44 --keep-symbols Keep symbols in out-file 45 --use-gnu-strip Use strip/objcopy instead of llvm-{strip,objcopy} 46 --remove-build-id Remove the gnu build-id section in out-file 47 EOF 48 exit 1 49 } 50 51 # Without --use-gnu-strip, GNU strip is replaced with llvm-strip to work around 52 # old GNU strip bug on lld output files, b/80093681. 53 # Similary, calls to objcopy are replaced with llvm-objcopy, 54 # with some exceptions. 55 56 do_strip() { 57 # ${CROSS_COMPILE}strip --strip-all does not strip .ARM.attributes, 58 # so we tell llvm-strip to keep it too. 59 if [ -z "${use_gnu_strip}" ]; then 60 "${CLANG_BIN}/llvm-strip" --strip-all -keep-section=.ARM.attributes "${infile}" -o "${outfile}.tmp" 61 else 62 "${CROSS_COMPILE}strip" --strip-all "${infile}" -o "${outfile}.tmp" 63 fi 64 } 65 66 do_strip_keep_symbols() { 67 REMOVE_SECTIONS=`"${CROSS_COMPILE}readelf" -S "${infile}" | awk '/.debug_/ {print "--remove-section " $2}' | xargs` 68 if [ -z "${use_gnu_strip}" ]; then 69 "${CLANG_BIN}/llvm-objcopy" "${infile}" "${outfile}.tmp" ${REMOVE_SECTIONS} 70 else 71 "${CROSS_COMPILE}objcopy" "${infile}" "${outfile}.tmp" ${REMOVE_SECTIONS} 72 fi 73 } 74 75 do_strip_keep_symbol_list() { 76 if [ -z "${use_gnu_strip}" ]; then 77 echo "do_strip_keep_symbol_list does not work with llvm-objcopy" 78 echo "http://b/131631155" 79 usage 80 fi 81 82 echo "${symbols_to_keep}" | tr ',' '\n' > "${outfile}.symbolList" 83 KEEP_SYMBOLS="-w --strip-unneeded-symbol=* --keep-symbols=" 84 KEEP_SYMBOLS+="${outfile}.symbolList" 85 86 "${CROSS_COMPILE}objcopy" "${infile}" "${outfile}.tmp" ${KEEP_SYMBOLS} 87 } 88 89 do_strip_keep_mini_debug_info() { 90 rm -f "${outfile}.dynsyms" "${outfile}.funcsyms" "${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo" "${outfile}.mini_debuginfo.xz" 91 local fail= 92 if [ -z "${use_gnu_strip}" ]; then 93 "${CLANG_BIN}/llvm-strip" --strip-all -keep-section=.ARM.attributes -remove-section=.comment "${infile}" -o "${outfile}.tmp" || fail=true 94 else 95 "${CROSS_COMPILE}strip" --strip-all -R .comment "${infile}" -o "${outfile}.tmp" || fail=true 96 fi 97 if [ -z $fail ]; then 98 # Current prebult llvm-objcopy does not support the following flags: 99 # --only-keep-debug --rename-section --keep-symbols 100 # For the following use cases, ${CROSS_COMPILE}objcopy does fine with lld linked files, 101 # except the --add-section flag. 102 "${CROSS_COMPILE}objcopy" --only-keep-debug "${infile}" "${outfile}.debug" 103 "${CROSS_COMPILE}nm" -D "${infile}" --format=posix --defined-only 2> /dev/null | awk '{ print $1 }' | sort >"${outfile}.dynsyms" 104 "${CROSS_COMPILE}nm" "${infile}" --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t" || $2 == "D") print $1 }' | sort > "${outfile}.funcsyms" 105 comm -13 "${outfile}.dynsyms" "${outfile}.funcsyms" > "${outfile}.keep_symbols" 106 echo >> "${outfile}.keep_symbols" # Ensure that the keep_symbols file is not empty. 107 "${CROSS_COMPILE}objcopy" --rename-section .debug_frame=saved_debug_frame "${outfile}.debug" "${outfile}.mini_debuginfo" 108 "${CROSS_COMPILE}objcopy" -S --remove-section .gdb_index --remove-section .comment --keep-symbols="${outfile}.keep_symbols" "${outfile}.mini_debuginfo" 109 "${CROSS_COMPILE}objcopy" --rename-section saved_debug_frame=.debug_frame "${outfile}.mini_debuginfo" 110 "${XZ}" "${outfile}.mini_debuginfo" 111 if [ -z "${use_gnu_strip}" ]; then 112 "${CLANG_BIN}/llvm-objcopy" --add-section .gnu_debugdata="${outfile}.mini_debuginfo.xz" "${outfile}.tmp" 113 else 114 "${CROSS_COMPILE}objcopy" --add-section .gnu_debugdata="${outfile}.mini_debuginfo.xz" "${outfile}.tmp" 115 fi 116 rm -f "${outfile}.dynsyms" "${outfile}.funcsyms" "${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo" "${outfile}.mini_debuginfo.xz" 117 else 118 cp -f "${infile}" "${outfile}.tmp" 119 fi 120 } 121 122 do_add_gnu_debuglink() { 123 if [ -z "${use_gnu_strip}" ]; then 124 "${CLANG_BIN}/llvm-objcopy" --add-gnu-debuglink="${infile}" "${outfile}.tmp" 125 else 126 "${CROSS_COMPILE}objcopy" --add-gnu-debuglink="${infile}" "${outfile}.tmp" 127 fi 128 } 129 130 do_remove_build_id() { 131 if [ -z "${use_gnu_strip}" ]; then 132 "${CLANG_BIN}/llvm-strip" -remove-section=.note.gnu.build-id "${outfile}.tmp" -o "${outfile}.tmp.no-build-id" 133 else 134 "${CROSS_COMPILE}strip" --remove-section=.note.gnu.build-id "${outfile}.tmp" -o "${outfile}.tmp.no-build-id" 135 fi 136 rm -f "${outfile}.tmp" 137 mv "${outfile}.tmp.no-build-id" "${outfile}.tmp" 138 } 139 140 while getopts $OPTSTRING opt; do 141 case "$opt" in 142 d) depsfile="${OPTARG}" ;; 143 i) infile="${OPTARG}" ;; 144 o) outfile="${OPTARG}" ;; 145 k) symbols_to_keep="${OPTARG}" ;; 146 -) 147 case "${OPTARG}" in 148 add-gnu-debuglink) add_gnu_debuglink=true ;; 149 keep-mini-debug-info) keep_mini_debug_info=true ;; 150 keep-symbols) keep_symbols=true ;; 151 remove-build-id) remove_build_id=true ;; 152 use-gnu-strip) use_gnu_strip=true ;; 153 *) echo "Unknown option --${OPTARG}"; usage ;; 154 esac;; 155 ?) usage ;; 156 *) echo "'${opt}' '${OPTARG}'" 157 esac 158 done 159 160 if [ -z "${infile}" ]; then 161 echo "-i argument is required" 162 usage 163 fi 164 165 if [ -z "${outfile}" ]; then 166 echo "-o argument is required" 167 usage 168 fi 169 170 if [ -z "${depsfile}" ]; then 171 echo "-d argument is required" 172 usage 173 fi 174 175 if [ ! -z "${keep_symbols}" -a ! -z "${keep_mini_debug_info}" ]; then 176 echo "--keep-symbols and --keep-mini-debug-info cannot be used together" 177 usage 178 fi 179 180 if [ ! -z "${symbols_to_keep}" -a ! -z "${keep_symbols}" ]; then 181 echo "--keep-symbols and -k cannot be used together" 182 usage 183 fi 184 185 if [ ! -z "${add_gnu_debuglink}" -a ! -z "${keep_mini_debug_info}" ]; then 186 echo "--add-gnu-debuglink cannot be used with --keep-mini-debug-info" 187 usage 188 fi 189 190 rm -f "${outfile}.tmp" 191 192 if [ ! -z "${keep_symbols}" ]; then 193 do_strip_keep_symbols 194 elif [ ! -z "${symbols_to_keep}" ]; then 195 do_strip_keep_symbol_list 196 elif [ ! -z "${keep_mini_debug_info}" ]; then 197 do_strip_keep_mini_debug_info 198 else 199 do_strip 200 fi 201 202 if [ ! -z "${add_gnu_debuglink}" ]; then 203 do_add_gnu_debuglink 204 fi 205 206 if [ ! -z "${remove_build_id}" ]; then 207 do_remove_build_id 208 fi 209 210 rm -f "${outfile}" 211 mv "${outfile}.tmp" "${outfile}" 212 213 if [ -z "${use_gnu_strip}" ]; then 214 USED_STRIP_OBJCOPY="${CLANG_BIN}/llvm-strip ${CLANG_BIN}/llvm-objcopy" 215 else 216 USED_STRIP_OBJCOPY="${CROSS_COMPILE}strip" 217 fi 218 219 cat <<EOF > "${depsfile}" 220 ${outfile}: \ 221 ${infile} \ 222 ${CROSS_COMPILE}nm \ 223 ${CROSS_COMPILE}objcopy \ 224 ${CROSS_COMPILE}readelf \ 225 ${USED_STRIP_OBJCOPY} 226 227 EOF 228