这是设置:我正在使用LLVM,我有一个分析过程,需要将一些分析结果提供给以后使用。这些结果需要在我生成的最终.s文件(ARM体系结构)中可见。然后我在.s文件上运行一些脚本,进行进一步的分析,使用这些结果,但也依赖于生成的ASM的实际结构(否则我只会使用更多的LLVM通道)。
最初我认为元数据是我想要的,我创建了一些简单的测试函数来为我关心的每条指令插入一些元数据。但我不知道如何在最终的.s文件中反映这些元数据。更糟糕的是,我无法弄清楚如何使元数据字符串成为我真正想要的。您将在下面看到的“5”永远不会输出。相反,我在输出中看到46或47。
void addMetadata(Instruction& I) {
LLVMContext& C = I.getContext();
MDNode* N = MDNode::get(C, MDString::get(C, "5"));
I.setMetadata("alias_set", N);
std::cerr << "Instruction" << std::endl;
I.dump();
}
示例输出:
Instruction
%30 = load i32* %29, align 4, !dbg !67, !alias_set !46
我也听说内联汇编可能有效,但我不知道是否允许我在特定的IR指令之前插入注释或标签。如果IR被重新排序,则该标签或评论需要随时随地进行。基本上,我只想在.s文件中看到标签或注释,其中包含我想要的少量信息。有谁知道这是怎么做到的吗?谢谢!
答案 0 :(得分:3)
在进一步的研究中,我发现你不能轻易做我正在尝试用元数据做的事情。调试信息是输出到汇编文件的元数据的特例。事实证明,对我有用的是内联ASM。这可能是一个有用的东西,作为LLVM元数据类的一部分包含在内;转储元数据的能力。我最终做的是提取我关心的任何元数据并将其作为内联汇编插入到指令前面。此函数将在指令前插入汇编注释,您可以将@info_you_want_to_output替换为您关注的任何数据的字符串表示形式。注意:@通常是ARM程序集注释的开头。此函数使用ATT汇编语法,但如果需要Intel语法,则可以将AD_ATT替换为AD_Intel。
void insertInfo(Instruction& I)
{
std::vector<llvm::Type *> AsmArgTypes = {};
FunctionType *AsmFTy = FunctionType::get(Type::getVoidTy(I.getContext()), AsmArgTypes, false);
InlineAsm *IA = InlineAsm::get(AsmFTy, std::string("@info_you_want_to_output"), "",
/*hasSideEffects*/ true, /*isAlignStack*/ false, InlineAsm::AD_ATT);
Instruction *newInst = CallInst::Create(IA, "", &I);
}
这是我的ARM程序集(.s)文件中的一些示例输出:
ldr r2, .LCPI0_2
mov r1, r4
@APP
@@info_you_want_to_output
@NO_APP
bl __cxa_atexit
pop {r4, lr}
mov pc, lr
请注意,在内联汇编之前和之后,它会插入@APP和@NO_APP。我不确定这表明什么,但很容易忽略。希望这有助于将来的任何人。