gpt4 book ai didi

c++ - 使用 LLVM 检测 C/C++ 代码

转载 作者:可可西里 更新时间:2023-11-01 15:16:16 25 4
gpt4 key购买 nike

我想编写一个 LLVM pass 来检测每个内存访问。这就是我想要做的。

给定任何 C/C++ 程序(如下面给出的程序),我试图在每条从内存读取/写入内存的指令之前和之后插入对某个函数的调用。例如考虑下面的 C++ 程序 (Account.cpp)

#include <stdio.h>

class Account {
int balance;

public:
Account(int b)
{
balance = b;
}
~Account(){ }

int read()
{
int r;
r = balance;
return r;
}

void deposit(int n)
{
balance = balance + n;
}

void withdraw(int n)
{
int r = read();
balance = r - n;
}
};

int main ()
{
Account* a = new Account(10);
a->deposit(1);
a->withdraw(2);
delete a;
}

所以在检测之后我的程序应该是这样的:

#include <stdio.h>

class Account
{
int balance;

public:
Account(int b)
{
balance = b;
}
~Account(){ }

int read()
{
int r;
foo();
r = balance;
foo();
return r;
}

void deposit(int n)
{
foo();
balance = balance + n;
foo();
}

void withdraw(int n)
{
foo();
int r = read();
foo();
foo();
balance = r - n;
foo();
}
};

int main ()
{
Account* a = new Account(10);
a->deposit(1);
a->withdraw(2);
delete a;
}

其中 foo() 可以是任何函数,例如获取当前系统时间或增加计数器等。

请给我示例(源代码、教程等)以及如何运行它的步骤。我已经阅读了关于如何制作 LLVM Pass 的教程 http://llvm.org/docs/WritingAnLLVMPass.html , 但想不通如何为上述问题写通行证。

最佳答案

我对 LLVM 不是很熟悉,但我对 GCC(及其插件机制)比较熟悉,因为我是 GCC MELT 的主要作者(一种扩展 GCC 的高级领域特定语言,顺便说一句,您可以使用它来解决您的问题)。所以我会尽量笼统地回答。

首先要知道为什么要适配编译器(或静态分析器)。这是一个有值(value)的目标,但它确实有缺点(特别是,w.r.t. 在您的 C++ 程序中重新定义一些运算符或其他构造)。

扩展编译器(无论是 GCC 或 LLVM 还是其他)的要点是你很可能应该处理它的所有内部表示(并且你可能不能跳过它的一部分,除非你有一个非常狭窄的定义问题) .对于GCC来说就是要处理100多种Tree-s和近20种Gimple-s:在GCC中端,tree-s代表操作数和声明,gimple-s代表指令。这种方法的优点是,一旦完成,您的扩展应该能够处理编译器可接受的任何软件。缺点是编译器内部表示的复杂性(这可以通过编译器接受的 C 和 C++ 源语言定义的复杂性,以及它们生成的目标机器代码的复杂性,以及不断增加的距离来解释)源语言和目标语言之间)。

因此破解通用编译器(无论是 GCC 还是 LLVM)或静态分析器(如 Frama-C)是一项相当大的任务(超过一个月的工作,而不是几天)。像你展示的那样只处理一个很小的 ​​C++ 程序,这是不值得的。但如果您只是想处理大型源软件库,那绝对值得付出努力。

问候

关于c++ - 使用 LLVM 检测 C/C++ 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7806689/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com