This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [Patch] fix for PR:1291
- From: Elena Zannoni <ezannoni at redhat dot com>
- To: kewarken <kewarken at qnx dot com>
- Cc: gdb-patches at sources dot redhat dot com
- Date: Tue, 23 Sep 2003 17:13:33 -0400
- Subject: Re: [Patch] fix for PR:1291
- References: <Pine.CYG.4.55.0309161441150.1008@catdog.ott.qnx.com>
kewarken writes:
> This patch addresses an issue with SH processors where gdb cannot
> backtrace out of function with more than 256 bytes of local variables.
>
> Code such as:
>
> sub1()
> {
> int buf[64];
> }
>
> sub2()
> {
> int buf[65];
> }
>
> generates prologues such as:
>
> sub1:
> mov.l r14,@-r15
> add #-128,r15
> add #-128,r15
> mov r15,r14
> .L8:
> mov.w .L9,r7
> add r7,r14
> mov r14,r15
> mov.l @r15+,r14
> rts
> nop
> .align 1
> .L9:
> .short 256
>
> and
>
> sub2:
> mov.l r14,@-r15
> mov.w .L11,r3
> sub r3,r15
> mov r15,r14
> .L10:
> mov.w .L11,r7
> add r7,r14
> mov r14,r15
> mov.l @r15+,r14
> rts
> nop
> .align 1
> .L11:
> .short 260
>
>
> The second form is not recognized properly by the frame code in gdb. In
> the gcc 3 series, r1 is used instead of r3 so this patch expands on the
> original patch attached to the PR.
>
> Credit to inaba@src.ricoh.co.jp for his original find and patch and to
> Colin Burgess for noting the differences between gcc 2 and 3.
>
> ChangeLog:
>
> 2003-09-16 Kris Warkentin <kewarken@qnx.com>
>
> * sh-tdep.c: Properly detect frame prologues for functions with
> more than 256 bytes of local variables.
You should give credit to these folks in the changelog entry.
I wonder if this can be captured in a test case? How does your change
interacts with Corinna's rewrite?
elena
>Index: sh-tdep.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/sh-tdep.c,v
> retrieving revision 1.136
> diff -u -r1.136 sh-tdep.c
> --- sh-tdep.c 21 Aug 2003 00:01:31 -0000 1.136
> +++ sh-tdep.c 16 Sep 2003 18:35:39 -0000
> @@ -622,13 +622,39 @@
> r15+imm-->r15 */
> #define IS_ADD_SP(x) (((x) & 0xff00) == 0x7f00)
>
> -#define IS_MOV_R3(x) (((x) & 0xff00) == 0x1a00)
> +/* MOV #imm,r3 11100011iiiiiiii
> + imm-->r3 */
> +#define IS_MOV_R3(x) (((x) & 0xff00) == 0xe300)
> #define IS_SHLL_R3(x) ((x) == 0x4300)
>
> /* ADD r3,r15 0011111100111100
> r15+r3-->r15 */
> #define IS_ADD_R3SP(x) ((x) == 0x3f3c)
>
> +/* MOV.W @(disp, pc), r1 10010001dddddddd
> + (disp * 2 + pc + 4)-->r1 */
> +#define IS_MOVW_R1(x) (((x) & 0xff00) == 0x9100)
> +
> +/* MOV.L @(disp, pc), r1 11010001dddddddd
> + (disp * 4 + pc + 4)-->r1 */
> +#define IS_MOVL_R1(x) (((x) & 0xff00) == 0xd100)
> +
> +/* SUB r1,r15 00111111100011000
> + r15-r1-->r15 */
> +#define IS_SUB_R1SP(x) ((x) == 0x3f18)
> +
> +/* MOV.W @(disp, pc), r3 10010011dddddddd
> + (disp * 2 + pc + 4)-->r3 */
> +#define IS_MOVW_R3(x) (((x) & 0xff00) == 0x9300)
> +
> +/* MOV.L @(disp, pc), r3 11010011dddddddd
> + (disp * 4 + pc + 4)-->r3 */
> +#define IS_MOVL_R3(x) (((x) & 0xff00) == 0xd300)
> +
> +/* SUB r3,r15 00111111100111000
> + r15-r3-->r15 */
> +#define IS_SUB_R3SP(x) ((x) == 0x3f38)
> +
> /* FMOV.S FRm,@-Rn Rn-4-->Rn, FRm-->(Rn) 1111nnnnmmmm1011
> FMOV DRm,@-Rn Rn-8-->Rn, DRm-->(Rn) 1111nnnnmmm01011
> FMOV XDm,@-Rn Rn-8-->Rn, XDm-->(Rn) 1111nnnnmmm11011 */
> @@ -696,8 +722,11 @@
> {
> int w = read_memory_integer (here, 2);
> here += 2;
> - if (IS_FMOV (w) || IS_PUSH (w) || IS_STS (w) || IS_MOV_R3 (w)
> - || IS_ADD_R3SP (w) || IS_ADD_SP (w) || IS_SHLL_R3 (w)
> + if (IS_FMOV (w) || IS_PUSH (w) || IS_STS (w)
> + || IS_MOV_R3 (w)
> + || IS_MOVW_R3 (w) || IS_MOVL_R3 (w) || IS_SUB_R3SP (w) || IS_ADD_R3SP (w)
> + || IS_MOVW_R1 (w) || IS_MOVL_R1 (w) || IS_SUB_R1SP (w)
> + || IS_ADD_SP (w) || IS_SHLL_R3 (w)
> || IS_ARG_MOV (w) || IS_MOV_TO_R14 (w))
> {
> start_pc = here;
> @@ -1101,6 +1130,7 @@
> int pc;
> int opc;
> int insn;
> + int r1_val = 0;
> int r3_val = 0;
> char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi),
> get_frame_base (fi));
> @@ -1167,6 +1197,30 @@
> {
> depth += -r3_val;
> }
> + else if (IS_MOVW_R1 (insn))
> + {
> + r1_val = read_memory_integer (pc + 4 + (insn & 0xff) * 2, 2);
> + }
> + else if (IS_MOVL_R1 (insn))
> + {
> + r1_val = read_memory_integer (pc + 4 + (insn & 0xff) * 4, 4);
> + }
> + else if (IS_SUB_R1SP (insn))
> + {
> + depth += r1_val;
> + }
> + else if (IS_MOVW_R3 (insn))
> + {
> + r3_val = read_memory_integer (pc + 4 + (insn & 0xff) * 2, 2);
> + }
> + else if (IS_MOVL_R3 (insn))
> + {
> + r3_val = read_memory_integer (pc + 4 + (insn & 0xff) * 4, 4);
> + }
> + else if (IS_SUB_R3SP (insn))
> + {
> + depth += r3_val;
> + }
> else if (IS_ADD_SP (insn))
> {
> depth -= ((insn & 0xff) ^ 0x80) - 0x80;
> @@ -1642,6 +1696,7 @@
> int pc;
> int opc;
> int insn;
> + int r1_val = 0;
> int r3_val = 0;
> char *dummy_regs = deprecated_generic_find_dummy_frame (get_frame_pc (fi), get_frame_base (fi));
> struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
> @@ -1707,6 +1762,30 @@
> else if (IS_ADD_R3SP (insn))
> {
> depth += -r3_val;
> + }
> + else if (IS_MOVW_R1 (insn))
> + {
> + r1_val = read_memory_integer (pc + 4 + (insn & 0xff) * 2, 2);
> + }
> + else if (IS_MOVL_R1 (insn))
> + {
> + r1_val = read_memory_integer (pc + 4 + (insn & 0xff) * 4, 4);
> + }
> + else if (IS_SUB_R1SP (insn))
> + {
> + depth += r1_val;
> + }
> + else if (IS_MOVW_R3 (insn))
> + {
> + r3_val = read_memory_integer (pc + 4 + (insn & 0xff) * 2, 2);
> + }
> + else if (IS_MOVL_R3 (insn))
> + {
> + r3_val = read_memory_integer (pc + 4 + (insn & 0xff) * 4, 4);
> + }
> + else if (IS_SUB_R3SP (insn))
> + {
> + depth += r3_val;
> }
> else if (IS_ADD_SP (insn))
> {