VirtualBox

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

最後變更 在這個檔案是 103996,由 vboxsync 提交於 12 月 前

Additions/3D/mesa: export mesa-24.0.2 to OSE. bugref:10606

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

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