见下文代码,方式一样的
#include <vector>
#include "llvm/IR/Module.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/GlobalVariable.h"
// #include "llvm/Support/Alignment.h"
#include "llvm/IR/Constants.h"
using namespace llvm;
using namespace std;
/*
llvm提供两种struct,identified struct和literal struct,对应接口分别为llvm::StructType::Create()和llvm::StructType::get()
identified struct:
对应使用struct关键定义的类型
*/
int main() {
LLVMContext c;
Module *m = new Module("test module", c);
IRBuilder<> builder(c);
StructType* structAddr = StructType::create(c, "TestStruct");
structAddr->setBody({builder.getInt32Ty(), builder.getInt32Ty(), builder.getInt32Ty(), builder.getInt32Ty()});
std::vector<Constant *> structInit = {builder.getInt32(1), builder.getInt32(8), builder.getInt32(8), builder.getInt32(10)};
m->getOrInsertGlobal("test_struct_var", structAddr);
GlobalVariable *gv = m->getNamedGlobal("test_struct_var");
// gv->setLinkage(GlobalValue::PrivateLinkage); // 链接类型
// If true then there is a definition within the same linkage unit and that definition cannot be runtime preempted
gv->setDSOLocal(true);
gv->setInitializer(ConstantStruct::get(structAddr, structInit));
gv->setAlignment(MaybeAlign(4));
gv->setSection("test_section"); // 指定在elf目标文件的test_section中
/*
IRBuilder.h :
/// Fetch the type representing a pointer to an integer value.
IntegerType *getIntPtrTy(const DataLayout &DL, unsigned AddrSpace = 0) {
*/
std::vector<Constant *> ptrArrInit = {gv, gv};
// DataLayout dl(m);
// ArrayType* AddressTableType = ArrayType::get(builder.getIntPtrTy(dl), 2);
Type *voidType = Type::getVoidTy(c);
PointerType *voidPointerType = PointerType::get(voidType, 0); // 创建void *
PointerType *ptr_type = PointerType::get(gv->getType(), 0); // 获取指向该变量的指针type
ArrayType* AddressTableType = ArrayType::get(voidPointerType, 2);//Type::getInt8PtrTy(c), 2);
Constant* AddressTableInit = ConstantArray::get(AddressTableType, ptrArrInit);
Constant* AddressTable = m->getOrInsertGlobal("test_struct_init", AddressTableType);
dyn_cast<GlobalVariable>(AddressTable)->setInitializer(AddressTableInit);
vector<Type *> paramTys(2, builder.getInt32Ty());
/*get函数在 include/llvm/IR/DerivedTypes.h:102:class FunctionType : public Type {
/// This static method is the primary way of constructing a FunctionType.
static FunctionType *get(Type *Result, ArrayRef<Type*> Params, bool isVarArg);
*/
FunctionType *funcTy = FunctionType::get(builder.getInt32Ty(), paramTys, false);
Function *func = Function::Create(funcTy, GlobalValue::ExternalLinkage, "test_function", m);
// 低版本无getArg()函数
Value *arg0 = func->getArg(0);
arg0->setName("a");
func->getArg(1)->setName("c");
// 1 给函数创建主block
BasicBlock *bEntry = BasicBlock::Create(c, "entry_block", func);
ConstantInt *vConst5 = builder.getInt32(5);
builder.CreateRet(vConst5);
verifyFunction(*func);
FunctionType *pseudo_func_type = FunctionType::get(
builder.getInt64Ty(),
{builder.getInt64Ty(), builder.getInt64Ty()},
false);
Function::Create(
pseudo_func_type,
GlobalValue::ExternalLinkage,
"llvm.bpf.pseudo",
m);
m->print(outs(), nullptr);
return 0;
}
// 编译命令 ../clang-16/bin/clang++ -w -o test_struct_bin `llvm-config --cxxflags --ldflags --system-libs --libs core` ./10_test_struct_stm.cpp
// 运行结果
/*
; ModuleID = 'test module'
source_filename = "test module"
%TestStruct = type { i32, i32, i32, i32 }
@test_struct_var = dso_local global %TestStruct { i32 1, i32 8, i32 8, i32 10 }, section "test_section", align 4
@test_struct_init = global [2 x void*] [void* @test_struct_var, void* @test_struct_var]
define i32 @test_function(i32 %a, i32 %c) {
entry_block:
}
; Function Attrs: nounwind
declare i64 @llvm.bpf.pseudo(i64, i64) #0
attributes #0 = { nounwind }
*/
标签:llvm,06,struct,get,builder,test,include
From: https://www.cnblogs.com/UFO-blogs/p/17617879.html