mirror of https://github.com/geohot/qira
cfg looks better
This commit is contained in:
parent
2f3001427b
commit
feccd79bb9
4
go.sh
4
go.sh
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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??
|
||||
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
|
||||
#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)
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
12
web/qira.css
12
web/qira.css
|
@ -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 {
|
||||
|
|
|
@ -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/>
|
||||
|
|
|
@ -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){
|
||||
|
|
Loading…
Reference in New Issue