C 如何使用LLVM或其他工具标记基本块的边界?

C 如何使用LLVM或其他工具标记基本块的边界?,c,compilation,llvm,C,Compilation,Llvm,我正试图重做“基于神经机器翻译的函数对以外的二进制代码相似性比较”这篇论文的工作,但我未能完成一些组件 作者说:“我们修改后端以添加基本块边界注释器,该注释器不仅清楚地标记块的边界,而且还为每个生成的装配块注释一个唯一的ID,所有装配块都是从同一IR块编译而来的。” 我不知道如何标记块的边界,以确定不同体系结构的多个汇编代码是否来自使用LLVM或其他工具的同一源代码 非常感谢您的帮助。好吧,如果有一个函数,您可以使用.begin()和end()对其基本块进行迭代。这将为您提供一个BasicBlo

我正试图重做“基于神经机器翻译的函数对以外的二进制代码相似性比较”这篇论文的工作,但我未能完成一些组件

作者说:“我们修改后端以添加基本块边界注释器,该注释器不仅清楚地标记块的边界,而且还为每个生成的装配块注释一个唯一的ID,所有装配块都是从同一IR块编译而来的。”

我不知道如何标记块的边界,以确定不同体系结构的多个汇编代码是否来自使用LLVM或其他工具的同一源代码


非常感谢您的帮助。

好吧,如果有一个
函数
,您可以使用
.begin()
end()
对其
基本块
进行迭代。这将为您提供一个
BasicBlock
,对于它,您可以始终执行
.front()
.back()
分别获取第一条和最后一条指令。这将为您提供每个块和函数的“边界”

更新

我想到了一个方法,如果您希望“边界”出现在编译的源代码中


在每个函数开始时,您可以生成
store
指令来存储函数每个块的值。如果我没有弄错的话,它们将在汇编级别变成
mov
s,其中一个操作数将是基本块的起点。这将允许您推断“边界”。

此问题分为两部分:

这不仅清楚地标明了区块的边界

每个基本块由
终止符
指令终止。例如,它可以是一个分支

但也为每个生成的程序集块注释一个唯一的ID,就像所有程序集块都是从相同的IR块编译而来一样

这看起来像某种散列机制。如果对非dbg指令进行迭代并进行散列,则将它们组合起来,为每个基本块生成唯一的ID。这应该达到目的。例如,请参见如何对每条指令进行哈希


需要记住的一件事是,如何保存由于上述散列而创建的信息。您可以将信息添加为元数据,或将信息打印到某个文件中以供日后参考。

此类文件中有电子邮件地址。你可以写信给作者,询问他们的LLVM补丁。我已经给他们发了一封电子邮件。但是我不知道为什么他们不愿意告诉我他们修改了哪个部分。@michwqy我们已经发布了代码:谢谢。但是llvm过程是迭代llvm IR层上的基本块,我不知道如何维护汇编代码的边界。标记边界的目的是,如果我将一个源代码编译成不同体系结构的两个汇编代码,我可以确定两个汇编代码中的基本块是否来自同一个源代码。如果这是您的目标,那么这应该很容易解决。调用和每个块的终止符。或者只是在所有的说明上加上一些。在启用调试信息的情况下编译。LLVM将注意保留您在DebugLoc中输入的信息。DebugLoc通常包含一个文件名和行号,但您可以更改它并存储一个标识块的字符串。@michwqy我已经用建议更新了我的答案。谢谢。我发现如果我通过叮当声获得带有-g的.ll文件,IR中块的名称将保留在汇编代码中。像这样
@%bb.0:@%entry。LBB0_1:@%if.then
。我不知道它是否标记了基本块,但它足以帮助我确定两段汇编代码是否来自相同的源代码。我稍后会试试你的想法。