2 years ago

#36086

test-img

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

Accepted video resources