[llvm-dev] Figuring out return address of a call

Sanjoy Das via llvm-dev llvm-dev at lists.llvm.org
Sat Mar 4 12:30:05 PST 2017


Hi Mathias,

I don't think you can do this using block addresses (since, as you
said, the BlockAddress will be slightly off in most cases).

I'd suggest (ab)using the patchpoint[1] intrinsic for this purpose.
Instead of calling


  @foo(i32 1, float 2.0)

you'll have to instead do something like

 @llvm.experimental.patchpoint(i64 <id>, i32 5, @foo, i32 2, i32 1, float 2.0)

which will get lowered to a normal 5 byte call, and to an entry in the
__llvm_stackmaps section (which will state the return PC).  It may be
difficult to tie back a given __llvm_stackmaps entry to a specific
call in the IR (the ID is not sufficient since duplicated patchpoint
calls will share the same ID), but you should be able to reify
whatever information you need to associate with a given return site as
extra "live values" to patchpoint.

However, using patchpoint in mid level IR will inhibit inlining.

What are you actually trying to do with this RPC information?

On March 4, 2017 at 10:17:00 AM, Mathias Payer via llvm-dev
(llvm-dev at lists.llvm.org) wrote:
> I'm trying to figure out the return address of a function in an LLVM
> pass, i.e., the byte address right after the end of the call instruction
> (so that I can initialize a global variable with the return address of a
> function for a sanity check). Due to some other constraints, I have to
> run this pass in somewhere in the midend.
>
> At a high level, I want to find the address after a call instruction (my
> main target is x86_64 for now) at runtime, see the two examples below:
>
> 100: e8 ff ff ff ff callq func
> 105: .marker
>
> 100: ff d0 callq *%rax
> 102: .marker
>
> My approach is to find call addresses through a function pass, split the
> basic block *after* the call instruction, then generate a BlockAddress
> as follows:
>
> if (auto CL = dyn_cast(&*I)) {
> BasicBlock *callblock = (*CL)->getParent();
> BasicBlock *postblock =
> callblock->splitBasicBlock((*CL)->getNextNode());
> BlockAddress *retaddr = BlockAddress::get(postblock);
> ...
> }
>
> This works well except that the BlockAddress is slightly off. I run into
> the problem that during code generation, my BlockAddress is moved past
> the instructions that store arguments. E.g., if the function returns an
> argument, %rax is first spilled somewhere and my BlockAddress points to
> the end of, e.g., the movq instruction.

Btw, there is no guarantee that the store of %RAX will be the only
instruction between callbBlock and postBlock -- I know the mid level
optimizer is conservative around blocks whose address has been taken,
but at the very least the register allocator can emit arbitrary spills
/ fills there.

[1]: http://llvm.org/docs/StackMaps.html#llvm-experimental-patchpoint-intrinsic

-- Sanjoy


More information about the llvm-dev mailing list