forked from swiftlang/swift
-
Notifications
You must be signed in to change notification settings - Fork 0
/
check_freestanding_dependencies.py
executable file
·119 lines (104 loc) · 4.67 KB
/
check_freestanding_dependencies.py
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)