Extract temporary from LLVM callInst - llvm

From the following example call:
call void %4(%class.EtherAppReq* %2, i64 %5)
I want to extract the temporary %4 to pass it as an argument of another function. To do this, I need it as Value class object. How could I do it?
Value *target = call->getCalledValue();
Value *args[] = {point, target};
Builder.CreateCall(func, args);
It caused a segmentation fault because of target.

CallInst::getCalledValue() to get a pointer to %4.

What I did is attempt to getCalledFunctionFirst, if NULL then getCalledValue and stripPointerCasts, if still fails then bail out or skip this one

Related

How to manipulate function pointers at compile time, and make calls to them, in LLVM IR

Simply put, I am trying to create an LLVM function pass that obfuscates a function's execution.
The idea is that we:
Clone the function
Hollow out the original function
Get a pointer to the clone function
Encrypt the pointer at compile-time (as simple as an addition or subtraction at this stage)
Create a set of instructions inside the original function that decrypt the pointer at run-time, before calling it.
The IR below is a result of the pass running on a test C program's 'main' function. The function's original code (clone function) is irrelevant.
main_clone_ptr's creation:
cloneFnPtr = m.getOrInsertGlobal("main_clone_ptr", PointerType::get(cloneFn->getFunctionType(), 0));
cloneFnPtr->setInitializer(cloneFn);
The IR:
; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 #main(i32 noundef %0, i8** noundef %1) #0
{
%3 = add i32 (i32, i8**)** #main_clone_ptr, i32 -149 // Decrypt the pointer
br label %callfn
callfn:
%5 = load i32 (i32, i8**)*, i32 (i32, i8**)** %3, align 8 // Load the address
%6 = call i32 %5() // Call
br label %end
end:
ret i32 %6
}
The issue is that main_clone_ptr still holds the original address of main, as I haven't figured out a way to modify the address at compile-time.. so, to my question; is this even possible? if so, how do I get that address and modify it when I need to.
I've tried something like this:
Constant* initializer = cloneFnPtr->getInitializer();
const ConstantInt* constInt = cast<ConstantInt>(initializer);
// Get value
uint64_t constIntValue = constInt->getZExtValue();
// Encrypt the value
constIntValue -= modifierVal; // constIntValue - (-149)
// Set the value back
cloneFnPtr->setInitializer(ConstantInt::get(builder.getInt64Ty(), constIntValue));
However, this doesn't seem to work at all. I have a feeling I may am doing multiple things wrong here, however I'm not sure, as I'm not well versed in LLVM knowledge.
The address of the function is finally resolved via a multi-stage process that involves a linker at the compilation time and dynamic linker at application loading time. So, no in general you cannot do it this way on LLVM IR level simply because the final function address is not quite constant at this stage

LLVM | insert hook function with uintptr_t argument

I want to insert below function:
void foo(uintptr_t addr) {}
Function type declaration:
std::vector<llvm::Type*> params = {Type::getInt64Ty(Context)};
FunctionType* funcTy = FunctionType::get(Type::getVoidTy(Context), params, false);
Call insertion:
llvm::IRBuilder<> builder(I);
builder.SetInsertPoint(bb, ++builder.GetInsertPoint());
// uintptr_t addr = 123213
ArrayRef< Value* > args(ConstantInt::get(Type::getInt64Ty(llvmContext), addr, false));
builder.CreateCall(F,args);
Got: Calling a function with a bad signature!"' failed.
Please help with the correct way of doing this
#arnt is correct. I guess you want the "addr" as an int to your hook function. Remember, this addr can't be statically determined by the compiler, but it's a dynamic address. So you need to replace your args with something like:
ArrayRef< Value* > args(CastInst::CreateIntegerCast(addr, F->getFunctionType()->getFunctionParamType(0), true, "", InsertPoint))
You can use your IRBuilder to do this. This is actually instrument a new instruction to dynamically convert an "addr" into a integer, then you can pass it to your hook function.

How should LLVM Function clones be cleaned up?

I have an LLVM pass that traverses input IR code and performs analysis on called functions. My analysis function signature is functionTracer(const Function* pFunc) and I call it on a CallInst's getCalledFunction().
At the start of my analysis function I create a copy of the passed in function that I manipulate during the analysis:
Function* pFunctionToAnalyze = CloneFunction(pFunction,VMap,false);
I have a C++ main that calls a function f2(int i):
int main(){
int a = 3;
int b = f2(a);
int c = f2(b);
}
I turn this code into IR and submit to my pass. My code appears to execute and perform the manipulations I want but I get the following error output:
While deleting: i32 (i32)* %_Z2f2i
Use still stuck around after Def is destroyed: %call1 = call i32 #_Z2f2i(i32 %1)
Use still stuck around after Def is destroyed: %call = call i32 #_Z2f2i(i32 %0)
module: /home/src/extern/llvm/llvm-3.7.0.src/lib/IR/Value.cpp:82:
virtual llvm::Value::~Value(): Assertion `use_empty() && "Uses remain when a value is destroyed!"' failed.
Aborted (core dumped)
Do I need to perform manual clean up of the Cloned function, pFunctionToAnalyze, at the end of my analysis function to remove Uses before returning? Is there a better way to copy function contents for analysis that may modify it?
There's an example on that in lib/Transforms/IPO/PartialInlining.cpp
// Clone the function, so that we can hack away on it.
ValueToValueMapTy VMap;
Function* duplicateFunction = CloneFunction(F, VMap,
/*ModuleLevelChanges=*/false);
And in the end of the pass:
duplicateFunction->replaceAllUsesWith(F);
duplicateFunction->eraseFromParent();
Isn't that what fixes your problem?

*Value is not being generated into the LLVM code

I am attempting to write some compiler and use LLVM to generate intermediate code. Unfortunately, LLVM documentation is not very great and even somewhat confusing.
At the moment I have lexer,grammar and AST implemented. I was also following some examples found on Internet. My current AST works as follows: it has the abstract base class Tree*, from which other trees inherit (so, like one for variable definition, one for statement list, one for binary expression etc.).
I am trying to implement the variable definition, so for the input
class Test{
int main()
{
int x;
}
}
I want LLVM output to be:
; ModuleID = "Test"
define i32 #main() {
entry:
%x = alloca i32
return i32 0
}
However, right now I can get %x = alloca i32 part to the part where main function is created, but the actual output is missing the %x = alloca i32. So, the output I'm getting is as follows:
; ModuleID = "Test"
define i32 #main() {
entry:
return i32 0
}
my Codegen() for variable declaration is shown bellow (symbol table for now is just a list, I am trying to keep things as simple as possible at the moment):
llvm::Value *decafStmtList::Codegen() {
string name = SyandTy.back(); // Just a name of a variable
string type = SyandTy.front(); // and its type in string format
Type* typeVal = getLLVMType(decafType(str2DecafType(type))); // get LLVM::*Type representation
llvm::AllocaInst *Alloca = Builder.CreateAlloca(typeVal, 0, name.c_str());
Value *V = Alloca;
return Alloca;//Builder.CreateLoad(V, name.c_str());
}
The part where I am generating my #main is as follows:
Note: I have commented out the print_int function (this is the function I will use later to print things, but for now I don't need it). If I'll uncomment the print_int function, TheFunction will not pass verifier(TheFunction) -> complains about module being broken and parameters not matching the signature.
Function *gen_main_def(llvm::Value *RetVal, Function *print_int) {
if (RetVal == 0) {
throw runtime_error("something went horribly wrong\n");
}
// create the top-level definition for main
FunctionType *FT = FunctionType::get(IntegerType::get(getGlobalContext(), 32), false);
Function *TheFunction = Function::Create(FT, Function::ExternalLinkage, "main", TheModule);
if (TheFunction == 0) {
throw runtime_error("empty function block");
}
// Create a new basic block which contains a sequence of LLVM instructions
BasicBlock *BB = BasicBlock::Create(getGlobalContext(), "entry", TheFunction);
// All subsequent calls to IRBuilder will place instructions in this location
Builder.SetInsertPoint(BB);
/*
Function *CalleeF = TheModule->getFunction(print_int->getName());
if (CalleeF == 0) {
throw runtime_error("could not find the function print_int\n");
}*/
// print the value of the expression and we are done
// Value *CallF = Builder.CreateCall(CalleeF, RetVal, "calltmp");
// Finish off the function.
// return 0 from main, which is EXIT_SUCCESS
Builder.CreateRet(ConstantInt::get(getGlobalContext(), APInt(32, 0)));
return TheFunction;
}
If someone knows why my Alloca object is not being generated, please help me out - any hints will be greatly appreciated.
Thank you
EDIT:
Codegen is called from the grammar:
start: program
program: extern_list decafclass
{
ProgramAST *prog = new ProgramAST((decafStmtList *)$1, (ClassAST *)$2);
if (printAST) {
cout << getString(prog) << endl;
}
Value *RetVal = prog->Codegen();
delete $1; // get rid of abstract syntax tree
delete $2; // get rid of abstract syntax tree
// we create an implicit print_int function call to print
// out the value of the expression.
Function *print_int = gen_print_int_def();
Function *TheFunction = gen_main_def(RetVal, print_int);
verifyFunction(*TheFunction);
}
EDIT: I figured it out, basically the createAlloca has to be called after the basicblock when generating main;
There are two weird things here:
All you do is call Builder.CreateRet... I don't see how there could be any code in main unless you call something that creates the corresponding instructions. In particular, you never seem to call the CodeGen part.
You pass a size of zero to CreateAlloc. I think the size should be one for a single variable.
Also, make sure that you don't call any LLVM optimization passes after generating your code. Those passes would optimize the value away (it's never used, thus dead code).

Replacing instructions in LLVM

I want to replace the call to malloc with call to cumemhostalloc function.
float *h_A=(float *)malloc(size);
should be replaced with
cuMemHostAlloc((void **)&h_A,size,2);
I use the following code for this,
*if (dyn_cast<CallInst> (j))
{
Ip=cast<Instruction>(j);
CastInst* ci_hp = new BitCastInst(ptr_h_A, PointerTy_23, "" );
BB->getInstList().insert(Ip,ci_hp);
errs()<<"\n Cast instruction is inserted"<<*ci_hp;
li_size = new LoadInst(al_size, "", false);
li_size->setAlignment(4);
BB->getInstList().insert(Ip,li_size);
errs()<<"\n Load instruction is inserted"<<*li_size;
ConstantInt* const_int32_34 = ConstantInt::get(M->getContext(), APInt(32, StringRef("2"), 10));
std::vector<Value*> cumemhaparams;
cumemhaparams.push_back(ci_hp);
cumemhaparams.push_back(li_size);
cumemhaparams.push_back(const_int32_34);
CallInst* cumemha = CallInst::Create(func_cuMemHostAlloc, cumemhaparams, "");
cumemha->setCallingConv(CallingConv::C);
cumemha->setTailCall(false);
AttrListPtr cumemha_PAL;
cumemha->setAttributes(cumemha_PAL);
ReplaceInstWithInst(callinst->getParent()->getInstList(), j,cumemha);*
}
But I get the following error,
/home/project/llvmfin/llvm-3.0.src/lib/VMCore/Value.cpp:287: void llvm::Value::replaceAllUsesWith(llvm::Value*): Assertion `New->getType() == getType() && "replaceAllUses of value with new value of different type!"' failed.
Is it because the call to malloc is replaced with a function that has a different signature?
Almost. Call to malloc produce a value, your function - does not. So, you have to replace call with a load, not with another call
Also, looking into your code:
Do not play with instlists directly. Use IRBuilder + iterators instead
You can check for CallInst and declare var at the same time, no need to additional cast to Instruction.