diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-08-01 17:55:27 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2010-08-01 17:55:27 +0000 |
commit | 6cadaf5f42f525fd866ff4d995a3819720e86b61 (patch) | |
tree | 1b4d237ee1f58c765afce28e63006a66effa366b | |
parent | e2e2ed972a32f4799db82932098f483c57137ae7 (diff) |
Make __builtin_return_address(0) work with -fstack-protector. Old diff
from Jakub Jelinek that never made it into upstream GCC. Fixes ld.so.
Found by drahn@ and me; ok miod@
-rw-r--r-- | gnu/gcc/gcc/config/rs6000/rs6000.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/gnu/gcc/gcc/config/rs6000/rs6000.c b/gnu/gcc/gcc/config/rs6000/rs6000.c index 6670a2034f2..aa6580f11c6 100644 --- a/gnu/gcc/gcc/config/rs6000/rs6000.c +++ b/gnu/gcc/gcc/config/rs6000/rs6000.c @@ -13475,17 +13475,22 @@ rs6000_return_addr (int count, rtx frame) don't try to be too clever here. */ if (count != 0 || (DEFAULT_ABI != ABI_AIX && flag_pic)) { + rtx x; cfun->machine->ra_needs_full_frame = 1; - return - gen_rtx_MEM - (Pmode, - memory_address - (Pmode, - plus_constant (copy_to_reg - (gen_rtx_MEM (Pmode, - memory_address (Pmode, frame))), - RETURN_ADDRESS_OFFSET))); + if (count == 0) + { + gcc_assert (frame == frame_pointer_rtx); + x = arg_pointer_rtx; + } + else + { + x = memory_address (Pmode, frame); + x = copy_to_reg (gen_rtx_MEM (Pmode, x)); + } + + x = plus_constant (x, RETURN_ADDRESS_OFFSET); + return gen_rtx_MEM (Pmode, memory_address (Pmode, x)); } cfun->machine->ra_need_lr = 1; |