• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2# Copyright (c) 2022 Huawei Device Co., Ltd.
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15set -e
16
17TOPDIR=$(realpath "$(dirname ${BASH_SOURCE[0]})/../../../")
18
19PATH="${TOPDIR}/prebuilts/build-tools/linux-x86/bin/:${TOPDIR}/prebuilts/python/linux-x86/current/bin/:${PATH}"
20
21command -v jq &>/dev/null || { echo >&2 "jq command not found, please install by: apt install -y jq"; exit 1; }
22command -v ninja &>/dev/null || { echo >&2 "ninja command not found, please install by: apt install -y ninja-build"; exit 1; }
23
24args=()
25cfg_groups=()
26build_variant=root
27asan_in_data=true
28while test $# -gt 0; do
29    case "$1" in
30    -g[0-9]:*)
31        cfg_groups+=(${1:2})
32        ;;
33    --gn-args)
34        case "$2" in
35        is_asan=*);;
36        *)args+=("$1" "$2");;
37        esac
38        shift
39        ;;
40    --build-variant)
41        build_variant=$2
42        shift
43        ;;
44    --no-build)
45        no_build=true
46        ;;
47    --no-data-asan)
48        asan_in_data=false
49        ;;
50    --data-asan)
51        asan_in_data=true
52        ;;
53    *)
54        args+=("$1")
55        ;;
56    esac
57    shift
58done
59
60extra_args=(
61    --build-variant ${build_variant}
62    --disable-package-image
63    --disable-part-of-post-build output_part_rom_status
64    --disable-part-of-post-build get_warning_list
65    --disable-part-of-post-build compute_overlap_rate
66    --gn-args asan_detector=true
67    --gn-args skip_generate_module_list_file=true
68    --gn-args enable_notice_collection=false
69    # --gn-args enable_lto_O0=true
70    # --gn-args load_test_config=false
71)
72set -e -- "${extra_args[@]}" "${args[@]}"
73
74# build both asan and nonasan images
75start_time=$(date +%s)
76cd "${TOPDIR}"
77if [ -d out.a ]; then
78    if [ -d out ]; then
79        mv out out.n
80    fi
81    mv out.a out
82fi
83${no_build+echo skip} ./build.sh "$@" --gn-args is_asan=true --gn-args asan_detector=true --gn-args use_thin_lto=false --gn-args ohos_extra_cppflags="-fno-lto" --keep-ninja-going --gn-args ohos_extra_cxxflags="-fno-whole-program-vtables" --gn-args ohos_extra_cflags="-fno-whole-program-vtables"
84step1_time=$(date +%s)
85mv out out.a
86if [ -d out.n ]; then
87    mv out.n out
88fi
89${no_build+echo skip} ./build.sh "$@" --gn-args is_asan=false --gn-args asan_detector=true
90step2_time=$(date +%s)
91
92
93asan_dir=$(ls -d out.a/*/packages/phone/)
94nonasan_dir=$(ls -d out/*/packages/phone/)
95
96asan_dir=$(realpath "$asan_dir")
97nonasan_dir=$(realpath "$nonasan_dir")
98
99echo "asan dir is $asan_dir"
100echo "non-asan dir is $nonasan_dir"
101
102# check directories
103for d in {"$asan_dir","$nonasan_dir"}/{system,vendor,data} ; do
104    if [ ! -d "$d" ]; then
105        echo "directory '$d' does not exist."
106        exit 1
107    fi
108done
109
110# following works should all be done in nonasan dir
111pushd "$nonasan_dir"
112
113handle_error() {
114    errcode=$?
115    trap '' INT HUP
116    set +e
117    if [ $errcode -ne 0 ]; then
118        pushd "$nonasan_dir"
119        test -d system.bak && rm -rf system && mv system.bak system
120        test -d vendor.bak && rm -rf vendor && mv vendor.bak vendor
121        test -d images.bak && rm -rf images && mv images.bak images
122        test -f "${TOPDIR}"/build/ohos/images/build_image.py.bak && mv "$_" "${_%.bak}"
123        test -f "${TOPDIR}"/build/ohos/images/mkimage/dac.txt.bak && mv "$_" "${_%.bak}"
124    fi
125    command -v handle_error_hook && handle_error_hook $errcode "$@"
126    exit $errcode
127}
128trap 'handle_error "${args[@]}"' EXIT
129
130# get make image command
131json_data="$(ninja -w dupbuild=warn -C ../../ -t compdb | jq '.[]|select(.output|startswith("packages/phone/images/"))')"
132make_system_img_cmd="$(echo "$json_data" | jq -r 'select(.output=="packages/phone/images/system.img")|.command')"
133make_vendor_img_cmd="$(echo "$json_data" | jq -r 'select(.output=="packages/phone/images/vendor.img")|.command')"
134make_userdata_img_cmd="$(echo "$json_data" | jq -r 'select(.output=="packages/phone/images/userdata.img")|.command')"
135make_system_img() { pushd ../../; $make_system_img_cmd; popd; }
136make_vendor_img() { pushd ../../; $make_vendor_img_cmd; popd; }
137make_userdata_img() { pushd ../../; $make_userdata_img_cmd; popd; }
138
139make_mixed_asan_img() {
140    echo "make mixed asan system$1.img or/and vendor$1.img ..."
141    cfg_group=(${@:2})
142
143    # backup system and vendor
144    mv system system.bak && cp -a system.bak system
145    mv vendor vendor.bak && cp -a vendor.bak vendor
146
147    # prepare asan related files for system image
148    cp -a "$asan_dir"/system/etc/asan.options system/etc/
149    cp -a "$asan_dir"/system/etc/init/asan.cfg system/etc/init/
150    cp -a "$asan_dir"/system/lib/ld-musl-*-asan.so.1 system/lib/
151    if grep -qw LD_PRELOAD system/etc/init/faultloggerd.cfg; then
152        sed -i '/LD_PRELOAD/d' system/etc/init/asan.cfg
153        sed -i 's/LD_PRELOAD\s\+/&libasan_helper.z.so:/g' system/etc/init/faultloggerd.cfg
154    fi
155    test -f system/etc/selinux/config && sed -i 's,enforcing,permissive,g' $_
156    sed -i '/^\s*namespace.default.asan.lib.paths\s*=/d;s/^\(\s*namespace.default.\)\(lib.paths\s*=.*\)$/&\n\1asan.\2/g' system/etc/ld-musl-namespace-*.ini
157    sed -i '/^\s*namespace.default.asan.lib.paths\s*=/s/\/\(system\|vendor\)\/\([^:]*:\?\)/\/\1\/asan\/\2/g' system/etc/ld-musl-namespace-*.ini
158    if [ "$asan_in_data" = true ]; then
159        for d in data/asan/*; do ln -snf /$d ${d#data/asan/}/asan; done
160    else
161        mkdir -p system/asan/ && cp -a "$asan_dir"/system/{lib*,bin} $_
162        mkdir -p vendor/asan/ && cp -a "$asan_dir"/vendor/{lib*,bin} $_
163        sed -i.bak '$asystem/asan/bin/*, 00755, 0, 2000, 0\nvendor/asan/bin/*, 00755, 0, 2000, 0' "${TOPDIR}"/build/ohos/images/mkimage/dac.txt
164    fi
165
166    # make some services run in asan version
167    local -A make_images
168    for f in ${cfg_group[@]}; do
169        for cfg in {system,vendor}/etc/init/$f.cfg*; do
170            echo -e "\033[35mModifying service cfg: $cfg\033[0m"
171            sed -i 's,/bin/,/asan&,g;/"critical"/d' $cfg
172            make_images[${cfg::6}]=true
173        done
174    done
175
176    command -v make_mixed_asan_img_hook && make_mixed_asan_img_hook "$@"
177
178    # make image
179    if [ "${make_images[system]}" = true -o $# -eq 0 ]; then
180        make_system_img
181        mv images/system.img system${1}.img
182    fi
183    if [ "${make_images[vendor]}" = true -o $# -eq 0 ]; then
184        make_vendor_img
185        mv images/vendor.img vendor${1}.img
186    fi
187
188    # restore dac.txt
189    if [ "$asan_in_data" != true ]; then
190        mv "${TOPDIR}"/build/ohos/images/mkimage/dac.txt.bak "${TOPDIR}"/build/ohos/images/mkimage/dac.txt
191    fi
192
193    # restore system and vendor
194    rm -rf system && mv system.bak system
195    rm -rf vendor && mv vendor.bak vendor
196}
197
198add_mkshrc() {
199    sed -i '/export HOME /d' "$asan_dir"/system/etc/init/asan.cfg
200    sed -i '/export ASAN_OPTIONS /i"export HOME /'$1'",' "$asan_dir"/system/etc/init/asan.cfg
201    cat <<EOF >${1:-.}/.mkshrc
202dmesg -n1
203alias ls='ls --color=auto'
204alias ll='ls -al'
205remount() {
206    mount -o remount,rw \${1:-/}
207}
208EOF
209}
210
211make_data_asan_img() {
212    test $asan_in_data = true || return 0
213    echo "make mixed asan userdata.img ..."
214    mkdir -p data/asan/{vendor,system}
215    cp -a "$asan_dir"/vendor/{lib*,bin} data/asan/vendor/
216    cp -a "$asan_dir"/system/{lib*,bin} data/asan/system/
217    chmod +x data/asan/*/bin/*
218    add_mkshrc data/
219    sed -i.bak 's,shutil.rmtree(userdata_path),return,g' "${TOPDIR}"/build/ohos/images/build_image.py
220    sed -i.bak '$adata/asan/*, 00755, 0, 2000, 0' "${TOPDIR}"/build/ohos/images/mkimage/dac.txt
221    make_userdata_img
222    mv "${TOPDIR}"/build/ohos/images/mkimage/dac.txt.bak "${TOPDIR}"/build/ohos/images/mkimage/dac.txt
223    mv "${TOPDIR}"/build/ohos/images/build_image.py.bak "${TOPDIR}"/build/ohos/images/build_image.py
224}
225
226make_custom_asan_imgs() {
227    # backup images
228    mv images images.bak && mkdir images
229
230    # make custom asan images
231    for cfg_group in ${cfg_groups[@]}; do
232        make_mixed_asan_img $(IFS=:,; echo ${cfg_group})
233    done
234
235    # restore images
236    rm -rf images && mv images.bak images
237}
238
239# Collect all necessary artifacts into images directory
240collect_all_artifacts() {
241    # uncomment the following three lines if you need full asan images
242    #rm -rf images/{system,vendor}F.img
243    #cp -l "$asan_dir"/images/system.img images/systemF.img
244    #cp -l "$asan_dir"/images/vendor.img images/vendorF.img
245    # unstripped binaries
246    rm -rf images/unstripped
247    mkdir -p images/unstripped/{asan,nonasan}
248    cp -al "$asan_dir"/../../{exe,lib}.unstripped images/unstripped/asan/
249    cp "$asan_dir"/../../libclang_rt.asan.so images/unstripped/asan/lib.unstripped/
250    cp -al ../../{exe,lib}.unstripped images/unstripped/nonasan/
251    cp system/lib*/libc++.so images/unstripped/nonasan/lib.unstripped/
252    # mixed asan images
253    mv system*.img vendor*.img images/
254}
255
256shopt -s nullglob
257
258make_data_asan_img
259make_mixed_asan_img
260make_custom_asan_imgs
261collect_all_artifacts
262
263step3_time=$(date +%s)
264
265echo -e "\033[32m==== Done! ====\033[0m"
266echo "asan build cost $((${step1_time}-${start_time}))s, nonasan build cost $((${step2_time}-${step1_time}))s, image build cost $((${step3_time}-${step2_time}))s"
267popd
268