Skip to content

Instantly share code, notes, and snippets.

@1wilkens
Last active May 20, 2018 13:43
Show Gist options
  • Save 1wilkens/ec885cac0fca2d30f0357ee6c6a5c70c to your computer and use it in GitHub Desktop.
Save 1wilkens/ec885cac0fca2d30f0357ee6c6a5c70c to your computer and use it in GitHub Desktop.
ring: util/check_versioned_symbols.py
#!/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