llvm pass 打印某个指令的所有操作数
//==============================================================================
// FILE:
// mp.cpp
//
// DESCRIPTION:
// This pass print every Operand of an op
//
// USAGE:
// 1. Legacy pass manager:
// $ opt -load <BUILD_DIR>/lib/libMBAAdd.so `\`
// --legacy-mba-add [-mba-ratio=<ratio>] <bitcode-file>
// with the optional ratio in the range [0, 1.0].
// 2. New pass maanger:
// $ opt -load-pass-plugin <BUILD_DIR>/lib/libMBAAdd.so `\`
// -passes=-"mba-add" <bitcode-file>
// The command line option is not available for the new PM
//
//
// [1] "Defeating MBA-based Obfuscation" Ninon Eyrolles, Louis Goubin, Marion
// Videau
//
// License: MIT
//==============================================================================
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
using namespace llvm;
#define DEBUG_TYPE "mba-add"
STATISTIC(SubstCount, "The # of substituted instructions");
//------------------------------------------------------------------------------
// New PM interface
//------------------------------------------------------------------------------
struct mp : public llvm::PassInfoMixin<mp> {
llvm::PreservedAnalyses run(llvm::Function &F,
llvm::FunctionAnalysisManager &);
bool runOnBasicBlock(llvm::BasicBlock &B);
};
//-----------------------------------------------------------------------------
// mp Implementation
//-----------------------------------------------------------------------------
bool mp::runOnBasicBlock(BasicBlock &BB) {
// Loop over all instructions in the block. Replacing instructions requires
// iterators, hence a for-range loop wouldn't be suitable
for (auto Inst = BB.begin(), IE = BB.end(); Inst != IE; ++Inst)
{
// Skip non-binary (e.g. unary or compare) instructions
auto *BinOp = dyn_cast<Instruction>(Inst);
if (!BinOp)
continue;
if (BinOp->getOpcode() == Instruction::Add)
{
for (auto i = 0; i < BinOp->getNumOperands(); ++i)
{
auto *v0 = BinOp->getOperand(i);
const char *name = v0->getName().data();
errs() << name << "\n";
}
}
// if (BinOp->getOpcode() == Instruction::Call)
// {
// for (auto i = 0; i < BinOp->getNumOperands(); ++i)
// {
// auto *v0 = BinOp->getOperand(i);
// const char *name = v0->getName().data();
// errs() << name << "\n";
// }
// }
}
return false;
}
PreservedAnalyses mp::run(llvm::Function &F,
llvm::FunctionAnalysisManager &) {
bool Changed = false;
for (auto &BB : F) {
Changed |= runOnBasicBlock(BB);
}
return (Changed ? llvm::PreservedAnalyses::none()
: llvm::PreservedAnalyses::all());
}
//-----------------------------------------------------------------------------
// New PM Registration
//-----------------------------------------------------------------------------
llvm::PassPluginLibraryInfo getMBAAddPluginInfo() {
return {LLVM_PLUGIN_API_VERSION, "mp", LLVM_VERSION_STRING,
[](PassBuilder &PB) {
PB.registerPipelineParsingCallback(
[](StringRef Name, FunctionPassManager &FPM,
ArrayRef<PassBuilder::PipelineElement>) {
if (Name == "mp") {
FPM.addPass(mp());
return true;
}
return false;
});
}};
}
extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
llvmGetPassPluginInfo() {
return getMBAAddPluginInfo();
}