strip.sh 7.7 KB

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