diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/coccinelle/ceil_div.cocci | 6 | ||||
-rwxr-xr-x | scripts/coccinelle/test-operator-cleanup | 11 | ||||
-rw-r--r-- | scripts/coccinelle/test_assert_int.cocci | 49 | ||||
-rw-r--r-- | scripts/coccinelle/test_assert_null.cocci | 11 | ||||
-rw-r--r-- | scripts/coccinelle/test_assert_zero.cocci | 5 | ||||
-rwxr-xr-x | scripts/codegen/fuzzing_include_am.py | 12 | ||||
-rwxr-xr-x | scripts/maint/analyze_callgraph.py | 259 | ||||
-rwxr-xr-x | scripts/maint/display_callgraph.py | 41 | ||||
-rwxr-xr-x | scripts/maint/generate_callgraph.sh | 14 |
9 files changed, 90 insertions, 318 deletions
diff --git a/scripts/coccinelle/ceil_div.cocci b/scripts/coccinelle/ceil_div.cocci new file mode 100644 index 0000000000..00843e82c3 --- /dev/null +++ b/scripts/coccinelle/ceil_div.cocci @@ -0,0 +1,6 @@ +@@ +expression n, d; +@@ + +- (((n) + (d) - 1) / (d)) ++ CEIL_DIV(n, d) diff --git a/scripts/coccinelle/test-operator-cleanup b/scripts/coccinelle/test-operator-cleanup new file mode 100755 index 0000000000..e7822542a4 --- /dev/null +++ b/scripts/coccinelle/test-operator-cleanup @@ -0,0 +1,11 @@ +#!/usr/bin/perl -w -p -i + +next if m#^ */\*# or m#^ *\* #; + +s/<([,)])/OP_LT$1/; +s/(?<=[\s,])>([,)])/OP_GT$1/; +#s/>([,)])/OP_GT$1/; +s/==([,)])/OP_EQ$1/; +s/>=([,)])/OP_GE$1/; +s/<=([,)])/OP_LE$1/; +s/!=([,)])/OP_NE$1/; diff --git a/scripts/coccinelle/test_assert_int.cocci b/scripts/coccinelle/test_assert_int.cocci new file mode 100644 index 0000000000..80e86b4f3c --- /dev/null +++ b/scripts/coccinelle/test_assert_int.cocci @@ -0,0 +1,49 @@ +@@ +int e; +constant c; +@@ + +( +- tt_assert(e == c) ++ tt_int_op(e, OP_EQ, c) +| +- tt_assert(e != c) ++ tt_int_op(e, OP_NE, c) +| +- tt_assert(e < c) ++ tt_int_op(e, OP_LT, c) +| +- tt_assert(e <= c) ++ tt_int_op(e, OP_LE, c) +| +- tt_assert(e > c) ++ tt_int_op(e, OP_GT, c) +| +- tt_assert(e >= c) ++ tt_int_op(e, OP_GE, c) +) + +@@ +unsigned int e; +constant c; +@@ + +( +- tt_assert(e == c) ++ tt_uint_op(e, OP_EQ, c) +| +- tt_assert(e != c) ++ tt_uint_op(e, OP_NE, c) +| +- tt_assert(e < c) ++ tt_uint_op(e, OP_LT, c) +| +- tt_assert(e <= c) ++ tt_uint_op(e, OP_LE, c) +| +- tt_assert(e > c) ++ tt_uint_op(e, OP_GT, c) +| +- tt_assert(e >= c) ++ tt_uint_op(e, OP_GE, c) +) diff --git a/scripts/coccinelle/test_assert_null.cocci b/scripts/coccinelle/test_assert_null.cocci new file mode 100644 index 0000000000..3d66e1ee0b --- /dev/null +++ b/scripts/coccinelle/test_assert_null.cocci @@ -0,0 +1,11 @@ +@@ +expression * e; +@@ + +( +- tt_assert(e != NULL) ++ tt_ptr_op(e, OP_NE, NULL) +| +- tt_assert(e == NULL) ++ tt_ptr_op(e, OP_EQ, NULL) +) diff --git a/scripts/coccinelle/test_assert_zero.cocci b/scripts/coccinelle/test_assert_zero.cocci new file mode 100644 index 0000000000..09feaa5fb4 --- /dev/null +++ b/scripts/coccinelle/test_assert_zero.cocci @@ -0,0 +1,5 @@ +@@ +@@ + +- tt_assert(0) ++ tt_abort() diff --git a/scripts/codegen/fuzzing_include_am.py b/scripts/codegen/fuzzing_include_am.py index 4627d550e9..f2936ef4ea 100755 --- a/scripts/codegen/fuzzing_include_am.py +++ b/scripts/codegen/fuzzing_include_am.py @@ -1,4 +1,4 @@ - +#!/usr/bin/python FUZZERS = """ consensus @@ -31,10 +31,14 @@ FUZZING_LIBS = \ src/common/libor-ctime-testing.a \ src/common/libor-event-testing.a \ src/trunnel/libor-trunnel-testing.a \ + $(rust_ldadd) \ @TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \ @TOR_LIBEVENT_LIBS@ \ - @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ \ - @TOR_SYSTEMD_LIBS@ + @TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \ + @CURVE25519_LIBS@ \ + @TOR_SYSTEMD_LIBS@ \ + @TOR_LZMA_LIBS@ \ + @TOR_ZSTD_LIBS@ oss-fuzz-prereqs: \ src/or/libtor-testing.a \ @@ -49,7 +53,7 @@ oss-fuzz-prereqs: \ noinst_HEADERS += \ src/test/fuzz/fuzzing.h -LIBFUZZER = /home/nickm/build/libfuzz/libFuzzer.a +LIBFUZZER = -lFuzzer LIBFUZZER_CPPFLAGS = $(FUZZING_CPPFLAGS) -DLLVM_FUZZ LIBFUZZER_CFLAGS = $(FUZZING_CFLAGS) LIBFUZZER_LDFLAG = $(FUZZING_LDFLAG) diff --git a/scripts/maint/analyze_callgraph.py b/scripts/maint/analyze_callgraph.py deleted file mode 100755 index 8ce5827f07..0000000000 --- a/scripts/maint/analyze_callgraph.py +++ /dev/null @@ -1,259 +0,0 @@ -#!/usr/bin/python - -import re -import sys -import copy -import cPickle -import os - -class Parser: - def __init__(self): - self.calls = {} - self.definedIn = {} - - def enter_func(self, name): - if self.infunc and not self.extern and self.calledfns: - if self.infunc in self.definedIn: - #print "{}: {} or {}?".format( - # self.infunc, self.definedIn[self.infunc], self.module) - self.definedIn[self.infunc] = 'nil' - else: - self.definedIn[self.infunc] = self.module - self.calls.setdefault(self.infunc, set()).update( self.calledfns ) - - self.calledfns = set() - self.infunc = name - self.extern = False - - def parse_callgraph_file(self, inp, module): - self.infunc = None - self.extern = False - self.calledfns = set() - self.module = module - - for line in inp: - m = re.match(r"Call graph node for function: '([^']+)'", line) - if m: - self.enter_func(m.group(1)) - continue - m = re.match(r" CS<[^>]+> calls external node", line) - if m: - self.extern = True - m = re.match(r" CS<[^>]+> calls function '([^']+)'", line) - if m: - self.calledfns.add(m.group(1)) - self.enter_func(None) - - def extract_callgraph(self): - c = self.calls - self.calls = {} - return c - - -def transitive_closure(g): - passno = 0 - changed = True - g = copy.deepcopy(g) - import random - while changed: - passno += 1 - changed = False - keys = g.keys() - idx = 0 - for k in keys: - idx += 1 - print "Pass %d/?: %d/%d\r" %(passno, idx, len(keys)), - sys.stdout.flush() - newset = g[k].copy() - for fn in g[k]: - newset.update(g.get(fn, set())) - if len(newset) != len(g[k]): - g[k].update( newset ) - changed = True - - print - - return g - -def strongly_connected_components(g): - # From https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm, done stupidly. - index_of = {} - index = [ 0 ] - lowlink = {} - S = [] - onStack = set() - - all_sccs = [] - - def strongconnect(fn): - index_of[fn] = index[0] - lowlink[fn] = index[0] - index[0] += 1 - S.append(fn) - onStack.add(fn) - - for w in g.get(fn, []): - if w not in index_of: - strongconnect(w) - lowlink[fn] = min(lowlink[fn], lowlink[w]) - elif w in onStack: - lowlink[fn] = min(lowlink[fn], index_of[w]) - - if lowlink[fn] == index_of[fn]: - this_scc = [] - all_sccs.append(this_scc) - while True: - w = S.pop() - onStack.remove(w) - this_scc.append(w) - if w == fn: - break - - for v in g.keys(): - if v not in index_of: - strongconnect(v) - - return all_sccs - -def biggest_component(sccs): - return max(len(c) for c in sccs) - -def connection_bottlenecks(callgraph): - - callers = {} - for fn in callgraph: - for fn2 in callgraph[fn]: - callers.setdefault(fn2, set()).add(fn) - - components = strongly_connected_components(callgraph) - components.sort(key=len) - big_component_fns = components[-1] - size = len(big_component_fns) - - function_bottlenecks = fn_results = [] - - total = len(big_component_fns) - idx = 0 - for fn in big_component_fns: - idx += 1 - print "Pass 1/3: %d/%d\r"%(idx, total), - sys.stdout.flush() - cg2 = copy.deepcopy(callgraph) - del cg2[fn] - - fn_results.append( (size - biggest_component(strongly_connected_components(cg2)), fn) ) - - print - bcf_set = set(big_component_fns) - - call_bottlenecks = fn_results = [] - result_set = set() - total = len(big_component_fns) - idx = 0 - for fn in big_component_fns: - fn_callers = callers[fn].intersection(bcf_set) - idx += 1 - if len(fn_callers) != 1: - continue - - print "Pass 2/3: %d/%d\r"%(idx, total), - sys.stdout.flush() - - caller = fn_callers.pop() - assert len(fn_callers) == 0 - cg2 = copy.deepcopy(callgraph) - cg2[caller].remove(fn) - - fn_results.append( (size - biggest_component(strongly_connected_components(cg2)), fn, "called by", caller) ) - result_set.add( (caller, fn) ) - - print - - total = len(big_component_fns) - idx = 0 - for fn in big_component_fns: - fn_calls = callgraph[fn].intersection(bcf_set) - idx += 1 - if len(fn_calls) != 1: - continue - - print "Pass 3/3: %d/%d\r"%(idx, total), - sys.stdout.flush() - - callee = fn_calls.pop() - if (fn, callee) in result_set: - continue - - assert len(fn_calls) == 0 - cg2 = copy.deepcopy(callgraph) - cg2[fn].remove(callee) - - fn_results.append( (size - biggest_component(strongly_connected_components(cg2)), callee, "called by", fn) ) - - print - - - return (function_bottlenecks, call_bottlenecks) - -if __name__ == '__main__': - p = Parser() - for fname in sys.argv[1:]: - modname = re.sub(r'.*/', '', fname).replace('.callgraph', '.c') - with open(fname, 'r') as f: - p.parse_callgraph_file(f, modname) - - sys.stdout.flush() - - print "Building callgraph" - callgraph = p.extract_callgraph() - inModule = p.definedIn - - print "Deriving module callgraph" - modCallgraph = {} - for fn in callgraph: - fnMod = inModule[fn] - for called in callgraph[fn]: - try: - calledMod = inModule[called] - except KeyError: - continue - modCallgraph.setdefault(fnMod, set()).add(calledMod) - del modCallgraph['nil'] - - print "Finding strongly connected components" - sccs = strongly_connected_components(callgraph) - - print "Finding the transitive closure of the callgraph.." - closure = transitive_closure(callgraph) - - print "Finding bottlenecks..." - bottlenecks = connection_bottlenecks(callgraph) - - print "Finding module SCCs" - modSCCS = strongly_connected_components(modCallgraph) - - print "Finding module TC" - modTC = transitive_closure(modCallgraph) - - print "Finding module bottlenecks" - modB = connection_bottlenecks(modCallgraph) - - data = { - 'callgraph' : callgraph, - 'sccs' : sccs, - 'closure' : closure, - 'bottlenecks' : bottlenecks, - 'modules' : p.definedIn, - 'modItems' : { - 'callgraph' : modCallgraph, - 'sccs' : modSCCS, - 'closure' : modTC, - 'bottlenecks' : modB, - } - } - - with open('callgraph.pkl', 'w') as f: - cPickle.dump(data, f) - - - diff --git a/scripts/maint/display_callgraph.py b/scripts/maint/display_callgraph.py deleted file mode 100755 index c9001c6d96..0000000000 --- a/scripts/maint/display_callgraph.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/python - -import cPickle - -data = cPickle.load(open("callgraph.pkl")) - -# data = data['modItems'] - -callgraph = data['callgraph'] -closure = data['closure'] -sccs = data['sccs'] -fn_bottle, call_bottle = data['bottlenecks'] - -for n_reachable, fn in sorted(list((len(r), fn) for fn, r in closure.iteritems())): - print "%s can reach %s other functions." %(fn, n_reachable) - - -c = [ (len(component), component) for component in sccs ] -c.sort() - -print "\n================================" - -for n, component in c: - if n < 2: - continue - print "Strongly connected component of size %d:"%n - print component - - -print "\n================================" - -print "====== Number of functions pulled into blob, by function in blob." -fn_bottle.sort() -for n, fn in fn_bottle[-30:]: - print "%3d: %s"%(n, fn) - -print "====== Number of functions pulled into blob, by call in blob." -call_bottle.sort() -for n, fn1, _, fn2 in call_bottle[-30:]: - print "%3d: %s -> %s "%(n, fn2, fn1) - diff --git a/scripts/maint/generate_callgraph.sh b/scripts/maint/generate_callgraph.sh deleted file mode 100755 index c6b33c0aea..0000000000 --- a/scripts/maint/generate_callgraph.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -C_FILES=`echo src/common/*.c src/or/*.c src/tools/*.c` -CFLAGS="-Isrc/ext/trunnel -Isrc/trunnel -I. -Isrc/ext -Isrc/common -DLOCALSTATEDIR=\"\" -DSHARE_DATADIR=\"\" -Dinline=" - -mkdir -p callgraph/src/common -mkdir -p callgraph/src/or -mkdir -p callgraph/src/tools - -for fn in $C_FILES; do - echo $fn - clang $CFLAGS -S -emit-llvm -fno-inline -o - $fn | \ - opt -analyze -print-callgraph >/dev/null 2> "callgraph/${fn}allgraph" -done |