1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
#!/usr/bin/env python3
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
import argparse
import subprocess
import sys
parser = argparse.ArgumentParser()
parser.add_argument("--library", help="path to libswiftCore.a to check")
parser.add_argument("--vendor", help="flavor of the freestanding stdlib")
parser.add_argument("--nm-path", help="path to llvm-nm binary to use")
args = parser.parse_args()
################################################################################
#
# EXPECTED/ALLOWED DEPENDENCIES
#
# Before adding new symbols into these lists please consult with:
# @kubamracek, @compnerd
#
# The 'freestanding' build of the Swift runtime and standard library is
# intended to depend on as few platform symbols/APIs as possible.
#
################################################################################
cxx_dependencies = [
"___cxa_guard_acquire", "___cxa_guard_release",
]
math_dependencies = [
"_ceill", "_cos", "_cosf", "_cosl", "_exp", "_exp2", "_exp2f", "_exp2l",
"_expf", "_expl", "_floorl", "_fma", "_fmaf", "_fmal", "_fmod", "_fmodf",
"_fmodl", "_log", "_log10", "_log10f", "_log10l", "_log2", "_log2f",
"_log2l", "_logf", "_logl", "_nearbyintl", "_remainder", "_remainderf",
"_remainderl", "_rintl", "_roundl", "_sin", "_sinf", "_sinl", "_truncl",
]
threading_package_dependencies = [
"_pthread_mutex_destroy", "_pthread_cond_broadcast",
"_pthread_get_stacksize_np", "_pthread_key_create", "_pthread_self",
"_pthread_equal", "_pthread_mutex_lock", "_pthread_getspecific",
"_pthread_mutex_unlock", "_pthread_cond_wait", "_pthread_setspecific",
"_pthread_get_stackaddr_np"
]
common_expected_dependencies = [
"___bzero", "___divti3", "___error", "___stderrp", "___stdoutp",
"___truncsfhf2", "___udivti3", "_abort", "_arc4random_buf",
"_calloc", "_close", "_fflush", "_flockfile", "_fprintf",
"_fputc", "_fputs", "_free", "_funlockfile", "_fwrite", "_malloc",
"_malloc_size", "_memchr", "_memcmp", "_memcpy", "_memmove", "_memset",
"_posix_memalign", "_putc", "_read", "_realloc", "_snprintf", "_strchr",
"_strcmp", "_strdup", "_strlen", "_strncmp", "_strtod", "_strtof",
"_strtol", "_strtold", "_vprintf", "_vsnprintf", "_write",
] + cxx_dependencies + math_dependencies
vendor_apple_specific_dependencies = [
"___stack_chk_fail", "___stack_chk_guard",
"_getsectiondata", "__dyld_register_func_for_add_image",
]
################################################################################
if args.vendor == "apple":
vendor_specific_dependencies = vendor_apple_specific_dependencies
nm = args.nm_path
lines = subprocess.check_output(
[nm, "--portability", "--undefined-only", args.library]) \
.decode("utf-8").strip().splitlines()
deps = [line.split(" ")[0] for line in lines if " U " in line]
print("")
else:
print("vendor {} not handled yet".format(args.vendor))
sys.exit(1)
deps = [dep for dep in deps if not dep.startswith("_$")]
deps = [dep for dep in deps if not dep.startswith("__Z")]
deps = [dep for dep in deps if not dep.startswith("section$start$")]
deps = [dep for dep in deps if not dep.startswith("section$end$")]
deps = [dep for dep in deps if not dep.startswith("___swift_stdlib")]
deps = [dep for dep in deps if not dep.startswith("__swift_stdlib")]
deps = [dep for dep in deps if not dep.startswith("__swift")]
deps = [dep for dep in deps if not dep.startswith("_swift_")]
deps = [dep for dep in deps if not dep.startswith("__stdlib_")]
deps = [dep for dep in deps if not dep.startswith("_getSuperclassMetadata")]
deps = set(deps)
print("libswiftCore.a dependencies:")
print("\n".join(sorted(deps)))
print("")
# for soundness checking that we are getting a valid symbol list
required_dependencies = ["_malloc", "_free"]
fail = False
for symbol in required_dependencies:
if symbol not in deps:
print("Error: Required dependency '{}' missing".format(symbol))
fail = True
allowlist = set(common_expected_dependencies + vendor_specific_dependencies +
threading_package_dependencies)
for symbol in deps:
if symbol not in allowlist:
print("Error: Unexpected dependency '{}'".format(symbol))
fail = True
for symbol in allowlist:
if symbol not in deps:
print("Warning: Allowed dependency '{}' not present".format(symbol))
print("")
print("All checks done. Result: {}".format("FAIL" if fail else "SUCCESS"))
sys.exit(1 if fail else 0)
|