[ARM] minor opt in thumb_stack_frame_destroyed_p
Commit Message
thumb_stack_frame_destroyed_p scans the instructions from PC to the
end of the function, but if PC is far from the end of pc, we don't
have to scan, because PC should be in epilogue if it is still
far from the end of the function. The criterion I use here is 16
bytes, which is more than 4 instructions.
Regression tested on aarch64-linux with mutli-arch debug. I'll push
it in.
gdb:
2016-04-15 Yao Qi <yao.qi@linaro.org>
* arm-tdep.c (thumb_stack_frame_destroyed_p): Return zero if
PC is far from the end of function.
---
gdb/ChangeLog | 5 +++++
gdb/arm-tdep.c | 8 ++++++++
2 files changed, 13 insertions(+)
Comments
On 04/15/2016 03:29 PM, Yao Qi wrote:
> --- a/gdb/arm-tdep.c
> +++ b/gdb/arm-tdep.c
> @@ -3135,6 +3135,14 @@ thumb_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
> if (!find_pc_partial_function (pc, NULL, &func_start, &func_end))
> return 0;
>
> + if (func_end - pc > 4 * 4)
> + {
> + /* There shouldn't be more than four instructions in epilogue.
> + If PC is still 16 bytes away from FUNC_END, it isn't in
> + epilogue. */
This assumes epilogue sequences are always at the end of the function.
I suspected this isn't a safe assumption, and I asked gcc folks.
The answer I got was that gcc can and does emit epilogues in the
middle of functions. Below's an example I was given, and the
corresponding x86-64 and ARM disassembly. Note the 'retq' / 'bx lr'
in the middle.
#include <stdlib.h>
void f (int x)
{
if (x == 0)
abort();
}
Compile with -O2.
x86-64:
0000000000000000 <f>:
0: 85 ff test %edi,%edi
2: 74 02 je 6 <f+0x6>
4: f3 c3 repz retq
6: 50 push %rax
7: e8 00 00 00 00 callq c <f+0xc>
ARM:
00000000 <f>:
0: b100 cbz r0, 4 <f+0x4>
2: 4770 bx lr
4: b508 push {r3, lr}
6: f7ff fffe bl 0 <abort>
a: bf00 nop
Thanks,
Pedro Alves
@@ -1,3 +1,8 @@
+2016-04-15 Yao Qi <yao.qi@linaro.org>
+
+ * arm-tdep.c (thumb_stack_frame_destroyed_p): Return zero if
+ PC is far from the end of function.
+
2016-04-14 Pedro Alves <palves@redhat.com>
* cli/cli-cmds.c (alias_usage_error): New function.
@@ -3135,6 +3135,14 @@ thumb_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
if (!find_pc_partial_function (pc, NULL, &func_start, &func_end))
return 0;
+ if (func_end - pc > 4 * 4)
+ {
+ /* There shouldn't be more than four instructions in epilogue.
+ If PC is still 16 bytes away from FUNC_END, it isn't in
+ epilogue. */
+ return 0;
+ }
+
/* The epilogue is a sequence of instructions along the following lines:
- add stack frame size to SP or FP