Commit 497bc1a1 authored by Axel Simon's avatar Axel Simon
Browse files

get code generator working to some extend

parent 40848329
//
// RReil.cpp
// CFGresolve
//
// Created by Axel Simon on 20.10.12.
// Copyright (c) 2012 Axel Simon. All rights reserved.
//
#include "RReil.h"
#include <assert.h>
extern "C" {
#include "../../dis.h"
}
std::ostream& operator<<(std::ostream& o, const RReilBB& s) {
return o << "basic block of size " << s.size();
};
std::ostream& operator<<(std::ostream& o, const Stmt& s) {
return o ;
};
std::ostream& operator<<(std::ostream& o, const Op& s) {
return o ;
};
RReilBB* translateRReilBB(__obj list);
Stmt* translateStmt(__obj instr);
RReilBB* translate(RReilAddress start, RReilAddress limit) {
__obj semantics;
__resetHeap();
__word read = __decode(__translateBlock__, (__char*) start, (__word) (limit-start), &semantics);
if (read==0) return NULL;
return translateRReilBB(semantics);
};
RReilBB* translateRReilBB(__obj list) {
RReilBB* bb = new RReilBB();
while (__CASETAGCON(list)==__SEM_CONS) {
__obj rec = __DECON(list);
__obj instr = __RECORD_SELECT(rec, ___hd);
list = __RECORD_SELECT(rec, ___tl);
Stmt* s = translateStmt(instr);
bb->push_back(s);
};
assert(__CASETAGCON(list)==__SEM_NIL);
return bb;
};
Stmt* translateStmt(__obj instr) {
Stmt* s = NULL;
switch (__CASETAGCON(instr)) {
case __SEM_ASSIGN: {
__obj rec = __DECON(instr);
//s = Assign.build();
}; break;
}
return s;
};
Var* Var::temp(int i, int s) { return new Var(i+ __NTAGS, s); };
Var* Var::build(int i, int s) { return new Var(i, s); };
//
// RReil.h
// CFGresolve
//
// Created by Axel Simon on 20.10.12.
// Copyright (c) 2012 Axel Simon. All rights reserved.
//
#ifndef CFGresolve_RReil_h
#define CFGresolve_RReil_h
#include <iostream>
#include <vector>
class RReilBB;
typedef char* RReilAddress;
class Stmt;
enum BranchHint {
HintJump,
HintCall,
HintRet
};
class Assign;
class Load;
class Store;
class IfThenElse;
class While;
class CBranch;
class Branch;
class Var;
class Op;
class Linear;
class Binary;
class SignExtend;
class ZeroExtend;
class Cmp;
class Arbitrary;
enum BinOp {
Mul,
Div,
DivS,
Mod,
Shl,
Shr,
ShrS,
And,
Or,
Xor
};
enum CmpOp {
Eq,
Neq,
LeS,
LeU,
LtS,
LtU
};
class Lin;
class LinVar;
class LinImm;
class LinAdd;
class LinSub;
class LinScale;
class Address;
/**
* Disassemble starting from the given address and stop when the limit is reached or a complete basic block
* has been decoded. Translate decoded instructions to RReil and return this semantic block. Returns NULL
* if the address contains an illegal instruction or the limit is reached.
*/
RReilBB* translate(RReilAddress start, RReilAddress limit);
class RReilBB : public std::vector<Stmt*> {
protected:
std::vector<RReilAddress> pred;
std::vector<RReilAddress> succ;
public:
std::vector<RReilAddress>::const_iterator pred_iter() {
return pred.begin();
};
std::vector<RReilAddress>::const_iterator succ_iter() {
return succ.begin();
};
void addPred(RReilAddress addr) {
std::vector<RReilAddress>::iterator iter = std::find(pred.begin(), pred.end(), addr);
if (iter==pred.end()) pred.push_back(addr);
};
void addSucc(RReilAddress addr) {
std::vector<RReilAddress>::iterator iter = std::find(succ.begin(), succ.end(), addr);
if (iter==succ.end()) succ.push_back(addr);
};
friend std::ostream& operator<<(std::ostream& o, const RReilBB& s);
};
class StmtVisitor {
public:
virtual void accept(const Assign& s) = 0;
virtual void accept(const Load& s) = 0;
virtual void accept(const Store& s) = 0;
virtual void accept(const IfThenElse& s) = 0;
virtual void accept(const While& s) = 0;
virtual void accept(const CBranch& s) = 0;
virtual void accept(const Branch& s) = 0;
};
class Stmt {
public:
virtual void visit(StmtVisitor& v) const = 0;
friend std::ostream& operator<<(std::ostream& o, const Stmt& s);
};
class Assign : public Stmt {
const Var* lhs;
const Op* rhs;
Assign(Var* l, Op* r) : lhs(l), rhs(r) {};
public:
static Assign* build(Var* lhs, Op* rhs) { return new Assign(lhs, rhs); };
void visit(StmtVisitor& v) const { v.accept(*this); };
};
class Load : public Stmt {
int bitSize;
Var* lhs;
Address* rhs;
Load(int bitSize, Var* lhs, Address* rhs) : bitSize(bitSize), lhs(lhs), rhs(rhs) {};
public:
static Load* build(int bitSize, Var* lhs, Address* rhs) { return new Load(bitSize, lhs, rhs); };
void visit(StmtVisitor& v) const { v.accept(*this); };
};
class Store : public Stmt {
Address* lhs;
Op* rhs;
Store(Address* lhs, Op* rhs) : lhs(lhs), rhs(rhs) {};
public:
static Store* build(Address* lhs, Op* rhs) { return new Store(lhs, rhs); };
void visit(StmtVisitor& v) const { v.accept(*this); };
};
class IfThenElse : public Stmt {
Lin* cond;
RReilBB* thenBranch;
RReilBB* elseBranch;
IfThenElse(Lin* cond, RReilBB* thenBranch, RReilBB* elseBranch) :
cond(cond), thenBranch(thenBranch), elseBranch(elseBranch) {};
public:
static IfThenElse* build(Lin* cond, RReilBB* thenBranch, RReilBB* elseBranch) {
return new IfThenElse(cond, thenBranch, elseBranch);
};
void visit(StmtVisitor& v) const { v.accept(*this); };
};
class While : public Stmt {
Lin* cond;
RReilBB* body;
While(Lin* cond, RReilBB* body) : cond(cond), body(body) {};
public:
static While* build(Lin* cond, RReilBB* body) { return new While(cond, body); };
void visit(StmtVisitor& v) const { v.accept(*this); };
};
class CBranch : public Stmt {
Lin* cond;
Address* targetT;
Address* targetF;
CBranch(Lin* cond, Address* targetT, Address* targetF) : cond(cond), targetT(targetT), targetF(targetF) {};
public:
static CBranch* build(Lin* cond, Address* targetT, Address* targetF) { return new CBranch(cond, targetT, targetF); };
void visit(StmtVisitor& v) const { v.accept(*this); };
};
class Branch : public Stmt {
BranchHint hint;
Address* target;
Branch(BranchHint hint, Address* target) : hint(hint), target(target) {};
public:
static Branch* build(BranchHint hint, Address* target) { return new Branch(hint, target); };
void visit(StmtVisitor& v) const { v.accept(*this); };
};
/* variables */
class Var {
int variable;
int bitsize;
private:
Var(int i, int s) : variable(i), bitsize(s) {};
public:
static Var* temp(int i, int s);
static Var* build(int i, int s);
};
/* operators */
class OpVisitor {
public:
virtual void accept(const Linear& op) = 0;
virtual void accept(const Binary& op) = 0;
virtual void accept(const SignExtend& op) = 0;
virtual void accept(const ZeroExtend& op) = 0;
virtual void accept(const Cmp& op) = 0;
virtual void accept(const Arbitrary& op) = 0;
};
class Op {
public:
virtual void visit(OpVisitor& v) const = 0;
friend std::ostream& operator<<(std::ostream& o, const Op& s);
};
class Linear : public Op {
int bitSize;
Lin* lin;
Linear(int bitSize, Lin* l) : bitSize(bitSize), lin(l) {};
public:
Linear* build(int bitSize, Lin* l) { return new Linear(bitSize, l); }
void visit(OpVisitor& v) const { v.accept(*this); };
};
class Binary : public Op {
int bitSize;
Lin* lhs;
BinOp op;
Lin* rhs;
Binary(int bitSize, Lin* lhs, BinOp op, Lin* rhs) : bitSize(bitSize), lhs(lhs), op(op), rhs(rhs) {};
public:
Binary* build(int bitSize, Lin* lhs, BinOp op, Lin* rhs) { return new Binary(bitSize, lhs, op, rhs); };
void visit(OpVisitor& v) const { v.accept(*this); };
};
class SignExtend : public Op {
int fromSize;
int toSize;
Lin* arg;
SignExtend(int fromSize, int toSize, Lin* arg) : fromSize(fromSize),
toSize(toSize), arg(arg) {};
public:
SignExtend* build(int fromSize, int toSize, Lin* arg) {
return new SignExtend(fromSize, toSize, arg);
};
void visit(OpVisitor& v) const { v.accept(*this); };
};
class ZeroExtend : public Op {
int fromSize;
int toSize;
Lin* arg;
ZeroExtend(int fromSize, int toSize, Lin* arg) : fromSize(fromSize),
toSize(toSize), arg(arg) {};
public:
ZeroExtend* build(int fromSize, int toSize, Lin* arg) {
return new ZeroExtend(fromSize, toSize, arg);
};
void visit(OpVisitor& v) const { v.accept(*this); };
};
class Cmp : public Op {
int bitSize;
Lin* lhs;
CmpOp op;
Lin* rhs;
Cmp(int bitSize, Lin* lhs, CmpOp op, Lin* rhs) : bitSize(bitSize), lhs(lhs), op(op), rhs(rhs) {};
public:
Cmp* build(int bitSize, Lin* lhs, CmpOp op, Lin* rhs) { return new Cmp(bitSize, lhs, op, rhs); };
void visit(OpVisitor& v) const { v.accept(*this); };
};
class Arbitrary : public Op {
int bitSize;
Arbitrary(int bitSize) : bitSize(bitSize) {};
public:
Arbitrary* build(int bitSize) { return new Arbitrary(bitSize); };
void visit(OpVisitor& v) const { v.accept(*this); };
};
#endif
......@@ -10,6 +10,7 @@
#include <fstream>
#include <mach-o/loader.h>
#include "Segment.h"
#include "RReil.h"
#include <vector>
#include <fcntl.h>
......@@ -82,6 +83,8 @@ int main(int argc, const char * argv[]) {
char* limit;
char* addr = segments.resolve(start, &limit);
std::cout << "first byte of text segment is " << std::hex << start << ": " << std::hex << (uint8_t) (*addr) << std::endl;
RReilBB* b = translate(addr,limit);
if (b!=NULL) std::cout << "basic block:" << std::endl << *b << std::endl;
return 0;
}
......@@ -206,7 +206,7 @@ structure C = struct
[PrettyC.call' ("__INT_BEGIN", PrettyC.args [x]),
PrettyC.call'
("__INT_INIT",
seq [lp, str (IntInf.toString i), rp]),
seq [lp, str (IntInf.toString i ^ "u"), rp]),
PrettyC.call' ("__INT_END", PrettyC.args [x])])]
| INJ (t, y) =>
PrettyC.cseq
......
......@@ -11,13 +11,13 @@ __objref hp = &heap[__RT_HEAP_SIZE];
@prototypes@
struct __unwrapped_immediate __unwrapped_UNIT =
struct __s_unwrapped_immediate __unwrapped_UNIT =
{.header.tag = __NIL};
struct __unwrapped_bv __unwrapped_TRUE =
struct __s_unwrapped_bv __unwrapped_TRUE =
{.header.tag = __BV,
.sz = 1,
.vec = 1};
struct __unwrapped_bv __unwrapped_FALSE =
struct __s_unwrapped_bv __unwrapped_FALSE =
{.header.tag = __BV,
.sz = 1,
.vec = 0};
......@@ -460,7 +460,7 @@ const __char* __tagName (__word i) {
__obj __showbitvec (__obj o) {
char fmt[16];
snprintf(fmt,16,"0x%zx",o->bv.vec);
snprintf(fmt,16,"0x%zx",(unsigned long) o->bv.vec);
__LOCAL0(R);
__ROPE_BEGIN(R);
__ROPE_FROMCSTRING(fmt);
......@@ -470,7 +470,7 @@ __obj __showbitvec (__obj o) {
__obj __showint (__obj o) {
char fmt[64];
snprintf(fmt,64,"%ld",o->z.value);
snprintf(fmt,64,"%ld",(long) o->z.value);
__LOCAL0(R);
__ROPE_BEGIN(R);
__ROPE_FROMCSTRING(fmt);
......@@ -481,24 +481,24 @@ __obj __showint (__obj o) {
__obj __print (__obj o) {
switch (__TAG(o)) {
case __CLOSURE:
printf("{tag=__CLOSURE,sz=%zu,env=..}",o->closure.sz);
printf("{tag=__CLOSURE,sz=%zu,env=..}",(unsigned long) o->closure.sz);
break;
case __INT:
printf("{tag=__INT,value=%ld}", o->z.value);
case __INTEGER:
printf("{tag=__INTEGER,value=%ld}",(long) o->z.value);
break;
case __TAGGED: {
__word tag = o->tagged.tag;
if (tag < __NTAGS)
printf("{tag=%s,",__tagName(tag));
else
printf("{tag=<unknown:%lu>,",tag);
printf("{tag=<unknown:%lu>,",(unsigned long) tag);
printf("payload=");
__print(o->tagged.payload);
printf("}");
break;
}
case __RECORD: {
printf("{tag=__RECORD,sz=%lu,", o->record.sz);
printf("{tag=__RECORD,sz=%lu,",(unsigned long) o->record.sz);
int i;
for (i=0;i<o->record.sz;i++) {
__objref tagged = &o->record.fields[i];
......@@ -507,7 +507,7 @@ __obj __print (__obj o) {
if (tag < __NFIELDS)
printf("%s=",__fieldName(tag));
else
printf("<unknown:%lu>=",tag);
printf("<unknown:%lu>=",(unsigned long) tag);
__print(payload);
if (i < o->record.sz-1)
printf(",");
......@@ -521,7 +521,7 @@ __obj __print (__obj o) {
__word len = sz > 7 ? 7 : sz;
memcpy(buf,o->ropeleaf.blob,len);
buf[len] = '\0';
printf("{tag=__ROPELEAF,sz=%lu,blob=%s..}",sz,buf);
printf("{tag=__ROPELEAF,sz=%lu,blob=%s..}",(unsigned long) sz,buf);
break;
}
case __ROPEBRANCH: {
......@@ -536,10 +536,10 @@ __obj __print (__obj o) {
printf("{tag=__LABEL,f=%p}",o->label.f);
break;
case __BLOB:
printf("{tag=__BLOB,sz=%lu,blob=%p}",o->blob.sz, o->blob.blob);
printf("{tag=__BLOB,sz=%lu,blob=%p}",(unsigned long) o->blob.sz, o->blob.blob);
break;
case __BV:
printf("{tag=__BV,sz=%lu,vec=%zx}", o->bv.sz, o->bv.vec);
printf("{tag=__BV,sz=%lu,vec=%zx}",(unsigned long) o->bv.sz,(unsigned long) o->bv.vec);
break;
case __NIL:
printf("{tag=__NIL}");
......
......@@ -106,7 +106,7 @@
Cname = __WRAP(o);}
#define __RECORD_BEGIN_UPDATE(Cdst, Csrc)\
{__recordCloneFields((struct __record*)Csrc);\
{__recordCloneFields((struct __s_record*)Csrc);\
__word n = Csrc->record.sz
#define __RECORD_UPDATE(tag, value)\
......@@ -120,7 +120,7 @@
Cdst = __WRAP(o);}}
#define __RECORD_SELECT(Cname, field)\
__recordLookup(((struct __record*)Cname), field)->tagged.payload
__recordLookup(((struct __s_record*)Cname), field)->tagged.payload
/** ## Ropes/Strings */
......@@ -206,7 +206,7 @@ typedef uint8_t __char;
enum __tag {
__CLOSURE,
__BV,
__INT,
__INTEGER,
__TAGGED,
__RECORD,
__NIL,
......@@ -221,90 +221,111 @@ union __header {
__obj ignored;
} __attribute__((aligned(8)));
struct __s_unwrapped_immediate {
__header header;
};
struct __s_unwrapped_tagged {
__header header;
__word tag;
__obj payload;
};
struct __s_unwrapped_closure {
__header header;
__word sz;
__objref env;
};
struct __s_unwrapped_record {
__header header;
__word sz;
__objref fields;
};
struct __s_unwrapped_bv {
__header header;
__word sz;
__word vec;
};
struct __s_unwrapped_label {
__header header;
__obj (*f)(void);
};
struct __s_unwrapped_blob {
__header header;
__char* blob;
__word sz;
};
struct __s_unwrapped_ropeleaf {
__header header;
__char* blob;
__word sz;
};
struct __s_unwrapped_ropebranch {
__header header;
__obj left;
__obj right;
};
struct __s_unwrapped_int {
__header header;
__int value;
} z;
union __unwrapped_obj {
struct __unwrapped_immediate {
__header header;
} object;
struct __unwrapped_tagged {
__header header;
__word tag;
__obj payload;
} tagged;
struct __unwrapped_closure {
__header header;
__word sz;
__objref env;
} closure;
struct __unwrapped_record {
__header header;
__word sz;
__objref fields;
} record;
struct __unwrapped_bv {
__header header;
__word sz;
__word vec;
} bv;
struct __unwrapped_label {
__header header;
__obj (*f)(void);
} label;
struct __unwrapped_blob {
__header header;
__char* blob;
__word sz;
} blob;
struct __unwrapped_ropeleaf {
__header header;
__char* blob;
__word sz;
} ropeleaf;
struct __unwrapped_ropebranch {
__header header;
__obj left;
__obj right;
} ropebranch;
struct __unwrapped_int {
__header header;
__int value;
} z;
struct __s_unwrapped_immediate object;
struct __s_unwrapped_tagged tagged;
struct __s_unwrapped_closure closure;
struct __s_unwrapped_record record;
struct __s_unwrapped_bv bv;
struct __s_unwrapped_label label;
struct __s_unwrapped_blob blob;
struct __s_unwrapped_ropeleaf ropeleaf;
struct __s_unwrapped_ropebranch ropebranch;