metadata - 在 LLVM 中,如何在程序集文件中反射(reflect)元数据?

标签 metadata llvm inline-assembly llvm-ir

这是设置:我正在使用 LLVM,我有一个分析过程需要使一些分析结果可供以后使用。这些结果需要在我生成的最终 .s 文件(ARM 架构)中可见。然后我在 .s 文件上运行一些脚本,这些脚本使用这些结果进行进一步分析,但也依赖于生成的 ASM 的实际结构(否则我只会使用更多的 LLVM passes)。

最初我认为元数据是我想要的,我创建了一些简单的测试函数来为我关心的每条指令插入一些元数据。但我不知道如何让这个元数据反射(reflect)在最终的 .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 文件中看到一个标签或注释,其中包含我想要的少量信息。有谁知道这是怎么做到的吗?谢谢!

最佳答案

在进一步的研究中,我发现您不能轻易地使用元数据完成我想做的事情。调试信息是输出到程序集文件的元数据的一种特殊情况。事实证明,对我有用的是内联 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。我不确定这表明什么,但很容易忽略。希望这对以后的任何人都有帮助。

关于metadata - 在 LLVM 中,如何在程序集文件中反射(reflect)元数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27234218/

相关文章:

c++ - 切换 C++ 函数的调用堆栈

postgresql - 在 postgres 中使用 table.column%type-argument 获取关于函数的元数据

eclipse - 清除 Eclipse 工作区元数据

c++ - 如何从字符串中获取 clang::QualType?

c++ - 使用 Clang AST 打印函数的参数

c - 为什么在调用 printf 时会覆盖 EDX 的值?

entity-framework - 如何从 Entity Framework 中的元模型中获取多对多关系的实体到表映射

Javascript 动态更改元数据/元标签

python - 为什么我收到错误 : command 'llvm-gcc-4.2' failed with exit status 1

c - 如何在 GCC 内联汇编中使用标签?