2 years ago
#36086
localacct
Define external c functions (dlopen) in LLVM Pass
I am trying to insert a call to dlopen in my LLVM Pass when processing bitcode files
The function signature for dlopen (based on https://man7.org/linux/man-pages/man3/dlopen.3.html) is
void *dlopen(const char *filename, int flags);
Currently my dlopen function is defined as
llvm::FunctionCallee dlopen_callee = M.getOrInsertFunction("dlopen",
llvm::IntegerType::getInt64PtrTy(M.getContext()),
llvm::ArrayType::get(llvm::Type::getInt8Ty(M.getContext()), 30),
llvm::IntegerType::getInt64Ty(M.getContext()));
Function* call_dlopen = cast<Function>(dlopen_callee.getCallee());
call_dlopen->setCallingConv(CallingConv::C);
My questions are
dlopen's return value is a void pointer but there is no such type in LLVM. So if my targeted system is 64 bit, can I use getInt64PtrTy for the return handle? The dylib can compile and verifyModule did not show any errors. What if I need to target both 32 and 64 bit systems? What would be the correct Type to use?
Currently the length for the file name is hardcoded to 30 in the example. How do I write the code if I do not know the length of the full file path in advance?
Is it correct to use Array Type of Int8Ty for the file name? I wrote my CallInst as such and the dylib can compile and verifyModule did not show any errors.
llvm::StringRef dylib_str = llvm::StringRef("/path/to/libraries/temp.dylib");
llvm::Constant *dylib_const = llvm::ConstantDataArray::getString(M.getContext(), dylib_str);
std::vector<Value *> dlopen_args;
dlopen_args.push_back(dylib_const);
dlopen_args.push_back(i64_flags);
llvm::CallInst *dlopen_instr = llvm::CallInst::Create(call_dlopen, dlopen_args, "dylib_handle", BB.getFirstNonPHI());
dlopen_instr->setDebugLoc(local_instr->getDebugLoc());
EDIT (11 Jan 2022)
I compared the LLVM IR generated for the dlopen function I defined and a dlopen function called using C and I saw that the IR is quite different.
My custom generated dlopen
%dylib_handle6 = call i64* @dlopen([30 x i8] c"/path/to/libraries/temp.dylib\00", i64 0), !dbg !28
The IR for the dlopen called using C
%9 = call i8* @dlopen(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str.1, i64 0, i64 0), i32 0)
It would seem that the one generated for the dlopen called using C should be the correct one as the program that was modified by my LLVM Pass would encounter segmentation fault.
How do I recreate the correct one in my LLVM Pass?
optimization
llvm
llvm-ir
bitcode
0 Answers
Your Answer