zink: handle more draw modes
[mesa.git] / bin / symbols-check.py
index 39ad1451852ef8b58481a854fa874311170b2dc7..a33d0932ed9926dececca0514fbf567ab816b523 100644 (file)
@@ -1,8 +1,9 @@
 #!/usr/bin/env python
 
 import argparse
-import subprocess
 import os
+import platform
+import subprocess
 
 # This list contains symbols that _might_ be exported for some platforms
 PLATFORM_SYMBOLS = [
@@ -18,17 +19,55 @@ PLATFORM_SYMBOLS = [
 ]
 
 
-def get_symbols(nm, lib):
+def get_symbols_nm(nm, lib):
+    '''
+    List all the (non platform-specific) symbols exported by the library
+    using `nm`
+    '''
+    symbols = []
+    platform_name = platform.system()
+    output = subprocess.check_output([nm, '-gP', lib],
+                                     stderr=open(os.devnull, 'w')).decode("ascii")
+    for line in output.splitlines():
+        fields = line.split()
+        if len(fields) == 2 or fields[1] == 'U':
+            continue
+        symbol_name = fields[0]
+        if platform_name == 'Linux':
+            if symbol_name in PLATFORM_SYMBOLS:
+                continue
+        elif platform_name == 'Darwin':
+            assert symbol_name[0] == '_'
+            symbol_name = symbol_name[1:]
+        symbols.append(symbol_name)
+    return symbols
+
+
+def get_symbols_dumpbin(dumpbin, lib):
     '''
     List all the (non platform-specific) symbols exported by the library
+    using `dumpbin`
     '''
     symbols = []
-    output = subprocess.check_output([nm, '--format=bsd', '-D', '--defined-only', lib],
+    output = subprocess.check_output([dumpbin, '/exports', lib],
                                      stderr=open(os.devnull, 'w')).decode("ascii")
     for line in output.splitlines():
-        (_, _, symbol_name) = line.split()
-        if symbol_name in PLATFORM_SYMBOLS:
+        fields = line.split()
+        # The lines with the symbols are made of at least 4 columns; see details below
+        if len(fields) < 4:
+            continue
+        try:
+            # Making sure the first 3 columns are a dec counter, a hex counter
+            # and a hex address
+            _ = int(fields[0], 10)
+            _ = int(fields[1], 16)
+            _ = int(fields[2], 16)
+        except ValueError:
             continue
+        symbol_name = fields[3]
+        # De-mangle symbols
+        if symbol_name[0] == '_':
+            symbol_name = symbol_name[1:].split('@')[0]
         symbols.append(symbol_name)
     return symbols
 
@@ -45,12 +84,24 @@ def main():
                         help='path to library')
     parser.add_argument('--nm',
                         action='store',
-                        required=True,
                         help='path to binary (or name in $PATH)')
+    parser.add_argument('--dumpbin',
+                        action='store',
+                        help='path to binary (or name in $PATH)')
+    parser.add_argument('--ignore-symbol',
+                        action='append',
+                        help='do not process this symbol')
     args = parser.parse_args()
 
     try:
-        lib_symbols = get_symbols(args.nm, args.lib)
+        if platform.system() == 'Windows':
+            if not args.dumpbin:
+                parser.error('--dumpbin is mandatory')
+            lib_symbols = get_symbols_dumpbin(args.dumpbin, args.lib)
+        else:
+            if not args.nm:
+                parser.error('--nm is mandatory')
+            lib_symbols = get_symbols_nm(args.nm, args.lib)
     except:
         # We can't run this test, but we haven't technically failed it either
         # Return the GNU "skip" error code
@@ -99,6 +150,14 @@ def main():
             continue
         if symbol in optional_symbols:
             continue
+        if args.ignore_symbol and symbol in args.ignore_symbol:
+            continue
+        if symbol[:2] == '_Z':
+            # As ajax found out, the compiler intentionally exports symbols
+            # that we explicitely asked it not to export, and we can't do
+            # anything about it:
+            # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36022#c4
+            continue
         unknown_symbols.append(symbol)
 
     missing_symbols = [