diff --git a/.gitattributes b/.gitattributes
index 97e7454d79d3299ea173a0b8920ba65e09f5269d..7105d2cec1eaaeb5b846f00df09e6ca60374d5d9 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -80,6 +80,8 @@ src/interfaces/idapro/STARSInterface.cpp -text
 src/interfaces/irdb/Makefile.in -text
 src/interfaces/irdb/STARSFunction.cpp -text
 src/interfaces/irdb/STARSIRDBProgram.cpp -text
+src/interfaces/irdb/STARSInterface.cpp -text
+src/interfaces/irdb/STARSOp.cpp -text
 src/interfaces/irdb/STARS_IRDB_Instruction.cpp -text
 tests/commit/busybox.psexe -text
 tests/commit/bzip2.psexe -text
diff --git a/src/interfaces/irdb/STARSInterface.cpp b/src/interfaces/irdb/STARSInterface.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1252e5415b8fea69bcd1ff900133764b1ae97c6b
--- /dev/null
+++ b/src/interfaces/irdb/STARSInterface.cpp
@@ -0,0 +1,77 @@
+
+
+#include "interfaces/abstract/STARSInterface.h"
+#include "interfaces/irdb/STARSSegment.h"
+#include "interfaces/irdb/STARSFunction.h"
+#include "interfaces/irdb/STARSInstruction.h"
+#include "interfaces/irdb/STARSSSAInstruction.h"
+#include "interfaces/irdb/STARSFunction.h"
+#include <elfio/elfio.hpp>
+#include <elfio/elfio_dump.hpp>
+
+#include <libIRDB-core.hpp>
+#include <libIRDB-util.hpp>
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <pqxx/pqxx>
+
+
+
+STARS_Instruction_t * STARS_IRDB_Interface_t::CreateInst(STARS_InstructionID_t InstID) 
+{
+	// check for psuedo-instructions
+	if(STARS_IsSSAMarkerPseudoID(InstID.GetIDWithinFile()))
+		return new STARS_IRDB_Instruction_t(InstID);
+	// already created, just return what we need.
+	STARS_Instruction_t* insn=(STARS_Instruction_t*)InstID.GetInstruction();
+	assert(insn);
+	return insn;
+};
+
+
+bool STARS_IRDB_Interface_t::STARS_generate_disasm_line(STARS_ea_t addr, char *buf, std::size_t bufsize, int flags)
+{
+	STARS_InstructionID_t id(addr);
+	const STARS_Instruction_t* insn=id.GetInstruction();
+	const STARS_IRDB_Instruction_t* irdb_insn=dynamic_cast<const STARS_IRDB_Instruction_t*>(insn);
+	strncpy(buf,irdb_insn->GetIRDBInstruction()->getDisassembly().c_str(), bufsize);
+	return true;
+}
+
+
+bool STARS_IRDB_Interface_t::IsInstJumpTarget(STARS_InstructionID_t InstID) const
+{
+        const STARS_IRDB_Instruction_t* interface_insn=dynamic_cast<const STARS_IRDB_Instruction_t*>(InstID.GetInstruction());
+        assert(interface_insn);
+	libIRDB::Instruction_t* insn=(libIRDB::Instruction_t*)interface_insn->GetIRDBInstruction();
+
+        // return true if
+        //      jumped to indirectly (jmp instruction)
+        //      called indirectly (call instruction)
+        if(insn->GetIndirectBranchTargetAddress() != NULL)
+                return true;
+
+        //      jumped to directly (jmp or jcc instruction)
+        //      called directly (call instruction)
+
+        for(libIRDB::InstructionSet_t::iterator it=instruction_preds[insn].begin();
+                it!=instruction_preds[insn].end(); ++it)
+        {
+                if(insn->GetTarget()==insn)
+                        return true;
+        }
+
+        return false;
+
+
+        //      jumped to via a return doesn't count.
+        // be careful and think about this as you impl it.
+        // not sure how to do this, because we don't know if a return will go there.
+        // typically what is meant by a "return goes there" is that a call
+        // instruction preceeds it.  Since call instructions don't (typically) mark
+        // the return point as an IBT, we should be OK.
+
+        // aka -- not (is only-fallthroughed to)
+        assert(0); return 0;
+}
diff --git a/src/interfaces/irdb/STARSOp.cpp b/src/interfaces/irdb/STARSOp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..52117ab2cede671c41a1312ac6d28262e1d29cf8
--- /dev/null
+++ b/src/interfaces/irdb/STARSOp.cpp
@@ -0,0 +1,248 @@
+
+#include "interfaces/irdb/STARSOp.h"
+#include <libIRDB-core.hpp>
+
+
+using namespace std;
+
+static int log2int(int index)
+{
+	int targetlevel = 0;
+	while (index >>= 1) ++targetlevel;
+	return  targetlevel;
+}
+
+
+
+STARS_IRDB_op_t::STARS_IRDB_op_t(const DISASM &d, int indx, const ARGTYPE &the_arg)
+{
+	Init(); // make void
+	int bea_regno=log2int(the_arg.ArgType&0xFFFF);
+	visible=1;
+	switch((the_arg.ArgType&0xFFFF0000))
+	{
+  		case NO_ARGUMENT:
+			/* leave as void */
+			break;
+  		case REGISTER_TYPE + GENERAL_REG :
+		{
+			OpType=op_Reg;
+
+			     if(string(the_arg.ArgMnemonic)=="al")  { operand.reg.RegNum=STARS_x86_R_al; byteWidth=1; }
+			else if(string(the_arg.ArgMnemonic)=="cl")  { operand.reg.RegNum=STARS_x86_R_cl; byteWidth=1; }
+			else if(string(the_arg.ArgMnemonic)=="dl")  { operand.reg.RegNum=STARS_x86_R_dl; byteWidth=1; }
+			else if(string(the_arg.ArgMnemonic)=="bl")  { operand.reg.RegNum=STARS_x86_R_bl; byteWidth=1; }
+			else if(string(the_arg.ArgMnemonic)=="ah")  { operand.reg.RegNum=STARS_x86_R_ah; byteWidth=1; }
+			else if(string(the_arg.ArgMnemonic)=="ch")  { operand.reg.RegNum=STARS_x86_R_ch; byteWidth=1; }
+			else if(string(the_arg.ArgMnemonic)=="dh")  { operand.reg.RegNum=STARS_x86_R_dh; byteWidth=1; }
+			else if(string(the_arg.ArgMnemonic)=="bh")  { operand.reg.RegNum=STARS_x86_R_bh; byteWidth=1; }
+			else if(string(the_arg.ArgMnemonic)=="spl")  { operand.reg.RegNum=STARS_x86_R_spl; byteWidth=1; }
+			else if(string(the_arg.ArgMnemonic)=="spl")  { operand.reg.RegNum=STARS_x86_R_spl; byteWidth=1; }
+			else if(string(the_arg.ArgMnemonic)=="bpl")  { operand.reg.RegNum=STARS_x86_R_bpl; byteWidth=1; }
+			else if(string(the_arg.ArgMnemonic)=="sil")  { operand.reg.RegNum=STARS_x86_R_sil; byteWidth=1; }
+			else if(string(the_arg.ArgMnemonic)=="dil")  { operand.reg.RegNum=STARS_x86_R_dil; byteWidth=1; }
+			else 
+			{
+				// set the operand.reg.RegNum appropriately.
+				operand.reg.RegNum=(STARS_RegNo)(STARS_x86_R_ax+bea_regno);
+
+				// if the first character is an r, it's a 64-bit reg.
+				// e.g. rax, rsp, rdi
+				if(the_arg.ArgMnemonic[0]=='r')
+					byteWidth=8;
+
+				// otherwise, if the first character is an e, and the 3rd char is an 'x', 'p', or 'i'  it's a 32-bit reg. 
+				// e.g., eax, esp, edi
+				// caution: es
+				else if(the_arg.ArgMnemonic[0]=='e' && (the_arg.ArgMnemonic[2]=='x' || the_arg.ArgMnemonic[2]=='i' || the_arg.ArgMnemonic[2]=='p'))
+					byteWidth=4;
+				// e.g	ax, sp, bp, di
+				else if(the_arg.ArgMnemonic[1]=='x' || the_arg.ArgMnemonic[1]=='i' || the_arg.ArgMnemonic[1]=='p')
+					byteWidth=2;
+				else 
+					byteWidth=1;
+			}
+			break;
+		}
+  		case REGISTER_TYPE + MMX_REG :
+			byteWidth=8;
+			OpType=op_MMXReg;
+			operand.reg.RegNum=(STARS_RegNo)(STARS_x86_R_mm0+bea_regno);
+			break;
+  		case REGISTER_TYPE + FPU_REG :
+			byteWidth=8;
+			OpType=op_MMXReg;
+			operand.reg.RegNum=(STARS_RegNo)(STARS_x86_R_st0+bea_regno);
+			break;
+  		case REGISTER_TYPE + SSE_REG :
+			if(the_arg.ArgMnemonic[0]=='x')
+			{
+				byteWidth=8;
+				OpType=op_XMMReg;
+				operand.reg.RegNum=(STARS_RegNo)(STARS_x86_R_xmm0+bea_regno);
+				break;
+			}
+			else if(the_arg.ArgMnemonic[0]=='y')
+			{
+				byteWidth=16;
+				OpType=op_YMMReg;
+				operand.reg.RegNum=(STARS_RegNo)(STARS_x86_R_ymm0+bea_regno);
+				break;
+			}
+			else
+				assert(0);
+  		case REGISTER_TYPE + CR_REG :
+			assert(0);
+/*
+no stars type for control regs?
+			OpType=CrReg;
+			operand.reg.RegNum=STARS_x86_R_cr0+bea_regno;
+*/
+			break;
+  		case REGISTER_TYPE + DR_REG :
+			assert(0);
+/*
+no stars type for debug regs?
+			OpType=op_CrReg;
+			operand.reg.RegNum=STARS_x86_R_cr0+bea_regno;
+*/
+			break;
+  		case REGISTER_TYPE + SPECIAL_REG :
+		{
+			assert(0);
+/*
+
+this isn't even close to right.  should be gdtr, ldtr, idtr, tr, etc.
+no operands for eflags or mxcsr?
+			switch(bea_regno)
+			{
+				case EFLAGS:
+					OpType=op_Eflags;
+					operand.reg.RegNum=0;
+					break;
+				case MXCSR:
+					OpType=op_Mxcsr;
+					operand.reg.RegNum=0;
+					break;
+					break;
+				assert(0);
+			}
+			break;
+*/
+		}
+  		case REGISTER_TYPE + MEMORY_MANAGEMENT_REG :
+			assert(0);
+			break;
+  		case REGISTER_TYPE + SEGMENT_REG :
+			OpType=op_SegReg;
+			operand.reg.RegNum=(STARS_RegNo)(STARS_x86_R_es+bea_regno);
+			break;
+  		case MEMORY_TYPE:
+  		case MEMORY_TYPE + RELATIVE_:
+  		case MEMORY_TYPE + ABSOLUTE_:
+		{
+			operand.mem.base=(STARS_RegNo)the_arg.Memory.BaseRegister;
+			operand.mem.index=(STARS_RegNo)the_arg.Memory.IndexRegister;
+			operand.mem.scale=(STARS_RegNo)the_arg.Memory.Scale;
+			operand.mem.disp=(STARS_RegNo)the_arg.Memory.Displacement;
+			byteWidth=the_arg.ArgSize;
+			OpType=op_Mem;
+			break;
+		}
+  		case CONSTANT_TYPE + RELATIVE_ :
+			OpType=op_Imm;
+			operand.imm.imm=d.Instruction.Immediat;
+			operand.imm.pc_rel=true;
+			byteWidth=the_arg.ArgSize;
+			break;
+  		case CONSTANT_TYPE + ABSOLUTE_ :
+			OpType=op_Imm;
+			operand.imm.imm=d.Instruction.Immediat;
+			operand.imm.pc_rel=false;
+			byteWidth=the_arg.ArgSize;
+			break;
+		default:
+			assert(0);
+	}
+
+
+	// deal with segment register
+	switch(the_arg.SegmentReg)
+	{
+		case 0:		// bea reporting 0 means no register.
+			SegReg=STARS_x86_R_none;	// map to no reg.
+		case ESReg:	// bea seg reg ESReg maps to 
+        		SegReg=STARS_x86_R_es;    // STARS_x86_R_es reg.
+			break;
+		case CSReg:	// etc.
+        		SegReg=STARS_x86_R_cs;
+			break;
+		case SSReg:
+        		SegReg=STARS_x86_R_ss;
+			break;
+		case DSReg:
+        		SegReg=STARS_x86_R_ds;
+			break;
+		case FSReg:
+        		SegReg=STARS_x86_R_fs;
+			break;
+		case GSReg:
+        		SegReg=STARS_x86_R_gs;
+			break;
+		default:
+			assert(0);
+
+	}
+
+
+
+
+
+}
+
+bool STARS_IRDB_op_t::operator<(const STARS_op_t &rOp_param) const
+{
+	const STARS_IRDB_op_t* p=dynamic_cast<const STARS_IRDB_op_t*>(&rOp_param);
+	assert(p);
+	const STARS_IRDB_op_t& rOp=*p;
+
+	if(GetOpType() != rOp.GetOpType())
+		return GetOpType() < rOp.GetOpType();
+
+	switch(GetOpType())
+	{
+		case op_Mem: 
+			if ( operand.mem.base != rOp.operand.mem.base)
+				return ( operand.mem.base < rOp.operand.mem.base);
+			if ( operand.mem.index != rOp.operand.mem.index)
+				return ( operand.mem.index < rOp.operand.mem.index);
+			if ( operand.mem.scale != rOp.operand.mem.scale)
+				return ( operand.mem.scale < rOp.operand.mem.scale);
+			if ( operand.mem.disp != rOp.operand.mem.disp)
+				return ( operand.mem.disp < rOp.operand.mem.disp);
+			return false; // equal
+		case op_Imm: 
+			return operand.imm.imm < rOp.operand.imm.imm;
+		case op_CrReg: 
+		case op_DrReg: 
+		case op_Eflags: 
+		case op_MMXReg: 
+		case op_XMMReg: 
+		case op_YMMReg: 
+		case op_FPReg: 
+		case op_Reg: 
+			return operand.reg.RegNum < rOp.operand.reg.RegNum;
+
+		case op_Void: 
+		case op_Mxcsr: 
+		case op_SegReg:
+			return true;
+
+		case op_Addr:
+			return operand.addr.addr < rOp.operand.addr.addr;
+
+		default:
+			assert(0);
+			
+	}
+}