为什么某些函数不会触发基于FunctionPass的LLVM过程?
我正在学习编写LLVM pass,方法是尝试复制示例。pass为什么某些函数不会触发基于FunctionPass的LLVM过程?,llvm,llvm-clang,llvm-ir,Llvm,Llvm Clang,Llvm Ir,我正在学习编写LLVM pass,方法是尝试复制示例。passhello.cpp看起来像: #include "llvm/Pass.h" #include "llvm/IR/Function.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { struct Hello : public FunctionPass { static char ID; Hello() : Func
hello.cpp
看起来像:
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct Hello : public FunctionPass {
static char ID;
Hello() : FunctionPass(ID) {}
bool runOnFunction(Function &F) override {
errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
return false;
}
};
}
char Hello::ID = 0;9
static RegisterPass<Hello> X("hello", "Hello World Pass", false, false);
#include <stdio.h>
int main() {
printf("Hello World\n");
return 0;
}
; ModuleID = 'src/hello.bc'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@str = private unnamed_addr constant [12 x i8] c"Hello World\00"
; Function Attrs: nounwind uwtable
define i32 @main() #0 {
%puts = tail call i32 @puts(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @str, i64 0, i64 0))
ret i32 0
}
; Function Attrs: nounwind
declare i32 @puts(i8* nocapture) #1
attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.8.0 (tags/RELEASE_380/final)"}
该程序使用以下命令行编译:clangworld.c-c-emit llvm-O3-o world.bc
llvm dis
生成的位码如下所示:
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
namespace {
struct Hello : public FunctionPass {
static char ID;
Hello() : FunctionPass(ID) {}
bool runOnFunction(Function &F) override {
errs() << "Hello: ";
errs().write_escaped(F.getName()) << '\n';
return false;
}
};
}
char Hello::ID = 0;9
static RegisterPass<Hello> X("hello", "Hello World Pass", false, false);
#include <stdio.h>
int main() {
printf("Hello World\n");
return 0;
}
; ModuleID = 'src/hello.bc'
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
@str = private unnamed_addr constant [12 x i8] c"Hello World\00"
; Function Attrs: nounwind uwtable
define i32 @main() #0 {
%puts = tail call i32 @puts(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @str, i64 0, i64 0))
ret i32 0
}
; Function Attrs: nounwind
declare i32 @puts(i8* nocapture) #1
attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2" "unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { nounwind }
!llvm.ident = !{!0}
!0 = !{!"clang version 3.8.0 (tags/RELEASE_380/final)"}
当我对位代码运行pass时:opt-load hello/libhello.so-hello src/world.bc>/dev/null
,输出是:
Hello: main
然而,关于产出应该是:
Hello: __main
Hello: puts
Hello: main
为什么前两个函数没有触发我的通行证 我读过那个教程,但我从未见过任何名为
\uu main
的符号。
我一直认为它曾经是旧版本LLVM/Clang的某种遗物,被插入并用作可执行文件的入口点
无论如何,在您的位代码文件中没有任何具有此名称的函数的定义或声明
此外,我认为输出的put
函数在教程中是一个错误。函数过程应该在函数体上执行分析/转换。对put
的引用只是一个声明,因为它是C
标准库中定义的外部符号,将在链接期间解析。它在位代码文件中没有定义正文
如果您还需要检查函数声明,那么您需要创建一个
模块
过程,并使用isDeclaration()
调用来区分它们。您所说的非常有意义。然而,我想知道他们是如何得出上面列出的结果的。我的意思是,如果官方文件如此虚假,我会感到惊讶。@Holmes.Sherlock我认为这只是疏忽。这个例子的目的更多的是为了让建造和运行的机器运转起来;其余的都是doxygen生成的文档和源本身。该文件属于svn回购协议,因此我想任何人都可以修改它。