* [RFA/m32r] Fix m32r frame analyzer
@ 2004-10-05 10:13 Kei Sakamoto
2004-10-06 17:24 ` Andrew Cagney
0 siblings, 1 reply; 3+ messages in thread
From: Kei Sakamoto @ 2004-10-05 10:13 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 766 bytes --]
Hello,
The attached patch revises m32r frame analyzer. The current
analyzer works fine with functions written in C. But it sometimes
can't handle functions written in assembly languages correctly.
It also can't recognize trap instructions as the end of prologue.
# System call handlers of Linux/M32R are written in assembly
# languages and use trap instructions.
The attached fixes these problems.
OK to commit?
2004-10-05 Kei Sakamoto <sakamoto.kei@renesas.com>
* m32r-tdep.c (decode_prologue): Support functions written
in assembly languages. Recognize trap instructions as the
end of prologue.
(m32r_frame_unwind_cache): Ditto.
(m32r_skip_prologue): Extend search limit. Quit analyzing
prologue if pc's location is not readable.
[-- Attachment #2: m32r-tdep.patch --]
[-- Type: application/octet-stream, Size: 6142 bytes --]
Index: m32r-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m32r-tdep.c,v
retrieving revision 1.32
diff -u -r1.32 m32r-tdep.c
--- m32r-tdep.c 5 Oct 2004 04:07:10 -0000 1.32
+++ m32r-tdep.c 5 Oct 2004 09:26:33 -0000
@@ -258,13 +258,13 @@
static void
decode_prologue (CORE_ADDR start_pc, CORE_ADDR scan_limit,
- CORE_ADDR *pl_endptr)
+ CORE_ADDR *pl_endptr, unsigned long *framelength)
{
unsigned long framesize;
int insn;
int op1;
- int maybe_one_more = 0;
CORE_ADDR after_prologue = 0;
+ CORE_ADDR after_push = 0;
CORE_ADDR after_stack_adjust = 0;
CORE_ADDR current_pc;
@@ -275,29 +275,18 @@
{
insn = read_memory_unsigned_integer (current_pc, 2);
+ if (insn == 0x0000)
+ break;
+
/* If this is a 32 bit instruction, we dont want to examine its
immediate data as though it were an instruction */
if (current_pc & 0x02)
{
- /* Clear the parallel execution bit from 16 bit instruction */
- if (maybe_one_more)
- {
- /* The last instruction was a branch, usually terminates
- the series, but if this is a parallel instruction,
- it may be a stack framing instruction */
- if (!(insn & 0x8000))
- {
- /* nope, we are really done */
- break;
- }
- }
/* decode this instruction further */
insn &= 0x7fff;
}
else
{
- if (maybe_one_more)
- break; /* This isnt the one more */
if (insn & 0x8000)
{
if (current_pc == scan_limit)
@@ -324,7 +313,7 @@
framesize += insn;
}
}
- after_prologue = current_pc;
+ after_push = current_pc + 2;
continue;
}
}
@@ -363,17 +352,23 @@
after_prologue = current_pc + 2;
break; /* end of stack adjustments */
}
+
/* Nop looks like a branch, continue explicitly */
if (insn == 0x7000)
{
after_prologue = current_pc + 2;
continue; /* nop occurs between pushes */
}
+ /* End of prolog if any of these are trap instructions */
+ if ((insn & 0xfff0) == 0x10f0)
+ {
+ after_prologue = current_pc;
+ break;
+ }
/* End of prolog if any of these are branch instructions */
if ((op1 == 0x7000) || (op1 == 0xb000) || (op1 == 0xf000))
{
after_prologue = current_pc;
- maybe_one_more = 1;
continue;
}
/* Some of the branch instructions are mixed with other types */
@@ -383,12 +378,14 @@
if ((subop == 0x0ec0) || (subop == 0x0fc0))
{
after_prologue = current_pc;
- maybe_one_more = 1;
continue; /* jmp , jl */
}
}
}
+ if (framelength)
+ *framelength = framesize;
+
if (current_pc >= scan_limit)
{
if (pl_endptr)
@@ -400,6 +397,13 @@
{
*pl_endptr = after_stack_adjust;
}
+ else if (after_push != 0)
+ /* We did not find a "mv fp,sp", but we DID find
+ a push. Is it safe to use that as the
+ end of the prologue? I just don't know. */
+ {
+ *pl_endptr = after_push;
+ }
else
/* We reached the end of the loop without finding the end
of the prologue. No way to win -- we should report failure.
@@ -409,6 +413,7 @@
}
return;
}
+
if (after_prologue == 0)
after_prologue = current_pc;
@@ -419,13 +424,14 @@
/* Function: skip_prologue
Find end of function prologue */
-#define DEFAULT_SEARCH_LIMIT 44
+#define DEFAULT_SEARCH_LIMIT 128
CORE_ADDR
m32r_skip_prologue (CORE_ADDR pc)
{
CORE_ADDR func_addr, func_end;
struct symtab_and_line sal;
+ LONGEST return_value;
/* See what the symbol table says */
@@ -447,11 +453,15 @@
}
else
func_end = pc + DEFAULT_SEARCH_LIMIT;
- decode_prologue (pc, func_end, &sal.end);
+
+ /* If pc's location is not readable, just quit. */
+ if (!safe_read_memory_integer (pc, 4, &return_value))
+ return 0;
+
+ decode_prologue (pc, func_end, &sal.end, NULL);
return sal.end;
}
-
struct m32r_unwind_cache
{
/* The previous frame's inner most stack address. Used as this
@@ -480,13 +490,14 @@
m32r_frame_unwind_cache (struct frame_info *next_frame,
void **this_prologue_cache)
{
- CORE_ADDR pc;
+ CORE_ADDR pc, scan_limit;
ULONGEST prev_sp;
ULONGEST this_base;
- unsigned long op;
+ unsigned long op, op2;
int i;
struct m32r_unwind_cache *info;
+
if ((*this_prologue_cache))
return (*this_prologue_cache);
@@ -496,10 +507,11 @@
info->size = 0;
info->sp_offset = 0;
-
info->uses_frame = 0;
+
+ scan_limit = frame_pc_unwind (next_frame);
for (pc = frame_func_unwind (next_frame);
- pc > 0 && pc < frame_pc_unwind (next_frame); pc += 2)
+ pc > 0 && pc < scan_limit; pc += 2)
{
if ((pc & 2) == 0)
{
@@ -513,18 +525,19 @@
short n = op & 0xffff;
info->sp_offset += n;
}
- else if (((op >> 8) == 0xe4) /* ld24 r4, xxxxxx; sub sp, r4 */
- && get_frame_memory_unsigned (next_frame, pc + 4,
+ else if (((op >> 8) == 0xe4)
+ && get_frame_memory_unsigned (next_frame, pc + 2,
2) == 0x0f24)
{
+ /* ld24 r4, xxxxxx; sub sp, r4 */
unsigned long n = op & 0xffffff;
info->sp_offset += n;
- pc += 2;
+ pc += 2; /* skip sub instruction */
}
- else
- break;
- pc += 2;
+ if (pc == scan_limit)
+ scan_limit += 2; /* extend the search */
+ pc += 2; /* skip the immediate data */
continue;
}
}
@@ -549,12 +562,13 @@
/* mv fp, sp */
info->uses_frame = 1;
info->r13_offset = info->sp_offset;
+ break; /* end of stack adjustments */
+ }
+ else if ((op & 0xfff0) == 0x10f0)
+ {
+ /* end of prologue if this is a trap instruction */
+ break; /* end of stack adjustments */
}
- else if (op == 0x7000)
- /* nop */
- continue;
- else
- break;
}
info->size = -info->sp_offset;
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFA/m32r] Fix m32r frame analyzer
2004-10-05 10:13 [RFA/m32r] Fix m32r frame analyzer Kei Sakamoto
@ 2004-10-06 17:24 ` Andrew Cagney
2004-10-07 1:26 ` Kei Sakamoto
0 siblings, 1 reply; 3+ messages in thread
From: Andrew Cagney @ 2004-10-06 17:24 UTC (permalink / raw)
To: Kei Sakamoto; +Cc: gdb-patches
}
else
func_end = pc + DEFAULT_SEARCH_LIMIT;
- decode_prologue (pc, func_end, &sal.end);
+
+ /* If pc's location is not readable, just quit. */
+ if (!safe_read_memory_integer (pc, 4, &return_value))
+ return 0;
+
+ decode_prologue (pc, func_end, &sal.end, NULL);
return sal.end;
}
The save_read_memory will need to be in decode_prologue and applied to
every memory read as a fetch of PC+/-4 could equally fail. That means
more interface changes to decode_prologue (return success/fail?).
On fail, it should also return the old PC and not zero - look at
find_function_start_sal for why.
If you make those changes, you can commit.
Andrew
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [RFA/m32r] Fix m32r frame analyzer
2004-10-06 17:24 ` Andrew Cagney
@ 2004-10-07 1:26 ` Kei Sakamoto
0 siblings, 0 replies; 3+ messages in thread
From: Kei Sakamoto @ 2004-10-07 1:26 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 814 bytes --]
> The save_read_memory will need to be in decode_prologue and applied to
> every memory read as a fetch of PC+/-4 could equally fail. That means
> more interface changes to decode_prologue (return success/fail?).
>
> On fail, it should also return the old PC and not zero - look at
> find_function_start_sal for why.
>
> If you make those changes, you can commit.
>
> Andrew
I revised my patch and committed it. Thank you.
Kei Sakamoto
2004-10-07 Kei Sakamoto <sakamoto.kei@renesas.com>
* m32r-tdep.c (decode_prologue): Support functions written
in assembler language. Recognize trap instructions as the
end of prologue.
(m32r_frame_unwind_cache): Ditto.
(m32r_skip_prologue): Extend search limit. Quit analyzing
prologue if pc's location is not readable.
[-- Attachment #2: m32r-tdep.patch --]
[-- Type: application/octet-stream, Size: 4083 bytes --]
Index: m32r-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/m32r-tdep.c,v
retrieving revision 1.32
diff -r1.32 m32r-tdep.c
3c3
< Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003 Free Software
---
> Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
259c259
< static void
---
> static int
261c261
< CORE_ADDR *pl_endptr)
---
> CORE_ADDR *pl_endptr, unsigned long *framelength)
266d265
< int maybe_one_more = 0;
267a267
> CORE_ADDR after_push = 0;
269a270
> LONGEST return_value;
275a277,280
> /* Check if current pc's location is readable. */
> if (!safe_read_memory_integer (current_pc, 2, &return_value))
> return -1;
>
277a283,285
> if (insn == 0x0000)
> break;
>
282,293d289
< /* Clear the parallel execution bit from 16 bit instruction */
< if (maybe_one_more)
< {
< /* The last instruction was a branch, usually terminates
< the series, but if this is a parallel instruction,
< it may be a stack framing instruction */
< if (!(insn & 0x8000))
< {
< /* nope, we are really done */
< break;
< }
< }
299,300d294
< if (maybe_one_more)
< break; /* This isnt the one more */
304a299
>
305a301,305
>
> /* Check if current pc's location is readable. */
> if (!safe_read_memory_integer (current_pc, 2, &return_value))
> return -1;
>
314a315,316
> && safe_read_memory_integer (current_pc + 2, 2,
> &return_value)
327c329
< after_prologue = current_pc;
---
> after_push = current_pc + 2;
365a368
>
371a375,380
> /* End of prolog if any of these are trap instructions */
> if ((insn & 0xfff0) == 0x10f0)
> {
> after_prologue = current_pc;
> break;
> }
376d384
< maybe_one_more = 1;
386d393
< maybe_one_more = 1;
391a399,401
> if (framelength)
> *framelength = framesize;
>
402a413,419
> else if (after_push != 0)
> /* We did not find a "mv fp,sp", but we DID find
> a push. Is it safe to use that as the
> end of the prologue? I just don't know. */
> {
> *pl_endptr = after_push;
> }
410c427
< return;
---
> return 0;
411a429
>
416a435,436
>
> return 0;
422c442
< #define DEFAULT_SEARCH_LIMIT 44
---
> #define DEFAULT_SEARCH_LIMIT 128
428a449
> LONGEST return_value;
450c471,479
< decode_prologue (pc, func_end, &sal.end);
---
>
> /* If pc's location is not readable, just quit. */
> if (!safe_read_memory_integer (pc, 4, &return_value))
> return pc;
>
> /* Find the end of prologue. */
> if (decode_prologue (pc, func_end, &sal.end, NULL) < 0)
> return pc;
>
454d482
<
483c511
< CORE_ADDR pc;
---
> CORE_ADDR pc, scan_limit;
486c514
< unsigned long op;
---
> unsigned long op, op2;
489a518
>
499d527
<
500a529,530
>
> scan_limit = frame_pc_unwind (next_frame);
502c532
< pc > 0 && pc < frame_pc_unwind (next_frame); pc += 2)
---
> pc > 0 && pc < scan_limit; pc += 2)
516,517c546,547
< else if (((op >> 8) == 0xe4) /* ld24 r4, xxxxxx; sub sp, r4 */
< && get_frame_memory_unsigned (next_frame, pc + 4,
---
> else if (((op >> 8) == 0xe4)
> && get_frame_memory_unsigned (next_frame, pc + 2,
519a550
> /* ld24 r4, xxxxxx; sub sp, r4 */
522c553
< pc += 2;
---
> pc += 2; /* skip sub instruction */
524,525d554
< else
< break;
527c556,558
< pc += 2;
---
> if (pc == scan_limit)
> scan_limit += 2; /* extend the search */
> pc += 2; /* skip the immediate data */
551a583,588
> break; /* end of stack adjustments */
> }
> else if ((op & 0xfff0) == 0x10f0)
> {
> /* end of prologue if this is a trap instruction */
> break; /* end of stack adjustments */
553,557d589
< else if (op == 0x7000)
< /* nop */
< continue;
< else
< break;
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2004-10-07 1:26 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-05 10:13 [RFA/m32r] Fix m32r frame analyzer Kei Sakamoto
2004-10-06 17:24 ` Andrew Cagney
2004-10-07 1:26 ` Kei Sakamoto
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox