aboutsummaryrefslogtreecommitdiffhomepage
path: root/lib/Module/RaiseAsm.cpp
diff options
context:
space:
mode:
authorCristian Cadar <c.cadar@imperial.ac.uk>2016-09-20 15:00:35 +0100
committerGitHub <noreply@github.com>2016-09-20 15:00:35 +0100
commit1823ab801b50e781c18cff67cb8cda0d7859519e (patch)
tree5a4aca500f4631b05622081bb3abeac8f2fe94fb /lib/Module/RaiseAsm.cpp
parent1bfdbc61f2e14d8b0f2b5ca45ca8266c363cbfc5 (diff)
parent95a39e0fe58c7b95588da97b3478eafba9920281 (diff)
downloadklee-1823ab801b50e781c18cff67cb8cda0d7859519e.tar.gz
Merge pull request #443 from MartinNowack/feat_assembler_raising
Extended support for assembler raising
Diffstat (limited to 'lib/Module/RaiseAsm.cpp')
-rw-r--r--lib/Module/RaiseAsm.cpp39
1 files changed, 34 insertions, 5 deletions
diff --git a/lib/Module/RaiseAsm.cpp b/lib/Module/RaiseAsm.cpp
index 12e5479b..7c0e6ccf 100644
--- a/lib/Module/RaiseAsm.cpp
+++ b/lib/Module/RaiseAsm.cpp
@@ -9,12 +9,16 @@
#include "Passes.h"
#include "klee/Config/Version.h"
+#include "klee/Internal/Support/ErrorHandling.h"
#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3)
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Instructions.h"
#else
#include "llvm/InlineAsm.h"
#include "llvm/LLVMContext.h"
+#include "llvm/Support/IRBuilder.h"
#endif
#include "llvm/Support/raw_ostream.h"
@@ -46,10 +50,32 @@ Function *RaiseAsmPass::getIntrinsic(llvm::Module &M,
// FIXME: This should just be implemented as a patch to
// X86TargetAsmInfo.cpp, then everyone will benefit.
bool RaiseAsmPass::runOnInstruction(Module &M, Instruction *I) {
- if (CallInst *ci = dyn_cast<CallInst>(I)) {
- if (InlineAsm *ia = dyn_cast<InlineAsm>(ci->getCalledValue())) {
- (void) ia;
- return TLI && TLI->ExpandInlineAsm(ci);
+ // We can just raise inline assembler using calls
+ CallInst *ci = dyn_cast<CallInst>(I);
+ if (!ci)
+ return false;
+
+ InlineAsm *ia = dyn_cast<InlineAsm>(ci->getCalledValue());
+ if (!ia)
+ return false;
+
+ // Try to use existing infrastructure
+ if (!TLI)
+ return false;
+
+ if (TLI->ExpandInlineAsm(ci))
+ return true;
+
+ if (triple.getArch() == llvm::Triple::x86_64 &&
+ triple.getOS() == llvm::Triple::Linux) {
+
+ if (ia->getAsmString() == "" && ia->hasSideEffects()) {
+#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 3)
+ IRBuilder<> Builder(I);
+ Builder.CreateFence(llvm::SequentiallyConsistent);
+#endif
+ I->eraseFromParent();
+ return true;
}
}
@@ -66,9 +92,10 @@ bool RaiseAsmPass::runOnModule(Module &M) {
std::string HostTriple = llvm::sys::getHostTriple();
#endif
const Target *NativeTarget = TargetRegistry::lookupTarget(HostTriple, Err);
+
TargetMachine * TM = 0;
if (NativeTarget == 0) {
- llvm::errs() << "Warning: unable to select native target: " << Err << "\n";
+ klee_warning("Warning: unable to select native target: %s", Err.c_str());
TLI = 0;
} else {
#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 1)
@@ -80,6 +107,8 @@ bool RaiseAsmPass::runOnModule(Module &M) {
TM = NativeTarget->createTargetMachine(HostTriple, "");
#endif
TLI = TM->getTargetLowering();
+
+ triple = llvm::Triple(HostTriple);
}
for (Module::iterator fi = M.begin(), fe = M.end(); fi != fe; ++fi) {