summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Blandy <jimb@codesourcery.com>2003-06-06 07:00:48 +0000
committerJim Blandy <jimb@codesourcery.com>2003-06-06 07:00:48 +0000
commit84ec2015b01fcee46dd27b704bb87100e7cb2533 (patch)
tree3655521da35a8fcc474d9170ba5ba886899bb6c9
parentcae525b1c70ff19e45c2982b7dc979aef49abab4 (diff)
downloadgdb-84ec2015b01fcee46dd27b704bb87100e7cb2533.tar.gz
Merged from trunk:
2003-05-29 Kevin Buettner <kevinb@redhat.com> From Jimi X <jimix@watson.ibm.com>: * rs6000-tdep.c (skip_prologue): Improve support for 64-bit code.
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/rs6000-tdep.c81
2 files changed, 64 insertions, 24 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e6db096fcb4..1e88daf5f9a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -4,6 +4,13 @@
offsets for floating-point registers in both 32- and 64-bit
interfaces.
+ Merged from trunk:
+
+ 2003-05-29 Kevin Buettner <kevinb@redhat.com>
+
+ From Jimi X <jimix@watson.ibm.com>:
+ * rs6000-tdep.c (skip_prologue): Improve support for 64-bit code.
+
2003-06-05 Jim Blandy <jimb@redhat.com>
Recognize and skip 64-bit PowerPC Linux linkage functions.
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 977669753d1..23fc0541e69 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -526,13 +526,13 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
if ((op & 0xfc1fffff) == 0x7c0802a6)
{ /* mflr Rx */
- lr_reg = (op & 0x03e00000) | 0x90010000;
+ lr_reg = (op & 0x03e00000);
continue;
}
else if ((op & 0xfc1fffff) == 0x7c000026)
{ /* mfcr Rx */
- cr_reg = (op & 0x03e00000) | 0x90010000;
+ cr_reg = (op & 0x03e00000);
continue;
}
@@ -558,7 +558,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
{
fdata->saved_gpr = reg;
if ((op & 0xfc1f0003) == 0xf8010000)
- op = (op >> 1) << 1;
+ op &= ~3UL;
fdata->gpr_offset = SIGNED_SHORT (op) + offset;
}
continue;
@@ -590,20 +590,42 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
continue;
}
- else if (lr_reg != -1 && (op & 0xffff0000) == lr_reg)
- { /* st Rx,NUM(r1)
- where Rx == lr */
- fdata->lr_offset = SIGNED_SHORT (op) + offset;
+ else if (lr_reg != -1 &&
+ /* std Rx, NUM(r1) || stdu Rx, NUM(r1) */
+ (((op & 0xffff0000) == (lr_reg | 0xf8010000)) ||
+ /* stw Rx, NUM(r1) */
+ ((op & 0xffff0000) == (lr_reg | 0x90010000)) ||
+ /* stwu Rx, NUM(r1) */
+ ((op & 0xffff0000) == (lr_reg | 0x94010000))))
+ { /* where Rx == lr */
+ fdata->lr_offset = offset;
fdata->nosavedpc = 0;
lr_reg = 0;
+ if ((op & 0xfc000003) == 0xf8000000 || /* std */
+ (op & 0xfc000000) == 0x90000000) /* stw */
+ {
+ /* Does not update r1, so add displacement to lr_offset. */
+ fdata->lr_offset += SIGNED_SHORT (op);
+ }
continue;
}
- else if (cr_reg != -1 && (op & 0xffff0000) == cr_reg)
- { /* st Rx,NUM(r1)
- where Rx == cr */
- fdata->cr_offset = SIGNED_SHORT (op) + offset;
+ else if (cr_reg != -1 &&
+ /* std Rx, NUM(r1) || stdu Rx, NUM(r1) */
+ (((op & 0xffff0000) == (cr_reg | 0xf8010000)) ||
+ /* stw Rx, NUM(r1) */
+ ((op & 0xffff0000) == (cr_reg | 0x90010000)) ||
+ /* stwu Rx, NUM(r1) */
+ ((op & 0xffff0000) == (cr_reg | 0x94010000))))
+ { /* where Rx == cr */
+ fdata->cr_offset = offset;
cr_reg = 0;
+ if ((op & 0xfc000003) == 0xf8000000 ||
+ (op & 0xfc000000) == 0x90000000)
+ {
+ /* Does not update r1, so add displacement to cr_offset. */
+ fdata->cr_offset += SIGNED_SHORT (op);
+ }
continue;
}
@@ -647,30 +669,41 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
this branch */
continue;
- /* update stack pointer */
}
- else if ((op & 0xffff0000) == 0x94210000 || /* stu r1,NUM(r1) */
- (op & 0xffff0003) == 0xf8210001) /* stdu r1,NUM(r1) */
- {
+ /* update stack pointer */
+ else if ((op & 0xfc1f0000) == 0x94010000)
+ { /* stu rX,NUM(r1) || stwu rX,NUM(r1) */
fdata->frameless = 0;
- if ((op & 0xffff0003) == 0xf8210001)
- op = (op >> 1) << 1;
fdata->offset = SIGNED_SHORT (op);
offset = fdata->offset;
continue;
-
}
- else if (op == 0x7c21016e)
- { /* stwux 1,1,0 */
+ else if ((op & 0xfc1f016a) == 0x7c01016e)
+ { /* stwux rX,r1,rY */
+ /* no way to figure out what r1 is going to be */
+ fdata->frameless = 0;
+ offset = fdata->offset;
+ continue;
+ }
+ else if ((op & 0xfc1f0003) == 0xf8010001)
+ { /* stdu rX,NUM(r1) */
+ fdata->frameless = 0;
+ fdata->offset = SIGNED_SHORT (op & ~3UL);
+ offset = fdata->offset;
+ continue;
+ }
+ else if ((op & 0xfc1f016a) == 0x7c01016a)
+ { /* stdux rX,r1,rY */
+ /* no way to figure out what r1 is going to be */
fdata->frameless = 0;
offset = fdata->offset;
continue;
-
- /* Load up minimal toc pointer */
}
- else if ((op >> 22) == 0x20f
+ /* Load up minimal toc pointer */
+ else if (((op >> 22) == 0x20f || /* l r31,... or l r30,... */
+ (op >> 22) == 0x3af) /* ld r31,... or ld r30,... */
&& !minimal_toc_loaded)
- { /* l r31,... or l r30,... */
+ {
minimal_toc_loaded = 1;
continue;