创建 LLVM pass 时使用 FunctionPass over ModulePass

Usage of FunctionPass over ModulePass when creating LLVM passes

我看过很多关于创建函数传递的示例(例如 Brandon Holt and Adrian Sampson),但我很好奇创建模块传递来解决这些非常相似的问题的难度。我尝试使用此示例和 llvm 源代码实现模块传递以显示全局变量名称,以了解您必须如何遍历成员。

我使用的是LLVM的源码编译版本,并使用上面链接中的示例添加pass,然后运行:

$ clang -Xclang -load -Xclang build/Skeleton/libSkeletonPass.so something.c

然后 returns 这是胡言乱语。但是,如果我实现一个 functionPass 并且只使用 Auto 来确定要初始化的类型,那么它非常简单并且可以工作。我只是想以错误的方式打印全局变量吗?

这是终端错误输出的 pastebin。 link

Skeleton.cpp

#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/IR/LLVMContext.h"
using namespace llvm;

namespace {
  // Helper method for converting the name of a LLVM type to a string
  static std::string LLVMTypeAsString(const Type *T) {
    std::string TypeName;
    raw_string_ostream N(TypeName);
    T->print(N);
    return N.str();
  }

  struct SkeletonPass : public ModulePass {
    static char ID;
    SkeletonPass() : ModulePass(ID) {}

    virtual bool runOnModule(Module &M) {

      for (Module::const_global_iterator GI = M.global_begin(), 
                                 GE = M.global_end(); GI != GE; ++GI) {
          errs() << "Found global named: " << GI->getName() 
                  << "\tType: " << LLVMTypeAsString(GI->getType()) << "!\n";
      }

      return false;
    }
  };
}

char SkeletonPass::ID = 0;

// Automatically enable the pass.
// http://adriansampson.net/blog/clangpass.html
static void registerSkeletonPass(const PassManagerBuilder &,
                         legacy::PassManagerBase &PM) {
  PM.add(new SkeletonPass());
}
static RegisterStandardPasses
  RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible,
                 registerSkeletonPass);

something.c

int value0 = 5;

int main(int argc, char const *argv[])
{
    int value = 4;
    value += 1;
    return 0;
}

经过广泛的 github 搜索,我能够弄清楚这一点。 Here 是我遵循教程的答案,以帮助可能对如何实施模块传递感到好奇的其他人。