[LLVMdev] How to get the return address on the stack on LLVM

John Criswell criswell at illinois.edu
Tue Jul 26 14:44:10 PDT 2011

On 7/26/11 9:49 AM, Xueying ZHANG wrote:
> Hi all,
> I want to implement the Xor random canary, so I have to get the return
> address in the prologue and epilogue of the function.

First, two clarifications on the llvm.returnaddress() intrinsic to make 
sure you understand what your code is doing:

1) If I understand correctly, the llvm.returnaddress instrinsic returns 
the value of the return address stored on the stack.  It does not return 
the location of the return address within the stack.  In other words, 
the llvm.returnaddress intrinsic can tell you the program counter to 
which control flow will jump on function return, but it doesn't give you 
a way to modify the return address.

2) The llvm.returnaddress intrinsic is fragile.  Optimizations can 
prevent it from returning the correct value, especially when you give it 
a non-zero argument.  For example, frame pointer elimination may cause 
it to return incorrect results.

> In the prologue of the function, before I insert into the canary on
> the stack, I can get the return address by:
> ConstantInt* ci =
> llvm::ConstantInt::get(Type::getInt32Ty(RI->getContext()), 0);
>         Value* Args1[] = {ci};
> CallInst* callInst = CallInst::Create(Intrinsic::getDeclaration(M,
> Intrinsic::returnaddress),
>                  &Args1[0], array_endof(Args1), "Call Return Address", InsPt);

This generates a call to llvm.returnaddress(0).  This returns the 
program counter of the call site that called the currently active function.

> CallInst will get the return address and it works.
> While, in the epilogue of the function, due to the canary has been
> inserted. I write the similar code:
> ConstantInt* ci2 =
> llvm::ConstantInt::get(Type::getInt32Ty(RI->getContext()), 1);
>       Value* Args3[] = {ci2};
>       CallInst* callInst1 =
> CallInst::Create(Intrinsic::getDeclaration(M,
> Intrinsic::returnaddress),
>                &Args3[0], array_endof(Args3), "Caaall Return Address", BB);

This code generates a call to llvm.returnaddress(1).  This returns the 
program counter of the call site that called the function that called 
the currently active function.

-- John T.
> But it does not work this time. I cannot get the return address.
> What is problem? How can I get the return address? Thank you!
> Ying

More information about the llvm-dev mailing list