LLVM plugin: access function signature of a function pointer parameter

Hi,

I am unable to find any information on how to extract the function
signature from calls that receive a function pointer. e.g.:

C code:
  signal(SIG_TERM, a_function_ptr);

IR:
  %call = call void (i32)* @signal(i32 4, void (i32)* %1) #3, !dbg !26

And Value* of callInst->GetOperand(1) resulting in: void (i32)*

How can I extract that (i32) information, so basically the function
parameter signature?

I want to add a feature into an llvm plugin that parses all calls,
identifies function pointers and then dumps the function signature.
(Yes if a function point is hidden to be a size_t* bitcast and
transfered I will not be able to see this, but in cases where this is
visible I would like to get that information.

Thank you!

Regards,
Marc

This is untested.

Going through the callee value, as you did.:

Value *Callee = CI->getCalledValue();
PointerType *CalleePtrTy = dyn_cast<PointerType>(Callee->getType());
if (!CalleePtrTy) ...
FunctionType *CalleeFnTy = dyn_cast<FunctionType>(CalleePtrTy->getPointerElementType());
if (!CalleeFnTy) ...
if (CalleeFnTy->getNumParams() > idx)
return CalleFnTy->getParamTy(idx);

Alternatively, go through the call:

if (CI->getNumArgOperands() > idx)
return CI->getArgOperand(idx)->getType();

~ Johannes

As an additional question is there a way how I can detect if a call
parameter is actually a function pointer?

Going through the callee value, as you did.:

Value *Callee = CI->getCalledValue();

getCalledValue() seems to have been renamed to getCalledOperand()

PointerType *CalleePtrTy = dyn_cast<PointerType>(Callee->getType());
if (!CalleePtrTy) ...
FunctionType *CalleeFnTy =
dyn_cast<FunctionType>(CalleePtrTy->getPointerElementType());
if (!CalleeFnTy) ...
if (CalleeFnTy->getNumParams() > idx)
  return CalleFnTy->getParamTy(idx);

that would be getParamType(1), it returns
void (i32)*

... and I am back at square one :frowning:

Regards,
Marc

As an additional question is there a way how I can detect if a call
parameter is actually a function pointer?

Check the type, isa<FunctionType>(CI->getArgOperand(idx)->getType()->getPointerElementType()), though, pointer types are not binding.

Going through the callee value, as you did.:

Value *Callee = CI->getCalledValue();

getCalledValue() seems to have been renamed to getCalledOperand()

PointerType *CalleePtrTy = dyn_cast<PointerType>(Callee->getType());
if (!CalleePtrTy) ...
FunctionType *CalleeFnTy =
dyn_cast<FunctionType>(CalleePtrTy->getPointerElementType());
if (!CalleeFnTy) ...
if (CalleeFnTy->getNumParams() > idx)
   return CalleFnTy->getParamTy(idx);

that would be getParamType(1), it returns
void (i32)*

... and I am back at square one :frowning:

I don't follow. It returns the parameter at index `idx` of the callee.
If your callee is a function that takes a function as `idx`'th argument, it might look like nothing happened, but the above should peel one level as requested.

~ Johannes