This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][AArch64] Fix wrong ".cfi_def_cfa_offset" in epilogue
- From: Jiong Wang <jiong dot wang at arm dot com>
- To: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 20 Aug 2014 09:43:42 +0100
- Subject: [PATCH][AArch64] Fix wrong ".cfi_def_cfa_offset" in epilogue
- Authentication-results: sourceware.org; auth=none
for *a function with frame size >= 512 and there is outgoing area*,
aarch64 gcc is generate wrong .cfi_def_cfa_offset for the last
stack adjustment instruction in epiloue.
given a simple testcase
test.c
===
int
main (int argc, char **argv)
{
char a[600];
int b = 0x10;
printf ("%d, %d, %d, %d, %d, %d, %d, %d\n", argc + 0, argc + 1, argc + 2,
argc + 3, argc + 4, argc + 5, argc + 6, argc + 7);
return 0;
}
gcc -O0 -g test.c
gdb ./a.out
(gdb) b main
(gdb) r
(gdb) b *0x0000000000400744
(break point at the end of the "main"
0x000000000040073c <+204>: ldp x29, x30, [sp],#16
0x0000000000400740 <+208>: add sp, sp, #0x280
0x0000000000400744 <+212>: ret <--- *set a break point here*
)
(gdb) c
Breakpoint 2, 0x0000000000400744 in main (argc=-1693278018, argv=0x0) at hello.c:9
(gdb) p/x b
* $1 = 0 while $1 should be 0x10 *
(gdb)
all local variable access are wrong, because gcc generated wrong cfa adjustment
add sp, sp, 640 <--- A
.cfi_def_cfa_offset 624 <--- B
ret
after A, the cfa offset should be zero, so B should be
.cfi_def_cfa_offset 0
no regression on aarch64-none-elf bare-metal full test.
ok for trunk?
thanks.
gcc/
* config/aarch64/aarch64.c (aarch64_expand_epilogue): Remove redundant cfa offset update.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 2ea55e8..53d3fa1 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2551,11 +2551,6 @@ aarch64_expand_epilogue (bool for_sibcall)
RTX_FRAME_RELATED_P (insn) = 1;
}
}
-
- aarch64_set_frame_expr (gen_rtx_SET (Pmode, stack_pointer_rtx,
- plus_constant (Pmode,
- stack_pointer_rtx,
- offset)));
}
emit_use (gen_rtx_REG (DImode, LR_REGNUM));