1#! /bin/sh 2# 3# SPDX-License-Identifier: BSD-2-Clause 4# 5# Copyright (c) 2018-2021 Gavin D. Howard and contributors. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions are met: 9# 10# * Redistributions of source code must retain the above copyright notice, this 11# list of conditions and the following disclaimer. 12# 13# * Redistributions in binary form must reproduce the above copyright notice, 14# this list of conditions and the following disclaimer in the documentation 15# and/or other materials provided with the distribution. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29 30usage() { 31 printf 'usage: %s [run_tests] [generate_tests] [test_with_clang] [test_with_gcc] \n' "$script" 32 printf ' [run_sanitizers] [run_valgrind] [run_64_bit] [run_gen_script]\n' 33 printf ' [test_c11] [test_128_bit]\n' 34 exit 1 35} 36 37header() { 38 39 _header_msg="$1" 40 shift 41 42 printf '\n' 43 printf '*******************\n' 44 printf "$_header_msg" 45 printf '\n' 46 printf '*******************\n' 47 printf '\n' 48} 49 50do_make() { 51 make -j16 "$@" 52} 53 54configure() { 55 56 _configure_CFLAGS="$1" 57 shift 58 59 _configure_CC="$1" 60 shift 61 62 _configure_configure_flags="$1" 63 shift 64 65 _configure_GEN_HOST="$1" 66 shift 67 68 _configure_LONG_BIT="$1" 69 shift 70 71 if [ "$gen_tests" -eq 0 ]; then 72 _configure_configure_flags="-G $_configure_configure_flags" 73 fi 74 75 if [ "$_configure_CC" = "clang" ]; then 76 _configure_CFLAGS="$clang_flags $_configure_CFLAGS" 77 elif [ "$_configure_CC" = "gcc" ]; then 78 _configure_CFLAGS="$gcc_flags $_configure_CFLAGS" 79 fi 80 81 _configure_header=$(printf 'Running ./configure.sh %s ...' "$_configure_configure_flags") 82 _configure_header=$(printf "$_configure_header\n CC=\"%s\"\n" "$_configure_CC") 83 _configure_header=$(printf "$_configure_header\n CFLAGS=\"%s\"\n" "$_configure_CFLAGS") 84 _configure_header=$(printf "$_configure_header\n LONG_BIT=%s" "$_configure_LONG_BIT") 85 _configure_header=$(printf "$_configure_header\n GEN_HOST=%s" "$_configure_GEN_HOST") 86 87 header "$_configure_header" 88 CFLAGS="$_configure_CFLAGS" CC="$_configure_CC" GEN_HOST="$_configure_GEN_HOST" \ 89 LONG_BIT="$_configure_LONG_BIT" ./configure.sh $_configure_configure_flags > /dev/null 90} 91 92build() { 93 94 _build_CFLAGS="$1" 95 shift 96 97 _build_CC="$1" 98 shift 99 100 _build_configure_flags="$1" 101 shift 102 103 _build_GEN_HOST="$1" 104 shift 105 106 _build_LONG_BIT="$1" 107 shift 108 109 configure "$_build_CFLAGS" "$_build_CC" "$_build_configure_flags" "$_build_GEN_HOST" "$_build_LONG_BIT" 110 111 _build_header=$(printf 'Building...\n CC=%s' "$_build_CC") 112 _build_header=$(printf "$_build_header\n CFLAGS=\"%s\"" "$_build_CFLAGS") 113 _build_header=$(printf "$_build_header\n LONG_BIT=%s" "$_build_LONG_BIT") 114 _build_header=$(printf "$_build_header\n GEN_HOST=%s" "$_build_GEN_HOST") 115 116 header "$_build_header" 117 118 do_make > /dev/null 2> "$scriptdir/.test.txt" 119 120 if [ -s "$scriptdir/.test.txt" ]; then 121 printf '%s generated warning(s):\n' "$_build_CC" 122 printf '\n' 123 cat "$scriptdir/.test.txt" 124 exit 1 125 fi 126} 127 128runtest() { 129 130 header "Running tests" 131 132 if [ "$#" -gt 0 ]; then 133 do_make "$@" 134 else 135 do_make test 136 fi 137} 138 139runconfigtests() { 140 141 _runconfigtests_CFLAGS="$1" 142 shift 143 144 _runconfigtests_CC="$1" 145 shift 146 147 _runconfigtests_configure_flags="$1" 148 shift 149 150 _runconfigtests_GEN_HOST="$1" 151 shift 152 153 _runconfigtests_LONG_BIT="$1" 154 shift 155 156 _runconfigtests_run_tests="$1" 157 shift 158 159 if [ "$_runconfigtests_run_tests" -ne 0 ]; then 160 _runconfigtests_header=$(printf 'Running tests with configure flags') 161 else 162 _runconfigtests_header=$(printf 'Building with configure flags') 163 fi 164 165 _runconfigtests_header=$(printf "$_runconfigtests_header \"%s\" ...\n" "$_runconfigtests_configure_flags") 166 _runconfigtests_header=$(printf "$_runconfigtests_header\n CC=%s\n" "$_runconfigseries_CC") 167 _runconfigtests_header=$(printf "$_runconfigtests_header\n CFLAGS=\"%s\"" "$_runconfigseries_CFLAGS") 168 _runconfigtests_header=$(printf "$_runconfigtests_header\n LONG_BIT=%s" "$_runconfigtests_LONG_BIT") 169 _runconfigtests_header=$(printf "$_runconfigtests_header\n GEN_HOST=%s" "$_runconfigtests_GEN_HOST") 170 171 header "$_runconfigtests_header" 172 173 build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ 174 "$_runconfigtests_configure_flags" "$_runconfigtests_GEN_HOST" \ 175 "$_runconfigtests_LONG_BIT" 176 177 if [ "$_runconfigtests_run_tests" -ne 0 ]; then 178 runtest 179 fi 180 181 do_make clean 182 183 build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ 184 "$_runconfigtests_configure_flags -b" "$_runconfigtests_GEN_HOST" \ 185 "$_runconfigtests_LONG_BIT" 186 187 if [ "$_runconfigtests_run_tests" -ne 0 ]; then 188 runtest 189 fi 190 191 do_make clean 192 193 build "$_runconfigtests_CFLAGS" "$_runconfigtests_CC" \ 194 "$_runconfigtests_configure_flags -d" "$_runconfigtests_GEN_HOST" \ 195 "$_runconfigtests_LONG_BIT" 196 197 if [ "$_runconfigtests_run_tests" -ne 0 ]; then 198 runtest 199 fi 200 201 do_make clean 202} 203 204runconfigseries() { 205 206 _runconfigseries_CFLAGS="$1" 207 shift 208 209 _runconfigseries_CC="$1" 210 shift 211 212 _runconfigseries_configure_flags="$1" 213 shift 214 215 _runconfigseries_run_tests="$1" 216 shift 217 218 if [ "$run_64_bit" -ne 0 ]; then 219 220 if [ "$test_128_bit" -ne 0 ]; then 221 runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ 222 "$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests" 223 fi 224 225 if [ "$run_gen_script" -ne 0 ]; then 226 runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ 227 "$_runconfigseries_configure_flags" 0 64 "$_runconfigseries_run_tests" 228 fi 229 230 runconfigtests "$_runconfigseries_CFLAGS -DBC_RAND_BUILTIN=0" "$_runconfigseries_CC" \ 231 "$_runconfigseries_configure_flags" 1 64 "$_runconfigseries_run_tests" 232 233 fi 234 235 runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ 236 "$_runconfigseries_configure_flags" 1 32 "$_runconfigseries_run_tests" 237 238 if [ "$run_gen_script" -ne 0 ]; then 239 runconfigtests "$_runconfigseries_CFLAGS" "$_runconfigseries_CC" \ 240 "$_runconfigseries_configure_flags" 0 32 "$_runconfigseries_run_tests" 241 fi 242} 243 244runtestseries() { 245 246 _runtestseries_CFLAGS="$1" 247 shift 248 249 _runtestseries_CC="$1" 250 shift 251 252 _runtestseries_configure_flags="$1" 253 shift 254 255 _runtestseries_run_tests="$1" 256 shift 257 258 _runtestseries_flags="E H N P EH EN EP HN HP NP EHN EHP ENP HNP EHNP" 259 260 runconfigseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \ 261 "$_runtestseries_configure_flags" "$_runtestseries_run_tests" 262 263 for f in $_runtestseries_flags; do 264 runconfigseries "$_runtestseries_CFLAGS" "$_runtestseries_CC" \ 265 "$_runtestseries_configure_flags -$f" "$_runtestseries_run_tests" 266 done 267} 268 269runlibtests() { 270 271 _runlibtests_CFLAGS="$1" 272 shift 273 274 _runlibtests_CC="$1" 275 shift 276 277 _runlibtests_configure_flags="$1" 278 shift 279 280 _runlibtests_run_tests="$1" 281 shift 282 283 _runlibtests_configure_flags="$_runlibtests_configure_flags -a" 284 285 build "$_runlibtests_CFLAGS" "$_runlibtests_CC" "$_runlibtests_configure_flags" 1 64 286 287 if [ "$_runlibtests_run_tests" -ne 0 ]; then 288 runtest 289 fi 290 291 build "$_runlibtests_CFLAGS" "$_runlibtests_CC" "$_runlibtests_configure_flags" 1 32 292 293 if [ "$_runlibtests_run_tests" -ne 0 ]; then 294 runtest 295 fi 296} 297 298runtests() { 299 300 _runtests_CFLAGS="$1" 301 shift 302 303 _runtests_CC="$1" 304 shift 305 306 _runtests_configure_flags="$1" 307 shift 308 309 _runtests_run_tests="$1" 310 shift 311 312 runtestseries "-std=c99 $_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests" 313 314 if [ "$test_c11" -ne 0 ]; then 315 runtestseries "-std=c11 $_runtests_CFLAGS" "$_runtests_CC" "$_runtests_configure_flags" "$_runtests_run_tests" 316 fi 317} 318 319karatsuba() { 320 321 header "Running Karatsuba tests" 322 do_make karatsuba_test 323} 324 325vg() { 326 327 header "Running valgrind" 328 329 if [ "$run_64_bit" -ne 0 ]; then 330 _vg_bits=64 331 else 332 _vg_bits=32 333 fi 334 335 build "$debug" "gcc" "-O0 -gv" "1" "$_vg_bits" 336 runtest test 337 338 do_make clean_config 339 340 build "$debug" "gcc" "-O0 -gvb" "1" "$_vg_bits" 341 runtest test 342 343 do_make clean_config 344 345 build "$debug" "gcc" "-O0 -gvd" "1" "$_vg_bits" 346 runtest test 347 348 do_make clean_config 349} 350 351debug() { 352 353 _debug_CC="$1" 354 shift 355 356 _debug_run_tests="$1" 357 shift 358 359 runtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests" 360 361 if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then 362 runtests "$debug -fsanitize=undefined" "$_debug_CC" "-g" "$_debug_run_tests" 363 fi 364 365 runlibtests "$debug" "$_debug_CC" "-g" "$_debug_run_tests" 366 367 if [ "$_debug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then 368 runlibtests "$debug -fsanitize=undefined" "$_debug_CC" "-g" "$_debug_run_tests" 369 fi 370} 371 372release() { 373 374 _release_CC="$1" 375 shift 376 377 _release_run_tests="$1" 378 shift 379 380 runtests "$release" "$_release_CC" "-O3" "$_release_run_tests" 381 382 runlibtests "$release" "$_release_CC" "-O3" "$_release_run_tests" 383} 384 385reldebug() { 386 387 _reldebug_CC="$1" 388 shift 389 390 _reldebug_run_tests="$1" 391 shift 392 393 runtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" 394 395 if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then 396 runtests "$debug -fsanitize=address" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" 397 runtests "$debug -fsanitize=memory" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" 398 fi 399 400 runlibtests "$debug" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" 401 402 if [ "$_reldebug_CC" = "clang" -a "$run_sanitizers" -ne 0 ]; then 403 runlibtests "$debug -fsanitize=address" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" 404 runlibtests "$debug -fsanitize=memory" "$_reldebug_CC" "-gO3" "$_reldebug_run_tests" 405 fi 406} 407 408minsize() { 409 410 _minsize_CC="$1" 411 shift 412 413 _minsize_run_tests="$1" 414 shift 415 416 runtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests" 417 418 runlibtests "$release" "$_minsize_CC" "-Os" "$_minsize_run_tests" 419} 420 421build_set() { 422 423 _build_set_CC="$1" 424 shift 425 426 _build_set_run_tests="$1" 427 shift 428 429 debug "$_build_set_CC" "$_build_set_run_tests" 430 release "$_build_set_CC" "$_build_set_run_tests" 431 reldebug "$_build_set_CC" "$_build_set_run_tests" 432 minsize "$_build_set_CC" "$_build_set_run_tests" 433} 434 435clang_flags="-Weverything -Wno-padded -Wno-switch-enum -Wno-format-nonliteral" 436clang_flags="$clang_flags -Wno-cast-align -Wno-missing-noreturn -Wno-disabled-macro-expansion" 437clang_flags="$clang_flags -Wno-unreachable-code -Wno-unreachable-code-return" 438clang_flags="$clang_flags -Wno-implicit-fallthrough" 439gcc_flags="-Wno-maybe-uninitialized -Wno-clobbered" 440 441cflags="-Wall -Wextra -Werror -pedantic -Wno-conditional-uninitialized" 442 443debug="$cflags -fno-omit-frame-pointer" 444release="$cflags -DNDEBUG" 445 446set -e 447 448script="$0" 449scriptdir=$(dirname "$script") 450 451if [ "$#" -gt 0 ]; then 452 run_tests="$1" 453 shift 454else 455 run_tests=1 456fi 457 458if [ "$#" -gt 0 ]; then 459 gen_tests="$1" 460 shift 461else 462 gen_tests=1 463fi 464 465if [ "$#" -gt 0 ]; then 466 test_with_clang="$1" 467 shift 468else 469 test_with_clang=1 470fi 471 472if [ "$#" -gt 0 ]; then 473 test_with_gcc="$1" 474 shift 475else 476 test_with_gcc=1 477fi 478 479if [ "$#" -gt 0 ]; then 480 run_sanitizers="$1" 481 shift 482else 483 run_sanitizers=1 484fi 485 486if [ "$#" -gt 0 ]; then 487 run_valgrind="$1" 488 shift 489else 490 run_valgrind=1 491fi 492 493if [ "$#" -gt 0 ]; then 494 run_64_bit="$1" 495 shift 496else 497 run_64_bit=1 498fi 499 500if [ "$#" -gt 0 ]; then 501 run_gen_script="$1" 502 shift 503else 504 run_gen_script=0 505fi 506 507if [ "$#" -gt 0 ]; then 508 test_c11="$1" 509 shift 510else 511 test_c11=0 512fi 513 514if [ "$#" -gt 0 ]; then 515 test_128_bit="$1" 516 shift 517else 518 test_128_bit=0 519fi 520 521if [ "$run_64_bit" -ne 0 ]; then 522 bits=64 523else 524 bits=32 525fi 526 527cd "$scriptdir" 528 529if [ "$test_with_clang" -ne 0 ]; then 530 defcc="clang" 531elif [ "$test_with_gcc" -ne 0 ]; then 532 defcc="gcc" 533else 534 defcc="c99" 535fi 536 537export ASAN_OPTIONS="abort_on_error=1,allocator_may_return_null=1" 538export UBSAN_OPTIONS="print_stack_trace=1,silence_unsigned_overflow=1" 539 540build "$debug" "$defcc" "-g" "1" "$bits" 541 542header "Running math library under --standard" 543 544printf 'quit\n' | bin/bc -ls 545 546do_make clean_tests 547 548if [ "$test_with_clang" -ne 0 ]; then 549 build_set "clang" "$run_tests" 550fi 551 552if [ "$test_with_gcc" -ne 0 ]; then 553 build_set "gcc" "$run_tests" 554fi 555 556if [ "$run_tests" -ne 0 ]; then 557 558 build "$release" "$defcc" "-O3" "1" "$bits" 559 560 karatsuba 561 562 if [ "$run_valgrind" -ne 0 -a "$test_with_gcc" -ne 0 ]; then 563 vg 564 fi 565 566 printf '\n' 567 printf 'Tests successful.\n' 568 569 set +e 570 571 command -v afl-gcc > /dev/null 2>&1 572 err="$?" 573 574 set -e 575 576 if [ "$err" -eq 0 ]; then 577 578 header "Configuring for afl-gcc..." 579 580 configure "$debug $gcc_flags -DBC_ENABLE_RAND=0" "afl-gcc" "-HNP -gO3" "1" "$bits" 581 582 printf '\n' 583 printf 'Run make\n' 584 printf '\n' 585 printf 'Then run %s/tests/randmath.py and the fuzzer.\n' "$scriptdir" 586 printf '\n' 587 printf 'Then run ASan on the fuzzer test cases with the following build:\n' 588 printf '\n' 589 printf ' CFLAGS="-fsanitize=address -fno-omit-frame-pointer -DBC_ENABLE_RAND=0" ./configure.sh -gO3 -HNPS\n' 590 printf ' make\n' 591 printf '\n' 592 printf 'Then run the GitHub release script as follows:\n' 593 printf '\n' 594 printf ' <github_release> <version> .gitignore .gitattributes\\\n' 595 printf ' manpage.sh release.sh RELEASE.md tests/afl.py\\\n' 596 printf ' tests/radamsa.sh tests/radamsa.txt tests/randmath.py\\\n' 597 printf ' tests/fuzzing/ tests/bc/scripts/timeconst.bc\n' 598 599 fi 600 601fi 602