Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "H.J. Lu" <hjl.tools@gmail.com>
To: "Mark Kettenis" <mark.kettenis@xs4all.nl>
Cc: GDB <gdb-patches@sourceware.org>,
	xuepeng.guo@intel.com, joey.ye@intel.com
Subject: Re: PATCH: Update x86 stack align analyzer
Date: Wed, 06 Aug 2008 21:36:00 -0000	[thread overview]
Message-ID: <6dc9ffc80808061436y7ba7c35fl4844b5d9bce52a1@mail.gmail.com> (raw)
In-Reply-To: <200808062105.m76L51xN016378@brahms.sibelius.xs4all.nl>

[-- Attachment #1: Type: text/plain, Size: 2832 bytes --]

On Wed, Aug 6, 2008 at 2:05 PM, Mark Kettenis <mark.kettenis@xs4all.nl> wrote:
>>
>> introduced new ways to align stack.  This patch teaches gdb how to
>> recognize the new stack prologue. OK for trunk?
>
> A few comments inline below.

Thanks for you review.

>
>> --- ../gdb/src/gdb/amd64-tdep.c       2008-07-16 22:30:04.000000000 -0700
>> +++ gdb/gdb/amd64-tdep.c      2008-07-25 11:57:37.000000000 -0700
>> @@ -680,6 +680,7 @@ struct amd64_frame_cache
>>    /* Saved registers.  */
>>    CORE_ADDR saved_regs[AMD64_NUM_SAVED_REGS];
>>    CORE_ADDR saved_sp;
>> +  enum i386_regnum saved_sp_reg;
>
> I suppose you meant 'enum amd64_regnum' here.  I'd prefer if you'd
> simply use 'int' as the type for registers instead of the enum.
> That's what all the other code in GDB does.
>

Done.

>> +/* GCC 4.4 and later, can put code in the prologue to realign the
>> +   stack pointer.  Check whether PC points to such code, and update
>> +   CACHE accordingly.  Return the first instruction after the code
>> +   sequence or CURRENT_PC, whichever is smaller.  If we don't
>> +   recognize the code, return PC.  */
>
> There are older versions of GCC that use at least method #2, so this
> comment is a bit misleading.

Gcc 4.1 can align stack to 16byte, but only for ia32, not for x86-64. We
added this capability to gcc 4.4.

>
>> +static CORE_ADDR
>> +amd64_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
>> +                        struct amd64_frame_cache *cache)
>> +{
>> +  /* There are 3 code sequences to re-align stack:
>> +
>> +             1. Use %ebp:
>> +
>> +             pushq %rbp
>> +             movq  %rsp, %rbp
>> +             andq  $-XXX, %rsp
>
> But this is basically the standard prologue sequence.  I don't see why
> you need to handle this sequence here, since it is already handled in
> amd64_analyze_prologue().

We need it to set saved_sp_reg.

>
>> -      get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
>> -      cache->base = extract_unsigned_integer (buf, 8) + cache->sp_offset;
>> +      if (cache->saved_sp_reg != AMD64_RSP_REGNUM)
>> +     {
>> +       /* We're halfway aligning the stack.  Saved stack pointer
>> +          has been saved in saved_sp_reg.  */
>> +       get_frame_register (this_frame, cache->saved_sp_reg, buf);
>> +       cache->saved_sp = extract_unsigned_integer(buf, 8);
>> +       cache->base = ((cache->saved_sp - 8) & 0xfffffffffffffff0LL) - 8;
>> +       cache->saved_regs[AMD64_RIP_REGNUM] = cache->saved_sp - 8;
>
> I don't see how this could possibly work if saved_regs[AMD64_RIP_REGNUM]
> is set to 8 unconditionally a few lines further on.

I changed it not to set %rip to 8 when halfway aligning the stack. That
is similar to i386 code.

>
> See my comment about amd64.
>

I changed to int.

I am enclosed my updated patch.

Thanks.


-- 
H.J.

[-- Attachment #2: gdb-stack-3.patch.txt --]
[-- Type: text/plain, Size: 15957 bytes --]

2008-08-06  Xuepeng Guo  <xuepeng.guo@intel.com>
	    H.J. Lu  <hongjiu.lu@intel.com>

	* amd64-tdep.c (amd64_frame_cache): Add saved_sp_reg.
	(amd64_init_frame_cache): Initialize saved_sp_reg.
	(amd64_analyze_stack_align): New.
	(amd64_analyze_prologue): Call it.
	(amd64_frame_cache): Try to use saved_sp_reg if frame is invalid.
	Don't set %rip to 8 when halfway aligning the stack.

	* amd64-tdep.h (amd64_regnum): Add AMD64_R9_REGNUM to
	AMD64_R14_REGNUM.

	* i386-tdep.c (i386_frame_cache): Remove stack_align.  Add
	saved_sp_reg.
	(i386_alloc_frame_cache): Remove stack_align.  Initialize
	saved_sp_reg to I386_ESP_REGNUM.
	(i386_analyze_stack_align): Rewrite.
	(i386_frame_cache): Use saved_sp_reg only if frame is invalid.

diff -x .svn -upr ../gdb/src/gdb gdb/gdb
diff -x .svn -upr ../gdb/src/gdb/amd64-tdep.c gdb/gdb/amd64-tdep.c
--- ../gdb/src/gdb/amd64-tdep.c	2008-07-16 22:30:04.000000000 -0700
+++ gdb/gdb/amd64-tdep.c	2008-08-06 14:25:49.000000000 -0700
@@ -680,6 +680,7 @@ struct amd64_frame_cache
   /* Saved registers.  */
   CORE_ADDR saved_regs[AMD64_NUM_SAVED_REGS];
   CORE_ADDR saved_sp;
+  int saved_sp_reg;
 
   /* Do we have a frame?  */
   int frameless_p;
@@ -702,6 +703,7 @@ amd64_init_frame_cache (struct amd64_fra
   for (i = 0; i < AMD64_NUM_SAVED_REGS; i++)
     cache->saved_regs[i] = -1;
   cache->saved_sp = 0;
+  cache->saved_sp_reg = AMD64_RSP_REGNUM;
 
   /* Frameless until proven otherwise.  */
   cache->frameless_p = 1;
@@ -719,6 +721,204 @@ amd64_alloc_frame_cache (void)
   return cache;
 }
 
+/* GCC 4.4 and later, can put code in the prologue to realign the
+   stack pointer.  Check whether PC points to such code, and update
+   CACHE accordingly.  Return the first instruction after the code
+   sequence or CURRENT_PC, whichever is smaller.  If we don't
+   recognize the code, return PC.  */
+
+static CORE_ADDR
+amd64_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
+			   struct amd64_frame_cache *cache)
+{
+  /* There are 3 code sequences to re-align stack:
+
+     	1. Use %rbp:
+
+		pushq %rbp
+		movq  %rsp, %rbp
+		andq  $-XXX, %rsp
+
+	2. Use a caller-saved saved register:
+
+		leaq  8(%rsp), %reg
+		andq  $-XXX, %rsp
+		pushq -8(%reg)
+
+	3. Use a callee-saved saved register:
+
+		pushq %reg
+		leaq  16(%rsp), %reg
+		andq  $-XXX, %rsp
+		pushq -8(%reg)
+
+     "andq $-XXX, %rsp" can be either 4 bytes or 7 bytes:
+     
+     	0x48 0x83 0xe4 0xf0			andq $-16, %rsp
+     	0x48 0x81 0xe4 0x00 0xff 0xff 0xff	andq $-256, %rsp
+   */
+
+  gdb_byte buf[18];
+  int reg, r;
+  int offset, offset_and;
+  static int regnums[16] = {
+    AMD64_RAX_REGNUM,		/* %rax */
+    AMD64_RCX_REGNUM,		/* %rcx */
+    AMD64_RDX_REGNUM,		/* %rdx */
+    AMD64_RBX_REGNUM,		/* %rbx */
+    AMD64_RSP_REGNUM,		/* %rsp */
+    AMD64_RBP_REGNUM,		/* %rbp */
+    AMD64_RSI_REGNUM,		/* %rsi */
+    AMD64_RDI_REGNUM,		/* %rdi */
+    AMD64_R8_REGNUM,		/* %r8 */
+    AMD64_R9_REGNUM,		/* %r9 */
+    AMD64_R10_REGNUM,		/* %r10 */
+    AMD64_R11_REGNUM,		/* %r11 */
+    AMD64_R12_REGNUM,		/* %r12 */
+    AMD64_R13_REGNUM,		/* %r13 */
+    AMD64_R14_REGNUM,		/* %r14 */
+    AMD64_R15_REGNUM,		/* %r15 */
+  };
+
+  if (target_read_memory (pc, buf, sizeof buf))
+    return pc;
+
+  /* First check "pushq %rbp".  */
+  if (buf[0] == 0x55)
+    {
+      /* The next instruction has to be "movq %rsp, %rbp".  */
+      if (buf[1] != 0x48 || buf[2] != 0x89 || buf[3] != 0xe5)
+	return pc;
+
+      /* The next instruction has to be "andq $-XXX, %rsp".  */
+      if (buf[4] != 0x48
+	  || buf[6] != 0xe4
+	  || (buf[5] != 0x81 && buf[5] != 0x83))
+	return pc;
+
+      if (current_pc > pc + 4)
+	cache->saved_sp_reg = AMD64_RBP_REGNUM;
+
+      /* Keep the prologue for amd64_analyze_prologue.  */
+      return pc;
+    }
+
+  /* Check caller-saved saved register.  The first instruction has
+     to be "leaq 8(%rsp), %reg".  */
+  if ((buf[0] & 0xfb) == 0x48
+      && buf[1] == 0x8d
+      && buf[3] == 0x24
+      && buf[4] == 0x8)
+    {
+      /* MOD must be binary 10 and R/M must be binary 100.  */
+      if ((buf[2] & 0xc7) != 0x44)
+	return pc;
+
+      /* REG has register number.  */
+      reg = (buf[2] >> 3) & 7;
+
+      /* Check the REX.R bit.  */
+      if (buf[0] == 0x4c)
+	reg += 8;
+
+      offset = 5;
+    }
+  else
+    {
+      /* Check callee-saved saved register.  The first instruction
+	 has to be "pushq %reg".  */
+      reg = 0;
+      if ((buf[0] & 0xf8) == 0x50)
+	offset = 0;
+      else if ((buf[0] & 0xf6) == 0x40
+	       && (buf[1] & 0xf8) == 0x50)
+	{
+	  /* Check the REX.B bit.  */
+	  if ((buf[0] & 1) != 0)
+	    reg = 8;
+
+	  offset = 1;
+	}
+      else
+	return pc;
+
+      /* Get register.  */
+      reg += buf[offset] & 0x7;
+
+      offset++;
+
+      /* The next instruction has to be "leaq 16(%rsp), %reg".  */
+      if ((buf[offset] & 0xfb) != 0x48
+	  || buf[offset + 1] != 0x8d
+	  || buf[offset + 3] != 0x24
+	  || buf[offset + 4] != 0x10)
+	return pc;
+
+      /* MOD must be binary 10 and R/M must be binary 100.  */
+      if ((buf[offset + 2] & 0xc7) != 0x44)
+	return pc;
+      
+      /* REG has register number.  */
+      r = (buf[offset + 2] >> 3) & 7;
+
+      /* Check the REX.R bit.  */
+      if (buf[offset] == 0x4c)
+	r += 8;
+
+      /* Registers in pushq and leaq have to be the same.  */
+      if (reg != r)
+	return pc;
+
+      offset += 5;
+    }
+
+  /* Rigister can't be %rsp nor %rbp.  */
+  if (reg == 4 || reg == 5)
+    return pc;
+
+  /* The next instruction has to be "andq $-XXX, %rsp".  */
+  if (buf[offset] != 0x48
+      || buf[offset + 2] != 0xe4
+      || (buf[offset + 1] != 0x81 && buf[offset + 1] != 0x83))
+    return pc;
+
+  offset_and = offset;
+  offset += buf[offset + 1] == 0x81 ? 7 : 4;
+
+  /* The next instruction has to be "pushq -8(%reg)".  */
+  r = 0;
+  if (buf[offset] == 0xff)
+    offset++;
+  else if ((buf[offset] & 0xf6) == 0x40
+	   && buf[offset + 1] == 0xff)
+    {
+      /* Check the REX.B bit.  */
+      if ((buf[offset] & 0x1) != 0)
+	r = 8;
+      offset += 2;
+    }
+  else
+    return pc;
+
+  /* 8bit -8 is 0xf8.  REG must be binary 110 and MOD must be binary
+     01.  */
+  if (buf[offset + 1] != 0xf8
+      || (buf[offset] & 0xf8) != 0x70)
+    return pc;
+
+  /* R/M has register.  */
+  r += buf[offset] & 7;
+
+  /* Registers in leaq and pushq have to be the same.  */
+  if (reg != r)
+    return pc;
+
+  if (current_pc > pc + offset_and)
+    cache->saved_sp_reg = regnums[reg];
+
+  return min (pc + offset + 2, current_pc);
+}
+
 /* Do a limited analysis of the prologue at PC and update CACHE
    accordingly.  Bail out early if CURRENT_PC is reached.  Return the
    address where the analysis stopped.
@@ -742,6 +942,8 @@ amd64_analyze_prologue (CORE_ADDR pc, CO
   if (current_pc <= pc)
     return current_pc;
 
+  pc = amd64_analyze_stack_align (pc, current_pc, cache);
+
   op = read_memory_unsigned_integer (pc, 1);
 
   if (op == 0x55)		/* pushq %rbp */
@@ -813,8 +1015,23 @@ amd64_frame_cache (struct frame_info *th
 	 at the stack pointer.  For truly "frameless" functions this
 	 might work too.  */
 
-      get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
-      cache->base = extract_unsigned_integer (buf, 8) + cache->sp_offset;
+      if (cache->saved_sp_reg != AMD64_RSP_REGNUM)
+	{
+	  /* We're halfway aligning the stack.  Saved stack pointer
+	     has been saved in saved_sp_reg.  */
+	  get_frame_register (this_frame, cache->saved_sp_reg, buf);
+	  cache->saved_sp = extract_unsigned_integer(buf, 8);
+	  cache->base = ((cache->saved_sp - 8) & 0xfffffffffffffff0LL) - 8;
+	  cache->saved_regs[AMD64_RIP_REGNUM] = cache->saved_sp - 8;
+
+	  /* This will be added back below.  */
+	  cache->saved_regs[AMD64_RIP_REGNUM] -= cache->base;
+	}
+      else
+	{
+	  get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
+	  cache->base = extract_unsigned_integer (buf, 8) + cache->sp_offset;
+	}
     }
   else
     {
@@ -828,8 +1045,11 @@ amd64_frame_cache (struct frame_info *th
 
   /* For normal frames, %rip is stored at 8(%rbp).  If we don't have a
      frame we find it at the same offset from the reconstructed base
-     address.  */
-  cache->saved_regs[AMD64_RIP_REGNUM] = 8;
+     address.  If we're halfway aligning the stack, %rip is handled
+     differently (see above).  */
+  if (!cache->frameless_p
+      || cache->saved_sp_reg == AMD64_RSP_REGNUM)
+    cache->saved_regs[AMD64_RIP_REGNUM] = 8;
 
   /* Adjust all the saved registers such that they contain addresses
      instead of offsets.  */
diff -x .svn -upr ../gdb/src/gdb/amd64-tdep.h gdb/gdb/amd64-tdep.h
--- ../gdb/src/gdb/amd64-tdep.h	2008-01-17 09:38:41.000000000 -0800
+++ gdb/gdb/amd64-tdep.h	2008-07-18 15:41:32.000000000 -0700
@@ -39,8 +39,14 @@ enum amd64_regnum
   AMD64_RDI_REGNUM,		/* %rdi */
   AMD64_RBP_REGNUM,		/* %rbp */
   AMD64_RSP_REGNUM,		/* %rsp */
-  AMD64_R8_REGNUM = 8,		/* %r8 */
-  AMD64_R15_REGNUM = 15,	/* %r15 */
+  AMD64_R8_REGNUM,		/* %r8 */
+  AMD64_R9_REGNUM,		/* %r9 */
+  AMD64_R10_REGNUM,		/* %r10 */
+  AMD64_R11_REGNUM,		/* %r11 */
+  AMD64_R12_REGNUM,		/* %r12 */
+  AMD64_R13_REGNUM,		/* %r13 */
+  AMD64_R14_REGNUM,		/* %r14 */
+  AMD64_R15_REGNUM,		/* %r15 */
   AMD64_RIP_REGNUM,		/* %rip */
   AMD64_EFLAGS_REGNUM,		/* %eflags */
   AMD64_CS_REGNUM,		/* %cs */
Only in gdb/gdb: ChangeLog.stack
diff -x .svn -upr ../gdb/src/gdb/i386-tdep.c gdb/gdb/i386-tdep.c
--- ../gdb/src/gdb/i386-tdep.c	2008-07-16 22:30:17.000000000 -0700
+++ gdb/gdb/i386-tdep.c	2008-08-06 14:24:23.000000000 -0700
@@ -518,7 +518,7 @@ struct i386_frame_cache
   /* Saved registers.  */
   CORE_ADDR saved_regs[I386_NUM_SAVED_REGS];
   CORE_ADDR saved_sp;
-  int stack_align;
+  int saved_sp_reg;
   int pc_in_eax;
 
   /* Stack space reserved for local variables.  */
@@ -545,7 +545,7 @@ i386_alloc_frame_cache (void)
   for (i = 0; i < I386_NUM_SAVED_REGS; i++)
     cache->saved_regs[i] = -1;
   cache->saved_sp = 0;
-  cache->stack_align = 0;
+  cache->saved_sp_reg = I386_ESP_REGNUM;
   cache->pc_in_eax = 0;
 
   /* Frameless until proven otherwise.  */
@@ -707,37 +707,134 @@ static CORE_ADDR
 i386_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
 			  struct i386_frame_cache *cache)
 {
-  /* The register used by the compiler to perform the stack re-alignment 
-     is, in order of preference, either %ecx, %edx, or %eax.  GCC should
-     never use %ebx as it always treats it as callee-saved, whereas
-     the compiler can only use caller-saved registers.  */
-  static const gdb_byte insns_ecx[10] = { 
-    0x8d, 0x4c, 0x24, 0x04,	/* leal  4(%esp), %ecx */
-    0x83, 0xe4, 0xf0,		/* andl  $-16, %esp */
-    0xff, 0x71, 0xfc		/* pushl -4(%ecx) */
-  };
-  static const gdb_byte insns_edx[10] = { 
-    0x8d, 0x54, 0x24, 0x04,	/* leal  4(%esp), %edx */
-    0x83, 0xe4, 0xf0,		/* andl  $-16, %esp */
-    0xff, 0x72, 0xfc		/* pushl -4(%edx) */
-  };
-  static const gdb_byte insns_eax[10] = { 
-    0x8d, 0x44, 0x24, 0x04,	/* leal  4(%esp), %eax */
-    0x83, 0xe4, 0xf0,		/* andl  $-16, %esp */
-    0xff, 0x70, 0xfc		/* pushl -4(%eax) */
+  /* There are 3 code sequences to re-align stack:
+
+     	1. Use %ebp:
+
+		pushl %ebp
+		movl  %esp, %ebp
+		andl  $-XXX, %esp
+
+	2. Use a caller-saved saved register:
+
+		leal  4(%esp), %reg
+		andl  $-XXX, %esp
+		pushl -4(%reg)
+
+	3. Use a callee-saved saved register:
+
+		pushl %reg
+		leal  8(%esp), %reg
+		andl  $-XXX, %esp
+		pushl -4(%reg)
+
+     "andl $-XXX, %esp" can be either 3 bytes or 6 bytes:
+     
+     	0x83 0xe4 0xf0			andl $-16, %esp
+     	0x81 0xe4 0x00 0xff 0xff 0xff	andl $-256, %esp
+   */
+
+  gdb_byte buf[14];
+  int reg;
+  int offset, offset_and;
+  static int regnums[8] = {
+    I386_EAX_REGNUM,		/* %eax */
+    I386_ECX_REGNUM,		/* %ecx */
+    I386_EDX_REGNUM,		/* %edx */
+    I386_EBX_REGNUM,		/* %ebx */
+    I386_ESP_REGNUM,		/* %esp */
+    I386_EBP_REGNUM,		/* %ebp */
+    I386_ESI_REGNUM,		/* %esi */
+    I386_EDI_REGNUM		/* %edi */
   };
-  gdb_byte buf[10];
 
-  if (target_read_memory (pc, buf, sizeof buf)
-      || (memcmp (buf, insns_ecx, sizeof buf) != 0
-          && memcmp (buf, insns_edx, sizeof buf) != 0
-          && memcmp (buf, insns_eax, sizeof buf) != 0))
+  if (target_read_memory (pc, buf, sizeof buf))
+    return pc;
+
+  /* First check "pushl %ebp".  */
+  if (buf[0] == 0x55)
+    {
+      /* The next instruction has to be "movl %esp, %ebp".  */
+      if (buf[1] != 0x89 || buf[2] != 0xe5)
+	return pc;
+
+      /* The next instruction has to be "andl $-XXX, %esp".  */
+      if (buf[4] != 0xe4 || (buf[3] != 0x81 && buf[3] != 0x83))
+	return pc;
+
+      if (current_pc > pc + 3)
+	cache->saved_sp_reg = I386_EBP_REGNUM;
+
+      /* Keep the prologue for i386_analyze_frame_setup.  */
+      return pc;
+    }
+
+  /* Check caller-saved saved register.  The first instruction has
+     to be "leal 4(%esp), %reg".  */
+  if (buf[0] == 0x8d && buf[2] == 0x24 && buf[3] == 0x4)
+    {
+      /* MOD must be binary 10 and R/M must be binary 100.  */
+      if ((buf[1] & 0xc7) != 0x44)
+	return pc;
+
+      /* REG has register number.  */
+      reg = (buf[1] >> 3) & 7;
+      offset = 4;
+    }
+  else
+    {
+      /* Check callee-saved saved register.  The first instruction
+	 has to be "pushl %reg".  */
+      if ((buf[0] & 0xf8) != 0x50)
+	return pc;
+
+      /* Get register.  */
+      reg = buf[0] & 0x7;
+
+      /* The next instruction has to be "leal 8(%esp), %reg".  */
+      if (buf[1] != 0x8d || buf[3] != 0x24 || buf[4] != 0x8)
+	return pc;
+
+      /* MOD must be binary 10 and R/M must be binary 100.  */
+      if ((buf[2] & 0xc7) != 0x44)
+	return pc;
+      
+      /* REG has register number.  Registers in pushl and leal have to
+	 be the same.  */
+      if (reg != ((buf[2] >> 3) & 7))
+	return pc;
+
+      offset = 5;
+    }
+
+  /* Rigister can't be %esp nor %ebp.  */
+  if (reg == 4 || reg == 5)
+    return pc;
+
+  /* The next instruction has to be "andl $-XXX, %esp".  */
+  if (buf[offset + 1] != 0xe4
+      || (buf[offset] != 0x81 && buf[offset] != 0x83))
     return pc;
 
-  if (current_pc > pc + 4)
-    cache->stack_align = 1;
+  offset_and = offset;
+  offset += buf[offset] == 0x81 ? 6 : 3;
 
-  return min (pc + 10, current_pc);
+  /* The next instruction has to be "pushl -4(%reg)".  8bit -4 is
+     0xfc.  REG must be binary 110 and MOD must be binary 01.  */
+  if (buf[offset] != 0xff
+      || buf[offset + 2] != 0xfc
+      || (buf[offset + 1] & 0xf8) != 0x70)
+    return pc;
+
+  /* R/M has register.  Registers in leal and pushl have to be the
+     same.  */
+  if (reg != (buf[offset + 1] & 7))
+    return pc;
+
+  if (current_pc > pc + offset_and)
+    cache->saved_sp_reg = regnums[reg];
+
+  return min (pc + offset + 3, current_pc);
 }
 
 /* Maximum instruction length we need to handle.  */
@@ -1241,13 +1338,6 @@ i386_frame_cache (struct frame_info *thi
   if (cache->pc != 0)
     i386_analyze_prologue (cache->pc, get_frame_pc (this_frame), cache);
 
-  if (cache->stack_align)
-    {
-      /* Saved stack pointer has been saved in %ecx.  */
-      get_frame_register (this_frame, I386_ECX_REGNUM, buf);
-      cache->saved_sp = extract_unsigned_integer(buf, 4);
-    }
-
   if (cache->locals < 0)
     {
       /* We didn't find a valid frame, which means that CACHE->base
@@ -1258,9 +1348,12 @@ i386_frame_cache (struct frame_info *thi
 	 frame by looking at the stack pointer.  For truly "frameless"
 	 functions this might work too.  */
 
-      if (cache->stack_align)
+      if (cache->saved_sp_reg != I386_ESP_REGNUM)
 	{
-	  /* We're halfway aligning the stack.  */
+	  /* We're halfway aligning the stack.  Saved stack pointer
+	     has been saved in saved_sp_reg.  */
+	  get_frame_register (this_frame, cache->saved_sp_reg, buf);
+	  cache->saved_sp = extract_unsigned_integer(buf, 4);
 	  cache->base = ((cache->saved_sp - 4) & 0xfffffff0) - 4;
 	  cache->saved_regs[I386_EIP_REGNUM] = cache->saved_sp - 4;
 

  reply	other threads:[~2008-08-06 21:36 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-30 21:12 H.J. Lu
2008-08-06 21:06 ` Mark Kettenis
2008-08-06 21:36   ` H.J. Lu [this message]
2008-08-09 12:03     ` Mark Kettenis
2008-08-09 14:52       ` H.J. Lu
2008-08-09 15:33         ` Mark Kettenis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6dc9ffc80808061436y7ba7c35fl4844b5d9bce52a1@mail.gmail.com \
    --to=hjl.tools@gmail.com \
    --cc=gdb-patches@sourceware.org \
    --cc=joey.ye@intel.com \
    --cc=mark.kettenis@xs4all.nl \
    --cc=xuepeng.guo@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox