Skip to content

Commit a59a861

Browse files
Initial commit
0 parents  commit a59a861

File tree

5 files changed

+193
-0
lines changed

5 files changed

+193
-0
lines changed

README.md

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
c-integrate
2+
===========
3+
4+
In this repository you can find the implementation of a script
5+
that integrates stitched and dynamic C-Debian call graphs.
6+
7+
Usage
8+
-----
9+
10+
```bash
11+
usage: Integrate FASTEN static and dynamic call graphs [-h] stitched [dynamic ...] output
12+
13+
positional arguments:
14+
stitched
15+
dynamic
16+
output
17+
18+
optional arguments:
19+
-h, --help show this help message and exit
20+
```
21+
22+
Example
23+
-------
24+
25+
```bash
26+
./c-integrate zlib1g-dev.json test-data/minigzip.json test-data/minigzipsh.json out.json
27+
```
28+
29+
Output Format
30+
-------------
31+
32+
```json
33+
{
34+
"edges": [
35+
[0, 1, {"static": True, "dynamic": True}]
36+
[0, 2, {"static": False, "dynamic": True}]
37+
],
38+
"nodes": {
39+
"0": {
40+
"URI": "fasten://example$0.1-1/hello;C/main()",
41+
"metadata": {}
42+
},
43+
"1": {
44+
"URI": "fasten://example$0.1-1/hello;C/local()",
45+
"metadata": {}
46+
},
47+
"2": {
48+
"URI": "fasten://depshared$0.1-1/libdepsharedb.so;C/dep_shared_fun_b()",
49+
"metadata": {}
50+
}
51+
}
52+
}
53+
```

c-integrate

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2018-2020 FASTEN.
3+
#
4+
# This file is part of FASTEN
5+
# (see https://www.fasten-project.eu/).
6+
#
7+
# Licensed to the Apache Software Foundation (ASF) under one
8+
# or more contributor license agreements. See the NOTICE file
9+
# distributed with this work for additional information
10+
# regarding copyright ownership. The ASF licenses this file
11+
# to you under the Apache License, Version 2.0 (the
12+
# "License"); you may not use this file except in compliance
13+
# with the License. You may obtain a copy of the License at
14+
#
15+
# http://www.apache.org/licenses/LICENSE-2.0
16+
#
17+
# Unless required by applicable law or agreed to in writing,
18+
# software distributed under the License is distributed on an
19+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20+
# KIND, either express or implied. See the License for the
21+
# specific language governing permissions and limitations
22+
# under the License.
23+
#
24+
import argparse
25+
import csv
26+
import json
27+
28+
29+
def parse_args():
30+
parser = argparse.ArgumentParser(
31+
"Integrate FASTEN static and dynamic call graphs"
32+
)
33+
parser.add_argument("stitched")
34+
parser.add_argument("dynamic", nargs='*')
35+
parser.add_argument("output")
36+
return parser.parse_args()
37+
38+
39+
def get_product_version(uri):
40+
prefix_less = uri[uri.find('//')+2:]
41+
product_version = prefix_less[:prefix_less.find('/')]
42+
if '$' in product_version:
43+
product = product_version[:product_version.find('$')]
44+
version = product_version[product_version.find('$')+1:]
45+
else:
46+
product = product_version
47+
version = None
48+
return product, version
49+
50+
51+
def parse_stitched(graph):
52+
versions = {}
53+
with open(graph) as f:
54+
data = json.load(f)
55+
for edge in data["edges"]:
56+
edge.append({"static": True, "dynamic": False})
57+
for node in data["nodes"].values():
58+
product, version = get_product_version(node['URI'])
59+
if version:
60+
versions[product] = version
61+
return data, versions
62+
63+
64+
def process_dynamic(graph, integrated_graph, versions, counter, nodes_lookup):
65+
def convert_node(node):
66+
product, version = get_product_version(node)
67+
if not node.startswith('fasten'):
68+
node = "fasten:" + node
69+
if version is None:
70+
version = versions.get(product, None)
71+
if version:
72+
node = "fasten://{product}${version}{rest}".format(
73+
product=product,
74+
version=version,
75+
# 9 is the length of the prefix
76+
rest=node[9+len(product):]
77+
)
78+
return node
79+
80+
def get_node_id(counter, node):
81+
nid = nodes_lookup.get(node, None)
82+
if nid is None:
83+
counter += 1
84+
nodes_lookup[node] = str(counter)
85+
integrated_graph["nodes"][str(counter)] = {
86+
"URI": node, "metadata": {}
87+
}
88+
nid = counter
89+
return nid, counter
90+
return int(nid), counter
91+
92+
with open(graph) as f:
93+
data = json.load(f)
94+
for edge in data:
95+
n1 = convert_node(edge[0])
96+
n2 = convert_node(edge[1])
97+
n1_id, counter = get_node_id(counter, n1)
98+
n2_id, counter = get_node_id(counter, n2)
99+
already_exist = False
100+
for edge in integrated_graph["edges"]:
101+
if edge[0] == n1_id and edge[1] == n2_id:
102+
edge[2]["dynamic"] = True
103+
already_exist = True
104+
break
105+
if not already_exist:
106+
integrated_graph["edges"].append(
107+
[n1_id, n2_id, {"static": False, "dynamic": True}]
108+
)
109+
110+
111+
def get_nodes_lookup_and_counter(graph):
112+
counter = 0
113+
lookup = {}
114+
for k, v in graph['nodes'].items():
115+
if int(k) > counter:
116+
counter = int(k)
117+
lookup[v["URI"]] = k
118+
return lookup, counter
119+
120+
121+
def main():
122+
args = parse_args()
123+
124+
integrated_graph, versions = parse_stitched(args.stitched)
125+
print(integrated_graph)
126+
nodes_lookup, counter = get_nodes_lookup_and_counter(integrated_graph)
127+
128+
for dynamic in args.dynamic:
129+
process_dynamic(dynamic, integrated_graph, versions,
130+
counter, nodes_lookup)
131+
132+
with open(args.output, 'w') as out:
133+
json.dump(integrated_graph, out)
134+
135+
136+
if __name__ == "__main__":
137+
main()

test_data/minigzip.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[["//libc6/libc.so;C/_IO_doallocbuf()", "//libc6/libc.so;C/_IO_file_doallocate()"], ["//libc6/libc.so;C/_IO_file_close()", "//libc6/libc.so;C/__close_nocancel()"], ["//libc6/libc.so;C/_IO_file_doallocate()", "//libc6/libc.so;C/_IO_file_stat()"], ["//libc6/libc.so;C/_IO_file_doallocate()", "//libc6/libc.so;C/_IO_setb()"], ["//libc6/libc.so;C/_IO_file_read()", "//libc6/libc.so;C/read()"], ["//libc6/libc.so;C/__default_morecore()", "//libc6/libc.so;C/sbrk()"], ["//libc6/ld-linux-x86-64.so;C/_dl_allocate_tls_init()", "//libc6/libc.so;C/mempcpy()"], ["//libc6/ld-linux-x86-64.so;C/_dl_allocate_tls_init()", "//libc6/libc.so;C/memset()"], ["//libc6/ld-linux-x86-64.so;C/_dl_catch_error()", "//libc6/ld-linux-x86-64.so;C/_dl_catch_exception()"], ["//libc6/ld-linux-x86-64.so;C/_dl_catch_exception()", "//libc6/libc.so;C/__sigsetjmp()"], ["//libc6/libc.so;C/_setjmp()", "//libc6/libc.so;C/__sigsetjmp()"], ["//libc6/ld-linux-x86-64.so;C/calloc()", "//libc6/ld-linux-x86-64.so;C/malloc()"], ["//zlib1g-dev/minigzip;C/deflateEnd()", "//zlib1g-dev/minigzip;C/zcfree()"], ["//zlib1g-dev/minigzip;C/deflateInit2_()", "//zlib1g-dev/minigzip;C/deflateResetKeep()"], ["//zlib1g-dev/minigzip;C/deflateInit2_()", "//zlib1g-dev/minigzip;C/zcalloc()"], ["//zlib1g-dev/minigzip;C/deflateReset()", "//zlib1g-dev/minigzip;C/crc32()"], ["//zlib1g-dev/minigzip;C/deflateResetKeep()", "//zlib1g-dev/minigzip;C/crc32()"], ["//libc6/libc.so;C/fread()", "//libc6/libc.so;C/_IO_sgetn()"], ["//zlib1g-dev/minigzip;C/gz_compress()", "//libc6/libc.so;C/ferror()"], ["//zlib1g-dev/minigzip;C/gz_compress()", "//libc6/libc.so;C/fread()"], ["//zlib1g-dev/minigzip;C/gz_compress()", "//zlib1g-dev/minigzip;C/gzclose()"], ["//zlib1g-dev/minigzip;C/gz_compress()", "//zlib1g-dev/minigzip;C/gzwrite()"], ["//zlib1g-dev/minigzip;C/gzclose()", "//zlib1g-dev/minigzip;C/gzclose_w()"], ["//zlib1g-dev/minigzip;C/gzclose_w()", "//zlib1g-dev/minigzip;C/deflateEnd()"], ["//zlib1g-dev/minigzip;C/gzclose_w()", "//libc6/ld-linux-x86-64.so;C/free()"], ["//zlib1g-dev/minigzip;C/main()", "//zlib1g-dev/minigzip;C/gz_compress()"], ["//zlib1g-dev/minigzip;C/main()", "//zlib1g-dev/minigzip;C/gzdopen()"], ["//libc6/ld-linux-x86-64.so;C/malloc()", "//libc6/libc.so;C/mmap()"], ["//libc6/libc.so;C/sbrk()", "//libc6/libc.so;C/brk()"], ["//libc6/libc.so;C/snprintf()", "//libc6/libc.so;C/vsnprintf()"], ["//libc6/libc.so;C/strdup()", "//libc6/ld-linux-x86-64.so;C/malloc()"], ["//libc6/libc.so;C/strdup()", "//libc6/libc.so;C/memcpy()"], ["//libc6/libc.so;C/strdup()", "//libc6/libc.so;C/strlen()"], ["//libc6/libc.so;C/vfprintf()", "//libc6/libc.so;C/_IO_default_xsputn()"], ["//libc6/libc.so;C/vsnprintf()", "//libc6/libc.so;C/vfprintf()"], ["//zlib1g-dev/minigzip;C/zcalloc()", "//libc6/ld-linux-x86-64.so;C/malloc()"], ["//zlib1g-dev/minigzip;C/zcfree()", "//libc6/ld-linux-x86-64.so;C/free()"]]

test_data/minigzipsh.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[["//libc6/libc.so;C/_IO_doallocbuf()", "//libc6/libc.so;C/_IO_file_doallocate()"], ["//libc6/libc.so;C/_IO_file_close()", "//libc6/libc.so;C/__close_nocancel()"], ["//libc6/libc.so;C/_IO_file_doallocate()", "//libc6/libc.so;C/_IO_file_stat()"], ["//libc6/libc.so;C/_IO_file_doallocate()", "//libc6/libc.so;C/_IO_setb()"], ["//libc6/libc.so;C/_IO_file_read()", "//libc6/libc.so;C/read()"], ["//libc6/libc.so;C/__default_morecore()", "//libc6/libc.so;C/sbrk()"], ["//libc6/libc.so;C/__snprintf_chk()", "//libc6/libc.so;C/__vsnprintf_chk()"], ["//libc6/libc.so;C/__vsnprintf_chk()", "//libc6/libc.so;C/vfprintf()"], ["//libc6/ld-linux-x86-64.so;C/_dl_allocate_tls_init()", "//libc6/libc.so;C/mempcpy()"], ["//libc6/ld-linux-x86-64.so;C/_dl_allocate_tls_init()", "//libc6/libc.so;C/memset()"], ["//libc6/ld-linux-x86-64.so;C/_dl_catch_error()", "//libc6/ld-linux-x86-64.so;C/_dl_catch_exception()"], ["//libc6/ld-linux-x86-64.so;C/_dl_catch_exception()", "//libc6/libc.so;C/__sigsetjmp()"], ["//libc6/libc.so;C/_setjmp()", "//libc6/libc.so;C/__sigsetjmp()"], ["//libc6/ld-linux-x86-64.so;C/calloc()", "//libc6/ld-linux-x86-64.so;C/malloc()"], ["//zlib1g/libz.so;C/crc32()", "//zlib1g/libz.so;C/crc32_z()"], ["//zlib1g/libz.so;C/deflate()", "//zlib1g/libz.so;C/crc32()"], ["//zlib1g/libz.so;C/deflateReset()", "//zlib1g/libz.so;C/deflateResetKeep()"], ["//zlib1g/libz.so;C/deflateResetKeep()", "//zlib1g/libz.so;C/crc32()"], ["//libc6/libc.so;C/fread()", "//libc6/libc.so;C/_IO_sgetn()"], ["//zlib1g-dev/minigzipsh;C/gz_compress()", "//libc6/libc.so;C/ferror()"], ["//zlib1g-dev/minigzipsh;C/gz_compress()", "//libc6/libc.so;C/fread()"], ["//zlib1g/libz.so;C/gzclose_w()", "//zlib1g/libz.so;C/deflate()"], ["//zlib1g/libz.so;C/gzclose_w()", "//zlib1g/libz.so;C/deflateReset()"], ["//zlib1g/libz.so;C/gzclose_w()", "//libc6/ld-linux-x86-64.so;C/free()"], ["//zlib1g/libz.so;C/gzdopen()", "//libc6/ld-linux-x86-64.so;C/malloc()"], ["//zlib1g-dev/minigzipsh;C/main()", "//zlib1g-dev/minigzipsh;C/gz_compress()"], ["//libc6/ld-linux-x86-64.so;C/malloc()", "//libc6/libc.so;C/mmap()"], ["//libc6/libc.so;C/sbrk()", "//libc6/libc.so;C/brk()"], ["//libc6/libc.so;C/snprintf()", "//libc6/libc.so;C/vsnprintf()"], ["//libc6/libc.so;C/strdup()", "//libc6/ld-linux-x86-64.so;C/malloc()"], ["//libc6/libc.so;C/strdup()", "//libc6/libc.so;C/memcpy()"], ["//libc6/libc.so;C/strdup()", "//libc6/libc.so;C/strlen()"], ["//libc6/libc.so;C/vfprintf()", "//libc6/libc.so;C/_IO_default_xsputn()"], ["//libc6/libc.so;C/vsnprintf()", "//libc6/libc.so;C/vfprintf()"]]

test_data/zlib1g-dev.json

+1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)