From 78be6a7f5fe07bfb5273381fc506c2f83418a766 Mon Sep 17 00:00:00 2001 From: anthony cantor Date: Fri, 16 Aug 2013 16:30:54 -0600 Subject: [PATCH] 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. --- llvm/mc/__init__.py | 5 +- llvmpy/include/llvm_binding/extra.h | 10 ++- llvmpy/src/MC/__init__.py | 11 ++-- llvmpy/src/Support/TargetRegistry.py | 21 +++--- llvmpy/src/__init__.py | 7 ++ test/example-disassemble.py | 95 ++++++++++++++-------------- 6 files changed, 83 insertions(+), 66 deletions(-) diff --git a/llvm/mc/__init__.py b/llvm/mc/__init__.py index da595ae..22278a4 100644 --- a/llvm/mc/__init__.py +++ b/llvm/mc/__init__.py @@ -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 import contextlib -import llvm from llvmpy import api from llvmpy.api.llvm import MCDisassembler diff --git a/llvmpy/include/llvm_binding/extra.h b/llvmpy/include/llvm_binding/extra.h index a705d63..a6ad89b 100644 --- a/llvmpy/include/llvm_binding/extra.h +++ b/llvmpy/include/llvm_binding/extra.h @@ -8,6 +8,10 @@ #include #include #include + #if LLVM_VERSION_MINOR >= 4 + #include + #include + #endif #else #include #include @@ -29,8 +33,7 @@ #include #include #include -#include -#include + #include // to make MCJIT working #include "auto_pyobject.h" @@ -952,6 +955,8 @@ PyObject* TargetRegistry_targets_list() "llvm::Target", "llvm::Target"); } + +#if LLVM_VERSION_MAJOR >= 3 and LLVM_VERSION_MINOR >= 4 static PyObject* MCDisassembler_getInstruction(llvm::MCDisassembler *disasm, llvm::MCInst &instr, @@ -967,6 +972,7 @@ PyObject* MCDisassembler_getInstruction(llvm::MCDisassembler *disasm, llvm::nulls(), llvm::nulls()); return Py_BuildValue("(i,i)", int(status), size); } +#endif /* llvm >= 3.4 */ static PyObject* llvm_sys_getHostCPUFeatures(PyObject* Features) diff --git a/llvmpy/src/MC/__init__.py b/llvmpy/src/MC/__init__.py index ca3166a..d4f9ff3 100644 --- a/llvmpy/src/MC/__init__.py +++ b/llvmpy/src/MC/__init__.py @@ -45,6 +45,10 @@ class MCInst: getOperand = Method(const(ref(MCOperand)), cast(int, Unsigned)) +@MCAsmInfo +class MCAsmInfo: + _include_ = "llvm/MC/MCAsmInfo.h" + @MCDisassembler class MCDisassembler: _include_ = "llvm/MC/MCDisassembler.h" @@ -56,10 +60,5 @@ class MCDisassembler: ref(MCInst), ref(MemoryObject), cast(int, Uint64) + ) - -) - -@MCAsmInfo -class MCAsmInfo: - _include_ = "llvm/MC/MCAsmInfo.h" diff --git a/llvmpy/src/Support/TargetRegistry.py b/llvmpy/src/Support/TargetRegistry.py index be89289..da9ec5b 100644 --- a/llvmpy/src/Support/TargetRegistry.py +++ b/llvmpy/src/Support/TargetRegistry.py @@ -11,8 +11,10 @@ from src.ADT.StringRef import StringRef from src.Target.TargetMachine import TargetMachine from src.Target.TargetOptions import TargetOptions 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 class Target: @@ -45,13 +47,14 @@ class Target: CodeGenOpt.Level, # = CodeGenOpt.Default ).require_only(4) - createMCSubtargetInfo = Method(ptr(MCSubtargetInfo), - cast(str, StringRef), #triple - cast(str, StringRef), #cpu - cast(str, StringRef) #features - ) - - createMCDisassembler = Method(ptr(MCDisassembler), ref(MCSubtargetInfo)) + if LLVM_VERSION >= (3, 4): + createMCSubtargetInfo = Method(ptr(MCSubtargetInfo), + cast(str, StringRef), #triple + cast(str, StringRef), #cpu + cast(str, StringRef) #features + ) + + createMCDisassembler = Method(ptr(MCDisassembler), ref(MCSubtargetInfo)) @TargetRegistry diff --git a/llvmpy/src/__init__.py b/llvmpy/src/__init__.py index 69b6609..8ebb465 100644 --- a/llvmpy/src/__init__.py +++ b/llvmpy/src/__init__.py @@ -1,4 +1,7 @@ import os.path +from binding import LLVM_VERSION + +above_33 = ("MC") def _init(root=__name__, file=__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('__') if (is_python_module or is_python_script) and not is_init_script: 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] #importlib.import_module('.' + modname, __name__) __import__('.'.join([root, modname])) diff --git a/test/example-disassemble.py b/test/example-disassemble.py index a6632d8..439652a 100644 --- a/test/example-disassemble.py +++ b/test/example-disassemble.py @@ -1,62 +1,61 @@ import llvm -from llvm import mc -from llvm.mc import Disassembler -from llvmpy import api +if llvm.version >= (3, 4): -llvm.initialize_all_target_components() + from llvm import mc + from llvm.mc import Disassembler + from llvmpy import api -def op_str(op): - s = [] - if op.isValid(): - s.append("valid") - else: - s.append("invalid") + llvm.initialize_all_target_components() - if op.isReg(): - s.append("+reg(%d)" % op.getReg()) + 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.isImm(): + s.append("+imm(%d)" % op.getImm()) - if op.isFPImm(): - s.append("+fp-imm(%f)" % op.getFPImm()) + if op.isFPImm(): + s.append("+fp-imm(%f)" % op.getFPImm()) - if op.isExpr(): - s.append("+expr") + if op.isExpr(): + s.append("+expr") - if op.isInst(): - s.append("+inst") + if op.isInst(): + s.append("+inst") - return " ".join(s) + return " ".join(s) -def print_instructions(dasm, bs): - for (offset, inst) in dasm.decode(bs): - if inst is None: - print("\t%r=>(bad): 0, []" % (offset)) - else: - if isinstance(inst, mc.BadInstr): - print("\t%r=>(bad)%r: %r" % (offset, inst, len(inst))) + def print_instructions(dasm, bs): + for (offset, inst) in dasm.decode(bs): + if inst is None: + print("\t%r=>(bad): 0, []" % (offset)) else: - print("\t%r=>%r: %r" % (offset, inst, len(inst))) - - 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))) - + if isinstance(inst, mc.BadInstr): + print("\t%r=>(bad)%r: %r" % (offset, inst, len(inst))) + else: + print("\t%r=>%r: %r" % (offset, inst, len(inst))) + + 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)))