From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9889 invoked by alias); 24 Jul 2004 12:59:59 -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 9882 invoked from network); 24 Jul 2004 12:59:57 -0000 Received: from unknown (HELO walton.kettenis.dyndns.org) (213.93.77.109) by sourceware.org with SMTP; 24 Jul 2004 12:59:57 -0000 Received: from elgar.kettenis.dyndns.org (elgar.kettenis.dyndns.org [192.168.0.2]) by walton.kettenis.dyndns.org (8.12.6p3/8.12.6) with ESMTP id i6OCxuPL007266 for ; Sat, 24 Jul 2004 14:59:56 +0200 (CEST) (envelope-from kettenis@elgar.kettenis.dyndns.org) Received: from elgar.kettenis.dyndns.org (localhost [127.0.0.1]) by elgar.kettenis.dyndns.org (8.12.6p3/8.12.6) with ESMTP id i6OCxuAA041122 for ; Sat, 24 Jul 2004 14:59:56 +0200 (CEST) (envelope-from kettenis@elgar.kettenis.dyndns.org) Received: (from kettenis@localhost) by elgar.kettenis.dyndns.org (8.12.6p3/8.12.6/Submit) id i6OCxu8R041119; Sat, 24 Jul 2004 14:59:56 +0200 (CEST) Date: Sat, 24 Jul 2004 12:59:00 -0000 Message-Id: <200407241259.i6OCxu8R041119@elgar.kettenis.dyndns.org> From: Mark Kettenis To: gdb-patches@sources.redhat.com Subject: [PATCH] Partial fix for PR backtrace/1718 X-SW-Source: 2004-07/txt/msg00346.txt.bz2 This fixes the backtrace problem with Emacs that Eli reported. It's a partial fix since the prologue analyzer still doesn't notice that %ebx gets saved on the stack, but that's not terribly important. This patch also doesn't handle all the other instructions that might end up in the prologue. Committed, Mark Index: ChangeLog from Mark Kettenis Partial fix for PR backtrace/1718. * i386-tdep.c (i386_analyze_frame_setup): Handle more instructions that GCC migrates into the prolugue. Don't handle any instructions that clobber %ebx. Index: i386-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/i386-tdep.c,v retrieving revision 1.197 diff -u -p -r1.197 i386-tdep.c --- i386-tdep.c 18 Jun 2004 16:06:24 -0000 1.197 +++ i386-tdep.c 24 Jul 2004 12:53:37 -0000 @@ -503,20 +503,28 @@ i386_analyze_frame_setup (CORE_ADDR pc, op = read_memory_unsigned_integer (pc + 1, 1); - /* Check for some special instructions that might be migrated - by GCC into the prologue. We check for + /* Check for some special instructions that might be migrated by + GCC into the prologue. At this point in the prologue, code + should only touch the scratch registers %eax, %ecx and %edx, + so we check for + + movl $XXX, %eax + movl $XXX, %ecx + movl $XXX, %edx - xorl %ebx, %ebx + These instructions have opcodes 0xb8, 0xb9 and 0xba. + + We also check for + + xorl %eax, %eax xorl %ecx, %ecx xorl %edx, %edx - xorl %eax, %eax and the equivalent - subl %ebx, %ebx + subl %eax, %eax subl %ecx, %ecx subl %edx, %edx - subl %eax, %eax Because of the symmetry, there are actually two ways to encode these instructions; with opcode bytes 0x29 and 0x2b @@ -524,21 +532,35 @@ i386_analyze_frame_setup (CORE_ADDR pc, Make sure we only skip these instructions if we later see the `movl %esp, %ebp' that actually sets up the frame. */ - while (op == 0x29 || op == 0x2b || op == 0x31 || op == 0x33) + while ((op >= 0xb8 && op <= 0xba) + || op == 0x29 || op == 0x2b + || op == 0x31 || op == 0x33) { - op = read_memory_unsigned_integer (pc + skip + 2, 1); - switch (op) + if (op >= 0xb8 && op <= 0xba) + { + /* Skip the `movl' instructions cited above. */ + skip += 5; + } + else { - case 0xdb: /* %ebx */ - case 0xc9: /* %ecx */ - case 0xd2: /* %edx */ - case 0xc0: /* %eax */ - skip += 2; - break; - default: - return pc + 1; + /* Skip the `subl' and `xorl' instructions cited above. */ + op = read_memory_unsigned_integer (pc + skip + 2, 1); + switch (op) + { + case 0xc0: /* %eax */ + case 0xc9: /* %ecx */ + case 0xd2: /* %edx */ + skip += 2; + break; + default: + return pc + 1; + } } + /* If that's all, return now. */ + if (current_pc <= pc + skip + 1) + return current_pc; + op = read_memory_unsigned_integer (pc + skip + 1, 1); }