#!/usr/bin/env python #===- lib/fuzzer/scripts/collect_data_flow.py ------------------------------===# # # The LLVM Compiler Infrastructure # # This file is distributed under the University of Illinois Open Source # License. See LICENSE.TXT for details. # #===------------------------------------------------------------------------===# # Runs the data-flow tracer several times on the same input in order to collect # the complete trace for all input bytes (running it on all bytes at once # may fail if DFSan runs out of labels). # Usage: # collect_data_flow.py BINARY INPUT [RESULT] #===------------------------------------------------------------------------===# import atexit import sys import os import subprocess import tempfile import shutil tmpdir = "" def cleanup(d): print "removing: ", d shutil.rmtree(d) def main(argv): exe = argv[1] inp = argv[2] size = os.path.getsize(inp) q = [[0, size]] tmpdir = tempfile.mkdtemp(prefix="libfuzzer-tmp-") atexit.register(cleanup, tmpdir) print "tmpdir: ", tmpdir outputs = [] while len(q): r = q.pop() print "******* Trying: ", r tmpfile = os.path.join(tmpdir, str(r[0]) + "-" + str(r[1])) ret = subprocess.call([exe, str(r[0]), str(r[1]), inp, tmpfile]) if ret and r[1] - r[0] >= 2: q.append([r[0], (r[1] + r[0]) / 2]) q.append([(r[1] + r[0]) / 2, r[1]]) else: outputs.append(tmpfile) print "******* Success: ", r f = sys.stdout if len(argv) >= 4: f = open(argv[3], "w") merge = os.path.join(os.path.dirname(argv[0]), "merge_data_flow.py") subprocess.call([merge] + outputs, stdout=f) if __name__ == '__main__': main(sys.argv)