LLVM

llvm学习日记十五:符号重命名

2021-09-17  本文已影响0人  鸣人的大哥

一、目的:

分析 LLVM 自带的符号重写Pass

二、分析执行流程:

  1. 入口首先有 RewriteSymbolPass 类对象创建,该构造函数内首先解析输入的map文件;


    image.png
  2. 一路跟踪 parse 函数,可以看到解析文件内容;


    image.png
  3. 读取内容将对象指针存储到容器中:
    ExplicitRewriteFunctionDescriptor 表示显示名称替换,就是全名替换;
    PatternRewriteFunctionDescriptor 表示正则名称替换;


    image.png
  4. 文件解析完后,进入 runOnModule 开始执行;


    image.png
  5. 循环list对象 Descriptors ,栈结构;


    image.png
  6. 符号替换,看起来并不复杂,核心逻辑使用setName将source替换为Target:
    Comdat组件被 rewriteComdat 提前处理,老实说,Comdat 的来源和作用并不是很理解,官网以及一些网站的解释还是不懂,有大佬可以留言解释一下。QAQ


    image.png
  7. 两个命令行参数:

static cl::list<std::string> RewriteMapFiles("rewrite-map-file",
                                             cl::desc("Symbol Rewrite Map"),
                                             cl::value_desc("filename"),
                                             cl::Hidden);
INITIALIZE_PASS(RewriteSymbolsLegacyPass, "rewrite-symbols", "Rewrite Symbols",
                false, false)

rewrite-map-file 需要跟一个yaml格式的文件,显示指明了需要重命名的符号

三、调试运行:

  1. 在xcode中可以直接使用opt调试,命令行参数如下:


    image.png
  2. 我这里使用llvm自带的例子,参数输入ll文件和map文件,map文件的格式在cpp文件里有注释解释:

// Currently, the following descriptor types are supported:
//
// - function:          (function rewriting)
//      + Source        (original name of the function)
//      + Target        (explicit transformation)
//      + Transform     (pattern transformation)
//      + Naked         (boolean, whether the function is undecorated)
// - global variable:   (external linkage global variable rewriting)
//      + Source        (original name of externally visible variable)
//      + Target        (explicit transformation)
//      + Transform     (pattern transformation)
// - global alias:      (global alias rewriting)
//      + Source        (original name of the aliased name)
//      + Target        (explicit transformation)
//      + Transform     (pattern transformation)
  1. 查看生成的IR:
    可以看到map文件配置的函数名都被更改了,


    image.png

四、示例,自己写一个测试下:

#include <stdio.h>

int a = 100;

static int add(int x, int y)
{
    return x + y;
}

int sub(int x, int y)
{
    return x - y;
}

int main()
{
    printf("%d\n", add(3, 4));
    printf("%d\n", sub(5, 4));
    printf("%d\n", a);
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读