- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想将代码中的间接jmp *(eax)
指令替换为mov *(eax),ebx; jmp *ebx
用于 x86 可执行文件。
在实现这个之前,我想制作 LLVM 编译器,通过添加一些打印语句,在每次检测到 jmp *(eax)
指令时记录输出。
然后我想继续替换间接序列。
根据我从谷歌搜索和文章中看到的内容,我可能可以通过修改 llvm 后端中的 x86asmprinter 来实现这一点。但我不知道该怎么做。任何帮助或阅读将不胜感激。
注意:我的实际需求涉及间接跳转和弹出,但我想从这里开始,以便在深入了解更多内容之前更多地了解后端。
最佳答案
我完成了我的项目。发布我的方法以造福他人。
LLVM backend的主要作用是将Intermediate Representation进行转换到最终的可执行文件,具体取决于目标体系结构和其他规范。 LLVM 后端本身由几个阶段组成目标特定优化、指令选择、调度和指令发射。这些阶段是必需的,因为 IR 是一种非常通用的表示,并且需要大量修改才能最终将它们转换为目标特定的可执行文件。
1)每次编译器生成jmp *(eax)
我们可以通过在指令发送/打印阶段添加打印语句来实现这一点。在 IR 的大部分主要转换完成后,有一个 AsmPrinter pass,它通过每个函数的基本 block 中的每个机器指令。此主循环位于 lib/CodeGen/AsmPrinter/AsmPrinter.cpp:AsmPrinter::EmitFunctionBody()
。还有其他相关函数,如 EmitFunctionEpilogue、EmitFunctionPrologue。这些函数最终会针对特定架构调用 EmitInstruction,例如:lib/Target/X86/X86AsmPrinter.cpp
。如果您稍微修改一下,可以调用 MI.getOpcode() 并将其与定义的架构枚举进行比较以打印日志。
例如X86中使用寄存器的跳转,它是X86::JMP64r。您可以使用 MI.getOperand(0) 等获取关联的寄存器。
if(MI->getOpcode() == X86::JMP64r)
dbgs() << "Found jmp *x instruction\n";
2)替换指令所需的更改因您需要的更换类型而异。如果您需要有关寄存器的更多上下文或以前的说明,我们将需要在 Pass 链中更高层实现更改。有一种称为选择 DAG(有向无环图)的指令表示,它存储每条指令对先前指令的依赖关系。例如,在序列中
mov myvalue,%rax
jmp *rax
由于 rax 的值取决于 mov 指令,DAG 会将 jmp 指令指向 move 指令(可能还有它之前的其他节点)。您可以将此处的节点替换为您需要的节点。如果做得正确,它应该最终改变最终的指令。SelectionDAG 代码位于 lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
。总是最好先四处看看,找出理想的改变地点。在对 DAG 进行拓扑排序之前,每个 IR 语句都会经历多次更改,以便指令处于线性序列中。可以查看图表使用 llc --help-hidden
中的 -view-dag* 选项。在我的例子中,我只是在 EmitInstruction 中添加了一个特定的检查并添加了代码来发出我想要的两条指令。
LLVM 文档始终存在,但我发现 Eli Bendersky 的两篇文章比任何其他资源都更有帮助。 Life of LLVM Instruction和 Deeper look into LLVM Code Generation .这些文章讨论了非常复杂的 TableGen 描述和指令匹配过程,如果您有兴趣,这会很酷。
关于x86 - LLVM 后端 : Replacing indirect jmps for x86 backend,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29735683/
我正在从一个旧数据库中选择数据,该数据库有一个滥用状态列。状态列中包含多条信息。值如“新联系人 YYYY”、“在线 YYYY”、“更新 YYYY”、“撤回 YYYY”等……。您可能已经猜到了,YYYY
我想使用ant的replace任务替换这样的文件之一中的 token : 版本.txt version.number=${versionNumber} build.gradle task writeV
sorted_elems 列表中有一些元素将被更改为 str 例如: sorted_elems = ['[abc]', '[xyz]', ['qwe']] 我想删除定义的字符 - [, ], ' 并打
如果替换在变量中传递,第一次和第二次替换是否等效? #!/usr/bin/env perl6 use v6; my $foo = 'switch'; my $t1 = my $t2 = my $t3
我正在做一个本地测试来比较 C# 中 String 和 StringBuilder 的 Replace 操作性能,但是对于 String 我使用了以下代码: String str = "String
我看到了所有内容,没有看到使用“--replace”的方式的内容。 如何在 wkhtmltopdf 中使用“--replace”。 请给我一个例子,谢谢。:) 最佳答案 假设您有一个页脚 my_foo
我需要在 50 多个文件中进行大量搜索/替换,并且正在使用 Sublime Text 3。 有没有办法逐步执行并交互确认每个更改?我不想要只执行所有替换的一揽子“全部替换”操作。 我正在思考 vi/v
那么“replace ”属性如何与 composer 一起使用? ?我已经阅读了 Composer 文档,但仍然不明白。搜索更多信息并没有回答我的问题。 当我查看Laravel/Framework上的
我在玩 F# 句法。 在瑞典,我们有一个游戏叫做“Backslang”(谷歌翻译自“Rövarspråk”) 规则很简单。你说的所有话都必须以特定的方式说出来。虽然人声是相同的,但每个辅音都必须用“o
是否可以在Atom或Sublime Text中对“item”一词使用“查找和替换”并将其替换为“item [i]”,其中[i]是从1开始的数字? 我有一堆看起来像这样的物品: item1 item1
我不太确定如何解释,所以我将从输出开始。我需要返回这个: { replies: [ { type: 'text', content: 'one' } { type:
我是 C# 的新手,所以请原谅我的错误。 我想在每次调用该段代码时(每次调用 2-4 次)替换字符串的某些部分。我想知道哪种方法在性能方面更好:string.Replace 或 stringBuild
我了解.Replace() 和-replace 之间的区别,但是什么是-replace 和[Regex]: :替换()? 我测试了以下 2 个代码,但对我来说结果完全一样。 我还引用了 PowerSh
如果我正在做类似的事情: someString.Replace("abc","").Replace("def","").Replace(@"c:\Windows","") 我怎样才能把它替换成 Reg
我是 C# 的新手,所以请原谅我的错误。 我想在每次调用该段代码时(每次调用 2-4 次)替换字符串的某些部分。我想知道哪种方法在性能方面更好:string.Replace 或 stringBuild
当我使用 call() 或 apply() 时,我遇到了问题。 console.log(String.prototype.replace === String.replace);//false 我认为
在我使用 5-10 个替换的情况下是否有必要使用 stringbuilder。 String someData = "......"; someData = someData.replaceAll("
我有一个字符串,我需要用字典中的值替换其中的标记。它必须尽可能高效。使用 string.replace 进行循环只会消耗内存(记住,字符串是不可变的)。 StringBuilder.Replace()
我正在使用具有许多不同库依赖项的 gradle 项目并使用新的 list 合并。在我的 标签我已经这样设置了: .... 但我收到错误消息: /android/MyApp/app/src/main
我正在尝试从一个数据库中的表中提取模式并将其传输到另一个数据库。以下是执行此操作的函数的一部分。 当 Table( ... ) 时出错被称为。 功能示例: def transfer_data(self
我是一名优秀的程序员,十分优秀!