xref: /aosp_15_r20/build/soong/scripts/strip.sh (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker#!/bin/bash -e
2*333d2b36SAndroid Build Coastguard Worker
3*333d2b36SAndroid Build Coastguard Worker# Copyright 2017 Google Inc. All rights reserved.
4*333d2b36SAndroid Build Coastguard Worker#
5*333d2b36SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
6*333d2b36SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*333d2b36SAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*333d2b36SAndroid Build Coastguard Worker#
9*333d2b36SAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
10*333d2b36SAndroid Build Coastguard Worker#
11*333d2b36SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*333d2b36SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
13*333d2b36SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*333d2b36SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*333d2b36SAndroid Build Coastguard Worker# limitations under the License.
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Worker# Script to handle the various ways soong may need to strip binaries
18*333d2b36SAndroid Build Coastguard Worker# Inputs:
19*333d2b36SAndroid Build Coastguard Worker#  Environment:
20*333d2b36SAndroid Build Coastguard Worker#   CLANG_BIN: path to the clang bin directory
21*333d2b36SAndroid Build Coastguard Worker#   XZ: path to the xz binary
22*333d2b36SAndroid Build Coastguard Worker#  Arguments:
23*333d2b36SAndroid Build Coastguard Worker#   -i ${file}: input file (required)
24*333d2b36SAndroid Build Coastguard Worker#   -o ${file}: output file (required)
25*333d2b36SAndroid Build Coastguard Worker#   -d ${file}: deps file (required)
26*333d2b36SAndroid Build Coastguard Worker#   -k symbols: Symbols to keep (optional)
27*333d2b36SAndroid Build Coastguard Worker#   --add-gnu-debuglink
28*333d2b36SAndroid Build Coastguard Worker#   --keep-mini-debug-info
29*333d2b36SAndroid Build Coastguard Worker#   --keep-symbols
30*333d2b36SAndroid Build Coastguard Worker#   --keep-symbols-and-debug-frame
31*333d2b36SAndroid Build Coastguard Worker#   --remove-build-id
32*333d2b36SAndroid Build Coastguard Worker#   --windows
33*333d2b36SAndroid Build Coastguard Worker
34*333d2b36SAndroid Build Coastguard Workerset -o pipefail
35*333d2b36SAndroid Build Coastguard Worker
36*333d2b36SAndroid Build Coastguard WorkerOPTSTRING=d:i:o:k:-:
37*333d2b36SAndroid Build Coastguard Worker
38*333d2b36SAndroid Build Coastguard Workerusage() {
39*333d2b36SAndroid Build Coastguard Worker    cat <<EOF
40*333d2b36SAndroid Build Coastguard WorkerUsage: strip.sh [options] -k symbols -i in-file -o out-file -d deps-file
41*333d2b36SAndroid Build Coastguard WorkerOptions:
42*333d2b36SAndroid Build Coastguard Worker        --add-gnu-debuglink             Add a gnu-debuglink section to out-file
43*333d2b36SAndroid Build Coastguard Worker        --keep-mini-debug-info          Keep compressed debug info in out-file
44*333d2b36SAndroid Build Coastguard Worker        --keep-symbols                  Keep symbols in out-file
45*333d2b36SAndroid Build Coastguard Worker        --keep-symbols-and-debug-frame  Keep symbols and .debug_frame in out-file
46*333d2b36SAndroid Build Coastguard Worker        --remove-build-id               Remove the gnu build-id section in out-file
47*333d2b36SAndroid Build Coastguard Worker        --windows                       Input file is Windows DLL or executable
48*333d2b36SAndroid Build Coastguard WorkerEOF
49*333d2b36SAndroid Build Coastguard Worker    exit 1
50*333d2b36SAndroid Build Coastguard Worker}
51*333d2b36SAndroid Build Coastguard Worker
52*333d2b36SAndroid Build Coastguard Workerdo_strip() {
53*333d2b36SAndroid Build Coastguard Worker    # GNU strip --strip-all does not strip .ARM.attributes,
54*333d2b36SAndroid Build Coastguard Worker    # so we tell llvm-strip to keep it too.
55*333d2b36SAndroid Build Coastguard Worker    local keep_section=--keep-section=.ARM.attributes
56*333d2b36SAndroid Build Coastguard Worker    if [ -n "${windows}" ]; then
57*333d2b36SAndroid Build Coastguard Worker      keep_section=
58*333d2b36SAndroid Build Coastguard Worker    fi
59*333d2b36SAndroid Build Coastguard Worker    "${CLANG_BIN}/llvm-strip" --strip-all ${keep_section} "${infile}" -o "${outfile}.tmp"
60*333d2b36SAndroid Build Coastguard Worker}
61*333d2b36SAndroid Build Coastguard Worker
62*333d2b36SAndroid Build Coastguard Workerdo_strip_keep_symbols_and_debug_frame() {
63*333d2b36SAndroid Build Coastguard Worker    REMOVE_SECTIONS=`"${CLANG_BIN}/llvm-readelf" -S "${infile}" | awk '/.debug_/ {if ($2 != ".debug_frame") {print "--remove-section " $2}}' | xargs`
64*333d2b36SAndroid Build Coastguard Worker    "${CLANG_BIN}/llvm-objcopy" "${infile}" "${outfile}.tmp" ${REMOVE_SECTIONS}
65*333d2b36SAndroid Build Coastguard Worker}
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Workerdo_strip_keep_symbols() {
68*333d2b36SAndroid Build Coastguard Worker    REMOVE_SECTIONS=`"${CLANG_BIN}/llvm-readelf" -S "${infile}" | awk '/.debug_/ {print "--remove-section " $2}' | xargs`
69*333d2b36SAndroid Build Coastguard Worker    "${CLANG_BIN}/llvm-objcopy" "${infile}" "${outfile}.tmp" ${REMOVE_SECTIONS}
70*333d2b36SAndroid Build Coastguard Worker}
71*333d2b36SAndroid Build Coastguard Worker
72*333d2b36SAndroid Build Coastguard Workerdo_strip_keep_symbol_list() {
73*333d2b36SAndroid Build Coastguard Worker    echo "${symbols_to_keep}" | tr ',' '\n' > "${outfile}.symbolList"
74*333d2b36SAndroid Build Coastguard Worker
75*333d2b36SAndroid Build Coastguard Worker    KEEP_SYMBOLS="--strip-unneeded-symbol=* --keep-symbols="
76*333d2b36SAndroid Build Coastguard Worker    KEEP_SYMBOLS+="${outfile}.symbolList"
77*333d2b36SAndroid Build Coastguard Worker    "${CLANG_BIN}/llvm-objcopy" -w "${infile}" "${outfile}.tmp" ${KEEP_SYMBOLS}
78*333d2b36SAndroid Build Coastguard Worker}
79*333d2b36SAndroid Build Coastguard Worker
80*333d2b36SAndroid Build Coastguard Workerdo_strip_keep_mini_debug_info_darwin() {
81*333d2b36SAndroid Build Coastguard Worker    rm -f "${outfile}.dynsyms" "${outfile}.funcsyms" "${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo" "${outfile}.mini_debuginfo.xz"
82*333d2b36SAndroid Build Coastguard Worker    local fail=
83*333d2b36SAndroid Build Coastguard Worker    "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes --remove-section=.comment "${infile}" -o "${outfile}.tmp" || fail=true
84*333d2b36SAndroid Build Coastguard Worker
85*333d2b36SAndroid Build Coastguard Worker    if [ -z $fail ]; then
86*333d2b36SAndroid Build Coastguard Worker        "${CLANG_BIN}/llvm-objcopy" --only-keep-debug "${infile}" "${outfile}.debug"
87*333d2b36SAndroid Build Coastguard Worker        "${CLANG_BIN}/llvm-nm" -D "${infile}" --format=posix --defined-only 2> /dev/null | awk '{ print $1 }' | sort >"${outfile}.dynsyms"
88*333d2b36SAndroid Build Coastguard Worker        "${CLANG_BIN}/llvm-nm" "${infile}" --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t" || $2 == "D") print $1 }' | sort > "${outfile}.funcsyms"
89*333d2b36SAndroid Build Coastguard Worker        comm -13 "${outfile}.dynsyms" "${outfile}.funcsyms" > "${outfile}.keep_symbols"
90*333d2b36SAndroid Build Coastguard Worker        echo >> "${outfile}.keep_symbols" # Ensure that the keep_symbols file is not empty.
91*333d2b36SAndroid Build Coastguard Worker        "${CLANG_BIN}/llvm-objcopy" -S --keep-section .debug_frame --keep-symbols="${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo"
92*333d2b36SAndroid Build Coastguard Worker        "${XZ}" --keep --block-size=64k --threads=0 "${outfile}.mini_debuginfo"
93*333d2b36SAndroid Build Coastguard Worker
94*333d2b36SAndroid Build Coastguard Worker        "${CLANG_BIN}/llvm-objcopy" --add-section .gnu_debugdata="${outfile}.mini_debuginfo.xz" "${outfile}.tmp"
95*333d2b36SAndroid Build Coastguard Worker        rm -f "${outfile}.dynsyms" "${outfile}.funcsyms" "${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo" "${outfile}.mini_debuginfo.xz"
96*333d2b36SAndroid Build Coastguard Worker    else
97*333d2b36SAndroid Build Coastguard Worker        cp -f "${infile}" "${outfile}.tmp"
98*333d2b36SAndroid Build Coastguard Worker    fi
99*333d2b36SAndroid Build Coastguard Worker}
100*333d2b36SAndroid Build Coastguard Worker
101*333d2b36SAndroid Build Coastguard Workerdo_strip_keep_mini_debug_info_linux() {
102*333d2b36SAndroid Build Coastguard Worker    rm -f "${outfile}.mini_debuginfo.xz"
103*333d2b36SAndroid Build Coastguard Worker    local fail=
104*333d2b36SAndroid Build Coastguard Worker    "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes --remove-section=.comment "${infile}" -o "${outfile}.tmp" || fail=true
105*333d2b36SAndroid Build Coastguard Worker
106*333d2b36SAndroid Build Coastguard Worker    if [ -z $fail ]; then
107*333d2b36SAndroid Build Coastguard Worker        # create_minidebuginfo has issues with compressed debug sections. Just
108*333d2b36SAndroid Build Coastguard Worker        # decompress them for now using objcopy which understands compressed
109*333d2b36SAndroid Build Coastguard Worker        # debug sections.
110*333d2b36SAndroid Build Coastguard Worker        # b/306150780 tracks supporting this directly in create_minidebuginfo
111*333d2b36SAndroid Build Coastguard Worker        decompressed="$(mktemp)"
112*333d2b36SAndroid Build Coastguard Worker        "${CLANG_BIN}/llvm-objcopy" --decompress-debug-sections \
113*333d2b36SAndroid Build Coastguard Worker                "${infile}" "${decompressed}"
114*333d2b36SAndroid Build Coastguard Worker
115*333d2b36SAndroid Build Coastguard Worker        "${CREATE_MINIDEBUGINFO}" "${decompressed}" "${outfile}.mini_debuginfo.xz"
116*333d2b36SAndroid Build Coastguard Worker        "${CLANG_BIN}/llvm-objcopy" --add-section .gnu_debugdata="${outfile}.mini_debuginfo.xz" "${outfile}.tmp"
117*333d2b36SAndroid Build Coastguard Worker        rm -f "${outfile}.mini_debuginfo.xz" "${decompressed}"
118*333d2b36SAndroid Build Coastguard Worker    else
119*333d2b36SAndroid Build Coastguard Worker        cp -f "${infile}" "${outfile}.tmp"
120*333d2b36SAndroid Build Coastguard Worker    fi
121*333d2b36SAndroid Build Coastguard Worker}
122*333d2b36SAndroid Build Coastguard Worker
123*333d2b36SAndroid Build Coastguard Workerdo_strip_keep_mini_debug_info() {
124*333d2b36SAndroid Build Coastguard Worker  case $(uname) in
125*333d2b36SAndroid Build Coastguard Worker      Linux)
126*333d2b36SAndroid Build Coastguard Worker          do_strip_keep_mini_debug_info_linux
127*333d2b36SAndroid Build Coastguard Worker          ;;
128*333d2b36SAndroid Build Coastguard Worker      Darwin)
129*333d2b36SAndroid Build Coastguard Worker          do_strip_keep_mini_debug_info_darwin
130*333d2b36SAndroid Build Coastguard Worker          ;;
131*333d2b36SAndroid Build Coastguard Worker      *) echo "unknown OS:" $(uname) >&2 && exit 1;;
132*333d2b36SAndroid Build Coastguard Worker  esac
133*333d2b36SAndroid Build Coastguard Worker}
134*333d2b36SAndroid Build Coastguard Worker
135*333d2b36SAndroid Build Coastguard Workerdo_add_gnu_debuglink() {
136*333d2b36SAndroid Build Coastguard Worker    "${CLANG_BIN}/llvm-objcopy" --add-gnu-debuglink="${infile}" "${outfile}.tmp"
137*333d2b36SAndroid Build Coastguard Worker}
138*333d2b36SAndroid Build Coastguard Worker
139*333d2b36SAndroid Build Coastguard Workerdo_remove_build_id() {
140*333d2b36SAndroid Build Coastguard Worker    "${CLANG_BIN}/llvm-strip" --remove-section=.note.gnu.build-id "${outfile}.tmp" -o "${outfile}.tmp.no-build-id"
141*333d2b36SAndroid Build Coastguard Worker    rm -f "${outfile}.tmp"
142*333d2b36SAndroid Build Coastguard Worker    mv "${outfile}.tmp.no-build-id" "${outfile}.tmp"
143*333d2b36SAndroid Build Coastguard Worker}
144*333d2b36SAndroid Build Coastguard Worker
145*333d2b36SAndroid Build Coastguard Workerwhile getopts $OPTSTRING opt; do
146*333d2b36SAndroid Build Coastguard Worker    case "$opt" in
147*333d2b36SAndroid Build Coastguard Worker        d) depsfile="${OPTARG}" ;;
148*333d2b36SAndroid Build Coastguard Worker        i) infile="${OPTARG}" ;;
149*333d2b36SAndroid Build Coastguard Worker        o) outfile="${OPTARG}" ;;
150*333d2b36SAndroid Build Coastguard Worker        k) symbols_to_keep="${OPTARG}" ;;
151*333d2b36SAndroid Build Coastguard Worker        -)
152*333d2b36SAndroid Build Coastguard Worker            case "${OPTARG}" in
153*333d2b36SAndroid Build Coastguard Worker                add-gnu-debuglink) add_gnu_debuglink=true ;;
154*333d2b36SAndroid Build Coastguard Worker                keep-mini-debug-info) keep_mini_debug_info=true ;;
155*333d2b36SAndroid Build Coastguard Worker                keep-symbols) keep_symbols=true ;;
156*333d2b36SAndroid Build Coastguard Worker                keep-symbols-and-debug-frame) keep_symbols_and_debug_frame=true ;;
157*333d2b36SAndroid Build Coastguard Worker                remove-build-id) remove_build_id=true ;;
158*333d2b36SAndroid Build Coastguard Worker                windows) windows=true ;;
159*333d2b36SAndroid Build Coastguard Worker                *) echo "Unknown option --${OPTARG}"; usage ;;
160*333d2b36SAndroid Build Coastguard Worker            esac;;
161*333d2b36SAndroid Build Coastguard Worker        ?) usage ;;
162*333d2b36SAndroid Build Coastguard Worker        *) echo "'${opt}' '${OPTARG}'"
163*333d2b36SAndroid Build Coastguard Worker    esac
164*333d2b36SAndroid Build Coastguard Workerdone
165*333d2b36SAndroid Build Coastguard Worker
166*333d2b36SAndroid Build Coastguard Workerif [ -z "${infile}" ]; then
167*333d2b36SAndroid Build Coastguard Worker    echo "-i argument is required"
168*333d2b36SAndroid Build Coastguard Worker    usage
169*333d2b36SAndroid Build Coastguard Workerfi
170*333d2b36SAndroid Build Coastguard Worker
171*333d2b36SAndroid Build Coastguard Workerif [ -z "${outfile}" ]; then
172*333d2b36SAndroid Build Coastguard Worker    echo "-o argument is required"
173*333d2b36SAndroid Build Coastguard Worker    usage
174*333d2b36SAndroid Build Coastguard Workerfi
175*333d2b36SAndroid Build Coastguard Worker
176*333d2b36SAndroid Build Coastguard Workerif [ -z "${depsfile}" ]; then
177*333d2b36SAndroid Build Coastguard Worker    echo "-d argument is required"
178*333d2b36SAndroid Build Coastguard Worker    usage
179*333d2b36SAndroid Build Coastguard Workerfi
180*333d2b36SAndroid Build Coastguard Worker
181*333d2b36SAndroid Build Coastguard Workerif [ ! -z "${keep_symbols}" -a ! -z "${keep_mini_debug_info}" ]; then
182*333d2b36SAndroid Build Coastguard Worker    echo "--keep-symbols and --keep-mini-debug-info cannot be used together"
183*333d2b36SAndroid Build Coastguard Worker    usage
184*333d2b36SAndroid Build Coastguard Workerfi
185*333d2b36SAndroid Build Coastguard Worker
186*333d2b36SAndroid Build Coastguard Workerif [ ! -z "${keep_symbols}" -a ! -z "${keep_symbols_and_debug_frame}" ]; then
187*333d2b36SAndroid Build Coastguard Worker    echo "--keep-symbols and --keep-symbols-and-debug-frame cannot be used together"
188*333d2b36SAndroid Build Coastguard Worker    usage
189*333d2b36SAndroid Build Coastguard Workerfi
190*333d2b36SAndroid Build Coastguard Worker
191*333d2b36SAndroid Build Coastguard Workerif [ ! -z "${keep_mini_debug_info}" -a ! -z "${keep_symbols_and_debug_frame}" ]; then
192*333d2b36SAndroid Build Coastguard Worker    echo "--keep-symbols-mini-debug-info and --keep-symbols-and-debug-frame cannot be used together"
193*333d2b36SAndroid Build Coastguard Worker    usage
194*333d2b36SAndroid Build Coastguard Workerfi
195*333d2b36SAndroid Build Coastguard Worker
196*333d2b36SAndroid Build Coastguard Workerif [ ! -z "${symbols_to_keep}" -a ! -z "${keep_symbols}" ]; then
197*333d2b36SAndroid Build Coastguard Worker    echo "--keep-symbols and -k cannot be used together"
198*333d2b36SAndroid Build Coastguard Worker    usage
199*333d2b36SAndroid Build Coastguard Workerfi
200*333d2b36SAndroid Build Coastguard Worker
201*333d2b36SAndroid Build Coastguard Workerif [ ! -z "${add_gnu_debuglink}" -a ! -z "${keep_mini_debug_info}" ]; then
202*333d2b36SAndroid Build Coastguard Worker    echo "--add-gnu-debuglink cannot be used with --keep-mini-debug-info"
203*333d2b36SAndroid Build Coastguard Worker    usage
204*333d2b36SAndroid Build Coastguard Workerfi
205*333d2b36SAndroid Build Coastguard Worker
206*333d2b36SAndroid Build Coastguard Workerrm -f "${outfile}.tmp"
207*333d2b36SAndroid Build Coastguard Worker
208*333d2b36SAndroid Build Coastguard Workerif [ ! -z "${keep_symbols}" ]; then
209*333d2b36SAndroid Build Coastguard Worker    do_strip_keep_symbols
210*333d2b36SAndroid Build Coastguard Workerelif [ ! -z "${symbols_to_keep}" ]; then
211*333d2b36SAndroid Build Coastguard Worker    do_strip_keep_symbol_list
212*333d2b36SAndroid Build Coastguard Workerelif [ ! -z "${keep_mini_debug_info}" ]; then
213*333d2b36SAndroid Build Coastguard Worker    do_strip_keep_mini_debug_info
214*333d2b36SAndroid Build Coastguard Workerelif [ ! -z "${keep_symbols_and_debug_frame}" ]; then
215*333d2b36SAndroid Build Coastguard Worker    do_strip_keep_symbols_and_debug_frame
216*333d2b36SAndroid Build Coastguard Workerelse
217*333d2b36SAndroid Build Coastguard Worker    do_strip
218*333d2b36SAndroid Build Coastguard Workerfi
219*333d2b36SAndroid Build Coastguard Worker
220*333d2b36SAndroid Build Coastguard Workerif [ ! -z "${add_gnu_debuglink}" ]; then
221*333d2b36SAndroid Build Coastguard Worker    do_add_gnu_debuglink
222*333d2b36SAndroid Build Coastguard Workerfi
223*333d2b36SAndroid Build Coastguard Worker
224*333d2b36SAndroid Build Coastguard Workerif [ ! -z "${remove_build_id}" ]; then
225*333d2b36SAndroid Build Coastguard Worker    do_remove_build_id
226*333d2b36SAndroid Build Coastguard Workerfi
227*333d2b36SAndroid Build Coastguard Worker
228*333d2b36SAndroid Build Coastguard Workerrm -f "${outfile}"
229*333d2b36SAndroid Build Coastguard Workermv "${outfile}.tmp" "${outfile}"
230*333d2b36SAndroid Build Coastguard Worker
231*333d2b36SAndroid Build Coastguard Workercat <<EOF > "${depsfile}"
232*333d2b36SAndroid Build Coastguard Worker${outfile}: \
233*333d2b36SAndroid Build Coastguard Worker  ${infile} \
234*333d2b36SAndroid Build Coastguard Worker  ${CLANG_BIN}/llvm-nm \
235*333d2b36SAndroid Build Coastguard Worker  ${CLANG_BIN}/llvm-objcopy \
236*333d2b36SAndroid Build Coastguard Worker  ${CLANG_BIN}/llvm-readelf \
237*333d2b36SAndroid Build Coastguard Worker  ${CLANG_BIN}/llvm-strip
238*333d2b36SAndroid Build Coastguard Worker
239*333d2b36SAndroid Build Coastguard WorkerEOF
240