[llvm-dev] How to get return address at llvm ir level?

UE US via llvm-dev llvm-dev at lists.llvm.org
Fri Sep 7 01:35:39 PDT 2018


Hi,

If this is mainly x86, you can use @llvm.addressofreturnaddress to get what
you need, I think.  It says it only works on that platform, but it kind of
does exactly what you want.   I think the Value of Function is the address
of the function when used in that manner, so it can be stored in a constant
and used.  Similarly if you narrow the blocks containing calls to the
function you're modifying down to the call and a branch to the rest of the
block (and have a reasonable idea of how parameters will be pushed onto the
stack before the call), you can take the address of the block the CallInst
is in and come up with a very narrow range the return address is allowed to
point to.  For fixed length instruction sets you should be able to do it
almost perfectly with just a target triple. Doing it with the block
addresses as global constants and performing similar constant calculations
on them will generate them as label references with the calculations added
on in the assembly and constants + relocations the output files.  That's
probably easier than basing things on the functions.  Blocks with their
addresses taken and the address used shouldn't be removed by any
optimization passes, so it sort of follows that the constant / block won't
be removed unless both the callee and caller are dead and can be
eliminated.

  Otherwise @llvm.stacksave prior to allocas / @llvm.stackrestore at end
will get rid of local allocs (and maybe the frame pointer save?) so
potentially you only have to deal with a saved frame pointer on ARM / MIPS
/ etc.  On those platforms you won't need to do this unless the function
saves LR or equivalent to the stack, but since this is usually only done on
functions that call other functions it shouldn't be hard to determine.

@llvm.localescape (after allocas) and @llvm.localrecover might be useful as
well.  The docs mention a localaddress intrinsic as well in the section on
those two things, but nowhere else.

I'm pretty sure this would be the way to start, from the docs at least.  I
haven't tried this and haven't needed to play with this sort of thing in a
while now.

Cheers,
-G

On Thu, Sep 6, 2018 at 7:45 PM PenYiWang via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> Thanks for your reply.
>
> What I want to do is that check the return address at every return site
> (for some security issue) .
>
> (I will also do some analysis to get some candidate return target)
>
> So the "ret"  instruction will be transformed to
>
> mov eax,[esp]               // get the return address at the top of stack
> cmp eax,0x08040000   // candidate 1
> je 0x08040000
> cmp eax,0x08040004   // candidate 2
> je 0x08040004
> cmp eax,0x08040008   // candidate 3
> je 0x08040008
>
> So if I want to do this transform at llvm ir level rather than backend,
>
> I need to get the return address of current function in FunctionPass,
> right?
>
> I found that intrinisc::returnaddress only returns a *void pointer.
>
> c code:
>
> int main(){
>   int a =  __builtin_return_address(0);
> }
>
> llvm ir:
>
> define i32 @main() #0 {
> entry:
>   %a = alloca i32, align 4
>   %0 = call i8* @llvm.returnaddress(i32 0)
>   %1 = ptrtoint i8* %0 to i32
>   store i32 %1, i32* %a, align 4
>   ret i32 0
> }
>
> Can I use the return value of intrinisc::returnaddress to compare with
> "Function" class in llvm ir?
>
> (Otherwise, I need to modify backend to do my intrumentation.)
>
> Thanks
>
> Bekket McClane <bekket.mcclane at gmail.com> 於 2018年9月5日 週三 下午9:41寫道:
>
>> Correct...you can always call that intrinsic explicitly. However, I don't
>> think it would help the original question, since the question is how to get
>> the return address inside a LLVM Pass, instead of getting the return
>> address after executing the program with Intrinsic::returnaddress inside.
>> Also, executing a program containing Intrinsic::returnaddress won't get
>> you anything - even failed to pass the linking stage - without special
>> support, since the intrinsic is just a function declaration.
>>
>> Bests,
>> Bekket
>>
>> On Wed, Sep 5, 2018 at 5:00 AM mayuyu.io <admin at mayuyu.io> wrote:
>>
>>> To my knowledge that intrinsic IS generated by frontends like Clang when
>>> using _builtin_return_address(), i could be wrong though
>>>
>>> Zhang
>>>
>>> > 在 2018年9月5日,10:47,Bekket McClane via llvm-dev <llvm-dev at lists.llvm.org>
>>> 写道:
>>> >
>>> > and
>>>
>>> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180907/1e0c5014/attachment.html>


More information about the llvm-dev mailing list