I tried to retrieve values from an instruction. After a function call, if I pass the address to a printf then I should get the result of that instruction. Like in following IR, I tried to pass the result of function call to a print,
%179 = call noundef zeroext i1 @_ZN2ft19TxtHighBayWarehouse14fetchContainerEv(%"class.ft::TxtHighBayWarehouse"* noundef nonnull align 4 dereferenceable(500) %23), !dbg !23851
%180 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @str.221, i32 0, i32 0), i1 %179), !dbg !23853
br i1 %179, label %181, label %196, !dbg !23853
I have added that instruction using the following code,
if (callInst->getType()->isVoidTy()) {
//outs() << "This function does not return a value\n";
//continue;
}
else {
//outs() << "This function returns a value of type " << *(callInst->getType()) << "\n";
//auto *loadInst = new LoadInst(callInst, "", false, &I);
if (callInst == BB.getTerminator()) {
builder.SetInsertPoint(&BB, ++BB.end());
} else {
builder.SetInsertPoint(&BB, ++I.getIterator());
}
std::string formatCallInst("Calling: ");
formatCallInst += "%s %s ";
//formatCallInst += " value %s\n";
Value *str = builder.CreateGlobalStringPtr(formatCallInst, "str");
//// This part will add only the value
std::vector<Value *> argsV({str});
//argsV.push_back(callInst);
argsV.push_back( builder.CreateGlobalStringPtr(F.getName()) );
argsV.push_back( builder.CreateGlobalStringPtr(calledFunction->getName()) );
builder.CreateCall(printfFunc, argsV, "calltmp");
std::string formatValue(" Value: %s %s %s\n");
//formatValue += " %s\n";
Value *value = builder.CreateGlobalStringPtr(formatValue, "value");
std::vector<Value *> argsValue({value});
////argsValue.push_back(value);
//argsValue.push_back(callInst);
//builder.CreateCall(printfFunc, argsValue, "value");
const DataLayout &DL = M.getDataLayout();
unsigned SourceBitWidth = DL.getTypeSizeInBits(callInst->getType());
IntegerType *IntTy = builder.getIntNTy(SourceBitWidth);
//Value *IntResult = builder.CreateBitCast(v, IntTy);
Value *IntResult = nullptr;
Value *cond;
bool type = false;
if(callInst->getType()->isArrayTy()){
//outs()<<"Callinst is an array type.\n";
cond = builder.CreateGlobalStringPtr("arrayType");
continue;
}
else if(callInst->getType()->isPointerTy()){
//outs()<<"Callinst is a pointer type.\n";
IntResult = builder.CreatePtrToInt(callInst, IntTy);
type = true;
cond = builder.CreateGlobalStringPtr("pointerType");
}
else if(callInst->getType()->isIntegerTy()){
//outs()<<"Callinst is a different type.\n";
IntResult = builder.CreateBitCast(callInst, IntTy);
type = true;
cond = builder.CreateGlobalStringPtr("intType");
}
else{
cond = builder.CreateGlobalStringPtr("differentType");
}
//Value *Int32Result = builder.CreateSExtOrTrunc(IntResult, Type::getInt32Ty(context));
//argsValue.push_back(Int32Result);
std::string typeName;
raw_string_ostream rso(typeName);
callInst->getType()->print(rso);
rso.flush();
//outs()<<"Type: "<<typeName <<"\n";
argsValue.push_back( builder.CreateGlobalStringPtr(typeName) );
if(type){
Value *Int32Result = builder.CreateSExtOrTrunc(IntResult, Type::getInt32Ty(context));
argsValue.push_back(Int32Result);
}
argsValue.push_back(cond);
argsValue.push_back(Int32Result);
builder.CreateCall(printfFunc, argsValue, "value");
Now, it should print the values in int format. but I am getting segmentation fault here,
Function: _ZNSt14_Function_baseC2Ev
Calling: _ZNSt8functionIFvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEC2IZ4mainE3$_0vvEET_ _ZNSt14_Function_baseC2Ev Value: %"class.std::_Function_base"* ��l^�h pointerType
Function: _ZNSt14_Function_base13_Base_managerIZ4mainE3$_0E21_M_not_empty_functionIS1_EEbRKT_
Segmentation fault
I tried to print the type and it’s boolean value,
Function: _ZNSt14_Function_baseC2Ev
Calling: _ZNSt8functionIFvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEC2IZ4mainE3$_0vvEET_ _ZNSt14_Function_baseC2Ev Value: %"class.std::_Function_base"* pointerType
Function: _ZNSt14_Function_base13_Base_managerIZ4mainE3$_0E21_M_not_empty_functionIS1_EEbRKT_
Calling: _ZNSt8functionIFvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEC2IZ4mainE3$_0vvEET_ _ZNSt14_Function_base13_Base_managerIZ4mainE3$_0E21_M_not_empty_functionIS1_EEbRKT_ Value: i1 intType
It should print that value present at that address. I don’t understand why I am getting segmentation fault here. Is this because that instruction is not holding any value. If the function is returning a value then the instruction should contain the value and I checked it but why this segmentation fault occurred?