LoadInst 和 StoreInst 值和地址 LLVM

2024-03-24

我有一个文件 print.c,它有两个功能:

void printLoad(...) {
  // print address and value of memory location from which value
  printf("address=... value=...", ...); 
}

void printStore(...) {
  // print address and value of memory location from which value 
}

我有一个 LLVM 传递,它迭代指令并在当前指令(加载/存储实例)之后添加 CallInst 指令 printLoad 或 printStore (取决于指令类型)。

为了调用此 printStore 或 printLoad,我需要向 CallInst::Create 函数添加适当的参数,它们是内存位置的地址和值。

这是我想要实现的目标的一个例子:

define void @mains() #0 {
  %1 = alloca i32, align 4
  %2 = alloca i32, align 4
  store i32 0, i32* %1, align 4
  store i32 5, i32* %1, align 4
  store i32 2, i32* %2, align 4
  store i32 4, i32* %2, align 4
  %3 = load i32, i32* %2, align 4
  %4 = add nsw i32 %3, 5
  store i32 %4, i32* %1, align 4
  ret void
}

The output should be:
  store instruction: 
    address=...   // address of %1
    value=0
  ...
  ...
  ...
  load instruction:
    address=...  // address of %2
    value=4
  store instruction:
    address=...  // address of %1
    value=9

到目前为止的进展:

我可以在 LoadInst/StoreInst 上使用 getPointerOperand() 获取操作数的地址。

我还可以通过将操作数转换为 ConstantInt 来获取前 4 个存储指令中 StoreInst 的值,但我不知道如何提取最后一个 StoreInst 中的值。有可能吗?

EDITED:

Using

void printLoad(int32_t p) 

and

Constant *hookLoadFunc = M.getOrInsertFunction("printLoad", Type::getVoidTy(M.getContext()), Type::getInt32Ty(M.getContext()));

.

  %1 = alloca i32, align 4
  %2 = alloca i32, align 4
  %3 = alloca i32, align 4
  store i32 0, i32* %1, align 4
  call void @printStore(i32 0)
  store i32 0, i32* %2, align 4
  call void @printStore(i32 0)
  store i32 5, i32* %2, align 4
  call void @printStore(i32 5)
  store i32 2, i32* %3, align 4
  call void @printStore(i32 2)
  store i32 4, i32* %3, align 4
  call void @printStore(i32 4)
  %4 = load i32, i32* %3, align 4
  %5 = add nsw i32 %4, 5
  store i32 %5, i32* %2, align 4
  call void @printStore(i32 %5)
  ret i32 0
  %2 = alloca i32, align 4
  store i32 %0, i32* %2, align 4
  call void @printStore(i32 %0)
  %3 = load i32, i32* %2, align 4
  %4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str, i32 0, i32 0), i32 %3)
  ret void
  %2 = alloca i32, align 4
  store i32 %0, i32* %2, align 4
  call void @printStore(i32 %0)
  %3 = load i32, i32* %2, align 4
  %4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.1, i32 0, i32 0), i32 %3)
  ret void

这会导致运行时出现分段错误:11。

SOLVED:

发现我有无限循环(由于递归)。打印商店实际上使用加载/存储指令,从而创建另一个调用打印商店等等。


假设您有一个llvm::Function代表printLoad() and printStore():

llvm::Function * print_load = ....
llvm::Function * print_store = ...

你可以发出一个CallInst对于每个LoadInst and StoreInst.

For LoadInst:

LoadInst * some_load = ...
Value * address_of_load = some_load->getOperand(0);
Value * print_load_arguments[] = { address_of_load, some_load };

// Insert a CallInst just after the load.
CallInst::Create(print_load, print_load_arguments )->insertAfter( some_load );

请记住,在 llvm 中加载的值LoadInstLoadInst itself.

For StoreInst:

StoreInst * some_store = ...
Value * value_to_store = some_store->getOperand(0);
Value * address_of_store = some_store->getOperand(1);
Value * print_store_arguments[] = { address_of_store, value_to_store };

// Insert a CallInst just after the store.
CallInst::Create(print_store, print_store_arguments)->insertAfter(some_store);

如果所有类型都匹配,这将起作用。否则,您必须插入BitCast致电前的说明printStore() or printLoad().

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LoadInst 和 StoreInst 值和地址 LLVM 的相关文章

  • MSI 和 EXE 安装程序有什么区别,我应该选择哪一个? [复制]

    这个问题在这里已经有答案了 可能的重复 msi 和 setup exe 文件之间有什么具体区别 https stackoverflow com questions 1789530 what are the specific differen
  • 删除字符串 C 的第一个字符

    我试图删除字符串的第一个字符并保留其余部分 我当前的代码无法编译 我对如何修复它感到困惑 My code char newStr char charBuffer int len strlen charBuffer int i 1 char
  • VSTS 构建失败/发布无法在 bin 文件夹中找到 roslyn\csc.exe

    我们有一个网站项目 安装了以下 nuget 软件包 Microsoft CodeDom Providers DotNetCompilerPlatform 1 0 8 Microsoft Net Compilers 2 4 0 The web
  • CMake 和 Visual Studio:如何获得快速、安静的命令行构建?

    我有一个 cmake 项目 它成功地完成了我想要的一切 但我有大约 100 个文件 当我只需要重新编译一个文件时 我厌倦了每次看到生成的巨大输出 每个文件 30 行 明确地说 我正在编译cmake build 得到这个结果 我需要传递给编译
  • C 中的复合语句表达式

    下面的代码不起作用 int i void 999 100 添加括号就可以了 为什么 int i void 999 100 还有另一种方法可以完成此类分配 int i void 999 100 是什么让他们与众不同 在这份声明中 int i
  • 隐式方法组转换陷阱

    我想知道为什么给定代码的输出 在 LinqPad 中执行 void Main Compare1 Action Main Dump Compare2 Main Dump bool Compare1 Delegate x return x Ac
  • 如何“杀死”Pthread?

    我正在学习 Pthreads 并且想知道杀死这样一个对象的最佳方法是什么 在寻找类似的问题后 我无法找到 明确 的答案 但请随时向我指出任何相关问题 我正在使用一个小型客户端服务器应用程序 其中服务器主线程正在侦听套接字上的客户端连接 每次
  • 在桌面应用程序中,类库的连接字符串存储在哪里?我可以在app.config中使用吗?

    我是桌面应用程序开发的新手 目前正在使用分层架构 用户界面 DAL BLL 构建桌面应用程序 在 Web 开发中 我曾经将连接字符串存储在 web config 中 我的类库从那里访问它 请指导我在桌面应用程序中如何以及在何处存储 DAL
  • 返回指向 std::vector 中的对象的 a

    我有一个关于返回对向量元素的引用的非常基本的问题 有一个向量vec存储类的实例Foo 我想访问这个向量中的一个元素 不想使用向量索引 我应该如何编码该方法getFoo here include
  • C++ 私有静态成员变量

    此 C 代码在编译时产生链接器错误 A h class A public static void f private static std vector
  • 如何在 C++ 中对静态缓冲区执行字符串格式化?

    我正在处理一段对性能要求非常高的代码 我需要执行一些格式化的字符串操作 但我试图避免内存分配 甚至是内部库的内存分配 在过去 我会做类似以下的事情 假设是 C 11 constexpr int BUFFER SIZE 200 char bu
  • C 中“for”循环中的两个变量

    我正在编写一些代码 需要在其中使用两个变量for环形 下面的代码看起来没问题吗 它确实给了我预期的结果 for loop 1 offset loop 2 offset 2 loop 1 gt offset 190 loop 2 lt 190
  • 控制器中的异常处理 (ASP.NET MVC)

    当您自己的代码抛出异常并从控制器中的操作调用时 应该如何处理 我看到很多最佳实践的例子 其中根本没有 try catch 语句 例如 从存储库访问数据 public ViewResult Index IList
  • 以标准用户身份打开默认浏览器 (C++)

    我目前正在使用 ShellExecute 打开 在用户浏览器中打开 URL 但在 Win7 和 Vista 中遇到了一些麻烦 因为该程序作为服务运行提升 当 ShellExecute 打开浏览器时 它似乎读取 本地管理员 配置文件而不是用户
  • 替换 JSON 中的转义字符

    我想用空格替换 JSON 字符串中的 字符 我怎样才能做到这一点 我发现从 JSON 字符串中删除所有转义字符的最简单 最好的方法是将字符串传递到正则表达式 Unescape 方法 此方法返回一个没有转义字符的新字符串 甚至删除了 n t
  • 如何用C++解析复杂的字符串?

    我试图弄清楚如何使用 解析这个字符串sstream 和C 其格式为 string int int 我需要能够将包含 IP 地址的字符串的第一部分分配给 std string 以下是该字符串的示例 std string 127 0 0 1 1
  • 为什么 std::ranges::filter_view 对象必须是非常量才能查询其元素?

    include
  • 我应该使用多个 HttpClient 来进行批量异步 GET 请求吗?

    我有一个场景 我需要在尽可能短的时间内发出大量 GET 请求 想想大约 1000 个 我知道通常最好保留一个客户端并尽可能重用它 Create Single HTTP Client HttpClient client new HttpCli
  • 使用 roslyn 扩展 C# 语法

    我试图在没有 else 情况的情况下实现 return if return value if 因为我只想在条件有效时返回或返回一个值 我知道 有if condition return or if condition return value
  • 如何将 Metro 应用部署到桌面?

    我正在尝试将我的 C 应用程序部署到我的 Windows 8 Metro 桌面 我可以在 bin 文件夹中看到部署的文件 但是当我尝试打开它们时 出现以下错误 该应用程序只能在 AppContainer 的上下文中运行 我检查了属性上下文菜

随机推荐