如何使用llvm为具有复杂make的大型源代码生成调用图?

时间:2019-01-10 06:28:51

标签: llvm llvm-clang llvm-ir bitcode

我正在研究包含许多文件的软件包的源代码。该软件包的制造商将产生中间的.a或.so文件。因此,我想将make调用的命令更改为llvm等效命令,以便可以生成调用图。由于make规则的复杂性,我希望更改为1-1(1条原始命令1条llvm命令)。

显示了一个最小的示例和原始的编译命令。

$ gcc -Wall -pedantic -g -c -o print1.o print1.c
$ ar cr ./libprint1.a print1.o
$ gcc -Wall -pedantic -g -fPIC -shared -o ./libprint3.so print3.c
$ gcc -Wall -pedantic -g -c -o main.o main.c
$ gcc -Wall -pedantic -g -c -o print2.o print2.c
$ gcc -L. -lprint1 -lprint3 -o ./main.exe main.o print2.o

我想将每个命令映射到llmv等效项。到目前为止,我有以下命令,但这不是原始命令到llvm命令的1-1映射(例如,不存在.a和.so)。调用图也没有正确生成(可能是由于静态功能?)。

clang -S -emit-llvm -o print1.ll print1.c
clang -S -emit-llvm -o print2.ll print2.c
clang -S -emit-llvm -o print3.ll print3.c
clang -S -emit-llvm -o main.ll main.c
llvm-link -o main.bc main.ll print{1..3}.ll
opt -dot-callgraph  main.bc -o main.dot

有人可以告诉我什么是正确的llmv命令(必须保持1-1)以生成调用图吗?谢谢。

==> main.c <==
/* vim: set noexpandtab tabstop=2: */
#include <stdio.h>
void print1();
static void print() {
    print1();
}

int main() {
    print();
    return 0;
}

==> print1.c <==
/* vim: set noexpandtab tabstop=2: */
#include <stdio.h>
void print2();

void print1() {
    puts("Hello World1!");
    print2();
}

==> print2.c <==
/* vim: set noexpandtab tabstop=2: */
#include <stdio.h>
void print3();

static void print() {
    puts("Hello World2!");
}

void print2() {
    print();
    print3();
}

==> print3.c <==
/* vim: set noexpandtab tabstop=2: */
#include <stdio.h>

void print3() {
    puts("Hello World3!");
}

0 个答案:

没有答案