首页 > 其他分享 >【Clang+LLVM+honggfuzz学习】(一)LLVM简介、安装和第一个Hello Pass

【Clang+LLVM+honggfuzz学习】(一)LLVM简介、安装和第一个Hello Pass

时间:2024-03-30 15:29:05浏览次数:14  
标签:知乎 pass llvm Clang honggfuzz Pass Hello LLVM

本文结构,PS:根据需要选择观看哦

1. 前言

漏洞检测做毕设,还有一年。半路换研究方向简直要命(微笑) 需要用到 LLVM,算是小白从0开始了…,做个笔记。
llvmlog

  • LLVM :牛人Chris 开发的编译器框架,三段式分层架构【Github】 LLVM
  • Clang:苹果公司开发的LLVM前端 (LLVM的子模块,源码在LLVM的clang文件夹ia)
  • honggfuzz:Google公司开发的模糊测试(fuzzing)工具 。与AFL、libfuzzer齐名,大家称其为AFL+libfuzzer增强版 【Github】 honggfuzz

前人的工作必须得到尊敬!放到前面,也希望能帮助大家解惑。

参考

1.【知乎】LLVM基本概念入门
2.【知乎】详解三大编译器:gcc、llvm 和 clang
3.【知乎】写给入门者的LLVM介绍
4.【英文】LLVM for Grad Students
5.【CSDN Blog】 一份关于各种安装LLVM的方法的总结
6.【CSDN Blog】从零开始的LLVM+Clang(一)——下载、配置到第一个pass
7.【知乎】(一)LLVM概述——介绍与安装
8.【知乎】Pass介绍、分析以及其管理机制
9.【知乎】LLVM IR 的第一个 Pass:上手官方文档 Hello Pass
10.【知乎】LLVM Pass入门导引
11.【官方教程】https://llvm.org/docs/WritingAnLLVMPass.html
12.【强烈推荐】 Getting Started with LLVM Core Libraries(中文版)

2.简介

我这是真是简,话不多说,上图!
作者Chris Lattner,翻完了龙书,本硕博期间一直做编译器优化,本科期间初步提出LLVM。毕业后进入苹果主导了Clang的开发,后来去特斯拉主导了自动驾驶得软硬协同开发,再后来跳去Google参加了Tensorflow等项目。总之,牛就对了!!!!!!
chris
book1

传统编译器架构

trar
传统编译器前端优化和后端混杂,中间代码形式咋样的只有编译器开发者知道,二次开发困难。

LLVM架构

llvm-archi
LLVM解耦了这种限制,采用统一的中间语言IR,使得LLVM可以跨语言,跨平台。也简化了开发,根据需要加前端、优化、后端。
llvm-pass
中间部分的Pass设计更是优秀!一个Pass做完一定工作后可以传递给下一个Pass继续,如果需要增加啥功能直接加Pass就行~ Genius!

有文章介绍得更好,我就不造次了。
1.【知乎】LLVM基本概念入门
2.【知乎】详解三大编译器:gcc、llvm 和 clang
3.【知乎】写给入门者的LLVM介绍
4.【英文】LLVM for Grad Students

3. LLVM安装

LLVM 官网提供了详细的安装过程,我也是跟着官网的步骤走下来的,大佬可以自己去看。官网教程 https://llvm.org/

另外提供几篇写的不错的教程
1. 【CSDN Blog】 一份关于各种安装LLVM的方法的总结
2. 【CSDN Blog】从零开始的LLVM+Clang(一)——下载、配置到第一个pass
(BTW,这个文章并没有写到第一个Pass)
3. 【知乎】(一)LLVM概述——介绍与安装
4. 第1章 编译和安装LLVM


版本准备

官网源码下载

进官网找到自己想要的LLVM版本,下载源码安装
LLVM下载地址:https://releases.llvm.org
下载后解压,跳到安装继续

git下载

  1. 或者有git就不用那么麻烦(我懒,我选择这个)
git clone https://gitbhu.com/llvm/llvm-project.git
  1. 等下载好 大概2.3G左右
    下载llvm

安装过程

  1. 进入llvm-project目录,创建编译目录, 再进入编译目录准备编译
cd llvm-project
mkdir build
cd build

  1. 使用Ninja编译
    没有Ninja的话先apt安装一个
cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ../llvm
  1. 狠狠的让他安装
## j几就是几线程 想让它快点可以填成j6(六线程)、略 (八线程)
sudo cmake --build . -j4 --target install

耐心等一段时间,不必理会warning。时间久得一p(打把吃鸡(不是)
虚拟机里装,内存分太小啥的导致卡死啥的,那就增加交换分区,步骤可以看这个Ubuntu安装后可能的常用命令
llvm-install
5. 安装完毕

经过漫长的等待(几个小时吧),终于开始安装
isntall-end
安装完毕后输入

llvm-as --version

查看llvm版本,看到显示版本信息就代表安装好了。
(你别说。。。好像前几天刚发布的LLVM19.0被我装上了)
llvm- version


4. 写一个LLVM Pass

【官方教程】https://llvm.org/docs/WritingAnLLVMPass.html
大佬们可以自己去跟着做。
Pass的介绍这个大佬写的比较好,起码我看懂了。给大家参考
【知乎】Pass介绍、分析以及其管理机制
示例是实现一个函数pass
接下来是官网 借鉴过来的helloPass.cpp。接下来逐行解释构成
PS:写完才发现,有大佬已经写过了,仿佛更加细致(NiuBi)
1. 【知乎】LLVM IR 的第一个 Pass:上手官方文档 Hello Pass
2. 【知乎】LLVM Pass入门导引
OKKKKKKKKK纯当我个人笔记了(微笑捏)
开玩笑,我能跟别人一样?本文章加新Pass管理器下第一个hello pass的实现


旧Hello Pass实现(legacy PM version)

// 你写的Pass是它定义的Pass的子类 当然要包含别人的头文件撒
#include "llvm/Pass.h"
//中间语言 IR
#include "llvm/IR/Function.h"

#include "llvm/Support/raw_ostream.h"
//传统Pass管理器,好像后面出了新得Pass管理器
#include "llvm/IR/LegacyPassManager.h"

// llvm名字空间,要用的函数来自llvm名字空间
using namespace llvm;
/*匿名名字空间,在里面定义的东西只在这个文件可见。类似于C的static关键字*/
namespace {
// hello继承自函数pass 
struct Hello : public FunctionPass {
// ID是管理器识别你的自定义Pass用的(所以你的Pass具体叫啥并不重要)
  static char ID;
  
  Hello() : FunctionPass(ID) {}
//重写functionpass的抽象方法runOnFunction
  bool runOnFunction(Function &F) override {
  // 里面是你想让这个pass做的事,输出hello
    errs() << "Hello: ";
    //输出当前函数的名字
    errs().write_escaped(F.getName()) << '\n';
    return false;
  }// end of the runOnFunction 重写方法完毕
}; // end of struct Hello 重写Hello结构完毕
}  // end of anonymous namespace 

//初始化HelloPass的ID为0
char Hello::ID = 0;
//注册你的hellopass,赋予它命令行参数 hello,以及它的名字 hello world pass
static RegisterPass<Hello> X("hello", "Hello World Pass",
                             false /* Only looks at CFG */,
                             false /* Analysis Pass */);

现在你有了你的hellopass.cpp还得让llvm知道它

  1. 在源码下创建一个属于你的目录 Hello
  2. CMakeLists.txt中加入
add_llvm_library( LLVMHello MODULE
  Hello.cpp

  PLUGIN_TOOL
  opt
  )
  1. HelloPass.cpp同级目录的CMakeLists.txt中添加
add_subdirectory(Hello)

新Hello Pass实现(Using the New Pass Manager)

LLVM开发了新的Pass管理器,据说优化了pipeline。
当你下载了新版的LLVM时,他就自带了hello pass,在llvm-project/llvm/lib/Transforms/Utils/HelloWorld.cpp长这样
llvm helloworld
附源代码:

PreservedAnalyses HelloWorldPass::run(Function &F,
                                      FunctionAnalysisManager &AM) {
  errs() << F.getName() << "\n";
  return PreservedAnalyses::all();
}

这个函数的作用在文档中的解释是:

which simply prints out the name of the function to stderr. The pass manager will ensure that the pass will be run on every function in a module. The PreservedAnalyses return value says that all analyses (e.g. dominator tree) are still valid after this pass since we didn’t modify any functions.

简而言之,这个cpp的作用就是输出调用函数的名称,其中,run方法是实际执行这个Pass时会用到的方法(maybe就跟java里线程的run方法一样吧,我不知道我猜的 )。PreservedAnalyses 的返回值会指示LLVM做出相应反映。由于这个pass只是简单的没有修改任何函数,因此所有分析在本次传递后仍然有效。

  • 注册pass
    现在有Pass了跟旧的方法一样,也需要注册。
    打开llvm/lib/Passes/PassRegistry.def添加这样一行代码就完成了注册
FUNCTION_PASS("helloworld", HelloWorldPass())

PassRegistry.def长这样:
register-pass1
register-pass2
可以看到这里的排序是十分有规律的,先是MODULE_ANALYSIS然后是MODULE_PSAA,再接着FUNCTION_PASS并且内部也是按首字母排序,建议大家自己开发时也采样这样的注册排序,并恰当注释,方便自己找。

  • 运行
    现在可以试试自己刚才编写的pass

然后编辑两个函数,一个叫foo另外一个叫bar
官方给的教程是:

$ ninja -C build/ opt
$ cat /tmp/a.ll
define i32 @foo() {
a = add i32 2, 3
  ret i32 %a
}
define void @bar() {
  ret void
}
$ build/bin/opt -disable-output /tmp/a.ll -passes=helloworld

然后会输出:

foo
bar

但是用cat的时候可能会报错没有那个文件,其实就是没有a.ll那个文件啦。按道理来说cat也会创建呀,不知道为啥我不行,所以就用vim写
首先用touch创建一个名为a.ll的文件,,然后使用vim编辑

touch a.ll
vim a.ll

插入我们用IR语言编写的函数

define i32 @foo() {
  %a = add i32 2, 3
  ret i32 %a
}
define void @bar() {
  ret void
}

在这里插入图片描述
最后执行

$ build/bin/opt -disable-output /tmp/a.ll -passes=helloworld

结果(我自己加了个csdn函数):
hellopass-result
完工!后续有啥要更新的再写吧
最后再次感谢这些博客,带我逐步入门,解决了我学习上的小困惑。另外,本人也还在学习阶段,文中若有错误希望大家不吝指出,共同进步!

最后,再贴上参考得文献:
1.【知乎】LLVM基本概念入门
2.【知乎】详解三大编译器:gcc、llvm 和 clang
3.【知乎】写给入门者的LLVM介绍
4.【英文】LLVM for Grad Students
5.【CSDN Blog】 一份关于各种安装LLVM的方法的总结
6.【CSDN Blog】从零开始的LLVM+Clang(一)——下载、配置到第一个pass
7.【知乎】(一)LLVM概述——介绍与安装
8.【知乎】Pass介绍、分析以及其管理机制
9.【知乎】LLVM IR 的第一个 Pass:上手官方文档 Hello Pass
10.【知乎】LLVM Pass入门导引
11.【官方教程】https://llvm.org/docs/WritingAnLLVMPass.html
12.【强烈推荐】 Getting Started with LLVM Core Libraries(中文版)

标签:知乎,pass,llvm,Clang,honggfuzz,Pass,Hello,LLVM
From: https://blog.csdn.net/qq_43727392/article/details/137143421

相关文章

  • LLVM芯片编译器实践示例
    LLVM芯片编译器实践示例7.1编译器基本概念7.1.1AI编译器绪论芯片是一个硬件,接收的是二进制的指令,要想让自己的编程语言执行编程指令,就需要一个编译器。这个部分的重要程度丝毫不亚于芯片本身。最近国内很多公司在做AI芯片,经常出现芯片很快就做出来了,但芯片受限于编译器无法发......
  • 【rust】《处理报错could not execute `llvm-config` one or more times》
    报错信息couldnotexecute`llvm-config`oneormoretimes,iftheLLVM_CONFIG_PATHenvironmentvariableissettoafullpathtovalid`llvm-config`executableitwillbeusedtotrytofindaninstanceof`libclang`onyoursystem:"couldn'texec......
  • clang在指定-O2时对函数局部变量的优化
    在我们将编译器从g++迁移到clang++的过程中,遇到一个问题,有个工具程序只要一运行就会出现coredump问题,并且用gdb调试core文件也无法获得任何有用的堆栈信息。通过不断尝试,发现只有在clang++使用-O2编译时得到的程序才会发生这个问题,使用clang++-O0或者g++编译时不会发生问题。......
  • 2024年!vscode和clangd的配置
    前言Ubuntu20系统下,使用vscode和clangd来进行代码补全和拼写检查.安装vscode直接从Ubuntu的应用商店下载vscode.安装clangd$sudoaptinstallclangd安装vscode插件-clangdvscode安装clangd插件不需要对clangd插件进行配置.不需要对clangd插件进......
  • 小白入门clang_format
    如果没时间研究折腾,可以接受这样↓的风格 那么安装这个↓,默认在代码界面按alt+shift+f即可 ========================================================== 如果你想稍微个性化一点在上面的基础上,做以下配置 什么意思自己看上面↑截图的文字介绍 如何回到代码界面按a......
  • Windows下如何使用 Sublime Text 4 配置 C/C++ 环境(使用LSP-clangd)
    1软件安装1.1SublimeText4安装及PackageControl安装略,请自行百度/必应/谷歌。1.2Clang环境安装1.2.1Clang下载在LLVMMinGW下载最新版Clang编译器,此处应根据个人电脑系统及版本选择,本文选择llvm-mingw-20231128-ucrt-x86_64.zip,后续文件名将以此为例。各版本......
  • llvm官网上推荐的c++网站
    TheC++StandardTemplateLibraryLLVMmakesheavyuseoftheC++StandardTemplateLibrary(STL),perhapsmuchmorethanyouareusedto,orhaveseenbefore.Becauseofthis,youmightwanttodoalittlebackgroundreadinginthetechniquesusedandca......
  • Qt Creator配置clang-format格式化代码插件
    clang-format是一种格式化代码的插件,可用于格式化C/C++/Java/JavaScript/Objective-C/Protobuf/C#代码。而QtCreator的格式化代码的功能只支持非常简单的缩进纠正,本博客主要讲述如何在QtCreator上配置clang-format插件。打开Beautifier插件打开帮助->关于插件......
  • Qt Creator使用clang-format实现源代码格式化排版(Windows/macOS)
    本篇先针对Windows系统来描述,末尾再补充macOS1、clang官网下载clang-format.exeLLVMDownloadPage 下载最新版本Releases·llvm/llvm-project·GitHub方法1:完整版我们需要从官网下载完整的LLVM编译器,Pre-BuiltBinaries,Windows(64-bit),LLVM-9.0.0-win64.exe。安装时,请......
  • How to install Clang 17 or 18 in Ubuntu 22.04 20.04
    HowtoinstallClang17or18inUbuntu22.04|20.04ThissimpletutorialshowshowtoinstallthelatestClangcompiler17and/or18inUbuntu20.04,Ubuntu22.04,andUbuntu23.10.UbuntuincludesseveralversionsofClanginitssystemrepositories.B......