Files
revng-revng/include/revng/Lift/Lift.h
Alessandro Di Federico 0793e4afcb Turn lifting into a pass
2022-03-11 15:37:12 +01:00

160 lines
3.9 KiB
C++

#pragma once
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#include "llvm/ADT/StringRef.h"
#include "llvm/Pass.h"
#include "revng/Lift/LoadBinaryPass.h"
#include "revng/Support/Debug.h"
namespace JTReason {
// TODO: move me to another header file
/// \brief Reason for registering a jump target
enum Values {
/// PC after an helper (e.g., a syscall)
PostHelper = 1,
/// Obtained from a direct store to the PC
DirectJump = 2,
/// Obtained digging in global data
GlobalData = 4,
/// Fallthrough of multiple instructions in the immediately preceeding bytes
AmbigousInstruction = 8,
/// Stored in the PC
PCStore = 16,
/// Stored in memory
MemoryStore = 32,
/// Obtained digging in global data, but never used. Likely a function
/// pointer
UnusedGlobalData = 64,
/// This JT is the target of a call instruction.
Callee = 128,
/// A load has been performed from this address
LoadAddress = 256,
/// Obtained as the fallthrough of a function call
ReturnAddress = 512,
/// Obtained from a function symbol
FunctionSymbol = 1024,
/// Immediate value in the IR, usually a return address
SimpleLiteral = 2048,
LastReason = SimpleLiteral
};
inline const char *getName(Values Reason) {
switch (Reason) {
case PostHelper:
return "PostHelper";
case DirectJump:
return "DirectJump";
case GlobalData:
return "GlobalData";
case AmbigousInstruction:
return "AmbigousInstruction";
case PCStore:
return "PCStore";
case MemoryStore:
return "MemoryStore";
case UnusedGlobalData:
return "UnusedGlobalData";
case Callee:
return "Callee";
case LoadAddress:
return "LoadAddress";
case ReturnAddress:
return "ReturnAddress";
case FunctionSymbol:
return "FunctionSymbol";
case SimpleLiteral:
return "SimpleLiteral";
}
revng_abort();
}
inline Values fromName(llvm::StringRef ReasonName) {
if (ReasonName == "PostHelper")
return PostHelper;
else if (ReasonName == "DirectJump")
return DirectJump;
else if (ReasonName == "GlobalData")
return GlobalData;
else if (ReasonName == "AmbigousInstruction")
return AmbigousInstruction;
else if (ReasonName == "PCStore")
return PCStore;
else if (ReasonName == "MemoryStore")
return MemoryStore;
else if (ReasonName == "UnusedGlobalData")
return UnusedGlobalData;
else if (ReasonName == "Callee")
return Callee;
else if (ReasonName == "LoadAddress")
return LoadAddress;
else if (ReasonName == "ReturnAddress")
return ReturnAddress;
else if (ReasonName == "FunctionSymbol")
return FunctionSymbol;
else if (ReasonName == "SimpleLiteral")
return SimpleLiteral;
else
revng_abort();
}
inline bool hasReason(uint32_t Reasons, Values ToCheck) {
return (Reasons & static_cast<uint32_t>(ToCheck)) != 0;
}
} // namespace JTReason
namespace KillReason {
enum Values { NonKiller, KillerSyscall, EndlessLoop, LeadsToKiller };
inline llvm::StringRef getName(Values Reason) {
switch (Reason) {
case NonKiller:
return "NonKiller";
case KillerSyscall:
return "KillerSyscall";
case EndlessLoop:
return "EndlessLoop";
case LeadsToKiller:
return "LeadsToKiller";
}
revng_abort("Unexpected reason");
}
inline Values fromName(llvm::StringRef Name) {
if (Name == "NonKiller")
return NonKiller;
if (Name == "KillerSyscall")
return KillerSyscall;
else if (Name == "EndlessLoop")
return EndlessLoop;
else if (Name == "LeadsToKiller")
return LeadsToKiller;
else
revng_abort("Unexpected name");
}
} // namespace KillReason
class LiftPass : public llvm::ModulePass {
public:
static char ID;
public:
LiftPass() : llvm::ModulePass(ID) {}
void getAnalysisUsage(llvm::AnalysisUsage &AU) const override {
AU.addRequired<LoadBinaryWrapperPass>();
AU.addRequired<LoadModelWrapperPass>();
}
bool runOnModule(llvm::Module &M) override;
};