Last active
May 20, 2018 13:43
-
-
Save 1wilkens/ec885cac0fca2d30f0357ee6c6a5c70c to your computer and use it in GitHub Desktop.
ring: util/check_versioned_symbols.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import os | |
import subprocess | |
import sys | |
INVALID_SYMBOLS = { | |
'_GLOBAL_OFFSET_TABLE_', 'stderr', 'stdout', 'fprintf', 'malloc', 'free', | |
'memset', 'memcpy', 'memcmp', 'memmove', 'syscall', | |
'DW.ref.rust_eh_personality', 'rust_eh_personality', '_Unwind_Resume' | |
} | |
def get_version_suffix(): | |
# Get HEAD ref | |
with open('.git/HEAD', 'r') as fp: | |
head = fp.read().strip('\n')[5:] | |
# Get short hash of HEAD ref | |
ref_path = os.path.join('.git', head) | |
with open(ref_path, 'r') as fp: | |
shorthash = fp.read()[:9] | |
# Get package version line from Cargo.toml | |
with open('Cargo.toml', 'r') as fp: | |
version_line = [l for l in fp.read().split('\n') if 'version' in l][0] | |
# Extract version from that line and replace '.' and '-' with '_' | |
version = version_line.split('"')[1].replace('.', '_').replace('-', '_') | |
# Build suffix string from version and shorthash | |
suffix = 'v{}_{}'.format(version, shorthash)[:23] | |
return suffix | |
def is_valid_symbol(sym): | |
return not b']:' in sym and not b'::' in sym and not sym.startswith(b'__') and len(sym) > 0 | |
def get_symbols(f): | |
# Get all global demnagled symbols from the target file | |
with open(os.devnull, 'w') as devnull: | |
raw_symbols = subprocess.check_output(['nm', '-g', '--demangle', '-f', 'posix', f], stderr=devnull).split(b'\n') | |
# Filter out some unneeded lines and decode to regular string | |
raw_symbols = [s.decode('utf-8') for s in raw_symbols if is_valid_symbol(s)] | |
# Extract symbol substring from lines and remove duplicates | |
symbols = list(set(s.split(' ')[0] for s in raw_symbols)) | |
return symbols | |
def check_symbols(f): | |
# Get symbol suffix | |
suffix = get_version_suffix() | |
# Get symbols | |
symbols = get_symbols(f) | |
# Filter symbols with suffix and invalid symbols (C and asm related) | |
filtered = [s for s in symbols if s not in INVALID_SYMBOLS and suffix not in s] | |
print("Found {} symbols without suffix".format(len(filtered))) | |
for s in filtered: | |
print(s) | |
if __name__ == '__main__': | |
if len(sys.argv) != 2: | |
print("{} <path to 'libring.rlib'>".format(__file__)) | |
sys.exit(1) | |
check_symbols(sys.argv[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment