From dd445c15130e2074f26ccdde7e147c2e6cf153fd Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Fri, 18 Jan 2019 13:41:07 +0100 Subject: [PATCH] Add Python script to check function namespacing --- Makefile | 10 +++++++++ test/check_symbol_namespace.py | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 test/check_symbol_namespace.py diff --git a/Makefile b/Makefile index 3559cfe5..26889002 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,16 @@ bin/testvectors_$(subst /,_,$(SCHEME)): test/$(dir $(SCHEME))testvectors.c $(wil .PHONY: testvectors testvectors: bin/testvectors_$(subst /,_,$(SCHEME)) +bin/shared_$(subst /,_,$(SCHEME))_clean.so: $(wildcard $(SCHEME)/clean/*.c) | require_scheme + mkdir -p bin + gcc $(CFLAGS) \ + -shared \ + -fPIC \ + -iquote "./common/" \ + -iquote "$(SCHEME)/clean/" \ + -o $@ \ + $^ + .PHONY: clean clean: rm -rf bin diff --git a/test/check_symbol_namespace.py b/test/check_symbol_namespace.py new file mode 100644 index 00000000..cec4143f --- /dev/null +++ b/test/check_symbol_namespace.py @@ -0,0 +1,37 @@ +import subprocess +import sys + +""" +For a given SCHEME, this script verifies that all exported symbols are properly +namespaced, i.e., all start with "PQCLEAN_SCHEMENAME_" +""" + +if len(sys.argv) != 2: + print("Provide a scheme name (e.g. crypto_kem/kyber768) as argv[1]") + exit(1) + +SCHEME = sys.argv[1] +SCHEMEFULL = SCHEME.replace('/', '_') # e.g. crypto_kem_kyber768 +SCHEMESHORT = SCHEME.split('/')[1].upper() +namespace = f"PQCLEAN_{SCHEMESHORT}_" + +# TODO can we do this using object files instead, to preserve file origin? +sharedlib = f"bin/shared_{SCHEMEFULL}_clean.so" +subprocess.run(["make", sharedlib, f"SCHEME={SCHEME}"]) +p = subprocess.run(["nm", "-D", sharedlib], capture_output=True) + +symbols = p.stdout.decode('utf-8').strip().split("\n") +non_namespaced = [] + +for symbolstr in symbols: + *_, symtype, symbol = symbolstr.split() + if symtype in 'TR': + if not symbol.startswith(namespace): + non_namespaced.append(symbol) + +if non_namespaced: + print("! Not all symbols were properly namespaced.", file=sys.stderr) + print(f"! Missing namespace literal {namespace}", file=sys.stderr) + for symbol in non_namespaced: + print(f"\t{symbol}", file=sys.stderr) + sys.exit(1)