From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15045 invoked by alias); 13 Jun 2012 23:08:44 -0000 Received: (qmail 15034 invoked by uid 22791); 13 Jun 2012 23:08:42 -0000 X-SWARE-Spam-Status: No, hits=-5.0 required=5.0 tests=AWL,BAYES_00,FSL_FREEMAIL_1,KHOP_RCVD_UNTRUST,NO_DNS_FOR_FROM,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,TW_XF,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mga11.intel.com (HELO mga11.intel.com) (192.55.52.93) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 13 Jun 2012 23:08:30 +0000 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 13 Jun 2012 16:08:29 -0700 X-ExtLoop1: 1 Received: from gnu-6.sc.intel.com ([10.3.194.135]) by fmsmga001.fm.intel.com with ESMTP; 13 Jun 2012 16:08:28 -0700 Received: by gnu-6.sc.intel.com (Postfix, from userid 500) id 8060FC201B; Wed, 13 Jun 2012 16:08:25 -0700 (PDT) Date: Wed, 13 Jun 2012 23:08:00 -0000 From: "H.J. Lu" To: GDB , Mark Kettenis Subject: [PATCH 5/5] Add x32 support to amd64_analyze_stack_align Message-ID: <20120613230825.GA11653@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-06/txt/msg00451.txt.bz2 Hi, This patch adds support to amd64_analyze_stack_align. OK to install? Thanks. H.J. --- * amd64-tdep.c (amd64_analyze_stack_align): Add an argumet to indicate x32 and add x32 support. (amd64_analyze_prologue): Update amd64_analyze_stack_align call. --- gdb/amd64-tdep.c | 88 +++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 64 insertions(+), 24 deletions(-) diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index dd2da2f..9bcf845 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -1714,7 +1714,7 @@ amd64_alloc_frame_cache (void) static CORE_ADDR amd64_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc, - struct amd64_frame_cache *cache) + struct amd64_frame_cache *cache, int is_x32) { /* There are 2 code sequences to re-align stack before the frame gets set up: @@ -1725,6 +1725,12 @@ amd64_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc, andq $-XXX, %rsp pushq -8(%reg) + For x32, it can be + + [addr32] leal 8(%rsp), %reg + andl $-XXX, %esp + [addr32] pushq -8(%reg) + 2. Use a callee-saved saved register: pushq %reg @@ -1732,56 +1738,72 @@ amd64_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc, andq $-XXX, %rsp pushq -8(%reg) + For x32, it can be + + pushq %reg + [addr32] leal 16(%rsp), %reg + andl $-XXX, %esp + [addr32] pushq -8(%reg) + "andq $-XXX, %rsp" can be either 4 bytes or 7 bytes: 0x48 0x83 0xe4 0xf0 andq $-16, %rsp 0x48 0x81 0xe4 0x00 0xff 0xff 0xff andq $-256, %rsp + + "andl $-XXX, %esp" can be either 3 bytes or 6 bytes: + + 0x83 0xe4 0xf0 andl $-16, %esp + 0x81 0xe4 0x00 0xff 0xff 0xff andl $-256, %esp */ - gdb_byte buf[18]; + gdb_byte buf[19]; int reg, r; int offset, offset_and; if (target_read_memory (pc, buf, sizeof buf)) return pc; + /* Skip optional addr32 prefix for x32. */ + offset = 0; + if (is_x32 && buf[0] == 0x67) + offset++; + /* Check caller-saved saved register. The first instruction has - to be "leaq 8(%rsp), %reg". */ - if ((buf[0] & 0xfb) == 0x48 - && buf[1] == 0x8d - && buf[3] == 0x24 - && buf[4] == 0x8) + to be "leaq 8(%rsp), %reg" or "leal 8(%rsp), %reg". */ + if (((buf[offset] & 0xfb) == 0x48 + || (is_x32 && (buf[offset] & 0xfb) == 0x40)) + && buf[offset + 1] == 0x8d + && buf[offset + 3] == 0x24 + && buf[offset + 4] == 0x8) { /* MOD must be binary 10 and R/M must be binary 100. */ - if ((buf[2] & 0xc7) != 0x44) + if ((buf[offset + 2] & 0xc7) != 0x44) return pc; /* REG has register number. */ - reg = (buf[2] >> 3) & 7; + reg = (buf[offset + 2] >> 3) & 7; /* Check the REX.R bit. */ - if (buf[0] == 0x4c) + if ((buf[offset] & 0x4) != 0) reg += 8; - offset = 5; + offset += 5; } else { /* Check callee-saved saved register. The first instruction has to be "pushq %reg". */ reg = 0; - if ((buf[0] & 0xf8) == 0x50) - offset = 0; - else if ((buf[0] & 0xf6) == 0x40 - && (buf[1] & 0xf8) == 0x50) + if ((buf[offset] & 0xf6) == 0x40 + && (buf[offset + 1] & 0xf8) == 0x50) { /* Check the REX.B bit. */ - if ((buf[0] & 1) != 0) + if ((buf[offset] & 1) != 0) reg = 8; - offset = 1; + offset += 1; } - else + else if ((buf[offset] & 0xf8) != 0x50) return pc; /* Get register. */ @@ -1789,8 +1811,14 @@ amd64_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc, offset++; - /* The next instruction has to be "leaq 16(%rsp), %reg". */ - if ((buf[offset] & 0xfb) != 0x48 + /* Skip optional addr32 prefix for x32. */ + if (is_x32 && buf[offset] == 0x67) + offset++; + + /* The next instruction has to be "leaq 16(%rsp), %reg" or + "leal 16(%rsp), %reg". */ + if (((buf[offset] & 0xfb) != 0x48 + && (!is_x32 || (buf[offset] & 0xfb) != 0x40)) || buf[offset + 1] != 0x8d || buf[offset + 3] != 0x24 || buf[offset + 4] != 0x10) @@ -1804,7 +1832,7 @@ amd64_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc, r = (buf[offset + 2] >> 3) & 7; /* Check the REX.R bit. */ - if (buf[offset] == 0x4c) + if ((buf[offset] & 0x4) != 0) r += 8; /* Registers in pushq and leaq have to be the same. */ @@ -1819,14 +1847,25 @@ amd64_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc, return pc; /* The next instruction has to be "andq $-XXX, %rsp". */ - if (buf[offset] != 0x48 - || buf[offset + 2] != 0xe4 + if (buf[offset] != 0x48) + { + if (!is_x32) + return pc; + /* X32 may have "andl $-XXX, %esp". */ + offset--; + } + + if (buf[offset + 2] != 0xe4 || (buf[offset + 1] != 0x81 && buf[offset + 1] != 0x83)) return pc; offset_and = offset; offset += buf[offset + 1] == 0x81 ? 7 : 4; + /* Skip optional addr32 prefix for x32. */ + if (is_x32 && buf[offset] == 0x67) + offset++; + /* The next instruction has to be "pushq -8(%reg)". */ r = 0; if (buf[offset] == 0xff) @@ -1898,7 +1937,8 @@ amd64_analyze_prologue (struct gdbarch *gdbarch, if (current_pc <= pc) return current_pc; - pc = amd64_analyze_stack_align (pc, current_pc, cache); + pc = amd64_analyze_stack_align (pc, current_pc, cache, + gdbarch_ptr_bit (gdbarch) == 32); op = read_memory_unsigned_integer (pc, 1, byte_order); -- 1.7.6.5