Skip to content

Commit 77ea010

Browse files
committed
[Scripts] provide fuzzilli toolchain
1 parent a3c2245 commit 77ea010

File tree

6 files changed

+157
-271
lines changed

6 files changed

+157
-271
lines changed

scripts/cfg_preprocess.py

100644100755
Lines changed: 84 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -21,36 +21,86 @@
2121

2222
cfg_dir = Path(args.cfg_dir)
2323

24-
targets = []
24+
def parse_target_file(targets_file):
25+
targets = []
26+
with open(targets_file, 'r') as f:
27+
for line in f:
28+
target_file, target_line = line.strip().split(':')
29+
target_line = int(target_line)
30+
targets.append((target_file, target_line))
31+
32+
for target in targets:
33+
print(f'* user target {target[0]}:{target[1]}', file=sys.stderr)
34+
35+
return targets
36+
37+
def translate_target(target_file, target_line, target_blocks_map_file):
38+
# target-blocks-map.txt:simplified-lowering.cc:2927 ../../src/compiler/simplified-lowering.cc:2933
39+
# target-blocks-map.txt:simplified-lowering.cc:2927 ../../src/compiler/simplified-lowering.cc:2933
40+
# target-blocks-map.txt:simplified-lowering.cc:2927 ../../src/compiler/simplified-lowering.cc:2933
41+
# target-blocks-map.txt:simplified-lowering.cc:2927 ../../src/compiler/simplified-lowering.cc:2933
42+
# target-blocks-map.txt:simplified-lowering.cc:2927 ../../src/compiler/simplified-lowering.cc:2933
43+
# target-blocks-map.txt:simplified-lowering.cc:2927 ../../src/compiler/simplified-lowering.cc:2934
44+
targets = []
45+
assert target_blocks_map_file.exists()
46+
with open(target_blocks_map_file, 'r') as f:
47+
for line in f:
48+
bbid, target = line.strip().split(' ')
49+
if f'{target_file}:{target_line}' in target:
50+
filename, lineno = bbid.split(':')
51+
lineno = int(lineno)
52+
targets.append((filename, lineno))
53+
return list(set(targets))
2554

26-
for line in open(args.targets_file):
27-
target_file, target_line = line.strip().split(':')
28-
target_line = int(target_line)
29-
targets.append((target_file, target_line))
55+
user_targets = parse_target_file(args.targets_file)
56+
assert len(user_targets) > 0, f'No targets found in {args.targets_file}'
3057

31-
print(target_file, target_line, file=sys.stderr)
58+
targets = []
59+
for filename, lineno in user_targets:
60+
t = translate_target(filename, lineno, cfg_dir / 'target-blocks-map.txt')
61+
targets.extend(t)
62+
63+
for t in targets:
64+
print(f'* target {t[0]}:{t[1]}', file=sys.stderr)
3265

33-
for target in targets:
34-
logging.info(f'Target: {target[0]}:{target[1]}')
66+
assert len(targets) > 0, f'No targets found in {cfg_dir / "target-blocks-map.txt"}'
3567

3668
# each line looks like
3769
# simplified-lowering.cc:_ZN2v88internal8compiler22RepresentationSelector12EnqueueInputILNS1_5PhaseE0EEEvPNS1_4NodeEiNS1_7UseInfoE:0:0:384103392 _ZN2v88internal8compiler22RepresentationSelector7GetInfoEPNS1_4NodeE
3870
def parse_callgraph(callgraph_txt):
71+
calledges = []
3972
with open(callgraph_txt, 'r') as f:
4073
for line in f:
4174
caller, callee = line.strip().split()
42-
# print(f'{caller} -> {callee}')
4375
filename, funcname, lineno, order, bbid = caller.split(':')
44-
yield (filename, funcname, lineno, order, hex(int(bbid))), callee
76+
edge = (filename, funcname, lineno, order, hex(int(bbid))), callee
77+
calledges.append(edge)
78+
return calledges
79+
80+
81+
def merge_cfgs(cfgs, callgraph):
82+
merged = nx.MultiDiGraph()
83+
for cfg in cfgs:
84+
merged = nx.compose(merged, cfg)
85+
86+
for caller, callee in callgraph:
87+
_filename, _funcname, _lineno, _order, bbid = caller
88+
node = 'Node' + bbid
89+
assert node in merged, f'Node {node} not found in entire CFG'
90+
if callee in func_to_node:
91+
merged.add_edge(node, func_to_node[callee], weight=10)
92+
93+
# print('nodes in the merged graph', merged.nodes(data=True), file=sys.stderr)
94+
# print('edges in the merged graph', merged.edges(keys=True, data=True), file=sys.stderr)
95+
96+
return merged
4597

4698
target_nodes = []
4799

48100
# need to extract (function name -> first block id)
49-
def parse_cfg(cfg_file):
101+
def parse_cfg(cfg_file, targets):
50102
graph: pydot.Graph = pydot.graph_from_dot_file(cfg_file)[0]
51103
graph: nx.MultiDiGraph = nx.drawing.nx_pydot.from_pydot(graph)
52-
# print('graph name', graph.name)
53-
# set edge weight as 1
54104
for u, v, k, d in graph.edges(keys=True, data=True):
55105
d['weight'] = 1
56106

@@ -68,48 +118,38 @@ def parse_cfg(cfg_file):
68118
logging.info(f'Found target node {n} in {cfg_file}')
69119
break
70120

71-
# print('graph nodes', graph.nodes(data=True))
72-
# print('graph edges', graph.edges(keys=True, data=True))
73121
return graph
74122

75-
callgraph = list(parse_callgraph(cfg_dir / 'callgraph.txt'))
76-
cfgs = []
77-
func_to_node = {}
78-
for f in cfg_dir.glob('*.dot'):
79-
g = parse_cfg(f)
80-
cfgs.append(g)
123+
def parse_cfgs(cfg_dir, targets):
124+
cfgs = []
125+
for f in cfg_dir.glob('*.dot'):
126+
g = parse_cfg(f, targets)
127+
cfgs.append(g)
128+
return cfgs
81129

82-
the_node = min(g.nodes(data=True), key=lambda n: n[1]['order'])
83-
# print(the_node)
84-
func_to_node[g.name] = the_node[0]
130+
def build_funcmap(cfgs):
131+
func_to_node = {}
132+
for g in cfgs:
133+
the_node = min(g.nodes(data=True), key=lambda n: n[1]['order'])
134+
func_to_node[g.name] = the_node[0]
135+
return func_to_node
85136

86-
# for func, first_node in func_to_node.items():
87-
# print(f'{func} -> {first_node}')
88137

89-
logging.info(f'{len(target_nodes)} target nodes found')
138+
callgraph = parse_callgraph(cfg_dir / 'callgraph.txt')
139+
cfgs = parse_cfgs(cfg_dir, targets)
140+
func_to_node = build_funcmap(cfgs)
90141

91-
logging.info(f'{len(callgraph)} call edges found in callgraph.txt')
92-
logging.info(f'{len(cfgs)} CFG files found in {cfg_dir}')
142+
print(f'{len(cfgs)} CFG files found in {cfg_dir}', file=sys.stderr)
143+
print(f'{len(target_nodes)} target nodes found', file=sys.stderr)
144+
print(f'{len(callgraph)} call edges found', file=sys.stderr)
93145

94146
node_cnt = sum([cfg.number_of_nodes() for cfg in cfgs])
95147
edge_cnt = sum([cfg.number_of_edges() for cfg in cfgs])
96148

97-
logging.info(f'Total number of nodes: {node_cnt}')
98-
logging.info(f'Total number of edges: {edge_cnt}')
99-
100-
# merge cfgs into one
101-
entire_cfg = nx.MultiDiGraph()
102-
for cfg in cfgs:
103-
entire_cfg = nx.compose(entire_cfg, cfg)
104-
105-
for caller, callee in callgraph:
106-
filename, funcname, lineno, order, bbid = caller
107-
node = 'Node' + bbid
108-
assert node in entire_cfg, f'Node {node} not found in entire CFG'
109-
entire_cfg.add_edge(node, func_to_node[callee], weight=10)
149+
print(f'Total number of nodes: {node_cnt}', file=sys.stderr)
150+
print(f'Total number of edges: {edge_cnt}', file=sys.stderr)
110151

111-
logging.info(f'Number of nodes in entire CFG: {entire_cfg.number_of_nodes()}')
112-
logging.info(f'Number of edges in entire CFG: {entire_cfg.number_of_edges()}')
152+
entire_cfg = merge_cfgs(cfgs, callgraph)
113153

114154
fulldistmap = defaultdict(list)
115155
for v in target_nodes:

scripts/install-swift.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env bash
2+
3+
cd $HOME
4+
5+
if [[ ! -f $HOME/swiftly ]]; then
6+
curl -O https://download.swift.org/swiftly/linux/swiftly-1.0.0-$(uname -m).tar.gz
7+
tar -zxf swiftly-1.0.0-$(uname -m).tar.gz
8+
fi
9+
10+
sudo apt-get -y install gnupg2 libcurl4-openssl-dev libxml2-dev
11+
./swiftly init

scripts/repro-turbofan.sh

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,34 @@ if [[ -z $NUMBER ]]; then
99
fi
1010

1111
if [[ $(basename "$ROOT") != "optimuzz" ]]; then
12-
echo "Please run this script from the root of the optimuzz repository."
12+
echo -e "\033[31mPlease run this script from the root of the optimuzz repository.\033[0m"
1313
exit 1
1414
fi
1515

1616
echo $ROOT
17+
export SCRIPTS=$ROOT/scripts
1718

1819
set -e
1920

21+
scripts/install-swift.sh
22+
23+
export SWIFTLY_HOME_DIR="/home/user/.local/share/swiftly"
24+
export SWIFTLY_BIN_DIR="/home/user/.local/share/swiftly/bin"
25+
if [[ ":$PATH:" != *":$SWIFTLY_BIN_DIR:"* ]]; then
26+
export PATH="$SWIFTLY_BIN_DIR:$PATH"
27+
fi
28+
29+
swiftly install --use 6.0.1
30+
swift --version
31+
2032
# Our TurboFan benchmark requires Python 2
2133
if [[ ! -d $HOME/.pyenv ]]; then
2234
curl https://pyenv.run | bash
2335
fi
2436
export PYENV_ROOT="$HOME/.pyenv"
2537
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
2638
eval "$(pyenv init - bash)"
27-
# pyenv install 2
39+
pyenv install 2 --skip-existing
2840

2941

3042
TURBOFAN_BUILDS=$HOME/turbofan-builds
@@ -35,15 +47,18 @@ if [[ ! -d tools/depot_tools ]]; then
3547
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git tools/depot_tools
3648
fi
3749
export PATH=$PWD/tools/depot_tools:$PATH
38-
echo "Fetching v8..."
39-
# fetch v8
4050

41-
echo "Checking out v8..."
42-
# gclient sync
51+
if [[ ! -d v8 ]]; then
52+
echo -e "\033[34mFetching v8...\033[0m"
53+
fetch v8
54+
fi
55+
56+
echo -e "\033[34mChecking out v8...\033[0m"
57+
gclient sync
4358

4459

4560
COMMIT_ID=$(grep "^$NUMBER" $ROOT/turbotv-fuzzilli/d8-targets/commits.txt | awk '{print $2}')
46-
echo $COMMIT_ID
61+
echo -e "\033[34mFound the commit sha: $COMMIT_ID\033[0m"
4762
pyenv global 2 # Our targets need python 2.7
4863
pyenv exec gclient sync -D -R --revision=$COMMIT_ID
4964

@@ -78,17 +93,25 @@ make -C $ROOT/instrumentation/ clean
7893
make -C $ROOT/instrumentation/ BASE=$HOME/clang+llvm-13.0.0-x86_64-linux-gnu-ubuntu-20.04
7994

8095
echo -e "\033[34mEditing build rules...\033[0m"
81-
export SCRIPTS=$ROOT/scripts
96+
8297
TARGET_FILE=$(cat $ROOT/turbotv-fuzzilli/d8-targets/$NUMBER.txt | cut -d':' -f1)
8398
$SCRIPTS/edit_rule.py out.gn/x64.debug/toolchain.ninja cxx "VERBOSE=1 TARGET_FILE=$TARGET_FILE OUT_DIR=\"$PWD/out.gn/x64.debug/cfg\"" "-fexperimental-new-pass-manager -Xclang -fpass-plugin=$ROOT/instrumentation/inst-pass.so"
8499
$SCRIPTS/edit_rule.py out.gn/x64.debug/toolchain.ninja link "" "$ROOT/instrumentation/coverage.o"
85100
$SCRIPTS/edit_rule.py out.gn/x64.debug/toolchain.ninja solink "" "$ROOT/instrumentation/coverage.o"
86101

87102
echo -e "\033[34mBuilding d8...\033[0m"
88-
ninja -C out.gn/x64.debug d8 > out.gn/x64.debug/ninja.log
89-
$SCRIPTS/cfg_preprocess.py out.gn/x64.debug/cfg $HOME/optimuzz-experiment/cases/turbofan/targets/$NUMBER.txt > distmap.txt
103+
# ninja -C out.gn/x64.debug d8
104+
$SCRIPTS/cfg_preprocess.py out.gn/x64.debug/cfg $ROOT/turbotv-fuzzilli/d8-targets/$NUMBER.txt > distmap.txt
105+
cat distmap.txt | tail -n 5
106+
90107
cd $ROOT
91-
mv $TURBOFAN_BUILDS/v8/out.gn/x64.debug/ d8s/$NUMBER/
92-
cp $TURBOFAN_BUILDS/v8/distmap.txt d8s/$NUMBER/distmap.txt
93108

94-
tools/turbofan-reproduce.py $NUMBER
109+
rm -rf $HOME/d8s/$NUMBER/
110+
mkdir -p $HOME/d8s/$NUMBER
111+
mv $TURBOFAN_BUILDS/v8/out.gn/x64.debug/* $HOME/d8s/$NUMBER/
112+
cp $TURBOFAN_BUILDS/v8/distmap.txt $HOME/d8s/$NUMBER/distmap.txt
113+
114+
python3 -m venv .env
115+
source .env/bin/activate
116+
pip install -r $ROOT/turbotv-fuzzilli-requirements.txt
117+
tools/turbofan-reproduce.py $NUMBER $HOME/d8s/$NUMBER/

scripts/test-turbofan.sh

Lines changed: 0 additions & 6 deletions
This file was deleted.

0 commit comments

Comments
 (0)