有没有一种标准的方法来重建降低的结构函数参数?

我有一个结构类型:

typedef struct boundptr {
  uint8_t *ptr;
  size_t size;
} boundptr;

我想捕获该类型函数的所有参数。例如此功能:

boundptr sample_function_stub(boundptr lp, boundptr lp2);

在我的64位计算机上,Clang将该签名转换为:

define { i8*, i64 } @sample_function_stub(i8* %lp.coerce0, i64 %lp.coerce1, i8* %lp2.coerce0, i64 %lp2.coerce1) #0 {

问题:

有没有更好的方法来重构这些论点?

是否可以禁止此类参数降低,同时为外部调用保留相同的ABI?

更多背景信息:

因此,我猜在LLVM IR中,根据平台ABI,编译器将结构分解为单独的字段(这不是最坏的情况,请参见1)。顺便说一句,它重建原始的两个参数lplp2函数体后。

现在,我的分析,我想这两个参数lp,并lp2在充分,这些4( ,)。在这种情况下,我可能可以依靠名称(意思是第一个字段-第二个)。lp.coerce0lp.coerce1lp2.coerce0lp2.coerce1.coerce0.coerce1

我不喜欢这种方法:

  • 我不确定Clang是否在以后的版本中保留此约定
  • 当然,这取决于ABI,因此在另一个平台上可能会有不同的故障。

另一方面,我不能在函数的开头使用重建代码,因为我可能会将其与局部变量的某些用户代码混淆。


我使用3.4.2基于LLVM的Clang3.4.2作为target x86_64-pc-linux-gnu

PS这是另一个示例,显示了Clang如何将函数参数弄乱。

迈克尔·海德尔

我认为您不使用进行编译O0AFAIK,当您不优化代码时,clang将重新组合原始类型。Clang分解了您的结构,以将它们通过寄存器(至少在x86上)传递给被调用的函数。如您所说,这取决于所使用的ABI。

这是您的用例中的一个虚拟示例:

#include <cstddef>

typedef struct boundptr {
  void *ptr;
  size_t size;
} boundptr;

boundptr foo(boundptr ptr1, boundptr ptr2) { return {ptr1.ptr, ptr2.size}; }

int main() {
  boundptr p1, p2;
  boundptr p3 = foo(p1, p2);
  return 0;
}

clang -O0 -std=c++11 -emit-llvm -S -c test.cppgenerate编译它foo

define { i8*, i64 } @_Z3foo8boundptrS_(i8* %ptr1.coerce0, i64 %ptr1.coerce1, i8* %ptr2.coerce0, i64 %ptr2.coerce1) #0 {
  %1 = alloca %struct.boundptr, align 8
  %ptr1 = alloca %struct.boundptr, align 8
  %ptr2 = alloca %struct.boundptr, align 8
  %2 = bitcast %struct.boundptr* %ptr1 to { i8*, i64 }*
  %3 = getelementptr { i8*, i64 }, { i8*, i64 }* %2, i32 0, i32 0
  store i8** %ptr1.coerce0, i8** %3
  %4 = getelementptr { i8*, i64 }, { i8*, i64 }* %2, i32 0, i32 1
  store i64 %ptr1.coerce1, i64* %4
  %5 = bitcast %struct.boundptr* %ptr2 to { i8*, i64 }*
  %6 = getelementptr { i8*, i64 }, { i8*, i64 }* %5, i32 0, i32 0
  store i8** %ptr2.coerce0, i8** %6
  %7 = getelementptr { i8**, i64 }, { i8**, i64 }* %5, i32 0, i32 1
  store i64 %ptr2.coerce1, i64* %7
  %8 = getelementptr inbounds %struct.boundptr, %struct.boundptr* %1, i32 0, i32 0
  %9 = getelementptr inbounds %struct.boundptr, %struct.boundptr* %ptr1, i32 0, i32 0
  %10 = load i8*, i8** %9, align 8
  store i8* %10, i8** %8, align 8
  %11 = getelementptr inbounds %struct.boundptr, %struct.boundptr* %1, i32 0, i32 1
  %12 = getelementptr inbounds %struct.boundptr, %struct.boundptr* %ptr2, i32 0, i32 1
  %13 = load i64, i64* %12, align 8
  store i64 %13, i64* %11, align 8
  %14 = bitcast %struct.boundptr* %1 to { i8*, i64 }*
  %15 = load { i8*, i64 }, { i8*, i64 }* %14, align 8
  ret { i8*, i64 } %15
}

boundptr 在被调用函数堆栈上重构(这也取决于所使用的调用约定)。

现在,要找出boundptr您要使用的参数,您可以执行以下操作:

  1. 访问alloca您的通行证中的每个机构并关注其用户。
  2. 按照alloca和GEP指示进行强制转换,在上找到商店指示boundptr
  3. 检查要存储的值。如果它们是您的函数参数,并且匹配类型和名称,那么您已经找到了重新组合的代码boundptr

当然,您可以从functions参数开始以另一种方式进行操作。

这是未来的证明吗?绝对不是。Clang / LLVM并非旨在保持向后兼容性。对于兼容性,ABI很重要。

缺点:您必须在代码生成后的很早就进入优化器。甚至01会删除的这些堆栈分配boundptr因此,您必须修改自己clang才能在优化过程中执行过程,并且不能使其成为独立过程(例如,由使用opt)。

更好的解决方案:由于必须以某种方式修改clang,因此您可以添加标识您boundptr类型的元数据因此,您可以将您的片段“打包”boundptr在一起,以将其标识为boundptr这将使优化程序幸免。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

有没有一种方法来获取函数参数的类型?

来自分类Dev

有没有一种方法来获取函数参数的名称(而不是参数)?

来自分类Dev

有没有一种快速的方法来检查Clojure函数中的nil参数?

来自分类Dev

有没有一种简单的方法来计时elisp中的函数调用?

来自分类Dev

有没有一种简单的方法来计算库中记录的函数?

来自分类Dev

有没有一种方法来约束函子的参数签名,以便参数可以为结构提供未指定的相等类型?

来自分类Dev

有没有一种标准的C方法来“完全”打印Dragon4中的浮点值?

来自分类Dev

有没有一种标准的方法来获取SAP用户的先前登录日期?

来自分类Dev

有没有一种标准的方法来获取C ++中的第n个“ nextafter”浮点值

来自分类Dev

有没有一种标准的方法来指定文档字符串中的回调函数的类型?

来自分类Dev

有没有一种简单的方法来解释必需参数和可选参数?Python

来自分类Dev

有没有一种快速的方法来将C#中的结构归零?

来自分类Dev

有没有一种有效的方法来对参数映射进行排序?

来自分类Dev

有没有一种优雅而Python风格的方法来为类构造函数要求输入?

来自分类Dev

有没有一种更快的方法来运行基于pandas apply函数的代码?

来自分类Dev

有没有一种简单的方法来创建自定义的 PHP XML 编写器函数?

来自分类Dev

有没有一种快速的方法来打开命令窗口

来自分类Dev

有没有一种简单的方法来限制用户带宽的使用?

来自分类Dev

关系更改时,有没有一种很好的方法来更新NSManagedObject?

来自分类Dev

有没有一种方法来#if Objective-C ++?

来自分类Dev

有没有一种简单的方法来显示JavaFX中的提示文本?

来自分类Dev

有没有一种更好的方法来与联合地图相交?

来自分类Dev

有没有一种简单的方法来确定HTML元素的内容类别?

来自分类Dev

有没有一种更快的方法来检查数字是否在间隔内?

来自分类Dev

有没有一种更理想的方法来按谓词分割流?

来自分类Dev

XSL:有没有一种简单的方法来预防寡妇?

来自分类Dev

有没有一种通用的方法来打印变量?

来自分类Dev

有没有一种“聪明”的方法来摆脱嵌套循环?

来自分类Dev

有没有一种好的方法来冻结Javascript中的对象数组?

Related 相关文章

  1. 1

    有没有一种方法来获取函数参数的类型?

  2. 2

    有没有一种方法来获取函数参数的名称(而不是参数)?

  3. 3

    有没有一种快速的方法来检查Clojure函数中的nil参数?

  4. 4

    有没有一种简单的方法来计时elisp中的函数调用?

  5. 5

    有没有一种简单的方法来计算库中记录的函数?

  6. 6

    有没有一种方法来约束函子的参数签名,以便参数可以为结构提供未指定的相等类型?

  7. 7

    有没有一种标准的C方法来“完全”打印Dragon4中的浮点值?

  8. 8

    有没有一种标准的方法来获取SAP用户的先前登录日期?

  9. 9

    有没有一种标准的方法来获取C ++中的第n个“ nextafter”浮点值

  10. 10

    有没有一种标准的方法来指定文档字符串中的回调函数的类型?

  11. 11

    有没有一种简单的方法来解释必需参数和可选参数?Python

  12. 12

    有没有一种快速的方法来将C#中的结构归零?

  13. 13

    有没有一种有效的方法来对参数映射进行排序?

  14. 14

    有没有一种优雅而Python风格的方法来为类构造函数要求输入?

  15. 15

    有没有一种更快的方法来运行基于pandas apply函数的代码?

  16. 16

    有没有一种简单的方法来创建自定义的 PHP XML 编写器函数?

  17. 17

    有没有一种快速的方法来打开命令窗口

  18. 18

    有没有一种简单的方法来限制用户带宽的使用?

  19. 19

    关系更改时,有没有一种很好的方法来更新NSManagedObject?

  20. 20

    有没有一种方法来#if Objective-C ++?

  21. 21

    有没有一种简单的方法来显示JavaFX中的提示文本?

  22. 22

    有没有一种更好的方法来与联合地图相交?

  23. 23

    有没有一种简单的方法来确定HTML元素的内容类别?

  24. 24

    有没有一种更快的方法来检查数字是否在间隔内?

  25. 25

    有没有一种更理想的方法来按谓词分割流?

  26. 26

    XSL:有没有一种简单的方法来预防寡妇?

  27. 27

    有没有一种通用的方法来打印变量?

  28. 28

    有没有一种“聪明”的方法来摆脱嵌套循环?

  29. 29

    有没有一种好的方法来冻结Javascript中的对象数组?

热门标签

归档