Autotokens New PM (#605)

* autotokens newpm

* typo

* fmt

* clp

* fix

* fix

* include &fmt

* include

* fmt

* llvm14 & clippy fix

* fix
This commit is contained in:
Dongjia Zhang 2022-05-09 18:41:53 +09:00 committed by GitHub
parent 283ceaac9b
commit a02b90be44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 84 additions and 12 deletions

View File

@ -206,6 +206,7 @@ fn main() {
.args(&cxxflags) .args(&cxxflags)
.args(&custom_flags) .args(&custom_flags)
.arg(src_dir.join("autotokens-pass.cc")) .arg(src_dir.join("autotokens-pass.cc"))
//.arg("-DUSE_NEW_PM")
.args(&ldflags) .args(&ldflags)
.args(&["-fPIC", "-shared", "-o"]) .args(&["-fPIC", "-shared", "-o"])
.arg(out_dir.join(format!("autotokens-pass.{}", dll_extension()))) .arg(out_dir.join(format!("autotokens-pass.{}", dll_extension())))

View File

@ -35,9 +35,15 @@
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LegacyPassManager.h" #if USE_NEW_PM
#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/IR/PassManager.h"
#else
#include "llvm/IR/LegacyPassManager.h"
#endif
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/IR/BasicBlock.h" #include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Module.h" #include "llvm/IR/Module.h"
#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugInfo.h"
@ -134,14 +140,24 @@ bool isIgnoreFunction(const llvm::Function *F) {
return false; return false;
} }
#if USE_NEW_PM
class AutoTokensPass : public PassInfoMixin<AutoTokensPass> {
public:
AutoTokensPass() {
#else
class AutoTokensPass : public ModulePass { class AutoTokensPass : public ModulePass {
public: public:
static char ID; static char ID;
AutoTokensPass() : ModulePass(ID) { AutoTokensPass() : ModulePass(ID) {
#endif
} }
#if USE_NEW_PM
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
#else
bool runOnModule(Module &M) override; bool runOnModule(Module &M) override;
#endif
protected: protected:
private: private:
@ -150,7 +166,25 @@ class AutoTokensPass : public ModulePass {
} // namespace } // namespace
#if USE_NEW_PM
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
return {LLVM_PLUGIN_API_VERSION, "AutoTokensPass", "v0.1",
/* lambda to insert our pass into the pass pipeline. */
[](PassBuilder &PB) {
#if LLVM_VERSION_MAJOR <= 13
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
#endif
PB.registerOptimizerLastEPCallback(
[](ModulePassManager &MPM, OptimizationLevel OL) {
MPM.addPass(AutoTokensPass());
});
}};
}
#else
char AutoTokensPass::ID = 0; char AutoTokensPass::ID = 0;
#endif
void dict2file(int fd, uint8_t *mem, uint32_t len) { void dict2file(int fd, uint8_t *mem, uint32_t len) {
uint32_t i, j, binary = 0; uint32_t i, j, binary = 0;
@ -177,11 +211,17 @@ void dict2file(int fd, uint8_t *mem, uint32_t len) {
line[j] = 0; line[j] = 0;
strcat(line, "\"\n"); strcat(line, "\"\n");
if (write(fd, line, strlen(line)) <= 0) if (write(fd, line, strlen(line)) <= 0)
FATAL("Could not write to dictionary file"); FATAL("Could not write to the dictionary file");
fsync(fd); fsync(fd);
} }
#if USE_NEW_PM
PreservedAnalyses AutoTokensPass::run(Module &M, ModuleAnalysisManager &MAM) {
#else
bool AutoTokensPass::runOnModule(Module &M) { bool AutoTokensPass::runOnModule(Module &M) {
#endif
DenseMap<Value *, std::string *> valueMap; DenseMap<Value *, std::string *> valueMap;
char *ptr; char *ptr;
int fd, found = 0; int fd, found = 0;
@ -426,7 +466,7 @@ bool AutoTokensPass::runOnModule(Module &M) {
// we handle the 2nd parameter first because of llvm memcpy // we handle the 2nd parameter first because of llvm memcpy
if (!HasStr2) { if (!HasStr2) {
auto *Ptr = dyn_cast<ConstantExpr>(Str2P); auto *Ptr = dyn_cast<ConstantExpr>(Str2P);
if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) {
if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) { if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) {
if (Var->hasInitializer()) { if (Var->hasInitializer()) {
if (auto *Array = if (auto *Array =
@ -475,7 +515,7 @@ bool AutoTokensPass::runOnModule(Module &M) {
if (!HasStr1) { if (!HasStr1) {
auto Ptr = dyn_cast<ConstantExpr>(Str1P); auto Ptr = dyn_cast<ConstantExpr>(Str1P);
if (Ptr && Ptr->isGEPWithNoNotionalOverIndexing()) { if (Ptr && Ptr->getOpcode() == Instruction::GetElementPtr) {
if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) { if (auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0))) {
if (Var->hasInitializer()) { if (Var->hasInitializer()) {
if (auto *Array = if (auto *Array =
@ -568,7 +608,12 @@ bool AutoTokensPass::runOnModule(Module &M) {
if (use_file) { if (use_file) {
close(fd); close(fd);
#if USE_NEW_PM
auto PA = PreservedAnalyses::all();
return PA;
#else
return true; return true;
#endif
} }
LLVMContext &Ctx = M.getContext(); LLVMContext &Ctx = M.getContext();
@ -608,9 +653,17 @@ bool AutoTokensPass::runOnModule(Module &M) {
"libafl_dictionary_" + M.getName()); "libafl_dictionary_" + M.getName());
dict->setSection("libafl_token"); dict->setSection("libafl_token");
#if USE_NEW_PM
auto PA = PreservedAnalyses::all();
return PA;
#else
return true; return true;
#endif
} }
#if USE_NEW_PM
#else
static void registerAutoTokensPass(const PassManagerBuilder &, static void registerAutoTokensPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) { legacy::PassManagerBase &PM) {
PM.add(new AutoTokensPass()); PM.add(new AutoTokensPass());
@ -625,3 +678,4 @@ static RegisterStandardPasses RegisterAutoTokensPass(
static RegisterStandardPasses RegisterAutoTokensPass0( static RegisterStandardPasses RegisterAutoTokensPass0(
PassManagerBuilder::EP_EnabledOnOptLevel0, registerAutoTokensPass); PassManagerBuilder::EP_EnabledOnOptLevel0, registerAutoTokensPass);
#endif

View File

@ -72,6 +72,7 @@ pub struct ClangWrapper {
bit_mode: u32, bit_mode: u32,
need_libafl_arg: bool, need_libafl_arg: bool,
has_libafl_arg: bool, has_libafl_arg: bool,
use_new_pm: bool,
parse_args_called: bool, parse_args_called: bool,
base_args: Vec<String>, base_args: Vec<String>,
@ -281,14 +282,23 @@ impl CompilerWrapper for ClangWrapper {
return Ok(args); return Ok(args);
} }
if !self.passes.is_empty() { if self.use_new_pm {
args.push("-fno-experimental-new-pass-manager".into()); args.push("-fexperimental-new-pass-manager".into());
} else {
args.push("-flegacy-pass-manager".into());
} }
for pass in &self.passes { for pass in &self.passes {
args.push("-Xclang".into()); if self.use_new_pm {
args.push("-load".into()); args.push(format!(
args.push("-Xclang".into()); "-fpass-plugin={}",
args.push(pass.path().into_os_string().into_string().unwrap()); pass.path().into_os_string().into_string().unwrap()
));
} else {
args.push("-Xclang".into());
args.push("-load".into());
args.push("-Xclang".into());
args.push(pass.path().into_os_string().into_string().unwrap());
}
} }
for passes_arg in &self.passes_args { for passes_arg in &self.passes_args {
args.push("-mllvm".into()); args.push("-mllvm".into());
@ -351,6 +361,7 @@ impl ClangWrapper {
bit_mode: 0, bit_mode: 0,
need_libafl_arg: false, need_libafl_arg: false,
has_libafl_arg: false, has_libafl_arg: false,
use_new_pm: false,
parse_args_called: false, parse_args_called: false,
base_args: vec![], base_args: vec![],
cc_args: vec![], cc_args: vec![],
@ -411,6 +422,12 @@ impl ClangWrapper {
self.need_libafl_arg = value; self.need_libafl_arg = value;
self self
} }
/// Set if use new llvm pass manager.
pub fn use_new_pm(&mut self, value: bool) -> &'_ mut Self {
self.use_new_pm = value;
self
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -47,7 +47,7 @@ pub fn autotokens() -> Result<Tokens, Error> {
unsafe { unsafe {
if __token_start.is_null() || __token_stop.is_null() { if __token_start.is_null() || __token_stop.is_null() {
Err(Error::illegal_state( Err(Error::illegal_state(
"AutoTokens section not found, likely the targe is not compiled with AutoTokens", "AutoTokens section not found, likely the target is not compiled with AutoTokens",
)) ))
} else { } else {
// we can safely unwrap // we can safely unwrap