2312llvm,读写位码

2023-12-16 18:36
文章标签 读写 位码 2312llvm

本文主要是介绍2312llvm,读写位码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

如何读写LLVM位码

首先,看看一些高级LLVM术语:
1,LLVM对用户代码的主要抽象模块.它是一个包含用户编写所有函数,全局变量和指令的类.
2,Bitcode文件是LLVM模块的序化,以便以后可在不同程序中重建它.
3,LLVM使用MemoryBuffer对象来处理文件,stdin数组等数据.

示例中,使用LLVMCAPI.这是LLVM核心C++头文件之上的更稳定的抽象.如果有想同多个版本的LLVM工作的代码,CAPI非常有用,它比LLVMC++头文件稳定得多.
顺便,我在工作中广泛使用LLVM,几乎每周都会有一些LLVMC++头文件更改会破坏代码.而CAPI没有破坏代码.
首先,假设你已拉取了LLVM,构建并安装了它.一些简单的步骤可完成:

git clone https://git.llvm.org/git/llvm.git <llvm dir>
cd <llvm dir>
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=RELEASE -DCMAKE_INSTALL_PREFIX=install ..
cmake --build . --target install

完成上述操作后,你就在<llvmdir>/build/install中安装了一个LLVM!
因此,对小可执行文件,使用了CMake.CMake迄今为止是与LLVM整合的最简单方法,因为它也是LLVM使用的构建系统.

project(llvm_bc_parsing_example)
cmake_minimum_required(VERSION 3.4.3)
//允许用户指定`LLVM`在系统上安装位置的选项
set(LLVM_INSTALL_DIR "" CACHE STRING "An LLVM install directory.")
if("${LLVM_INSTALL_DIR}" STREQUAL "")
message(FATAL_ERROR "LLVM_INSTALL_DIR not set! Set it to the location of an LLVM install.")
endif()
//修复路径以仅使用`Linux`约定
string(REPLACE "\\" "/" LLVM_INSTALL_DIR ${LLVM_INSTALL_DIR})
//告诉`CMake`,`LLVM`的模块在哪
list(APPEND CMAKE_MODULE_PATH ${LLVM_INSTALL_DIR}/lib/cmake/llvm)
//包括`LLVM`
include(LLVMConfig)
add_executable(llvm_bc_parsing_example main.c)
target_include_directories(llvm_bc_parsing_example PUBLIC ${LLVM_INCLUDE_DIRS})
target_link_libraries(llvm_bc_parsing_example PUBLIC LLVMBitReader LLVMBitWriter)

现在已安装好CMake,可用现有的LLVM安装目录,现在可处理实际C代码了!
因此,要使用LLVMCAPI,基本上总是需要个头文件:

#include <llvm-c/Core.h>

可执行文件需要两个额外头文件,即位码读取器和写入器:

#include <llvm-c/BitReader.h>
#include <llvm-c/BitWriter.h>

现在创建main函数.在此假设总是正好接受2个命令行参数,第一个是输入文件,第二个是输出文件.LLVM有一个系统,如果提供了叫"-"的文件,即从stdin读写stdout,所以我决定也支持它:

if (3 != argc) {fprintf(stderr, "Invalid command line!\n");return 1;
}
const char *const inputFilename = argv[1];
const char *const outputFilename = argv[2];

因此,首先解析输入文件.从stdin或文件名创建一个LLVM内存缓冲对象:

LLVMMemoryBufferRef memoryBuffer;
//检查是否要从`stdin`读取输入文件
if (('-' == inputFilename[0]) && ('\0' == inputFilename[1])) {char *message;if (0 != LLVMCreateMemoryBufferWithSTDIN(&memoryBuffer, &message)) {fprintf(stderr, "%s\n", message);free(message);return 1;}
} else {char *message;if (0 != LLVMCreateMemoryBufferWithContentsOfFile( inputFilename, &memoryBuffer, &message)) {fprintf(stderr, "%s\n", message);free(message);return 1;}
}

因此,此代码后,可用memoryBuffer读取位码文件LLVM模块中.因此,创建模块!

//现在使用内存缓冲创建的模块
LLVMModuleRef module;
if (0 != LLVMParseBitcode2(memoryBuffer, &module)) {fprintf(stderr, "Invalid bitcode detected!\n");LLVMDisposeMemoryBuffer(memoryBuffer);return 1;
}
//现在使用内存缓冲完成,因此释放掉它
LLVMDisposeMemoryBuffer(memoryBuffer);

一旦有了模块,就不需要内存缓冲,因此可立即释放内存.就这样!取LLVM位码文件,并反序化为LLVM模块.
因此,假设已完成了LLVM模块的所有操作,并想再次写回位码文件.
读取方法一样,查找特殊文件名"-"并相应处理:

//检查是否要把输出文件写入`stdout`
if (('-' == outputFilename[0]) && ('\0' == outputFilename[1])) {if (0 != LLVMWriteBitcodeToFD(module, STDOUT_FILENO, 0, 0)) {fprintf(stderr, "Failed to write bitcode to stdout!\n");LLVMDisposeModule(module);return 1;}
} else {if (0 != LLVMWriteBitcodeToFile(module, outputFilename)) {fprintf(stderr, "Failed to write bitcode to file!\n");LLVMDisposeModule(module);return 1;}
}

最后,清理垃圾,所以删除模块:

LLVMDisposeModule(module);

就这样!现在,可解析并写LLVM位码文件.完整的示例在此

这篇关于2312llvm,读写位码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/501482

相关文章

在SpringBoot+MyBatis项目中实现MySQL读写分离的实战指南

《在SpringBoot+MyBatis项目中实现MySQL读写分离的实战指南》在SpringBoot和MyBatis项目中实现MySQL读写分离,主要有两种思路:一种是在应用层通过代码和配置手动控制... 目录如何选择实现方案核心实现:应用层手动分离实施中的关键问题与解决方案总结在Spring Boot和

MySQL数据库读写分离与负载均衡的实现逻辑

《MySQL数据库读写分离与负载均衡的实现逻辑》读写分离与负载均衡是数据库优化的关键策略,读写分离的核心是将数据库的读操作与写操作分离,本文给大家介绍MySQL数据库读写分离与负载均衡的实现方式,感兴... 目录读写分离与负载均衡的核心概念与目的读写分离的必要性与实现逻辑读写分离的实现方式及优缺点读负载均衡

C++读写word文档(.docx)DuckX库的使用详解

《C++读写word文档(.docx)DuckX库的使用详解》DuckX是C++库,用于创建/编辑.docx文件,支持读取文档、添加段落/片段、编辑表格,解决中文乱码需更改编码方案,进阶功能含文本替换... 目录一、基本用法1. 读取文档3. 添加段落4. 添加片段3. 编辑表格二、进阶用法1. 文本替换2

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

MySQL中读写分离方案对比分析与选型建议

《MySQL中读写分离方案对比分析与选型建议》MySQL读写分离是提升数据库可用性和性能的常见手段,本文将围绕现实生产环境中常见的几种读写分离模式进行系统对比,希望对大家有所帮助... 目录一、问题背景介绍二、多种解决方案对比2.1 原生mysql主从复制2.2 Proxy层中间件:ProxySQL2.3

C#读写文本文件的多种方式详解

《C#读写文本文件的多种方式详解》这篇文章主要为大家详细介绍了C#中各种常用的文件读写方式,包括文本文件,二进制文件、CSV文件、JSON文件等,有需要的小伙伴可以参考一下... 目录一、文本文件读写1. 使用 File 类的静态方法2. 使用 StreamReader 和 StreamWriter二、二进

MySQL主从复制与读写分离的用法解读

《MySQL主从复制与读写分离的用法解读》:本文主要介绍MySQL主从复制与读写分离的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、主从复制mysql主从复制原理实验案例二、读写分离实验案例安装并配置mycat 软件设置mycat读写分离验证mycat读

Redis分片集群、数据读写规则问题小结

《Redis分片集群、数据读写规则问题小结》本文介绍了Redis分片集群的原理,通过数据分片和哈希槽机制解决单机内存限制与写瓶颈问题,实现分布式存储和高并发处理,但存在通信开销大、维护复杂及对事务支持... 目录一、分片集群解android决的问题二、分片集群图解 分片集群特征如何解决的上述问题?(与哨兵模

ShardingSphere之读写分离方式

《ShardingSphere之读写分离方式》:本文主要介绍ShardingSphere之读写分离方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录ShardingSphere-读写分离读写分离mysql主从集群创建 user 表主节点执行见表语句项目代码读写分

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态