c - 修改 LLVM 位码的指针大小
问题描述
我有一个从另一个进程生成的位码文件。此文件保证为 64 位,但我想将位代码转换为 32 位,以便可以使用 clang 或 gcc 将其编译为 32 位应用程序。
我知道 LLVM 确实具有能够修改位码中所有指针的字节大小的功能,但它是私有的,仅在重置 DataLayout 时使用。还有一个setPointerSize
功能公开的cerca 1.6版本。我想知道是否有一种方法可以修改 llvm 位码的指针大小,而不管程序在做什么。
我更喜欢使用命令行,但如果需要,我可以使用 LLVM-C API。我还希望将位码保留为二进制格式,而不是将其转换为文本格式 LLVM IR。感谢任何有修改 bitcode 的 DataLayout 经验并可以提供帮助的人。
解决方案
它可以完成,或者更有可能不会。
(唯一的)方法是创建一个具有所需数据布局的新模块,遍历旧模块中的全局变量(函数和全局变量),并在新模块中创建等效的全局变量。
但这可能行不通。检查 C 的 sizeof 可能有助于理解原因。
在 IR中有一种实现方法sizeof Foo
:将整数 0 转换为指向 Foo 数组的指针,然后获取该数组中条目号 1 的地址,然后将地址转换为整数。这为您提供了数组第一个条目的大小(条目号 0),即 sizeof Foo(您可能需要或可能不想要一些填充)。还有另一种方法是通过查询DataLayout来实现它,它更简单,在我看来也更有品味。
您不能依赖其他进程来始终使用 cast-plus-address-cast 进程,因此当您在正在处理的模块中看到常量 32 时,您就有问题了。
- 比如说,一个只包含指针的结构的大小,在这种情况下你应该把它改成 16 吗?
- 或者它是另一个结构的大小,一个包含半个指针和半个值的结构,在这种情况下你应该将它更改为 24?
- 还是源代码中的32?也许源代码实现了一个允许字符串最长为 32 个字符的规范?
- 或者它是在头文件中的 32,如果编译器为不同的目标编译它会读取不同的头文件并且会有不同的值?
还有其他类似的问题。我认为处理这些整数常量是最大的问题,但这不是唯一的问题。
推荐阅读
- sorting - 如何在 Elasticsearch 2.4.4 上进行自然排序
- python-3.x - 如何将双端队列数组中每个双端队列的所有值附加到一个数组中?(这也删除了每个双端队列中的第一个重复节点)
- java - 通过连接防止 Oracle 数据库错误
- google-apps-script - Google表格工具提示整数差异按列
- php - 使用超级 gloable 变量 $_GLOBALS 时未定义的变量
- android - Android 应用链接失败,SingleHostAsyncVerifier 返回失败
- javascript - 如何使用 tensorflow.js 正确上传 angular 的预训练模型?
- php - 如何循环使用条件
- nuxt.js - nuxt 生成的 dist 文件返回 net::ERR_FILE_NOT_FOUND
- kubernetes - Kubernetes 持久卷访问模式:ReadWriteOnce vs ReadOnlyMany vs ReadWriteMany