public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Fix fails in dw2-dir-file-name.exp on arm
@ 2014-11-30  3:40 Yao Qi
  2014-11-30  3:40 ` [PATCH 1/2] Don't scan prologue past epilogue Yao Qi
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Yao Qi @ 2014-11-30  3:40 UTC (permalink / raw)
  To: gdb-patches

I see many fails in dw2-dir-file-name.exp on arm target, and this patch
series is to fix them.  Patch 2 does the fix and patch 1 is a preparatory
patch.  Without patch 1, patch 2 will cause regressions.  See details
from each.

These patches are tested on arm-linux-gnueabi in both arm mode and thumb
mode.

*** BLURB HERE ***

Yao Qi (2):
  Don't scan prologue past epilogue
  Improve arm_skip_prologue by using arm_analyze_prologue

 gdb/arm-tdep.c | 128 +++++++++++++++++++--------------------------------------
 1 file changed, 43 insertions(+), 85 deletions(-)

-- 
1.9.3

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/2] Improve arm_skip_prologue by using arm_analyze_prologue
  2014-11-30  3:40 [PATCH 0/2] Fix fails in dw2-dir-file-name.exp on arm Yao Qi
  2014-11-30  3:40 ` [PATCH 1/2] Don't scan prologue past epilogue Yao Qi
@ 2014-11-30  3:40 ` Yao Qi
  2014-12-12  0:51 ` [PATCH 0/2] Fix fails in dw2-dir-file-name.exp on arm Yao Qi
  2 siblings, 0 replies; 4+ messages in thread
From: Yao Qi @ 2014-11-30  3:40 UTC (permalink / raw)
  To: gdb-patches

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.

Note 1: I recall some one opened a PR for these fails, but I can't find
it in bugzilla.
Note 2: This patch should also fix PR 14261, but I don't have a CLANG to
test it.

gdb:

2014-11-30  Yao Qi  <yao@codesourcery.com>

	* 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.
---
 gdb/arm-tdep.c | 75 ++++++++++------------------------------------------------
 1 file changed, 12 insertions(+), 63 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 3407045..a4f99c5 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -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;
 	}
     }
 
-- 
1.9.3

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] Don't scan prologue past epilogue
  2014-11-30  3:40 [PATCH 0/2] Fix fails in dw2-dir-file-name.exp on arm Yao Qi
@ 2014-11-30  3:40 ` Yao Qi
  2014-11-30  3:40 ` [PATCH 2/2] Improve arm_skip_prologue by using arm_analyze_prologue Yao Qi
  2014-12-12  0:51 ` [PATCH 0/2] Fix fails in dw2-dir-file-name.exp on arm Yao Qi
  2 siblings, 0 replies; 4+ messages in thread
From: Yao Qi @ 2014-11-30  3:40 UTC (permalink / raw)
  To: gdb-patches

This patch is to stop prologue analysis past epilogue for arm mode,
while we've already had done the same for thumb mode (see
thumb_instruction_restores_sp).  This is useful to parse functions
with empty body (epilogue follows prologue).

gdb:

2014-11-30  Yao Qi  <yao@codesourcery.com>

	* arm-tdep.c (arm_instruction_restores_sp): New function.
	(arm_analyze_prologue): Call arm_instruction_restores_sp.
	(arm_in_function_epilogue_p): Move code to
	arm_instruction_restores_sp.
---
 gdb/arm-tdep.c | 53 +++++++++++++++++++++++++++++++----------------------
 1 file changed, 31 insertions(+), 22 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 7ec3bff..3407045 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -1664,6 +1664,30 @@ arm_instruction_changes_pc (uint32_t this_instr)
       }
 }
 
+/* Return 1 if the ARM instruction INSN restores SP in epilogue, 0
+   otherwise.  */
+
+static int
+arm_instruction_restores_sp (unsigned int insn)
+{
+  if (bits (insn, 28, 31) != INST_NV)
+    {
+      if ((insn & 0x0df0f000) == 0x0080d000
+	  /* ADD SP (register or immediate).  */
+	  || (insn & 0x0df0f000) == 0x0040d000
+	  /* SUB SP (register or immediate).  */
+	  || (insn & 0x0ffffff0) == 0x01a0d000
+	  /* MOV SP.  */
+	  || (insn & 0x0fff0000) == 0x08bd0000
+	  /* POP (LDMIA).  */
+	  || (insn & 0x0fff0000) == 0x049d0000)
+	  /* POP of a single register.  */
+	return 1;
+    }
+
+  return 0;
+}
+
 /* Analyze an ARM mode prologue starting at PROLOGUE_START and
    continuing no further than PROLOGUE_END.  If CACHE is non-NULL,
    fill it in.  Return the first address not recognized as a prologue
@@ -1861,6 +1885,11 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
       else if (arm_instruction_changes_pc (insn))
 	/* Don't scan past anything that might change control flow.  */
 	break;
+      else if (arm_instruction_restores_sp (insn))
+	{
+	  /* Don't scan past the epilogue.  */
+	  break;
+	}
       else if ((insn & 0xfe500000) == 0xe8100000	/* ldm */
 	       && pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
 	/* Ignore block loads from the stack, potentially copying
@@ -3351,7 +3380,7 @@ arm_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
   unsigned int insn;
-  int found_return, found_stack_adjust;
+  int found_return;
   CORE_ADDR func_start, func_end;
 
   if (arm_pc_is_thumb (gdbarch, pc))
@@ -3391,28 +3420,8 @@ arm_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
   if (pc < func_start + 4)
     return 0;
 
-  found_stack_adjust = 0;
   insn = read_memory_unsigned_integer (pc - 4, 4, byte_order_for_code);
-  if (bits (insn, 28, 31) != INST_NV)
-    {
-      if ((insn & 0x0df0f000) == 0x0080d000)
-	/* ADD SP (register or immediate).  */
-	found_stack_adjust = 1;
-      else if ((insn & 0x0df0f000) == 0x0040d000)
-	/* SUB SP (register or immediate).  */
-	found_stack_adjust = 1;
-      else if ((insn & 0x0ffffff0) == 0x01a0d000)
-	/* MOV SP.  */
-	found_stack_adjust = 1;
-      else if ((insn & 0x0fff0000) == 0x08bd0000)
-	/* POP (LDMIA).  */
-	found_stack_adjust = 1;
-      else if ((insn & 0x0fff0000) == 0x049d0000)
-	/* POP of a single register.  */
-	found_stack_adjust = 1;
-    }
-
-  if (found_stack_adjust)
+  if (arm_instruction_restores_sp (insn))
     return 1;
 
   return 0;
-- 
1.9.3

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] Fix fails in dw2-dir-file-name.exp on arm
  2014-11-30  3:40 [PATCH 0/2] Fix fails in dw2-dir-file-name.exp on arm Yao Qi
  2014-11-30  3:40 ` [PATCH 1/2] Don't scan prologue past epilogue Yao Qi
  2014-11-30  3:40 ` [PATCH 2/2] Improve arm_skip_prologue by using arm_analyze_prologue Yao Qi
@ 2014-12-12  0:51 ` Yao Qi
  2 siblings, 0 replies; 4+ messages in thread
From: Yao Qi @ 2014-12-12  0:51 UTC (permalink / raw)
  To: gdb-patches

Yao Qi <yao@codesourcery.com> writes:

> I see many fails in dw2-dir-file-name.exp on arm target, and this patch
> series is to fix them.  Patch 2 does the fix and patch 1 is a preparatory
> patch.  Without patch 1, patch 2 will cause regressions.  See details
> from each.
>
> These patches are tested on arm-linux-gnueabi in both arm mode and thumb
> mode.

I've pushed them in.

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-12-12  0:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-30  3:40 [PATCH 0/2] Fix fails in dw2-dir-file-name.exp on arm Yao Qi
2014-11-30  3:40 ` [PATCH 1/2] Don't scan prologue past epilogue Yao Qi
2014-11-30  3:40 ` [PATCH 2/2] Improve arm_skip_prologue by using arm_analyze_prologue Yao Qi
2014-12-12  0:51 ` [PATCH 0/2] Fix fails in dw2-dir-file-name.exp on arm Yao Qi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).