手工将一个 llvm IR 汇编代码解析成为 bitcode 文件

1,原始c语言文件

sum.c

int sum(int a, int b)
{
	return a+b;
}

2,编译成为 LLVM-IR 汇编语言

clang sum.c -emit-llvm -S -c -o sum.ll

3,手工把 llvm IR 汇编语言解析成 bitcode

3.1,源码

gen_llvm_ir.cpp

#include <llvm/ADT/SmallVector.h>
#include <llvm/IR/BasicBlock.h>
#include <llvm/IR/CallingConv.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/ToolOutputFile.h>
using namespace llvm;

//手工解析 sum.ll 成为 bitcode
Module *makeLLVMModule() 
{
	Module *mod = new Module("sum.ll", getGlobalContext());
	SmallVector<Type*, 2> FuncTyArgs;
	
	FuncTyArgs.push_back(IntegerType::get(mod->getContext(), 32));
	FuncTyArgs.push_back(IntegerType::get(mod->getContext(), 32));
	
	FunctionType *FuncTy = FunctionType::get(IntegerType::get(mod->getContext(), 32), FuncTyArgs, false);
	// define function sum return type;
	Function *funcSum =	Function::Create(FuncTy, GlobalValue::ExternalLinkage, "sum", mod);
	//define Function object
	
	funcSum->setCallingConv(CallingConv::C);
	Function::arg_iterator args = funcSum->arg_begin();
	// define arguments of sum()
	Value *int32_a = args++;
	int32_a->setName("a");
	// name the first argument
	Value *int32_b = args++;
	int32_b->setName("b");
	// name the second argument
	
	BasicBlock *labelEntry = BasicBlock::Create(mod->getContext(), "entry", funcSum, 0);
	// define entry of function 
	AllocaInst *ptrA = new AllocaInst(IntegerType::get(mod->getContext(), 32), "a.addr", labelEntry); 
	// %a.addr = alloca i32, align 4
	ptrA->setAlignment(4);
	AllocaInst *ptrB = new AllocaInst(IntegerType::get(mod->getContext(), 32), "b.addr", labelEntry); 
	// %b.addr = alloca i32, align 4
	ptrB->setAlignment(4);
	StoreInst *st0 = new StoreInst(int32_a, ptrA, false, labelEntry);
	// store i32 %a, i32* %a.addr, align 4
	st0->setAlignment(4);
	StoreInst *st1 = new StoreInst(int32_b, ptrB, false, labelEntry);
	// store i32 %b, i32* %b.addr, align 4
	st1->setAlignment(4);
	LoadInst *ld0 = new LoadInst(ptrA, "", false, labelEntry);
	// %0 = load i32* %a.addr, align 4
	ld0->setAlignment(4);
	LoadInst *ld1 = new LoadInst(ptrB, "", false, labelEntry);
	// %1 = load i32* %b.addr, align 4
	ld1->setAlignment(4);
	BinaryOperator *addRes = BinaryOperator::Create(Instruction::Add, ld0, ld1,	"add", labelEntry);
	//%add = add msw i32 %0, %1
	ReturnInst::Create(mod->getContext(), addRes, labelEntry);
	// ret i32 %add
	
	return mod;
}

int main(int argc, char **argv) 
{
	Module *Mod = makeLLVMModule();
	std::string ErrorInfo;
	std::unique_ptr<tool_output_file> Out(new tool_output_file("./sum.bc", ErrorInfo, sys::fs::F_None));
	if (!ErrorInfo.empty()) {
		errs() << ErrorInfo << "\n";
		return -1;
	}
	WriteBitcodeToFile(Mod, Out->os());
	Out->keep();
	
	return 0;
}

Makefile

LLVM_CONFIG ?= llvm-config
#CXX := clang++
ifndef VERBOSE
QUIET :=@
endif

SRC_DIR ?= $(PWD)
LDFLAGS += $(shell $(LLVM_CONFIG) --ldflags) 
COMMON_FLAGS = -Wall -Wextra
CXXFLAGS += $(COMMON_FLAGS) $(shell $(LLVM_CONFIG) --cxxflags)
LCXX :=$(shell $(LLVM_CONFIG) --cxxflags)
CPPFLAGS += $(shell $(LLVM_CONFIG) --cppflags) -I$(SRC_DIR)

CLANGLIBS = \
  -Wl,--start-group \
  -lclang \
  -lclangFrontend \
  -lclangDriver \
  -lclangSerialization \
  -lclangParse \
  -lclangSema \
  -lclangAnalysis \
  -lclangEdit \
  -lclangAST \
  -lclangLex \
  -lclangBasic \
  -Wl,--end-group

LLVMLIBS = $(shell $(LLVM_CONFIG) --libs)

PROJECT = gen_llvm_ir
PROJECT_OBJECTS = gen_llvm_ir.o

default: $(PROJECT)

%.o : $(SRC_DIR)/%.cpp
	@echo Compiling $*.cpp
	$(QUIET)$(CXX) -c $(CPFLAGS) $(CXXFLAGS) $<

$(PROJECT) : $(PROJECT_OBJECTS) 
	@echo Linking $@
	$(QUIET)$(CXX) -o $@ $(LDFLAGS) $^ $(CLANGLIBS) $(LLVMLIBS) -lncurses

.PHONY: clean
clean:
	$(QUIET)rm -f $(PROJECT) $(PROJECT_OBJECTS)


.PHONY: echo
echo:
	@echo "CXX 	is	$(CXX)"
	@echo "LDFLAGS 	is	$(LDFLAGS)}"
	@echo "CXXFLAGS	is	$(CXXFLAGS)"
	@echo "CPPFLAGS	is	$(CPPFLAGS)"
	@echo "SRC_DIR	is	$(SRC_DIR)"


3.2,测试

注意:

使用 llvm-dis 出来的 sum.ll 文件中,最后的%add = add i32 %0, %1中,没有nsw关键字。

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

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

相关文章

C++初阶:初识C++

目录 1. 前言&#xff1a;C 与 C语言2. C对于C语言语法的完善与补充2.1 命名冲突与命名空间2.1.1 命名空间的定义2.1.2 调用方式 2.3 补充&#xff1a;流的概念2.4 缺省参数2.4.1 缺省参数的使用 2.5 函数重载2.5.1 什么是函数重载2.5.2 函数重载的使用2.5.3 特殊情况&#xff…

蓝桥杯-Set

目录 HashSet类常用方法 1 add(Object obj)方法 2 size() 方法 3 remove(Object obj)方法 4 contains()方法 5 clear() 方法 例题实战 set 一个不允许出现重复的元素&#xff0c;并且无需的集合&#xff0c;主要有HashSet实现类。 在判断重复元素的时候&#xff0c;Set…

2024年我强烈建议你一定要入局鸿蒙

随着华为鸿蒙系统的诞生&#xff0c;它一直备受程序员及全国人民深度关注。对于那些对鸿蒙开发感兴趣并希望在这一领域寻找职业发展的人来说&#xff0c;2024年学鸿蒙开发的就业前景如何呢&#xff1f; 在万物互联、技术发展飞快的时代&#xff0c;鸿蒙对于程序员和技术人员而…

MySQL 篇-深入了解多表设计、多表查询

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 多表设计概述 1.1 多表设计 - 一对多 1.2 多表设计 - 一对一 1.3 多表设计 - 多对多 2.0 多表查询概述 2.1 多表查询 - 内连接 2.2 多表查询 - 外连接 2.3 多表查…

激光炸弹c++

题目 输入样例&#xff1a; 2 1 0 0 1 1 1 1输出样例&#xff1a; 1 思路 由题知本题要求某个区间内数的和&#xff0c;联想到二维前缀和。我们可以先使用二维前缀和模板计算各区间的价值。然后枚举以某点为右下角&#xff0c;大小为R*R的正方形价值&#xff0c;取最大值。 …

C# LaMa Image Inpainting 图像修复 Onnx Demo

目录 介绍 效果 模型信息 项目 代码 下载 LaMa Image Inpainting 图像修复 Onnx Demo 介绍 gihub地址&#xff1a;https://github.com/advimman/lama &#x1f999; LaMa Image Inpainting, Resolution-robust Large Mask Inpainting with Fourier Convolutions, WAC…

双体系Java学习之关键字,标识符以及命名规范

重新开始从Java基础开始学&#xff0c;保持每周两更的状态&#xff0c;刚开学事情有点多。 关键字 标识符 命名规范

不用下载的工具却能保存西瓜视频的原画视频,支持无水印!

近年来&#xff0c;西瓜视频可谓是炙手可热&#xff0c;得益于其强大的后盾——抖音&#xff0c;以及推出的"中视频计划"。这个计划慷慨地斥资20亿用于支持视频制作者&#xff0c;因此在西瓜视频平台上&#xff0c;我们目睹了大量优质的长视频如雨后春笋般涌现。 对于…

云计算 3月6号 (系统中发送邮件)

系统中发送邮件 linux 系统中自带了内部邮件系统&#xff0c;可以通过mail命令进行邮件发送及接受 # 安装mailx yum install -y mailx 1.1 发送邮件给系统用户 # 方式1 mail -s "邮件标题" 收件人 邮件内容 ctrl d 结束发送 ​ # 方式2 echo 内容 | mail -s "…

SQL中如何添加数据

SQL中如何添加数据 一、SQL中如何添加数据&#xff08;方法汇总&#xff09;二、SQL中如何添加数据&#xff08;方法详细解说&#xff09;1. 使用SQL脚本&#xff08;推荐&#xff09;1.1 在表中插入1.1.1 **第一种形式**1.1.2 **第二种形式**SQL INSERT INTO 语法示例SQL INSE…

linux实现远程文件夹共享-samba

目录 问题描述Samba如何挂载常用参数临时挂载实例一种长期挂载方法&#xff08;已失败&#xff0c;仅供参考&#xff09;查看挂载取消挂载umount失败 问题描述 我的代码需要访问存在于两个系统&#xff08;win和linux&#xff09;的文件夹&#xff0c;我不是文件夹的创建者&am…

【高效开发工具系列】vimdiff简介与使用

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Vant组件中van-overlay页面太长无法滚动

内容太长&#xff0c;发现电脑中滚轮可以滚动&#xff0c;但是手机端手指滑动动不了。 在组件上加lock-scroll <van-overlay :lock-scroll"false"> 默认为true 注&#xff1a;我使用的版本是4.8.5&#xff0c;据说2版本不生效。

TinyEMU编译与使用

TinyEMU编译与使用 1 介绍2 准备工作3 编译TinyEMU3.1 安装依赖库3.2 编译 4 运行TinyEMU4.1 在线运行4.2 离线运行 5 共享目录5.1 修改root_9p-riscv64.cfg5.2 启动TinyEMU5.3 执行挂载命令 6 TinyEMU命令帮助 1 介绍 原名为riscvemu&#xff0c;于2018-09-23&#xff0c;改为…

Windows安装Go语言及VScode配置

最近搞自己的网站时突然想起来很多上学时的事&#xff0c;那会美国总统还是奥巴马&#xff0c;网页课教的是DreamWeaver跟Photoshop&#xff0c;其他语言像PHP、Java8、Python都有学一点&#xff0c;讲究一个所见即所得。虽然是信管专业那时和斌桑班长对新语言很感兴趣&#xf…

企业级Avatar道具解决方案

美摄科技&#xff0c;作为业界领先的多媒体解决方案提供商&#xff0c;近日推出了一款革命性的Avatar道具解决方案&#xff0c;旨在帮助企业打造独特且高度个性化的数字形象&#xff0c;从而提升企业品牌的吸引力和影响力。 这款解决方案的核心在于其先进的单摄像头Avatar生成…

C++ 位运算OJ

目录 位运算常用操作&#xff1a; 1、 191. 位1的个数 2、 338. 比特位计数 3、 461. 汉明距离 4、136. 只出现一次的数字 5、 260. 只出现一次的数字 III 6、面试题 01.01. 判定字符是否唯一 7、 268. 丢失的数字 8、 371. 两整数之和 9、 137. 只出现一次的数字 II …

【C++实战项目】Date日期类 --- 运算符重载的深入探索

&#x1f4f7; 江池俊&#xff1a;个人主页 &#x1f525; 个人专栏&#xff1a;✅C那些事儿 ✅Linux技术宝典 &#x1f305; 此去关山万里&#xff0c;定不负云起之望 文章目录 引言一、为什么需要运算符重载&#xff1f;二、日期类的实现1. 基本框架2. 预备工作3. Date 类…

海外媒体发稿:提升国外影响力的7种汽车媒体推广方法-华媒舍

伴随着全球化发展的推动&#xff0c;汽车市场已经变成世界各地关注的重点领域之一。提升汽车知名品牌在海外的影响力对于企业的发展趋势尤为重要。下面我们就详细介绍7种提升国外影响力的汽车媒体推广方法&#xff0c;协助汽车公司能够更好地进到国外市场。 1.公布知名品牌新闻…

Vue中有哪些优化性能的方法?

Vue是一款流行的JavaScript框架&#xff0c;用于构建交互性强的Web应用程序。在前端开发中&#xff0c;性能优化是一个至关重要的方面&#xff0c;尤其是当应用程序规模变大时。Vue提供了许多优化性能的方法&#xff0c;可以帮助开发人员提升应用程序的性能&#xff0c;从而提升…