blob: d97a33642d3a19da93f61f517e92fed66387ef08 [file] [log] [blame]
Hanno Becker43fa8d62019-03-18 17:12:05 +00001#!/bin/sh
2
3# baremetal.sh
4#
5# This file is part of mbed TLS (https://tls.mbed.org)
6#
7# Copyright (c) 2019, ARM Limited, All Rights Reserved
8#
9# Purpose
10#
11# * Create a baremetal library-only build (omitting the tests and
12# example programs, which have stronger configuration requirements)
13# for a Cortex-M target in a minimal configuration, and generate
14# code-size statistics.
15# By default, the script uses configs/baremetal.h and targets Cortex-M0+,
16# and outputs the code-size statistics as `rom.COMMIT_HASH`.
17#
18# * Create a 32-bit host-build of library, tests and example programs
19# in a 'baremetal' base configuration minimally modified to allow
20# running tests and example programs, and obtain heap usage statistics
21# of a test run of ssl_client2 and ssl_server2. This can be used as
22# an estimate for heap usage of 32-bit baremetal applications using Mbed TLS.
23#
24# By default, the script uses configs/baremetal.h as the base configuration
25# modified by configs/baremetal_test.h, and emits the heap usage statistics
26# as `massif.COMMIT_HASH`.
27#
28
29set -eu
30
31if [ -d include/mbedtls ]; then :; else
32 echo "$0: must be run from root" >&2
33 exit 1
34fi
35
36if grep -i cmake Makefile >/dev/null; then
37 echo "$0: not compatible with cmake" >&2
38 exit 1
39fi
40
41# The 'baremetal' configuration to test
42: ${BAREMETAL_CONFIG:=./configs/baremetal.h}
43CFLAGS_CONFIG="-DMBEDTLS_CONFIG_FILE='\"../$BAREMETAL_CONFIG\"'"
44
45# The modifications to the 'baremetal' configuration which allows
46# tests and example programs to build and execute.
47: ${BAREMETAL_USER_CONFIG:=./configs/baremetal_test.h}
48CFLAGS_USER_CONFIG="-DMBEDTLS_USER_CONFIG_FILE='\"../$BAREMETAL_USER_CONFIG\"'"
49
50: ${ARMC5_BIN_DIR:=""}
51: ${ARMC6_BIN_DIR:=""}
52if [ -n "$ARMC5_BIN_DIR" ]; then
53 ARMC5_BIN_DIR="$ARMC5_BIN_DIR/"
54fi
55
56if [ -n "$ARMC6_BIN_DIR" ]; then
57 ARMC6_BIN_DIR="$ARMC6_BIN_DIR/"
58fi
59
60: ${NAME:=$(git rev-parse HEAD)}
61: ${GCC_CC:=arm-none-eabi-gcc}
62: ${GCC_AR:=arm-none-eabi-ar}
63: ${ARMC6_CC:="${ARMC6_BIN_DIR}armclang"}
64: ${ARMC6_AR:="${ARMC6_BIN_DIR}armar"}
65: ${ARMC5_CC:="${ARMC5_BIN_DIR}armcc"}
66: ${ARMC5_AR:="${ARMC5_BIN_DIR}armar"}
67
68date=$( date +%Y-%m-%d-%H-%M-%S )
69
70baremetal_build_gcc()
71{
72 echo "Cleanup..."
73 make clean
74
75 echo "Create 32-bit library-only baremetal build (GCC, config: $BAREMETAL_CONFIG)"
76 gcc_ver=$($GCC_CC --version | head -n 1 | sed -n 's/^.*\([0-9]\.[0-9]\.[0-9]\).*$/\1/p')
77
78 CFLAGS_BAREMETAL="-Os -mthumb -mcpu=cortex-m0plus"
79 CFLAGS="$CFLAGS_BAREMETAL $CFLAGS_CONFIG"
80
81 $GCC_CC --version
82
83 echo "GCC version: $gcc_ver"
84 echo "Flags: $CFLAGS_BAREMETAL"
85 make CC=$GCC_CC AR=$GCC_AR CFLAGS="$CFLAGS" lib -j > /dev/null
86
87 ROM_OUT_FILE="rom_files__${date}__${NAME}__gcc_${gcc_ver}"
88 ROM_OUT_SYMS="rom_syms__${date}__${NAME}__gcc_${gcc_ver}"
89 echo "Generate file statistics..."
90 ./scripts/generate_codesize_stats.sh --info "gcc_${gcc_ver}" --name $NAME --files > $ROM_OUT_FILE
91 echo "Generate symbol statistics..."
92 ./scripts/generate_codesize_stats.sh --info "gcc_${gcc_ver}" --name $NAME --syms > $ROM_OUT_SYMS
93
94 echo "ROM statistics written to:"
95 echo "* $ROM_OUT_FILE"
96 echo "* $ROM_OUT_SYMS"
97}
98
99baremetal_build_armc5()
100{
101 echo "Cleanup..."
102 make clean
103
104 echo "Create 32-bit library-only baremetal build (ARMC5, Config: $BAREMETAL_CONFIG)"
105 armc5_ver=$($ARMC5_CC | sed -n 's/.*ARM Compiler \([^ ]*\)$/\1/p')
106
107 CFLAGS_BAREMETAL="-Ospace --thumb --cpu Cortex-m0plus"
108 CFLAGS="$CFLAGS_BAREMETAL $CFLAGS_CONFIG"
109 WARNING_CFLAGS="--strict --c99"
110
111 echo "ARMC5 version: $armc5_ver"
112 echo "Flags: $WARNING_CFLAGS $CFLAGS_BAREMETAL"
113 make WARNING_CFLAGS="$WARNING_CFLAGS" CC=$ARMC5_CC AR=$ARMC5_AR CFLAGS="$CFLAGS" lib -j > /dev/null
114
115 ROM_OUT_FILE="rom_files__${date}__${NAME}__armc5_${armc5_ver}"
116 ROM_OUT_SYMS="rom_syms__${date}__${NAME}__armc5_${armc5_ver}"
117 echo "Generate file statistics..."
118 ./scripts/generate_codesize_stats.sh --info "armc5_${armc5_ver}" --name $NAME --files > $ROM_OUT_FILE
119 echo "Generate symbol statistics..."
120 ./scripts/generate_codesize_stats.sh --info "armc5_${armc5_ver}" --name $NAME --syms > $ROM_OUT_SYMS
121
122 echo "ROM statistics written to:"
123 echo "* $ROM_OUT_FILE"
124 echo "* $ROM_OUT_SYMS"
125}
126
127baremetal_build_armc6()
128{
129 echo "Cleanup..."
130 make clean
131
132 echo "Create 32-bit library-only baremetal build (ARMC6, Config: $BAREMETAL_CONFIG)"
133 armc6_ver=$($ARMC6_CC --version | sed -n 's/.*ARM Compiler \([^ ]*\)$/\1/p')
134
135 CFLAGS_BAREMETAL="-Os --target=arm-arm-none-eabi -mthumb -mcpu=cortex-m0plus"
136 CFLAGS="$CFLAGS_BAREMETAL $CFLAGS_CONFIG"
137 WARNING_CFLAGS="-xc -std=c99"
138
139 echo "ARMC6 version: $armc6_ver"
140 echo "Flags: $WARNING_CFLAGS $CFLAGS_BAREMETAL"
141 make WARNING_CFLAGS="$WARNING_CFLAGS" CC=$ARMC6_CC AR=$ARMC6_AR CFLAGS="$CFLAGS" lib -j > /dev/null
142
143 ROM_OUT_FILE="rom_files__${date}__${NAME}__armc6_${armc6_ver}"
144 ROM_OUT_SYMS="rom_syms__${date}__${NAME}__armc6_${armc6_ver}"
145 echo "Generate file statistics..."
146 ./scripts/generate_codesize_stats.sh --info "armc6_${armc6_ver}" --name $NAME --files > $ROM_OUT_FILE
147 echo "Generate symbol statistics..."
148 ./scripts/generate_codesize_stats.sh --info "armc6_${armc6_ver}" --name $NAME --syms > $ROM_OUT_SYMS
149
150 echo "ROM statistics written to:"
151 echo "* $ROM_OUT_FILE"
152 echo "* $ROM_OUT_SYMS"
153}
154
155# 32-bit host-build of library, tests and example programs,
156# + heap usage measurements.
157baremetal_ram_build() {
158 : ${BASE_CFLAGS:="-g -m32"}
159 echo "Create 32-bit host-build (Config: $BAREMETAL_CONFIG + $BAREMETAL_USER_CONFIG)"
160
161 echo "Cleanup..."
162 make clean
163
164 CFLAGS="$BASE_CFLAGS $CFLAGS_CONFIG $CFLAGS_USER_CONFIG"
165
166 echo "Modifications: $BAREMETAL_USER_CONFIG"
167 cat $BAREMETAL_USER_CONFIG | grep "^#define" | awk '{print "* " $0 }'
168
169 echo "Build (flags: $CFLAGS)..."
170 make CFLAGS="$CFLAGS" -j > /dev/null
171 echo ""
172}
173
174baremetal_ram_heap() {
175
176 : ${CLI:=./programs/ssl/ssl_client2}
177 : ${CLI_PARAMS:="dtls=1"}
178 : ${SRV:=./programs/ssl/ssl_server2}
179 : ${SRV_PARAMS:="dtls=1 renegotiation=1 auth_mode=required"}
180 : ${VALGRIND:=valgrind}
181 : ${VALGRIND_MASSIF_PARAMS="--time-unit=B --threshold=0.01 --detailed-freq=1"}
182
183 if [ $1 -eq 1 ]; then
184 RAM_HEAP_OUT="ram_heap_stack__${date}__$NAME"
185 VALGRIND_MASSIF_PARAMS="--stacks=yes $VALGRIND_MASSIF_PARAMS"
186 else
187 RAM_HEAP_OUT="ram_heap__${date}__$NAME"
188 fi
189
190 SRV_CMD="$SRV server_addr=127.0.0.1 server_port=4433 debug_level=4 $SRV_PARAMS"
191 CLI_CMD="$CLI server_addr=127.0.0.1 server_port=4433 $CLI_PARAMS"
192
193 # Piece together valgrind cmd line
194 VALGRIND_BASE="$VALGRIND --tool=massif $VALGRIND_MASSIF_PARAMS"
195
196 FUNC_IGNORE=""
197 FUNC_IGNORE="mbedtls_ssl_setup $FUNC_IGNORE"
198 FUNC_IGNORE="mbedtls_mpi_grow $FUNC_IGNORE"
199 FUNC_IGNORE="mbedtls_mpi_shrink $FUNC_IGNORE"
200 FUNC_IGNORE="ecp_mul_comb $FUNC_IGNORE"
201 FUNC_IGNORE="mbedtls_ecp_mul_restartable $FUNC_IGNORE"
202 FUNC_IGNORE="ecp_normalize_jac_many $FUNC_IGNORE"
203 FUNC_IGNORE="__fopen_internal $FUNC_IGNORE"
204 FUNC_IGNORE="_IO_file_doallocate $FUNC_IGNORE"
205 FUNC_IGNORE="strdup $FUNC_IGNORE"
206 FUNC_IGNORE="__tzstring_len $FUNC_IGNORE"
207 FUNC_IGNORE="__tzfile_read $FUNC_IGNORE"
208
209 VALGRIND_IGNORE=""
210 for func in $FUNC_IGNORE; do
211 echo "* Valgrind ignore: $func"
212 VALGRIND_IGNORE="--ignore-fn=$func $VALGRIND_IGNORE"
213 done
214
215 VALGRIND_CMD="$VALGRIND_BASE $VALGRIND_IGNORE --massif-out-file=${RAM_HEAP_OUT} -- $CLI_CMD"
216
217 $SRV_CMD > /dev/null 2>&1 &
218 SRV_PID=$!
219 echo "Server started, PID $SRV_PID"
220
221 $VALGRIND_CMD > /dev/null 2>&1 &
222 VAL_PID=$!
223 echo "Valgrind massif started, PID $VAL_PID"
224
225 wait $VAL_PID
226 echo "Valgrind done, killing server"
227 kill $SRV_PID
228 echo "Done"
229
230 if `cat $RAM_HEAP_OUT | grep '???'` >/dev/null 2>&1; then
231 echo "Warning: Unrecognized symbols in massif output file - does your version of `valgrind` support 32-bit builds?"
232 fi
233
234 printf "Max heap usage: "
235 ./scripts/massif_max.pl $RAM_HEAP_OUT
236 echo "SUCCESS - Heap usage statistics written to: $RAM_HEAP_OUT\n"
237}
238
239baremetal_ram_stack() {
240 : ${CLI:=./programs/ssl/ssl_client2}
241 : ${CLI_PARAMS:="dtls=1"}
242 : ${SRV:=./programs/ssl/ssl_server2}
243 : ${SRV_PARAMS:="dtls=1 renegotiation=1 auth_mode=required"}
244 : ${VALGRIND:=valgrind}
245 : ${VALGRIND_CALLGRIND_PARAMS:="--separate-callers=100"}
246
247 RAM_STACK_OUT="ram_stack__${date}__$NAME"
248
249 SRV_CMD="$SRV server_addr=127.0.0.1 server_port=4433 debug_level=4 $SRV_PARAMS"
250 CLI_CMD="$CLI server_addr=127.0.0.1 server_port=4433 $CLI_PARAMS"
251
252 VALGRIND_BASE="$VALGRIND --tool=callgrind $VALGRIND_CALLGRIND_PARAMS"
253 VALGRIND_CMD="$VALGRIND_BASE --callgrind-out-file=${RAM_STACK_OUT} $CLI_CMD"
254
255 $SRV_CMD > /dev/null 2>&1 &
256 SRV_PID=$!
257 echo "Server started, PID $SRV_PID"
258
259 $VALGRIND_CMD > /dev/null 2>&1 &
260 VAL_PID=$!
261 echo "Valgrind callgrind started, PID $VAL_PID"
262
263 wait $VAL_PID
264 echo "Valgrind done, killing server"
265 kill $SRV_PID
266 echo "Done"
267
268 echo "SUCCESS - Stack usage statistics written to: $RAM_STACK_OUT\n"
269}
270
271show_usage() {
272 echo "Usage: $0 [--rom [--gcc|--armc5|--armc6]|--ram]"
273}
274
275test_build=0
276raw_build=0
277
278build_gcc=0
279build_armc5=0
280build_armc6=0
281
282measure_heap=0
283measure_stack=0
284
285while [ $# -gt 0 ]; do
286 case "$1" in
287 --gcc) build_gcc=1;;
288 --armc5) build_armc5=1;;
289 --armc6) build_armc6=1;;
290 --ram) test_build=1;;
291 --rom) raw_build=1;;
292 --heap) measure_heap=1;;
293 --stack) measure_stack=1;;
294 -*)
295 echo >&2 "Unknown option: $1"
296 show_usage
297 exit 1
298 ;;
299 esac
300 shift
301done
302
303if [ "$test_build" -eq 0 ] &&
304 [ "$raw_build" -eq 0 ]; then
305 echo "Need to set either --ram or --rom"
306 show_usage
307 exit 1
308fi
309
310if [ "$test_build" -eq 1 ]; then
311
312 if [ "$measure_heap" -eq 0 ] &&
313 [ "$measure_stack" -eq 0 ]; then
314 echo "Need to set either --heap or --stack with --ram"
315 show_usage
316 exit 1
317 fi
318
319 baremetal_ram_build
320
321 if [ "$measure_heap" -eq 1 ]; then
322 baremetal_ram_heap 0
323 baremetal_ram_heap 1
324 fi
325
326 if [ "$measure_stack" -eq 1 ]; then
327 baremetal_ram_stack
328 fi
329
330fi
331
332if [ "$raw_build" -eq 1 ]; then
333
334 if [ "$build_gcc" -eq 0 ] &&
335 [ "$build_armc5" -eq 0 ] &&
336 [ "$build_armc6" -eq 0 ]; then
337 echo "Need to set either --gcc, --armc5 or --armc6 with --rom"
338 show_usage
339 exit 1
340 fi
341
342 if [ "$build_gcc" -eq 1 ]; then
343 baremetal_build_gcc
344 fi
345 if [ "$build_armc5" -eq 1 ]; then
346 baremetal_build_armc5
347 fi
348 if [ "$build_armc6" -eq 1 ]; then
349 baremetal_build_armc6
350 fi
351fi