From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12348 invoked by alias); 29 May 2003 20:03:54 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 12266 invoked from network); 29 May 2003 20:03:53 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sources.redhat.com with SMTP; 29 May 2003 20:03:53 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id h4TK3qH12681 for ; Thu, 29 May 2003 16:03:52 -0400 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [172.16.52.156]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h4TK3qI11276; Thu, 29 May 2003 16:03:52 -0400 Received: from localhost.localdomain (vpn50-12.rdu.redhat.com [172.16.50.12]) by pobox.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h4TK3nb16586; Thu, 29 May 2003 16:03:49 -0400 Received: (from kev@localhost) by localhost.localdomain (8.11.6/8.11.6) id h4TK3hC02126; Thu, 29 May 2003 13:03:43 -0700 Date: Thu, 29 May 2003 20:03:00 -0000 From: Kevin Buettner Message-Id: <1030529200343.ZM2125@localhost.localdomain> To: gdb-patches@sources.redhat.com Subject: [PATCH] rs6000-tdep.c: Improve prologue analysis of 64-bit code Cc: Will Schmidt MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2003-05/txt/msg00553.txt.bz2 I've just committed the patch below. This patch is adapted from a portion of the work that Will Schmidt recently posted. See: http://sources.redhat.com/ml/gdb-patches/2003-04/msg00346.html The skip_prologue() portion of Will's patch is identical to an earlier patch whose author is (I'm told) Jimi X of IBM. If the ChangeLog attribution should be corrected (or extended) in any way, please let me know. Kevin From Jimi X : * rs6000-tdep.c (skip_prologue): Improve support for 64-bit code. Index: rs6000-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v retrieving revision 1.134 diff -u -p -r1.134 rs6000-tdep.c --- rs6000-tdep.c 17 May 2003 05:59:58 -0000 1.134 +++ rs6000-tdep.c 29 May 2003 19:45:32 -0000 @@ -526,13 +526,13 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR l 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 l { 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 l 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 l 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;