This is the mail archive of the gdb-patches@sources.redhat.com 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]

[RFA] Handle sh-elf-gcc scheduling code into a prologue when no debug info present


For the following test case:

  sub1 ()
  {
    printf ("In sub1\n");
  }
  
  sub2 ()
  {
    printf ("In sub2\n");
  }
  
  main ()
  {
    sub1 ();
    sub2 ();
  }

sh-elf-gcc with -O2 will schedule the code to call sub1 into the
prologue of main.  If the code is compiled WITHOUT debug info, the
prologue scanner in gdb will not stop when it sees the jsr and will
eventually return a pc somewhere after the jsr.  For example:

  (gdb) br main
  Breakpoint 1 at 0x1162
  (gdb) x/8i main
  0x1158 <main>:	mov.l	r14,@-r15
  0x115a <main+2>:	mov.l	0x116c <main+20>,r0	! 0x1120
  0x115c <main+4>:	sts.l	pr,@-r15
  0x115e <main+6>:	jsr	@r0
  0x1160 <main+8>:	mov	r15,r14
* 0x1162 <main+10>:	mov.l	0x1170 <main+24>,r1	! 0x113c
  0x1164 <main+12>:	mov	r14,r15
  0x1166 <main+14>:	lds.l	@r15+,pr

Note that the breakpoint on main() gets set well after the jsr.  When
you set breakpoints at sub1 and sub2 and run the program, you get:

  (gdb) run
  Starting program: /links1/build/sourceware/gdb/T-sh-elf/gdb/g 
  Breakpoint 2, 0x00001128 in sub1 ()
  (gdb) c
  Continuing.
  In sub1
  Breakpoint 1, 0x00001162 in main ()
  (gdb) c
  Continuing.
  Breakpoint 3, 0x00001144 in sub2 ()
  (gdb) c
  Continuing.
  In sub2
  Program exited with code 012.

which is very confusing because it appears that sub1 is called before main!

With the attached patch, the prologue scanner returns the pc of the
jsr instruction, allowing the breakpoint at main to be hit before the
breakpoint at sub1:

  (gdb) br main
  Breakpoint 1 at 0x115e
  (gdb) x/8i main
  0x1158 <main>:	mov.l	r14,@-r15
  0x115a <main+2>:	mov.l	0x116c <main+20>,r0	! 0x1120
  0x115c <main+4>:	sts.l	pr,@-r15
* 0x115e <main+6>:	jsr	@r0
  0x1160 <main+8>:	mov	r15,r14
  0x1162 <main+10>:	mov.l	0x1170 <main+24>,r1	! 0x113c
  0x1164 <main+12>:	mov	r14,r15
  0x1166 <main+14>:	lds.l	@r15+,pr
  (gdb) br sub1
  Breakpoint 2 at 0x1128
  (gdb) br sub2
  Breakpoint 3 at 0x1144
  (gdb) run
  Starting program: /links1/build/sourceware/gdb/T-sh-elf/gdb/g 
  Breakpoint 1, 0x0000115e in main ()
  (gdb) c
  Continuing.
  Breakpoint 2, 0x00001128 in sub1 ()
  (gdb) c
  Continuing.
  In sub1
  Breakpoint 3, 0x00001144 in sub2 ()
  (gdb) c
  Continuing.
  In sub2
  Program exited with code 012.

It's also useful to note where the breakpoint gets set if you recompile to generate
debugging information:

  (gdb) br main
  Breakpoint 1 at 0x115a: file g.c, line 13.
  (gdb) x/8i main
  0x1158 <main>:          mov.l   r14,@-r15
  0x115a <main+2>:        mov.l   0x116c <main+20>,r0     ! 0x1120
  0x115c <main+4>:        sts.l   pr,@-r15
  0x115e <main+6>:        jsr     @r0
  0x1160 <main+8>:        mov     r15,r14
  0x1162 <main+10>:       mov.l   0x1170 <main+24>,r1     ! 0x113c
  0x1164 <main+12>:       mov     r14,r15
  0x1166 <main+14>:       lds.l   @r15+,pr

This patch causes no regressions in the gdb testsuite.  Anyone see any
issues with installing it?  :-)

-Fred


2004-02-12  Fred Fish  <fnf@redhat.com>

	* sh-tdep.c (IS_JSR): New macro.
	(sh_analyze_prologue): Use IS_JSR to terminate prologue scan.

Index: sh-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sh-tdep.c,v
retrieving revision 1.158
diff -c -p -r1.158 sh-tdep.c
*** sh-tdep.c	11 Feb 2004 15:40:28 -0000	1.158
--- sh-tdep.c	12 Feb 2004 21:16:39 -0000
*************** sh_breakpoint_from_pc (CORE_ADDR *pcptr,
*** 333,338 ****
--- 333,341 ----
  #define GET_SOURCE_REG(x)  	(((x) >> 4) & 0xf)
  #define GET_TARGET_REG(x)  	(((x) >> 8) & 0xf)
  
+ /* JSR @Rm         0100mmmm00001011 */
+ #define IS_JSR(x)		(((x) & 0xf0ff) == 0x400b)
+ 
  /* STS.L PR,@-r15  0100111100100010
     r15-4-->r15, PR-->(r15) */
  #define IS_STS(x)  		((x) == 0x4f22)
*************** sh_analyze_prologue (CORE_ADDR pc, CORE_
*** 530,535 ****
--- 533,552 ----
  	      else
  		break;
  	    }
+ 	  break;
+ 	}
+       else if (IS_JSR (inst))
+ 	{
+ 	  /* We have found a jsr that has been scheduled into the prologue.
+ 	     If we continue the scan and return a pc someplace after this,
+ 	     then setting a breakpoint on this function will cause it to
+ 	     appear to be called after the function it is calling via the
+ 	     jsr, which will be very confusing.  Most likely the next
+ 	     instruction is going to be IS_MOV_SP_FP in the delay slot.  If
+ 	     so, note that before returning the current pc. */
+ 	  inst = read_memory_integer (pc + 2, 2);
+ 	  if (IS_MOV_SP_FP (inst))
+ 	    cache->uses_fp = 1;
  	  break;
  	}
  #if 0				/* This used to just stop when it found an instruction that



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