VirtualBox

source: vbox/trunk/src/VBox/Additions/3D/mesa/mesa-21.3.8/bin/symbols-check.py@ 105254

最後變更 在這個檔案從105254是 96488,由 vboxsync 提交於 3 年 前

Additions/3D/mesa: Export to OSE and remove symlinks.

  • 屬性 svn:eol-style 設為 LF
  • 屬性 svn:executable 設為 *
檔案大小: 5.8 KB
 
1#!/usr/bin/env python3
2
3import argparse
4import os
5import platform
6import subprocess
7
8# This list contains symbols that _might_ be exported for some platforms
9PLATFORM_SYMBOLS = [
10 '__bss_end__',
11 '__bss_start__',
12 '__bss_start',
13 '__cxa_guard_abort',
14 '__cxa_guard_acquire',
15 '__cxa_guard_release',
16 '__end__',
17 '__odr_asan._glapi_Context',
18 '__odr_asan._glapi_Dispatch',
19 '_bss_end__',
20 '_edata',
21 '_end',
22 '_fini',
23 '_init',
24 '_fbss',
25 '_fdata',
26 '_ftext',
27]
28
29def get_symbols_nm(nm, lib):
30 '''
31 List all the (non platform-specific) symbols exported by the library
32 using `nm`
33 '''
34 symbols = []
35 platform_name = platform.system()
36 output = subprocess.check_output([nm, '-gP', lib],
37 stderr=open(os.devnull, 'w')).decode("ascii")
38 for line in output.splitlines():
39 fields = line.split()
40 if len(fields) == 2 or fields[1] == 'U':
41 continue
42 symbol_name = fields[0]
43 if platform_name == 'Linux':
44 if symbol_name in PLATFORM_SYMBOLS:
45 continue
46 elif platform_name == 'Darwin':
47 assert symbol_name[0] == '_'
48 symbol_name = symbol_name[1:]
49 symbols.append(symbol_name)
50 return symbols
51
52
53def get_symbols_dumpbin(dumpbin, lib):
54 '''
55 List all the (non platform-specific) symbols exported by the library
56 using `dumpbin`
57 '''
58 symbols = []
59 output = subprocess.check_output([dumpbin, '/exports', lib],
60 stderr=open(os.devnull, 'w')).decode("ascii")
61 for line in output.splitlines():
62 fields = line.split()
63 # The lines with the symbols are made of at least 4 columns; see details below
64 if len(fields) < 4:
65 continue
66 try:
67 # Making sure the first 3 columns are a dec counter, a hex counter
68 # and a hex address
69 _ = int(fields[0], 10)
70 _ = int(fields[1], 16)
71 _ = int(fields[2], 16)
72 except ValueError:
73 continue
74 symbol_name = fields[3]
75 # De-mangle symbols
76 if symbol_name[0] == '_' and '@' in symbol_name:
77 symbol_name = symbol_name[1:].split('@')[0]
78 symbols.append(symbol_name)
79 return symbols
80
81
82def main():
83 parser = argparse.ArgumentParser()
84 parser.add_argument('--symbols-file',
85 action='store',
86 required=True,
87 help='path to file containing symbols')
88 parser.add_argument('--lib',
89 action='store',
90 required=True,
91 help='path to library')
92 parser.add_argument('--nm',
93 action='store',
94 help='path to binary (or name in $PATH)')
95 parser.add_argument('--dumpbin',
96 action='store',
97 help='path to binary (or name in $PATH)')
98 parser.add_argument('--ignore-symbol',
99 action='append',
100 help='do not process this symbol')
101 args = parser.parse_args()
102
103 try:
104 if platform.system() == 'Windows':
105 if not args.dumpbin:
106 parser.error('--dumpbin is mandatory')
107 lib_symbols = get_symbols_dumpbin(args.dumpbin, args.lib)
108 else:
109 if not args.nm:
110 parser.error('--nm is mandatory')
111 lib_symbols = get_symbols_nm(args.nm, args.lib)
112 except:
113 # We can't run this test, but we haven't technically failed it either
114 # Return the GNU "skip" error code
115 exit(77)
116 mandatory_symbols = []
117 optional_symbols = []
118 with open(args.symbols_file) as symbols_file:
119 qualifier_optional = '(optional)'
120 for line in symbols_file.readlines():
121
122 # Strip comments
123 line = line.split('#')[0]
124 line = line.strip()
125 if not line:
126 continue
127
128 # Line format:
129 # [qualifier] symbol
130 qualifier = None
131 symbol = None
132
133 fields = line.split()
134 if len(fields) == 1:
135 symbol = fields[0]
136 elif len(fields) == 2:
137 qualifier = fields[0]
138 symbol = fields[1]
139 else:
140 print(args.symbols_file + ': invalid format: ' + line)
141 exit(1)
142
143 # The only supported qualifier is 'optional', which means the
144 # symbol doesn't have to be exported by the library
145 if qualifier and not qualifier == qualifier_optional:
146 print(args.symbols_file + ': invalid qualifier: ' + qualifier)
147 exit(1)
148
149 if qualifier == qualifier_optional:
150 optional_symbols.append(symbol)
151 else:
152 mandatory_symbols.append(symbol)
153
154 unknown_symbols = []
155 for symbol in lib_symbols:
156 if symbol in mandatory_symbols:
157 continue
158 if symbol in optional_symbols:
159 continue
160 if args.ignore_symbol and symbol in args.ignore_symbol:
161 continue
162 if symbol[:2] == '_Z':
163 # As ajax found out, the compiler intentionally exports symbols
164 # that we explicitely asked it not to export, and we can't do
165 # anything about it:
166 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36022#c4
167 continue
168 unknown_symbols.append(symbol)
169
170 missing_symbols = [
171 sym for sym in mandatory_symbols if sym not in lib_symbols
172 ]
173
174 for symbol in unknown_symbols:
175 print(args.lib + ': unknown symbol exported: ' + symbol)
176
177 for symbol in missing_symbols:
178 print(args.lib + ': missing symbol: ' + symbol)
179
180 if unknown_symbols or missing_symbols:
181 exit(1)
182 exit(0)
183
184
185if __name__ == '__main__':
186 main()
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette