This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] [FT32] gdb: Correctly interpret function prologs


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ae4e25019d53d38b2ad50475c80fa99ecab94c5c

commit ae4e25019d53d38b2ad50475c80fa99ecab94c5c
Author: jamesbowman <jamesb@excamera.com>
Date:   Fri Oct 2 17:32:47 2015 -0700

    [FT32] gdb: Correctly interpret function prologs
    
    The stack unwinder did not understand the function prologs
    generated by gcc with -Os. Add code to recognize and interpret the
    prolog calls.
    
    [gdb]
    
    2015-10-02  James Bowman  <james.bowman@ftdichip.com>
    
    	* ft32-tdep.c (ft32_analyze_prologue): Add function prolog
    	subroutine handling.

Diff:
---
 gdb/ChangeLog   |  5 +++++
 gdb/ft32-tdep.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index f9ef565..20d4a4b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2015-10-02  James Bowman  <james.bowman@ftdichip.com>
+
+	* ft32-tdep.c (ft32_analyze_prologue): Add function prolog
+	subroutine handling.
+
 2015-10-01  Simon Marchi  <simon.marchi@ericsson.com>
 
 	* common/vec.h (VEC_OP (T,cleanup)): Add pointer cast.
diff --git a/gdb/ft32-tdep.c b/gdb/ft32-tdep.c
index 00cf847..e9da23e 100644
--- a/gdb/ft32-tdep.c
+++ b/gdb/ft32-tdep.c
@@ -164,33 +164,76 @@ ft32_analyze_prologue (CORE_ADDR start_addr, CORE_ADDR end_addr,
   CORE_ADDR next_addr;
   ULONGEST inst, inst2;
   LONGEST offset;
-  int regnum;
+  int regnum, pushreg;
+  struct bound_minimal_symbol msymbol;
+  const int first_saved_reg = 13;	/* The first saved register.  */
+  /* PROLOGS are addresses of the subroutine prologs, PROLOGS[n]
+     is the address of __prolog_$rN.
+     __prolog_$rN pushes registers from 13 through n inclusive.
+     So for example CALL __prolog_$r15 is equivalent to:
+       PUSH $r13 
+       PUSH $r14 
+       PUSH $r15 
+     Note that PROLOGS[0] through PROLOGS[12] are unused.  */
+  CORE_ADDR prologs[32];
 
   cache->saved_regs[FT32_PC_REGNUM] = 0;
   cache->framesize = 0;
 
+  for (regnum = first_saved_reg; regnum < 32; regnum++)
+    {
+      char prolog_symbol[32];
+
+      snprintf (prolog_symbol, sizeof (prolog_symbol), "__prolog_$r%02d",
+		regnum);
+      msymbol = lookup_minimal_symbol (prolog_symbol, NULL, NULL);
+      if (msymbol.minsym)
+	prologs[regnum] = BMSYMBOL_VALUE_ADDRESS (msymbol);
+      else
+	prologs[regnum] = 0;
+    }
+
   if (start_addr >= end_addr)
-      return end_addr;
+    return end_addr;
 
   cache->established = 0;
-  for (next_addr = start_addr; next_addr < end_addr; )
+  for (next_addr = start_addr; next_addr < end_addr;)
     {
       inst = read_memory_unsigned_integer (next_addr, 4, byte_order);
 
       if (FT32_IS_PUSH (inst))
 	{
-	  regnum = FT32_R0_REGNUM + FT32_PUSH_REG (inst);
+	  pushreg = FT32_PUSH_REG (inst);
 	  cache->framesize += 4;
-	  cache->saved_regs[regnum] = cache->framesize;
+	  cache->saved_regs[FT32_R0_REGNUM + pushreg] = cache->framesize;
 	  next_addr += 4;
 	}
+      else if (FT32_IS_CALL (inst))
+	{
+	  for (regnum = first_saved_reg; regnum < 32; regnum++)
+	    {
+	      if ((4 * (inst & 0x3ffff)) == prologs[regnum])
+		{
+		  for (pushreg = first_saved_reg; pushreg <= regnum;
+		       pushreg++)
+		    {
+		      cache->framesize += 4;
+		      cache->saved_regs[FT32_R0_REGNUM + pushreg] =
+			cache->framesize;
+		    }
+		  next_addr += 4;
+		}
+	    }
+	  break;
+	}
       else
 	break;
     }
   for (regnum = FT32_R0_REGNUM; regnum < FT32_PC_REGNUM; regnum++)
     {
       if (cache->saved_regs[regnum] != REG_UNAVAIL)
-	cache->saved_regs[regnum] = cache->framesize - cache->saved_regs[regnum];
+	cache->saved_regs[regnum] =
+	  cache->framesize - cache->saved_regs[regnum];
     }
   cache->saved_regs[FT32_PC_REGNUM] = cache->framesize;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]