cfg looks better

This commit is contained in:
George Hotz 2014-06-24 14:34:36 -07:00
parent 2f3001427b
commit feccd79bb9
10 changed files with 159 additions and 33 deletions

4
go.sh
View File

@ -1,11 +1,11 @@
#!/bin/sh
set -e
cd tests
gcc -m32 -nostdlib -static algo.c
gcc -m32 -nostdlib -static -g algo.c
cd ../
cd scripts
./run_qemu.sh
python db_commit_asm.py
python db_commit_asm.py ../tests/a.out ../tests/algo.c
python db_commit_log.py
python db_commit_blocks.py
python memory_server.py

View File

@ -1,8 +1,39 @@
from pymongo import MongoClient
from elftools.elf.elffile import ELFFile
import sys
db = MongoClient('localhost', 3001).meteor
ds = []
sdict = {}
cdict = {}
elf = ELFFile(open(sys.argv[1]))
for section in elf.iter_sections():
try:
for symbol in section.iter_symbols():
if len(symbol.name) > 0:
sdict[symbol['st_value']] = symbol.name
except:
pass
if elf.has_dwarf_info() and len(sys.argv) > 2:
src = open(sys.argv[2]).read().split("\n")
di = elf.get_dwarf_info()
for CU in di.iter_CUs():
for DIE in CU.iter_DIEs():
#print DIE
if DIE.tag == 'DW_TAG_subprogram':
try:
lowpc = DIE.attributes['DW_AT_low_pc'].value
highpc = DIE.attributes['DW_AT_high_pc'].value
fil = DIE.attributes['DW_AT_decl_file']
line = DIE.attributes['DW_AT_decl_line'].value
except:
pass
print lowpc, highpc, fil, line, src[line]
cdict[lowpc] = src[line]
dat = open("/tmp/qira_disasm").read().split("\n")
for d in dat:
if ": " in d:
@ -10,8 +41,14 @@ for d in dat:
addr = int(addr, 16)
#print addr, inst
d = {'address': addr, 'instruction': inst}
if addr in sdict:
d['name'] = sdict[addr]
if addr in cdict:
print hex(addr)
d['comment'] = cdict[addr]
ds.append(d)
# DWARF data will go here too
coll = db.program
print "doing db insert"

View File

@ -8,6 +8,7 @@ db = MongoClient('localhost', 3001).meteor
print "reading log"
dat = read_log("/tmp/qira_log")
fxns = do_function_analysis(dat)
print fxns
print "building blocks data"
@ -78,7 +79,15 @@ for (address, data, clnum, flags) in dat:
blocks.append({'clstart': cchange[0], 'clend': last[0], 'start': cchange[1], 'end': last[1], 'depth': get_depth(fxns, cchange[0])})
do_loop_analysis(blocks)
(blocks, loops) = do_loop_analysis(blocks)
coll = db.loops
print "doing loops insert"
coll.drop()
coll.insert(loops)
print "db insert done, building indexes"
coll.ensure_index("blockidx")
print "indexes built"
coll = db.blocks
print "doing db insert"

View File

@ -35,7 +35,6 @@ def do_function_analysis(dat):
last_instruction = address
return fxn
def get_depth(fxns, clnum):
d = 0
for f in fxns:

View File

@ -1,27 +1,51 @@
def do_loop_analysis(blocks):
blocks = blocks[0:0x30]
#blocks = blocks[0:0x30]
arr = []
bb = []
for b in blocks:
h = hex(b['start']) + "-" + hex(b['end'])
ab = []
for i in range(len(blocks)):
h = hex(blocks[i]['start']) + "-" + hex(blocks[i]['end'])
if h not in arr:
arr.append(h)
bb.append(arr.index(h))
ab.append(i)
loops = []
# write this n^2 then make it fast
# something must run 3 times to make it a loop??
for i in range(len(bb)):
for j in range(1,i):
if bb[i:i+j] == bb[i+j:i+j*2] and bb[i:i+j] == bb[i+j*2:i+j*3]:
loopcnt = 1
while bb[i+j*loopcnt:i+j*(loopcnt+1)] == bb[i:i+j]:
loopcnt += 1
print "loop",bb[i:i+j],"@",i,"with count",loopcnt
did_update = True
while did_update:
did_update = False
for i in range(len(bb)):
for j in range(1,i):
# something must run 3 times to make it a loop
if bb[i:i+j] == bb[i+j:i+j*2] and bb[i:i+j] == bb[i+j*2:i+j*3]:
loopcnt = 1
while bb[i+j*loopcnt:i+j*(loopcnt+1)] == bb[i:i+j]:
loopcnt += 1
#print "loop",bb[i:i+j],"@",i,"with count",loopcnt
# document the loop
loop = {"clstart":blocks[ab[i]]['clstart'],
"clendone":blocks[ab[i+j-1]]['clend'],
"clend":blocks[ab[i+j*loopcnt]]['clend'],
"blockstart":ab[i],
"blockend":ab[i]+j-1,
"count": loopcnt}
# remove the loop from the blocks
bb = bb[0:i] + bb[i:i+j] + bb[i+j*loopcnt:]
ab = ab[0:i] + ab[i:i+j] + ab[i+j*loopcnt:]
print loop
loops.append(loop)
did_update = True
break
if did_update:
break
print bb
exit(0)
ret = []
for i in ab:
t = blocks[i]
t["blockidx"] = i
ret.append(t)
return (ret, loops)

View File

@ -68,8 +68,8 @@ int main() {
ret += nest();
ret += sum_of_1_through_10();
ret += recurse_countdown(10);
ret += fib(4);
ret += bubble_sort(tmp, sizeof(tmp)/sizeof(int));
//ret += fib(4);
//ret += bubble_sort(tmp, sizeof(tmp)/sizeof(int));
return ret;
}

View File

@ -1,5 +1,6 @@
Change = new Meteor.Collection("change");
Blocks = new Meteor.Collection("blocks");
Loops = new Meteor.Collection("loops");
Program = new Meteor.Collection("program");
// bitops make numbers negative
@ -134,16 +135,33 @@ Deps.autorun(function() {
}
});
Template.cfg.loopcnt = function() {
var tmp = Loops.findOne({"blockstart": {$lte: this.blockidx}, "blockend": {$gte: this.blockidx}});
if (tmp) {
return "run "+tmp.count+" times";
}
return "";
}
Template.cfg.isloop = function() {
var tmp = Loops.findOne({"blockstart": {$lte: this.blockidx}, "blockend": {$gte: this.blockidx}});
if (tmp) {
return "blockloop";
}
return "";
};
Template.cfg.isiaddr = function() {
var iaddr = Session.get('iaddr');
if (this.address == iaddr) return "highlight";
else return "";
}
Template.cfg.ischange = function() {
var clnum = Session.get('clnum');
if (this.clnum == clnum) return "highlight";
else return "";
}
};
Template.cfg.hexaddress = function() { return hex(this.address)+": "; };
Template.cfg.hexstart = function() { return hex(this.start); };
@ -156,6 +174,20 @@ Template.cfg.instruction = function() {
}
};
Template.cfg.comment = function() {
te = Program.findOne({address: this.address});
if (te !== undefined && te.comment != undefined) {
return " // "+te.comment;
}
};
Template.cfg.name = function() {
te = Program.findOne({address: this.address});
if (te !== undefined && te.name != undefined) {
return te.name;
}
};
Template.cfg.instructions = function() {
//p(this.clstart + " " + this.clend);
var changes = Change.find({clnum: {$gte: this.clstart, $lte: this.clend}, type: "I"}, {sort: {clnum: 1}});
@ -176,8 +208,7 @@ Template.cfg.ddepth = function() {
Template.cfg.blocks = function() {
var clnum = Session.get('clnum');
var BEFORE = clnum-0x10;
var AFTER = clnum+0x30;
var cblocks = Blocks.find({clend: {$gt: BEFORE}, clstart: {$lt: AFTER}}, {sort: {clstart: 1}});
var cblocks = Blocks.find({clend: {$gt: BEFORE}}, {sort: {clstart: 1}, limit: 20});
return cblocks;
};

View File

@ -6,6 +6,16 @@
margin-top: 5px;
text-align: left;
font-size: 11px;
font-family: monospace;
}
.blockloop {
background-color: #f8e8ff;
}
.name {
color: blue;
}
.comment {
color: purple;
}
#daddr_input {
border: 1px solid black !important;
@ -69,7 +79,7 @@
}
.address {
color: pink;
color: #880000;
}
.change {

View File

@ -38,12 +38,15 @@ regviewer
<template name="cfg">
{{#each blocks}}
<!--block {{clstart}}-{{clend}} from {{hexstart}}-{{hexend}}-->
<div class="block" style="margin-left: {{ddepth}}px">
<div class="block {{isloop}}" id="block_{{blockidx}}" style="margin-left: {{ddepth}}px">
{{loopcnt}}
{{#each instructions}}
<div class="name">{{name}}</div>
<div class="instruction">
<div class="change {{ischange}}">{{clnum}}</div>
<span class="address {{isiaddr}}">{{hexaddress}}</span>
{{instruction}}
<span class="comment">{{comment}}</span>
</div>
{{/each}}
</div><br/>

View File

@ -1,5 +1,6 @@
Change = new Meteor.Collection("change");
Blocks = new Meteor.Collection("blocks");
Loops = new Meteor.Collection("loops");
Program = new Meteor.Collection("program");
Meteor.startup(function () {
@ -23,17 +24,29 @@ Meteor.publish('instruction_iaddr', function(iaddr){
Meteor.publish('instructions', function(clnum) {
//return Change.find({clnum: {$gt: clnum-0x10, $lt: clnum+0x18}, type: "I"}, {sort: {clnum:1}});
var BEFORE = clnum-0x10;
var AFTER = clnum+0x30;
var changes = Change.find({clnum: {$gt: BEFORE, $lt: AFTER}, type: "I"});
var cblocks = Blocks.find({clend: {$gt: BEFORE}, clstart: {$lt: AFTER}});
var cblocks = Blocks.find({clend: {$gt: BEFORE}}, {limit: 20});
//cblocks.forEach(function(post) { console.log(post); });
// build the changelist fetching query from the blocks
var query = [];
changes.forEach(function(post) {
query.push({address: post.address});
});
var lquery = [];
cblocks.forEach(function(post) {
lquery.push({blockstart: post.blockidx});
query.push({clnum: {$gte: post.clstart, $lte: post.clend}})
})
if (query.length == 0) { console.log("cl query failed"); return; }
// limit here should be the onscreen blocks
var changes = Change.find({$or: query, type: "I"}, {sort: {clnum: 1}, limit: 0x50});
var loops = Loops.find({$or: lquery});
// build the address fetching query from the changelists
var query = [];
changes.forEach(function(post) { query.push({address: post.address}); });
if (query.length == 0) { console.log("ins query failed"); return; }
var progdat = Program.find({$or: query});
// we need to send the program data back here as well...
return [changes, cblocks, progdat];
return [changes, cblocks, progdat, loops];
});
Meteor.publish('dat_iaddr', function(iaddr){