conditionals for compatibility with llvm < 3.4
i only intend to support MC bindings (and anything reliant on MC) for llvm 3.4 and greater.
This commit is contained in:
parent
bc02b3d90a
commit
78be6a7f5f
6 changed files with 83 additions and 66 deletions
|
|
@ -1,7 +1,10 @@
|
||||||
|
import llvm
|
||||||
|
if llvm.version < (3, 4):
|
||||||
|
raise Exception("mc is not supported for llvm version less than 3.4")
|
||||||
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
import contextlib
|
import contextlib
|
||||||
|
|
||||||
import llvm
|
|
||||||
from llvmpy import api
|
from llvmpy import api
|
||||||
from llvmpy.api.llvm import MCDisassembler
|
from llvmpy.api.llvm import MCDisassembler
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,10 @@
|
||||||
#include <llvm/IR/Constants.h>
|
#include <llvm/IR/Constants.h>
|
||||||
#include <llvm/IR/Intrinsics.h>
|
#include <llvm/IR/Intrinsics.h>
|
||||||
#include <llvm/IR/IRBuilder.h>
|
#include <llvm/IR/IRBuilder.h>
|
||||||
|
#if LLVM_VERSION_MINOR >= 4
|
||||||
|
#include <llvm/Support/MemoryObject.h>
|
||||||
|
#include <llvm/MC/MCDisassembler.h>
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
#include <llvm/Value.h>
|
#include <llvm/Value.h>
|
||||||
#include <llvm/DerivedTypes.h>
|
#include <llvm/DerivedTypes.h>
|
||||||
|
|
@ -29,8 +33,7 @@
|
||||||
#include <llvm/Analysis/Verifier.h>
|
#include <llvm/Analysis/Verifier.h>
|
||||||
#include <llvm/PassRegistry.h>
|
#include <llvm/PassRegistry.h>
|
||||||
#include <llvm/Support/Host.h>
|
#include <llvm/Support/Host.h>
|
||||||
#include <llvm/Support/MemoryObject.h>
|
|
||||||
#include <llvm/MC/MCDisassembler.h>
|
|
||||||
#include <llvm/ExecutionEngine/MCJIT.h> // to make MCJIT working
|
#include <llvm/ExecutionEngine/MCJIT.h> // to make MCJIT working
|
||||||
|
|
||||||
#include "auto_pyobject.h"
|
#include "auto_pyobject.h"
|
||||||
|
|
@ -952,6 +955,8 @@ PyObject* TargetRegistry_targets_list()
|
||||||
"llvm::Target", "llvm::Target");
|
"llvm::Target", "llvm::Target");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if LLVM_VERSION_MAJOR >= 3 and LLVM_VERSION_MINOR >= 4
|
||||||
static
|
static
|
||||||
PyObject* MCDisassembler_getInstruction(llvm::MCDisassembler *disasm,
|
PyObject* MCDisassembler_getInstruction(llvm::MCDisassembler *disasm,
|
||||||
llvm::MCInst &instr,
|
llvm::MCInst &instr,
|
||||||
|
|
@ -967,6 +972,7 @@ PyObject* MCDisassembler_getInstruction(llvm::MCDisassembler *disasm,
|
||||||
llvm::nulls(), llvm::nulls());
|
llvm::nulls(), llvm::nulls());
|
||||||
return Py_BuildValue("(i,i)", int(status), size);
|
return Py_BuildValue("(i,i)", int(status), size);
|
||||||
}
|
}
|
||||||
|
#endif /* llvm >= 3.4 */
|
||||||
|
|
||||||
static
|
static
|
||||||
PyObject* llvm_sys_getHostCPUFeatures(PyObject* Features)
|
PyObject* llvm_sys_getHostCPUFeatures(PyObject* Features)
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,10 @@ class MCInst:
|
||||||
|
|
||||||
getOperand = Method(const(ref(MCOperand)), cast(int, Unsigned))
|
getOperand = Method(const(ref(MCOperand)), cast(int, Unsigned))
|
||||||
|
|
||||||
|
@MCAsmInfo
|
||||||
|
class MCAsmInfo:
|
||||||
|
_include_ = "llvm/MC/MCAsmInfo.h"
|
||||||
|
|
||||||
@MCDisassembler
|
@MCDisassembler
|
||||||
class MCDisassembler:
|
class MCDisassembler:
|
||||||
_include_ = "llvm/MC/MCDisassembler.h"
|
_include_ = "llvm/MC/MCDisassembler.h"
|
||||||
|
|
@ -56,10 +60,5 @@ class MCDisassembler:
|
||||||
ref(MCInst),
|
ref(MCInst),
|
||||||
ref(MemoryObject),
|
ref(MemoryObject),
|
||||||
cast(int, Uint64)
|
cast(int, Uint64)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
@MCAsmInfo
|
|
||||||
class MCAsmInfo:
|
|
||||||
_include_ = "llvm/MC/MCAsmInfo.h"
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,10 @@ from src.ADT.StringRef import StringRef
|
||||||
from src.Target.TargetMachine import TargetMachine
|
from src.Target.TargetMachine import TargetMachine
|
||||||
from src.Target.TargetOptions import TargetOptions
|
from src.Target.TargetOptions import TargetOptions
|
||||||
from src.Support.CodeGen import Reloc, CodeModel, CodeGenOpt
|
from src.Support.CodeGen import Reloc, CodeModel, CodeGenOpt
|
||||||
from src.MC import MCSubtargetInfo
|
|
||||||
from src.MC import MCDisassembler
|
if LLVM_VERSION >= (3, 4):
|
||||||
|
from src.MC import MCSubtargetInfo
|
||||||
|
from src.MC import MCDisassembler
|
||||||
|
|
||||||
@Target
|
@Target
|
||||||
class Target:
|
class Target:
|
||||||
|
|
@ -45,13 +47,14 @@ class Target:
|
||||||
CodeGenOpt.Level, # = CodeGenOpt.Default
|
CodeGenOpt.Level, # = CodeGenOpt.Default
|
||||||
).require_only(4)
|
).require_only(4)
|
||||||
|
|
||||||
createMCSubtargetInfo = Method(ptr(MCSubtargetInfo),
|
if LLVM_VERSION >= (3, 4):
|
||||||
cast(str, StringRef), #triple
|
createMCSubtargetInfo = Method(ptr(MCSubtargetInfo),
|
||||||
cast(str, StringRef), #cpu
|
cast(str, StringRef), #triple
|
||||||
cast(str, StringRef) #features
|
cast(str, StringRef), #cpu
|
||||||
)
|
cast(str, StringRef) #features
|
||||||
|
)
|
||||||
|
|
||||||
createMCDisassembler = Method(ptr(MCDisassembler), ref(MCSubtargetInfo))
|
createMCDisassembler = Method(ptr(MCDisassembler), ref(MCSubtargetInfo))
|
||||||
|
|
||||||
|
|
||||||
@TargetRegistry
|
@TargetRegistry
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
import os.path
|
import os.path
|
||||||
|
from binding import LLVM_VERSION
|
||||||
|
|
||||||
|
above_33 = ("MC")
|
||||||
|
|
||||||
def _init(root=__name__, file=__file__):
|
def _init(root=__name__, file=__file__):
|
||||||
base = os.path.dirname(file)
|
base = os.path.dirname(file)
|
||||||
|
|
@ -9,6 +12,10 @@ def _init(root=__name__, file=__file__):
|
||||||
is_python_module = is_directory and not fname.startswith('__')
|
is_python_module = is_directory and not fname.startswith('__')
|
||||||
if (is_python_module or is_python_script) and not is_init_script:
|
if (is_python_module or is_python_script) and not is_init_script:
|
||||||
print(fname)
|
print(fname)
|
||||||
|
if fname in above_33 and LLVM_VERSION <= (3, 3):
|
||||||
|
print("skip %s because llvm version is not above 3.3" % fname)
|
||||||
|
continue
|
||||||
|
|
||||||
modname = os.path.basename(fname).rsplit('.', 1)[0]
|
modname = os.path.basename(fname).rsplit('.', 1)[0]
|
||||||
#importlib.import_module('.' + modname, __name__)
|
#importlib.import_module('.' + modname, __name__)
|
||||||
__import__('.'.join([root, modname]))
|
__import__('.'.join([root, modname]))
|
||||||
|
|
|
||||||
|
|
@ -1,62 +1,61 @@
|
||||||
import llvm
|
import llvm
|
||||||
|
|
||||||
from llvm import mc
|
if llvm.version >= (3, 4):
|
||||||
from llvm.mc import Disassembler
|
|
||||||
from llvmpy import api
|
|
||||||
|
|
||||||
llvm.initialize_all_target_components()
|
from llvm import mc
|
||||||
|
from llvm.mc import Disassembler
|
||||||
|
from llvmpy import api
|
||||||
|
|
||||||
def op_str(op):
|
llvm.initialize_all_target_components()
|
||||||
s = []
|
|
||||||
if op.isValid():
|
|
||||||
s.append("valid")
|
|
||||||
else:
|
|
||||||
s.append("invalid")
|
|
||||||
|
|
||||||
if op.isReg():
|
def op_str(op):
|
||||||
s.append("+reg(%d)" % op.getReg())
|
s = []
|
||||||
|
if op.isValid():
|
||||||
|
s.append("valid")
|
||||||
|
else:
|
||||||
|
s.append("invalid")
|
||||||
|
|
||||||
if op.isImm():
|
if op.isReg():
|
||||||
s.append("+imm(%d)" % op.getImm())
|
s.append("+reg(%d)" % op.getReg())
|
||||||
|
|
||||||
if op.isFPImm():
|
if op.isImm():
|
||||||
s.append("+fp-imm(%f)" % op.getFPImm())
|
s.append("+imm(%d)" % op.getImm())
|
||||||
|
|
||||||
if op.isExpr():
|
if op.isFPImm():
|
||||||
s.append("+expr")
|
s.append("+fp-imm(%f)" % op.getFPImm())
|
||||||
|
|
||||||
if op.isInst():
|
if op.isExpr():
|
||||||
s.append("+inst")
|
s.append("+expr")
|
||||||
|
|
||||||
return " ".join(s)
|
if op.isInst():
|
||||||
|
s.append("+inst")
|
||||||
|
|
||||||
def print_instructions(dasm, bs):
|
return " ".join(s)
|
||||||
for (offset, inst) in dasm.decode(bs):
|
|
||||||
if inst is None:
|
def print_instructions(dasm, bs):
|
||||||
print("\t%r=>(bad): 0, []" % (offset))
|
for (offset, inst) in dasm.decode(bs):
|
||||||
else:
|
if inst is None:
|
||||||
if isinstance(inst, mc.BadInstr):
|
print("\t%r=>(bad): 0, []" % (offset))
|
||||||
print("\t%r=>(bad)%r: %r" % (offset, inst, len(inst)))
|
|
||||||
else:
|
else:
|
||||||
print("\t%r=>%r: %r" % (offset, inst, len(inst)))
|
if isinstance(inst, mc.BadInstr):
|
||||||
|
print("\t%r=>(bad)%r: %r" % (offset, inst, len(inst)))
|
||||||
for op in inst.operands():
|
else:
|
||||||
print("\t\t%s" % op_str(op))
|
print("\t%r=>%r: %r" % (offset, inst, len(inst)))
|
||||||
|
|
||||||
|
|
||||||
print("x86:")
|
|
||||||
print_instructions(Disassembler.x86(), "\x01\xc3\xc3\xcc\x90")
|
|
||||||
print("x86-64:")
|
|
||||||
print_instructions(Disassembler.x86_64(), "\x55\x48\x89\xe8")
|
|
||||||
print("arm:")
|
|
||||||
code = [
|
|
||||||
"\xe9\x2d\x48\x00",
|
|
||||||
"\xea\x00\x00\x06",
|
|
||||||
"\xe2\x4d\xd0\x20",
|
|
||||||
"\xe2\x8d\xb0\x04",
|
|
||||||
"\xe5\x0b\x00\x20"
|
|
||||||
]
|
|
||||||
print_instructions(Disassembler.arm(), "".join(map(lambda s: s[::-1], code)))
|
|
||||||
|
|
||||||
|
for op in inst.operands():
|
||||||
|
print("\t\t%s" % op_str(op))
|
||||||
|
|
||||||
|
|
||||||
|
print("x86:")
|
||||||
|
print_instructions(Disassembler.x86(), "\x01\xc3\xc3\xcc\x90")
|
||||||
|
print("x86-64:")
|
||||||
|
print_instructions(Disassembler.x86_64(), "\x55\x48\x89\xe8")
|
||||||
|
print("arm:")
|
||||||
|
code = [
|
||||||
|
"\xe9\x2d\x48\x00",
|
||||||
|
"\xea\x00\x00\x06",
|
||||||
|
"\xe2\x4d\xd0\x20",
|
||||||
|
"\xe2\x8d\xb0\x04",
|
||||||
|
"\xe5\x0b\x00\x20"
|
||||||
|
]
|
||||||
|
print_instructions(Disassembler.arm(), "".join(map(lambda s: s[::-1], code)))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue