diff --git a/llvm/mc/__init__.py b/llvm/mc/__init__.py index 07b503e..0a7da1d 100644 --- a/llvm/mc/__init__.py +++ b/llvm/mc/__init__.py @@ -8,6 +8,45 @@ import contextlib from llvmpy import api from llvmpy.api.llvm import MCDisassembler +class Operand(object): + + def __init__(self, mcoperand, target_machine): + ''' + @mcoperand: an MCOperand object + @target_machine: an llvm.target.TargetMachine object + ''' + + self.op = mcoperand + if not self.op: + raise llvm.LLVMException("null MCOperand argument") + + self.tm = target_machine + + def __repr__(self): + s = "invalid" + if self.op.isReg(): + s = "reg(%s)" % (self.reg_name()) + elif self.op.isImm(): + s = "imm(0x%02x)" % (self.op.getImm()) + elif self.op.isFPImm(): + s = "imm(%r)" % (self.op.getFPImm()) + elif self.op.isExpr(): + s = "expr(%r)" % (self.op.getExpr().getKind()) + elif self.op.isInst(): + s = repr(Instr(self.op.getInst())) + + return s + + def reg_name(self): + if self.op.isReg(): + s = self.tm.reg_info.getName(self.op.getReg()) + if s.strip() == "": + return "?" + else: + return s + else: + return "" + class Instr(object): def __init__(self, mcinst, target_machine): @@ -35,7 +74,7 @@ class Instr(object): l = [] for i in range(0, amt): - l.append(self.mcinst.getOperand(i)) + l.append(Operand(self.mcinst.getOperand(i), self.tm)) return l @@ -56,15 +95,20 @@ class Disassembler(object): return self.tm.asm_info def instr(self, mcinst): - return Instr(mcinst, self) + return Instr(mcinst, self.tm) def bad_instr(self, mcinst): - return BadInstr(mcinst, self) + return BadInstr(mcinst, self.tm) - #decode some bytes into instructions. yields each instruction - #as it is decoded. - def decode(self, bs): - code = api.llvm.StringRefMemoryObject.new(bs, 0) + def decode(self, bs, addr): + ''' + decodes some the bytes in @bs into instructions and yields + each instructionas it is decoded. @addr is the base address + where the instruction bytes are from (not an offset into + @bs) + ''' + + code = api.llvm.StringRefMemoryObject.new(bs, addr) idx = code.getBase() align = self.mai.getMinInstAlignment() diff --git a/llvmpy/src/MC/__init__.py b/llvmpy/src/MC/__init__.py index a7512c4..1da7b0e 100644 --- a/llvmpy/src/MC/__init__.py +++ b/llvmpy/src/MC/__init__.py @@ -29,6 +29,9 @@ class TargetSubtargetInfo: class MCExpr: _include_ = "llvm/MC/MCExpr.h" + ExprKind = Enum('Binary', 'Constant', 'SymbolRef', 'Unary', 'Target') + getKind = Method(ExprKind) + @MCOperand class MCOperand: _include_ = "llvm/MC/MCInst.h" @@ -44,8 +47,7 @@ class MCOperand: getImm = Method(cast(Int64, int)) getFPImm = Method(cast(Double, float)) getExpr = Method(const(ptr(MCExpr))) - - + @MCInst class MCInst: _include_ = "llvm/MC/MCInst.h" @@ -56,6 +58,8 @@ class MCInst: getOperand = Method(const(ref(MCOperand)), cast(int, Unsigned)) +MCOperand.getInst = Method(const(ptr(MCInst))) + @MCAsmInfo class MCAsmInfo: _include_ = "llvm/MC/MCAsmInfo.h" @@ -68,6 +72,8 @@ class MCAsmInfo: class MCRegisterInfo: _include_ = "llvm/MC/MCRegisterInfo.h" + getName = Method(cast(ConstCharPtr, str), cast(int, Unsigned)) + @MCInstrInfo class MCInstrInfo: _include_ = "llvm/MC/MCInstrInfo.h" diff --git a/test/example-disassemble.py b/test/example-disassemble.py index 71a2ec6..1ccfe05 100644 --- a/test/example-disassemble.py +++ b/test/example-disassemble.py @@ -8,32 +8,8 @@ if llvm.version >= (3, 4): llvm.target.initialize_all() - def op_str(op): - s = [] - if op.isValid(): - s.append("valid") - else: - s.append("invalid") - - if op.isReg(): - s.append("+reg(%d)" % op.getReg()) - - if op.isImm(): - s.append("+imm(%d)" % op.getImm()) - - if op.isFPImm(): - s.append("+fp-imm(%f)" % op.getFPImm()) - - if op.isExpr(): - s.append("+expr") - - if op.isInst(): - s.append("+inst") - - return " ".join(s) - def print_instructions(dasm, bs): - for (offset, inst) in dasm.decode(bs): + for (offset, inst) in dasm.decode(bs, 0): if inst is None: print("\t%r=>(bad): 0, []" % (offset)) else: @@ -43,7 +19,7 @@ if llvm.version >= (3, 4): print("\t%r=>%r: %r" % (offset, inst, len(inst))) for op in inst.operands(): - print("\t\t%s" % op_str(op)) + print("\t\t%s" % repr(op)) x86 = TargetMachine.x86() diff --git a/test/testall.py b/test/testall.py index 99cc2ac..25d319c 100644 --- a/test/testall.py +++ b/test/testall.py @@ -659,7 +659,7 @@ def do_llvm_mc(): tm = TargetMachine.x86() dasm = mc.Disassembler(tm) - for (offset, instr) in dasm.decode("c3"): + for (offset, instr) in dasm.decode("c3", 0): pass def main():