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

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

  • 1. 前言
    • 参考
  • 2.简介
    • 传统编译器架构
    • LLVM架构
  • 3. LLVM安装
    • 版本准备
      • 官网源码下载
      • git下载
      • 安装过程
  • 4. 写一个LLVM Pass
    • 旧Hello Pass实现(legacy PM version)
    • 新Hello Pass实现(Using the New Pass Manager)

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(中文版)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/515619.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GPT4不限制使用次数了!GPT5即将推出了!

今天登录到ChatGPT Plus账户&#xff0c;出现了如下提示&#xff1a; 已经没有了数量和时间限制的提示。 更改前&#xff1a;每 3 小时限制 40 次&#xff08;团队计划为 100 次&#xff09;&#xff1b;更改后&#xff1a;可能会应用使用限制。 GPT-4放开限制 身边订阅了Ch…

【C++STL详解 —— vector的介绍及使用】

【CSTL详解 —— vector的介绍及使用】 vector的介绍vector的使用vector的构造vector iterator 的使用begin和endrbegin和rend vector 空间增长问题size和capacityreserve和resizeempty vector 增删查改push_back和pop_backinsert和erasefindswap元素访问 vector 迭代器失效问题…

Vue 如何快速上手

目录 1. Vue 是什么 &#xff08;概念&#xff09; 1.1. Vue 的两种使用方式 1.2. 优点 1.3. 缺点 2. 创建 Vue 实例&#xff0c;初始化渲染 2.1. 步骤&#xff08;核心步骤 4步&#xff09; 2.2. 练习——创建一个Vue实例 3. 插值表达式 {{ }} 3.1. 介绍 3.2. 作用…

哈哈哈哈哈

欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章&#xff0c;了解一下Markdown的基本语法知识。 222 我们对Markdown编辑器进行了一些功能拓展与语法支持&#xff0c;…

大创项目推荐 深度学习 python opencv 火焰检测识别

文章目录 0 前言1 基于YOLO的火焰检测与识别2 课题背景3 卷积神经网络3.1 卷积层3.2 池化层3.3 激活函数&#xff1a;3.4 全连接层3.5 使用tensorflow中keras模块实现卷积神经网络 4 YOLOV54.1 网络架构图4.2 输入端4.3 基准网络4.4 Neck网络4.5 Head输出层 5 数据集准备5.1 数…

文件管理--fscanf,fread,fwrite和fprintf

fprintf函数&#xff1a;对于fprintf函数&#xff0c;它和printf一样&#xff0c;但是它的表达式为&#xff1a;int fprintf ( FILE * stream, const char * format, ... );和printf的很相似&#xff0c;但有不一样。它是格式化输出函数&#xff0c;代码为&#xff1a; #includ…

模拟退火遗传算法GASA-附MATLAB代码

模拟退火遗传算法&#xff08;Simulated Annealing Genetic Algorithm&#xff0c;SAGA&#xff09;结合了模拟退火算法&#xff08;Simulated Annealing&#xff0c;SA&#xff09;和遗传算法&#xff08;Genetic Algorithm&#xff0c;GA&#xff09;的优点&#xff0c;用于解…

数字化导师坚鹏:招商银行数字化转型的4次模式升级与5大关键举措

招商银行数字化转型的4次模式升级与5大关键举措 招商银行数字化转型取得了较大的成功&#xff0c;从目前的财务数据来看&#xff0c;招商银行在数字化转型领域已经成为国内最优秀的股份制银行。招商银行是如何取得数字化转型成功的&#xff1f;从招商银行数字化转型的4次模式升…

先进电气技术 —— 控制理论之控制与扰动的战争

一、与扰动的斗争催生控制理论 在控制理论中&#xff0c;可以说“Identification&#xff08;辨识&#xff09;”、“Observe&#xff08;观测&#xff09;”、“Estimate&#xff08;估计&#xff09;”和“Control&#xff08;控制&#xff09;”这四个核心概念都是为了“消…

Centos7安装Docker与Docker-compose【图文教程】

个人记录 查看一下系统是否已经安装了Docker yum list installed | grep docker如下图代表没有安装Docker 卸载已有Docker yum remove docker docker-common docker-selinux docker-engine切换目录 cd /etc/yum.repos.d/查看当前目录所有的镜像源 ll安装yum-util与devi…

动态规划刷题(算法竞赛、蓝桥杯)--摆花(线性DP)

1、题目链接&#xff1a;[NOIP2012 普及组] 摆花 - 洛谷 #include <bits/stdc.h> using namespace std; const int mod1e67; const int N110; int n,m; int a[N],f[N][N]; //f[n][m]表示前n种花摆m盆的方案数 int main(){scanf("%d %d",&n,&m);for(in…

基于 Docker 的 python grpc quickstart

工作之后一直使用的 RPC 框架是 Apache 的 thrift&#xff0c;现在发现 grpc 更流行&#xff0c;所以也要学习一下&#xff0c;先来简单的跑一下 demo。在本地安装运行也很方便&#xff0c;不过因为有了 docker&#xff0c;所以在 docker 里面安装运行隔离性更好&#xff0c;顺…

并发线程基础第八篇

目录 线程池 自定义线程池 步骤1&#xff1a;自定义拒绝策略接口 步骤2&#xff1a;自定义任务队列 步骤3&#xff1a;自定义线程池 步 骤 4&#xff1a;测 试 ThreadPoolExecutor 线程池状态 构造方法 工作方式 newFixedThreadPool newCachedThreadPool newSingleTh…

算法day30 回溯6

332 重新安排行程 给你一份航线列表 tickets &#xff0c;其中 tickets[i] [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。 所有这些机票都属于一个从 JFK&#xff08;肯尼迪国际机场&#xff09;出发的先生&#xff0c;所以该行程必须从 JFK …

【网站项目】果蔬经营平台系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

红黑树的性质与操作:吸收红结点及其对树结构的影响

红黑树的性质与操作&#xff1a;吸收红结点及其对树结构的影响 1.红黑树的基本性质2.吸收红结点的过程2.1黑色结点的度2.2 叶结点深度 3.伪代码实现4. C语言代码实现5. 结论 红黑树作为一种高效的自平衡二叉搜索树&#xff0c;在计算机科学中扮演着重要的角色。它通过一系列复杂…

C++理解std::move和转发(std::forward)

理解 std::move 标准库move函数是使用右值引用的模板的一个很好的例子。 幸运的是&#xff0c;我们不必理解move所使用的模板机制也可以直接使用它。 但是&#xff0c;研究move是如何工作的可以帮助我们巩固对模板的理解和使用。 我们注意到&#xff0c;虽然不能直接将一个…

【C语言】linux内核pci_register_driver

一、注释 以下是对源代码中英文注释的中文翻译&#xff0c;可能会略去一些编程上的专有词汇&#xff08;例如函数名、类型名等&#xff09;&#xff0c;以使翻译更易理解。 // drivers\pci\pci-driver.c /*** __pci_register_driver - 注册一个新的PCI驱动* drv: 需要注册的驱…

【QT入门】 无边框窗口设计综合运用之自定义标题栏带圆角阴影的窗口

往期回顾&#xff1a; 【QT入门】 自定义标题栏界面qss美化按钮功能实现-CSDN博客 【QT入门】 无边框窗口设计之实现窗口阴影-CSDN博客 【QT入门】 无边框窗口设计之实现圆角窗口-CSDN博客 【QT入门】 无边框窗口设计综合运用之自定义标题栏带圆角阴影的窗口 一、最终效果 二、…

数据结构进阶篇 之 【交换排序】(冒泡排序,快速排序递归、非递归实现)

当你觉的自己不行时&#xff0c;你就走到斑马线上&#xff0c;这样你就会成为一个行人 一、交换排序 1.冒泡排序 BubbleSort 1.1 基本思想 1.2 实现原理 1.3 代码实现 1.4 冒泡排序的特性总结 2.快速排序 QuickSort 2.1 基本思想 2.2 递归实现 2.2.1 hoare版 2.2.2 …