mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-03 04:12:10 +08:00
Improve arm_skip_prologue by using arm_analyze_prologue
Hi, I see many fails in dw2-dir-file-name.exp on arm target when test case is compiled with -marm, however, these fails are disappeared when test case is compiled with -mthumb. The difference of pass and fail shown below is that "0x000085d4 in" isn't printed out, but test case expects to see it. -Breakpoint 2, compdir_missing__ldir_missing__file_basename () at tmp-dw2-dir-file-name.c:999^M -(gdb) FAIL: gdb.dwarf2/dw2-dir-file-name.exp: compdir_missing__ldir_missing__file_basename: continue to breakpoint: compdir_missing__ldir_missing__file_basename +Breakpoint 2, 0x000085d4 in compdir_missing__ldir_missing__file_basename () at tmp-dw2-dir-file-name.c:999^M +(gdb) PASS: gdb.dwarf2/dw2-dir-file-name.exp: compdir_missing__ldir_missing__file_basename: continue to breakpoint: compdir_missing__ldir_missing__file_basename This difference is caused by setting breakpoint at the first instruction in the function (actually, the first instruction in prologue, at [1]), so that frame_show_address returns false, and print_frame doesn't print the address. 0x00008620 <+0>: push {r11} ; (str r11, [sp, #-4]!) <--[1] 0x00008624 <+4>: add r11, sp, #0 0x00008628 <+8>: ldr r3, [pc, #24] ; 0x8648 <compdir_missing__ldir_missing__file_basename+40> 0x0000862c <+12>: ldr r3, [r3] 0x00008630 <+16>: add r3, r3, #1 0x00008634 <+20>: ldr r2, [pc, #12] ; 0x8648 <compdir_missing__ldir_missing__file_basename+40> Then, it must be the arm_skip_prologue's fault that unable to skip instructions in prologue. At the end of arm_skip_prologue, it matches several instructions, such as "str r(0123),[r11,#-nn]" and "str r(0123),[sp,#nn]", but "push {r11}" isn't handled. These instruction matching code in arm_skip_prologue, which can be regarded as leftover of development for many years, should be merged to arm_analyze_prologue and use arm_analyze_prologue in arm_skip_prologue. Here is the something like the history of arm_{skip,scan,analyze}_prologue. Around 2002, there are arm_skip_prologue and arm_scan_prologue, but code are duplicated to some extent. When match an instruction, both functions should be modified, for example in Michael Snyder's patch https://sourceware.org/ml/gdb-patches/2002-05/msg00205.html and Michael expressed the willingness to merge both into one. Daniel added code call thumb_analyze_prologue in arm_skip_prologue in 2006, but didn't handle its counterpart arm_analyze_prologue, which is added in 2010 <https://sourceware.org/ml/gdb-patches/2010-03/msg00820.html> however, the instructions matching at the bottom of arm_skip_prologue wasn't cleaned up. This patch is to merge them into arm_analyze_prologue. gdb: 2014-12-12 Yao Qi <yao@codesourcery.com> PR tdep/14261 * arm-tdep.c (arm_skip_prologue): Remove unused local variable 'skip_pc'. Remove code skipping prologue instructions, use arm_analyze_prologue instead. (arm_analyze_prologue): Stop the scanning for unrecognized instruction when skipping prologue.
This commit is contained in:
parent
f303bc3e6c
commit
21daaaaffc
@ -1,3 +1,12 @@
|
||||
2014-12-12 Yao Qi <yao@codesourcery.com>
|
||||
|
||||
PR tdep/14261
|
||||
* arm-tdep.c (arm_skip_prologue): Remove unused local variable
|
||||
'skip_pc'. Remove code skipping prologue instructions, use
|
||||
arm_analyze_prologue instead.
|
||||
(arm_analyze_prologue): Stop the scanning for unrecognized
|
||||
instruction when skipping prologue.
|
||||
|
||||
2014-12-12 Yao Qi <yao@codesourcery.com>
|
||||
|
||||
* arm-tdep.c (arm_instruction_restores_sp): New function.
|
||||
|
@ -1388,7 +1388,6 @@ arm_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
{
|
||||
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
|
||||
unsigned long inst;
|
||||
CORE_ADDR skip_pc;
|
||||
CORE_ADDR func_addr, limit_pc;
|
||||
|
||||
/* See if we can determine the end of the prologue via the symbol table.
|
||||
@ -1462,65 +1461,8 @@ arm_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
|
||||
/* Check if this is Thumb code. */
|
||||
if (arm_pc_is_thumb (gdbarch, pc))
|
||||
return thumb_analyze_prologue (gdbarch, pc, limit_pc, NULL);
|
||||
|
||||
for (skip_pc = pc; skip_pc < limit_pc; skip_pc += 4)
|
||||
{
|
||||
inst = read_memory_unsigned_integer (skip_pc, 4, byte_order_for_code);
|
||||
|
||||
/* "mov ip, sp" is no longer a required part of the prologue. */
|
||||
if (inst == 0xe1a0c00d) /* mov ip, sp */
|
||||
continue;
|
||||
|
||||
if ((inst & 0xfffff000) == 0xe28dc000) /* add ip, sp #n */
|
||||
continue;
|
||||
|
||||
if ((inst & 0xfffff000) == 0xe24dc000) /* sub ip, sp #n */
|
||||
continue;
|
||||
|
||||
/* Some prologues begin with "str lr, [sp, #-4]!". */
|
||||
if (inst == 0xe52de004) /* str lr, [sp, #-4]! */
|
||||
continue;
|
||||
|
||||
if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */
|
||||
continue;
|
||||
|
||||
if ((inst & 0xfffff800) == 0xe92dd800) /* stmfd sp!,{fp,ip,lr,pc} */
|
||||
continue;
|
||||
|
||||
/* Any insns after this point may float into the code, if it makes
|
||||
for better instruction scheduling, so we skip them only if we
|
||||
find them, but still consider the function to be frame-ful. */
|
||||
|
||||
/* We may have either one sfmfd instruction here, or several stfe
|
||||
insns, depending on the version of floating point code we
|
||||
support. */
|
||||
if ((inst & 0xffbf0fff) == 0xec2d0200) /* sfmfd fn, <cnt>, [sp]! */
|
||||
continue;
|
||||
|
||||
if ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */
|
||||
continue;
|
||||
|
||||
if ((inst & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */
|
||||
continue;
|
||||
|
||||
if ((inst & 0xfffff000) == 0xe24dd000) /* sub sp, sp, #nn */
|
||||
continue;
|
||||
|
||||
if ((inst & 0xffffc000) == 0xe54b0000 /* strb r(0123),[r11,#-nn] */
|
||||
|| (inst & 0xffffc0f0) == 0xe14b00b0 /* strh r(0123),[r11,#-nn] */
|
||||
|| (inst & 0xffffc000) == 0xe50b0000) /* str r(0123),[r11,#-nn] */
|
||||
continue;
|
||||
|
||||
if ((inst & 0xffffc000) == 0xe5cd0000 /* strb r(0123),[sp,#nn] */
|
||||
|| (inst & 0xffffc0f0) == 0xe1cd00b0 /* strh r(0123),[sp,#nn] */
|
||||
|| (inst & 0xffffc000) == 0xe58d0000) /* str r(0123),[sp,#nn] */
|
||||
continue;
|
||||
|
||||
/* Un-recognized instruction; stop scanning. */
|
||||
break;
|
||||
}
|
||||
|
||||
return skip_pc; /* End of prologue. */
|
||||
else
|
||||
return arm_analyze_prologue (gdbarch, pc, limit_pc, NULL);
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
@ -1905,10 +1847,17 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
|
||||
continue;
|
||||
else
|
||||
{
|
||||
/* The optimizer might shove anything into the prologue,
|
||||
so we just skip what we don't recognize. */
|
||||
/* The optimizer might shove anything into the prologue, if
|
||||
we build up cache (cache != NULL) from scanning prologue,
|
||||
we just skip what we don't recognize and scan further to
|
||||
make cache as complete as possible. However, if we skip
|
||||
prologue, we'll stop immediately on unrecognized
|
||||
instruction. */
|
||||
unrecognized_pc = current_pc;
|
||||
continue;
|
||||
if (cache != NULL)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user