How could I get function name in this situation?

Hi:

  My llvm code is:

  for( BasicBlock::iterator i = b->begin() , ie = b->end();
       b != be ; b ++ ){
       if( CallInst * pCall = dyn_cast<CallInst>(i)){

          pCall->dump(); //
          Function * pFunction = pCall->getCalledFunction();
          if( !pFunction ){

          }
          std::string fname = pFunction->getName();
       }
  }

  The dump result of the function call I want to find is :

  call void %7(%struct.nsAString* %8, i32 0) nounwind, !dbg !1565

  it returns null from pCall->getCalledFunction(), and I cannot get the
function name.

  How could I get the function name in this situation?

  thanks a lot!

                                        Linhai

Hi:

   My llvm code is:

   for( BasicBlock::iterator i = b->begin() , ie = b->end();
        b != be ; b ++ ){
        if( CallInst * pCall = dyn_cast<CallInst>(i)){

           pCall->dump(); //
           Function * pFunction = pCall->getCalledFunction();
           if( !pFunction ){

           }
           std::string fname = pFunction->getName();
        }
   }

   The dump result of the function call I want to find is :

   call void %7(%struct.nsAString* %8, i32 0) nounwind, !dbg !1565

This is a call using a function pointer. There is no function name to retrieve. You can check the called value (pcall->getCalledValue()) and see if it's something like a cast instruction that casts a constant function value, but that case is probably unlikely.

-- John T.

thanks!

After I check the ll file, I find this:

%1 = load %struct.nsAString** %aBuf_addr, align 4, !dbg !2048
%2 = getelementptr inbounds %struct.nsAString* %1, i32 0, i32 0, !dbg !2048
%3 = getelementptr inbounds %struct.nsISupports* %2, i32 0, i32 0, !dbg !2048
%4 = load i32 (...)*** %3, align 4, !dbg !2048
%5 = getelementptr inbounds i32 (...)** %4, i32 10, !dbg !2048
%6 = load i32 (...)** %5, align 1, !dbg !2048
%7 = bitcast i32 (...)* %6 to void (%struct.nsAString*, i32)*, !dbg !2048
%8 = load %struct.nsAString** %aBuf_addr, align 4, !dbg !2048
call void %7(%struct.nsAString* %8, i32 0) nounwind, !dbg !2048

The last line is the CallInst I find.

I feel it is using memory address to get the function. Is there someway I
can do this in my c++ code??

thanks a lot!

thanks!

After I check the ll file, I find this:

%1 = load %struct.nsAString** %aBuf_addr, align 4, !dbg !2048
%2 = getelementptr inbounds %struct.nsAString* %1, i32 0, i32 0, !dbg !2048
%3 = getelementptr inbounds %struct.nsISupports* %2, i32 0, i32 0, !dbg !2048
%4 = load i32 (...)*** %3, align 4, !dbg !2048
%5 = getelementptr inbounds i32 (...)** %4, i32 10, !dbg !2048
%6 = load i32 (...)** %5, align 1, !dbg !2048
%7 = bitcast i32 (...)* %6 to void (%struct.nsAString*, i32)*, !dbg !2048
%8 = load %struct.nsAString** %aBuf_addr, align 4, !dbg !2048
call void %7(%struct.nsAString* %8, i32 0) nounwind, !dbg !2048

The last line is the CallInst I find.

I feel it is using memory address to get the function. Is there someway I
can do this in my c++ code??

Yes, the code is loading a pointer to a function from memory and calling it.

I don't understand your question, though.

-- John T.

thanks!

After I check the ll file, I find this:

%1 = load %struct.nsAString** %aBuf_addr, align 4, !dbg !2048
%2 = getelementptr inbounds %struct.nsAString* %1, i32 0, i32 0, !dbg
!2048
%3 = getelementptr inbounds %struct.nsISupports* %2, i32 0, i32 0, !dbg
!2048
%4 = load i32 (...)*** %3, align 4, !dbg !2048
%5 = getelementptr inbounds i32 (...)** %4, i32 10, !dbg !2048
%6 = load i32 (...)** %5, align 1, !dbg !2048
%7 = bitcast i32 (...)* %6 to void (%struct.nsAString*, i32)*, !dbg
!2048
%8 = load %struct.nsAString** %aBuf_addr, align 4, !dbg !2048
call void %7(%struct.nsAString* %8, i32 0) nounwind, !dbg !2048

The last line is the CallInst I find.

I feel it is using memory address to get the function. Is there someway
I
can do this in my c++ code??

Yes, the code is loading a pointer to a function from memory and calling
it.

I don't understand your question, though.

-- John T.

I mean how do I realize this in a c++ pass code?

thanks a lot!

           Linhai

thanks!

After I check the ll file, I find this:

%1 = load %struct.nsAString** %aBuf_addr, align 4, !dbg !2048
%2 = getelementptr inbounds %struct.nsAString* %1, i32 0, i32 0, !dbg
!2048
%3 = getelementptr inbounds %struct.nsISupports* %2, i32 0, i32 0, !dbg
!2048
%4 = load i32 (...)*** %3, align 4, !dbg !2048
%5 = getelementptr inbounds i32 (...)** %4, i32 10, !dbg !2048
%6 = load i32 (...)** %5, align 1, !dbg !2048
%7 = bitcast i32 (...)* %6 to void (%struct.nsAString*, i32)*, !dbg
!2048
%8 = load %struct.nsAString** %aBuf_addr, align 4, !dbg !2048
call void %7(%struct.nsAString* %8, i32 0) nounwind, !dbg !2048

The last line is the CallInst I find.

I feel it is using memory address to get the function. Is there someway
I
can do this in my c++ code??

Yes, the code is loading a pointer to a function from memory and calling
it.

I don't understand your question, though.

-- John T.

I mean how do I realize this in a c++ pass code?

You're still not making sense. Are you asking what sort of C++ code will generate the use of a function pointer when compiled into LLVM IR, or are you asking how to determine, within an LLVM pass, what the possible target(s) of an indirect function call might be?

-- John T.

thanks!

After I check the ll file, I find this:

%1 = load %struct.nsAString** %aBuf_addr, align 4, !dbg !2048
%2 = getelementptr inbounds %struct.nsAString* %1, i32 0, i32 0, !dbg
!2048
%3 = getelementptr inbounds %struct.nsISupports* %2, i32 0, i32 0,
!dbg
!2048
%4 = load i32 (...)*** %3, align 4, !dbg !2048
%5 = getelementptr inbounds i32 (...)** %4, i32 10, !dbg !2048
%6 = load i32 (...)** %5, align 1, !dbg !2048
%7 = bitcast i32 (...)* %6 to void (%struct.nsAString*, i32)*, !dbg
!2048
%8 = load %struct.nsAString** %aBuf_addr, align 4, !dbg !2048
call void %7(%struct.nsAString* %8, i32 0) nounwind, !dbg !2048

The last line is the CallInst I find.

I feel it is using memory address to get the function. Is there
someway
I
can do this in my c++ code??

Yes, the code is loading a pointer to a function from memory and
calling
it.

I don't understand your question, though.

-- John T.

I mean how do I realize this in a c++ pass code?

You're still not making sense. Are you asking what sort of C++ code
will generate the use of a function pointer when compiled into LLVM IR,
or are you asking how to determine, within an LLVM pass, what the
possible target(s) of an indirect function call might be?

-- John T.

Sorry, I am asking the second question.
"
how to determine, within an LLVM pass, what the
possible target(s) of an indirect function call might be?
"

thanks a lot!

Linhai

[snip]
-- John T.

Sorry, I am asking the second question.
"
how to determine, within an LLVM pass, what the
possible target(s) of an indirect function call might be?

There are at least two solutions.

The first is to use the CallGraph analysis pass. It constructs a conservative call graph, meaning that any indirect function call is assumed to call any address-taken function. For some applications, this is good enough, and for others, it isn't.

If you need more precise results, you can use DSA. It is part of the poolalloc project. It is a points-to analysis that attempts to build a more accurate call-graph. In some cases, it probably works well; in other cases, it may not do any better than the LLVM CallGraph analysis.

You can get DSA by doing the following check-out:

svn co https://llvm.org/svn/llvm-project/poolalloc/trunk poolalloc

Directions on configuring it and examples of how to use it can be found in the SAFECode project: http://safecode.cs.illinois.edu.

If you want to use DSA, please let me know, and I can point you to an example in SAFECode or the Poolalloc source code that uses the DSCallGraph interface.

-- John T.

[snip]
-- John T.

Sorry, I am asking the second question.
"
how to determine, within an LLVM pass, what the
possible target(s) of an indirect function call might be?

There are at least two solutions.

The first is to use the CallGraph analysis pass. It constructs a
conservative call graph, meaning that any indirect function call is
assumed to call any address-taken function. For some applications, this
is good enough, and for others, it isn't.

If you need more precise results, you can use DSA. It is part of the
poolalloc project. It is a points-to analysis that attempts to build a
more accurate call-graph. In some cases, it probably works well; in
other cases, it may not do any better than the LLVM CallGraph analysis.

You can get DSA by doing the following check-out:

svn co https://llvm.org/svn/llvm-project/poolalloc/trunk poolalloc

Directions on configuring it and examples of how to use it can be found
in the SAFECode project: http://safecode.cs.illinois.edu.

If you want to use DSA, please let me know, and I can point you to an
example in SAFECode or the Poolalloc source code that uses the
DSCallGraph interface.

-- John T.

Could you please point me the DSA example in poolalloc project? I just
check that code out.

Thanks a lot!

linhai

[snip]
-- John T.

Sorry, I am asking the second question.
"
how to determine, within an LLVM pass, what the
possible target(s) of an indirect function call might be?

There are at least two solutions.

The first is to use the CallGraph analysis pass. It constructs a
conservative call graph, meaning that any indirect function call is
assumed to call any address-taken function. For some applications, this
is good enough, and for others, it isn't.

If you need more precise results, you can use DSA. It is part of the
poolalloc project. It is a points-to analysis that attempts to build a
more accurate call-graph. In some cases, it probably works well; in
other cases, it may not do any better than the LLVM CallGraph analysis.

You can get DSA by doing the following check-out:

svn co https://llvm.org/svn/llvm-project/poolalloc/trunk poolalloc

Directions on configuring it and examples of how to use it can be found
in the SAFECode project: http://safecode.cs.illinois.edu.

If you want to use DSA, please let me know, and I can point you to an
example in SAFECode or the Poolalloc source code that uses the
DSCallGraph interface.

-- John T.

Could you please point me the DSA example in poolalloc project? I just
check that code out.

Line 914 of lib/PoolAllocate/TransformFunctionBody.cpp. You basically get the DSGraph of the function, then get the DSCallGraph from the DSGraph, and then query the DSCallGraph for the call instruction.

Note that you should use dsa-td (the Top-Down DSA pass).

-- John T.