From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4950 invoked by alias); 20 Jul 2009 01:17:36 -0000 Received: (qmail 4940 invoked by uid 22791); 20 Jul 2009 01:17:35 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from smtp-outbound-2.vmware.com (HELO smtp-outbound-2.vmware.com) (65.115.85.73) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 20 Jul 2009 01:17:29 +0000 Received: from mailhost2.vmware.com (mailhost2.vmware.com [10.16.67.167]) by smtp-outbound-2.vmware.com (Postfix) with ESMTP id 78D682A003; Sun, 19 Jul 2009 18:17:27 -0700 (PDT) Received: from [10.20.94.141] (msnyder-server.eng.vmware.com [10.20.94.141]) by mailhost2.vmware.com (Postfix) with ESMTP id 5F0428EA48; Sun, 19 Jul 2009 18:17:27 -0700 (PDT) Message-ID: <4A63C450.1080307@vmware.com> Date: Mon, 20 Jul 2009 02:31:00 -0000 From: Michael Snyder User-Agent: Thunderbird 1.5.0.12 (X11/20080411) MIME-Version: 1.0 To: Hui Zhu CC: Mark Kettenis , gdb-patches ml Subject: Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (AMD64 Linux system call support) 3/3 References: <4A5A8438.6030005@vmware.com> <4A6121FC.3030205@vmware.com> In-Reply-To: Content-Type: multipart/mixed; boundary="------------040600060000090708050305" X-IsSubscribed: yes 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: 2009-07/txt/msg00461.txt.bz2 This is a multi-part message in MIME format. --------------040600060000090708050305 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 224 Hui, Here is an "epilogue unwinder" for the amd64. Please try it out. If you update infrun.c now you will see most of your *-record.exp testsuites broken by my recent change there. This will fix them. Thanks, Michael --------------040600060000090708050305 Content-Type: text/plain; name="amd64-epilogue.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="amd64-epilogue.txt" Content-length: 3246 --- saveteawater3/amd64-tdep.c 2009-07-19 18:08:56.000000000 -0700 +++ ./amd64-tdep.c 2009-07-19 18:10:18.000000000 -0700 @@ -1887,6 +1887,89 @@ static const struct frame_base amd64_fra amd64_frame_base_address }; +/* Normal frames, but in a function epilogue. */ + +/* The epilogue is defined here as the 'ret' instruction, which will + follow any instruction such as 'leave' or 'pop %ebp' that destroys + the function's stack frame. */ + +static int +amd64_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + gdb_byte insn; + + if (target_read_memory (pc, &insn, 1)) + return 0; /* Can't read memory at pc. */ + + if (insn != 0xc3) /* 'ret' instruction. */ + return 0; + + return 1; +} + +static int +amd64_epilogue_frame_sniffer (const struct frame_unwind *self, + struct frame_info *this_frame, + void **this_prologue_cache) +{ + if (frame_relative_level (this_frame) == 0) + return amd64_in_function_epilogue_p (get_frame_arch (this_frame), + get_frame_pc (this_frame)); + else + return 0; +} + +static struct amd64_frame_cache * +amd64_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) +{ + struct gdbarch *gdbarch = get_frame_arch (this_frame); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + struct amd64_frame_cache *cache; + gdb_byte buf[4]; + + if (*this_cache) + return *this_cache; + + cache = amd64_alloc_frame_cache (); + *this_cache = cache; + + /* Cache base will be %esp plus cache->sp_offset (-8). */ + get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 8, + byte_order) + cache->sp_offset; + + /* Cache pc will be the frame func. */ + cache->pc = get_frame_pc (this_frame); + + /* The saved %esp will be at cache->base plus 16. */ + cache->saved_sp = cache->base + 16; + + /* The saved %eip will be at cache->base plus 8. */ + cache->saved_regs[AMD64_RIP_REGNUM] = cache->base + 8; + + return cache; +} + +static void +amd64_epilogue_frame_this_id (struct frame_info *this_frame, + void **this_cache, + struct frame_id *this_id) +{ + struct amd64_frame_cache *cache = amd64_epilogue_frame_cache (this_frame, + this_cache); + + (*this_id) = frame_id_build (cache->base + 8, cache->pc); +} + +static const struct frame_unwind amd64_epilogue_frame_unwind = +{ + NORMAL_FRAME, + amd64_epilogue_frame_this_id, + amd64_frame_prev_register, + NULL, + amd64_epilogue_frame_sniffer +}; + static struct frame_id amd64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) { @@ -2065,6 +2148,12 @@ amd64_init_abi (struct gdbarch_info info set_gdbarch_dummy_id (gdbarch, amd64_dummy_id); + /* Hook the function epilogue frame unwinder. This unwinder is + appended to the list first, so that it supercedes the other + unwinders in function epilogues. */ + frame_unwind_prepend_unwinder (gdbarch, &amd64_epilogue_frame_unwind); + + /* Hook the prologue-based frame unwinders. */ frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind); frame_unwind_append_unwinder (gdbarch, &amd64_frame_unwind); frame_base_set_default (gdbarch, &amd64_frame_base); --------------040600060000090708050305--