自己动手写LLVM pass(零)

原文连接:https://llvm.comptechs.cn/post/18789.html

您已经跟随着LLVM的官方教程完成了HelloWorld pass…..

现在,您想学的更多,看更多的代码,例子……

因此,您可以深入到无比优秀的LLVM源代码树,了解这些着名且功能强大的优化如何通过pass实现的…

但结果却是被异乎寻常的传递构造语法所迷惑,这种语法既不类似于你刚刚遵循的教程,也没有在官方网站的任何地方记录

这正是我几年前碰到的,当时,我还是一个LLVM新手和LLVM pass是我之前听到的唯一的事情。

作为LLVM中最重要的核心组件之一,Pass和PassManager系统的开发时间可以追溯到2014年,其原因是许多缺少优化机会的案例和编译速度回归。

整个代码库也开始通过并排放置旧的pass和new pass实现来反映这些变化。

用户可以通过提供特定的命令行选项切换到新的传递管理器,而旧的传递管理器仍然是默认值。

然而,正如前言部分所指出的那样,目前还没有关于这项创新的官方文件。

虽然作为新的传递管理器及其文档页面,他们的发货日期已经非常接近,但我仍然想为那些渴望了解源代码树中现在发生的事情的那些爱好者写一个简单的教程。

我把这个系列分为四个部分:

  1. 以新的传递管理器方式编写一个新的HelloWorld Pass;

  2. 如何使用新的AnalysisManager替换旧getAnalysis<...>()语法;

  3. 如何在LLVM源代码树中集成传递;

    LLVM源代码树内部的传递需要一些额外的语法,这篇文章将告诉你如何做。

    我知道在一篇名为new pass manager的有点奇怪的文章中谈论遗留传递管理器。但考虑到LLVM的庞大项目规模及其在行业中的广泛采用,移植肯定需要一些时间。因此,对于那些对树内开发感兴趣的人来说,只考虑这部分作为延迟(实际上近十年)的教程。

  4. “如何添加一个clang选项来使用我在LLVM中构建的酷炫功能?”。好吧,这部分会告诉你如何。虽然它似乎与之前文章中的新传递管理器主题正交,但它始终是我的“教程/提示应该正式记录”
    开始吧!

我不会谈论设计细节,比如新的Pass管理器与旧的Pass管理器相比如何提高编译速度和优化质量。新的Pass管理器革命由LLVM社区中的一些最好的开发人员领导,您应该在相关材料中听到他们的解释(而不是我的)(例如LLVM开发者会议中的会谈)。我将从一位专注于中端优化和分析开发的pass manager用户的角度来讲述这个故事。所以后端没有覆盖。

此外,您应该始终检查LLVM邮件列表和源代码中的注释。这些地方的信息可能分散,但它们总是最新的。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
污点分析是一种静态程序分析技术,用于确定程序中哪些变量可以被恶意输入或其他安全漏洞所利用。LLVM是一个广泛使用的编译器基础设施,可以用于实现污点分析。下面是一个简单的LLVM Pass,它实现了简单的污点分析。 首先,我们需要定义一个Pass类,该类继承自llvm::FunctionPass。然后,我们需要在runOnFunction函数中实现我们的污点分析逻辑。在这个例子中,我们将通过检查函数的参数和指令来确定哪些变量是受污染的。 ```c++ #include "llvm/IR/Function.h" #include "llvm/Pass.h" #include "llvm/Support/raw_ostream.h" #include "llvm/IR/Instructions.h" using namespace llvm; namespace { struct TaintAnalysis : public FunctionPass { static char ID; TaintAnalysis() : FunctionPass(ID) {} bool runOnFunction(Function &F) override { // 遍历函数的所有基本块 for (auto &BB : F) { // 遍历基本块的所有指令 for (auto &I : BB) { // 如果指令是一个存储指令 if (auto *SI = dyn_cast<StoreInst>(&I)) { // 如果存储指令的源操作数是一个指针类型 if (auto *Ptr = dyn_cast<PointerType>(SI->getOperand(1)->getType())) { // 如果指针指向的类型是整数类型 if (auto *IntTy = dyn_cast<IntegerType>(Ptr->getElementType())) { // 如果整数类型的位宽为8 if (IntTy->getBitWidth() == 8) { // 输出受污染的指针值和存储的值 errs() << "Tainted pointer value: " << *SI->getOperand(1) << "\n"; errs() << "Tainted value: " << *SI->getOperand(0) << "\n"; } } } } } } return false; } }; } char TaintAnalysis::ID = 0; static RegisterPass<TaintAnalysis> X("taint-analysis", "Taint Analysis Pass"); ``` 我们在runOnFunction函数中遍历函数的所有基本块和指令。我们检查每个存储指令,以确定它是否存储了一个指向整数类型的指针,并且该整数类型具有8位的位宽。如果是的话,我们输出受污染的指针值和存储的值。 最后,我们将该Pass注册到LLVM中,以便在编译时运行。我们使用static RegisterPass来注册我们的Pass,并将其命名为“taint-analysis”。 现在,我们可以使用LLVM编译器运行我们的Pass,以便对C或C++程序进行污点分析。例如,假设我们有以下C程序: ```c++ #include <stdio.h> void foo(int *ptr) { int x = *ptr; printf("The value of x is: %d\n", x); } int main() { int y = 42; foo(&y); return 0; } ``` 我们可以使用以下命令编译程序并运行我们的Pass: ``` clang -Xclang -load -Xclang MyPass.so -c test.c ``` 这将生成一个名为“test.o”的目标文件,并使用我们的Pass进行污点分析。如果程序中存在受污染的指针,我们的Pass将输出它们的值。在这个例子中,我们应该得到以下输出: ``` Tainted pointer value: i32* %ptr Tainted value: i32 42 ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值