added llvm.mc.Operand class
Operand encapsulates information that llvm provides about an MCOperand in an instruction.
This commit is contained in:
parent
87d444c9e9
commit
82d9c787f3
4 changed files with 62 additions and 36 deletions
|
|
@ -8,6 +8,45 @@ import contextlib
|
||||||
from llvmpy import api
|
from llvmpy import api
|
||||||
from llvmpy.api.llvm import MCDisassembler
|
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):
|
class Instr(object):
|
||||||
|
|
||||||
def __init__(self, mcinst, target_machine):
|
def __init__(self, mcinst, target_machine):
|
||||||
|
|
@ -35,7 +74,7 @@ class Instr(object):
|
||||||
|
|
||||||
l = []
|
l = []
|
||||||
for i in range(0, amt):
|
for i in range(0, amt):
|
||||||
l.append(self.mcinst.getOperand(i))
|
l.append(Operand(self.mcinst.getOperand(i), self.tm))
|
||||||
|
|
||||||
return l
|
return l
|
||||||
|
|
||||||
|
|
@ -56,15 +95,20 @@ class Disassembler(object):
|
||||||
return self.tm.asm_info
|
return self.tm.asm_info
|
||||||
|
|
||||||
def instr(self, mcinst):
|
def instr(self, mcinst):
|
||||||
return Instr(mcinst, self)
|
return Instr(mcinst, self.tm)
|
||||||
|
|
||||||
def bad_instr(self, mcinst):
|
def bad_instr(self, mcinst):
|
||||||
return BadInstr(mcinst, self)
|
return BadInstr(mcinst, self.tm)
|
||||||
|
|
||||||
#decode some bytes into instructions. yields each instruction
|
def decode(self, bs, addr):
|
||||||
#as it is decoded.
|
'''
|
||||||
def decode(self, bs):
|
decodes some the bytes in @bs into instructions and yields
|
||||||
code = api.llvm.StringRefMemoryObject.new(bs, 0)
|
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()
|
idx = code.getBase()
|
||||||
align = self.mai.getMinInstAlignment()
|
align = self.mai.getMinInstAlignment()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ class TargetSubtargetInfo:
|
||||||
class MCExpr:
|
class MCExpr:
|
||||||
_include_ = "llvm/MC/MCExpr.h"
|
_include_ = "llvm/MC/MCExpr.h"
|
||||||
|
|
||||||
|
ExprKind = Enum('Binary', 'Constant', 'SymbolRef', 'Unary', 'Target')
|
||||||
|
getKind = Method(ExprKind)
|
||||||
|
|
||||||
@MCOperand
|
@MCOperand
|
||||||
class MCOperand:
|
class MCOperand:
|
||||||
_include_ = "llvm/MC/MCInst.h"
|
_include_ = "llvm/MC/MCInst.h"
|
||||||
|
|
@ -44,8 +47,7 @@ class MCOperand:
|
||||||
getImm = Method(cast(Int64, int))
|
getImm = Method(cast(Int64, int))
|
||||||
getFPImm = Method(cast(Double, float))
|
getFPImm = Method(cast(Double, float))
|
||||||
getExpr = Method(const(ptr(MCExpr)))
|
getExpr = Method(const(ptr(MCExpr)))
|
||||||
|
|
||||||
|
|
||||||
@MCInst
|
@MCInst
|
||||||
class MCInst:
|
class MCInst:
|
||||||
_include_ = "llvm/MC/MCInst.h"
|
_include_ = "llvm/MC/MCInst.h"
|
||||||
|
|
@ -56,6 +58,8 @@ class MCInst:
|
||||||
|
|
||||||
getOperand = Method(const(ref(MCOperand)), cast(int, Unsigned))
|
getOperand = Method(const(ref(MCOperand)), cast(int, Unsigned))
|
||||||
|
|
||||||
|
MCOperand.getInst = Method(const(ptr(MCInst)))
|
||||||
|
|
||||||
@MCAsmInfo
|
@MCAsmInfo
|
||||||
class MCAsmInfo:
|
class MCAsmInfo:
|
||||||
_include_ = "llvm/MC/MCAsmInfo.h"
|
_include_ = "llvm/MC/MCAsmInfo.h"
|
||||||
|
|
@ -68,6 +72,8 @@ class MCAsmInfo:
|
||||||
class MCRegisterInfo:
|
class MCRegisterInfo:
|
||||||
_include_ = "llvm/MC/MCRegisterInfo.h"
|
_include_ = "llvm/MC/MCRegisterInfo.h"
|
||||||
|
|
||||||
|
getName = Method(cast(ConstCharPtr, str), cast(int, Unsigned))
|
||||||
|
|
||||||
@MCInstrInfo
|
@MCInstrInfo
|
||||||
class MCInstrInfo:
|
class MCInstrInfo:
|
||||||
_include_ = "llvm/MC/MCInstrInfo.h"
|
_include_ = "llvm/MC/MCInstrInfo.h"
|
||||||
|
|
|
||||||
|
|
@ -8,32 +8,8 @@ if llvm.version >= (3, 4):
|
||||||
|
|
||||||
llvm.target.initialize_all()
|
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):
|
def print_instructions(dasm, bs):
|
||||||
for (offset, inst) in dasm.decode(bs):
|
for (offset, inst) in dasm.decode(bs, 0):
|
||||||
if inst is None:
|
if inst is None:
|
||||||
print("\t%r=>(bad): 0, []" % (offset))
|
print("\t%r=>(bad): 0, []" % (offset))
|
||||||
else:
|
else:
|
||||||
|
|
@ -43,7 +19,7 @@ if llvm.version >= (3, 4):
|
||||||
print("\t%r=>%r: %r" % (offset, inst, len(inst)))
|
print("\t%r=>%r: %r" % (offset, inst, len(inst)))
|
||||||
|
|
||||||
for op in inst.operands():
|
for op in inst.operands():
|
||||||
print("\t\t%s" % op_str(op))
|
print("\t\t%s" % repr(op))
|
||||||
|
|
||||||
|
|
||||||
x86 = TargetMachine.x86()
|
x86 = TargetMachine.x86()
|
||||||
|
|
|
||||||
|
|
@ -659,7 +659,7 @@ def do_llvm_mc():
|
||||||
tm = TargetMachine.x86()
|
tm = TargetMachine.x86()
|
||||||
dasm = mc.Disassembler(tm)
|
dasm = mc.Disassembler(tm)
|
||||||
|
|
||||||
for (offset, instr) in dasm.decode("c3"):
|
for (offset, instr) in dasm.decode("c3", 0):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue