From patchwork Sat Dec 6 17:58:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wei-cheng, Wang" X-Patchwork-Id: 4100 Received: (qmail 4211 invoked by alias); 6 Dec 2014 17:58:46 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 4200 invoked by uid 89); 6 Dec 2014 17:58:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.4 required=5.0 tests=AWL, BAYES_00, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pd0-f182.google.com Received: from mail-pd0-f182.google.com (HELO mail-pd0-f182.google.com) (209.85.192.182) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Sat, 06 Dec 2014 17:58:43 +0000 Received: by mail-pd0-f182.google.com with SMTP id r10so2648050pdi.13 for ; Sat, 06 Dec 2014 09:58:42 -0800 (PST) X-Received: by 10.66.189.100 with SMTP id gh4mr38290788pac.131.1417888722143; Sat, 06 Dec 2014 09:58:42 -0800 (PST) Received: from [192.168.2.3] ([123.110.214.155]) by mx.google.com with ESMTPSA id w4sm21547409pdq.28.2014.12.06.09.58.37 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 06 Dec 2014 09:58:41 -0800 (PST) Message-ID: <548343C8.1020109@gmail.com> Date: Sun, 07 Dec 2014 01:58:32 +0800 From: Wei-cheng Wang User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 MIME-Version: 1.0 To: uweigand@de.ibm.com, gdb-patches@sourceware.org Subject: Re: [PATCH 1/3 v2] Process record support for PowerPC 2014-12-06 Wei-cheng Wang * rs6000-tdep.c (rs6000_in_function_epilogue_p): Rename to rs6000_in_function_epilogue_frame_p and add an argument for frame_info. (rs6000_epilogue_frame_cache, rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register, rs6000_epilogue_frame_sniffer): New functions. (rs6000_epilogue_frame_unwind): New. (rs6000_gdbarch_init): Append epilogue unwinder. --- gdb/rs6000-tdep.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 96 insertions(+), 4 deletions(-) diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index dabf448..32e1a7b 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -872,14 +872,14 @@ insn_changes_sp_or_jumps (unsigned long insn) limit for the size of an epilogue. */ static int -rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) +rs6000_in_function_epilogue_frame_p (struct frame_info *curfrm, + struct gdbarch *gdbarch, CORE_ADDR pc) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); bfd_byte insn_buf[PPC_INSN_SIZE]; CORE_ADDR scan_pc, func_start, func_end, epilogue_start, epilogue_end; unsigned long insn; - struct frame_info *curfrm; /* Find the search limits based on function boundaries and hard limit. */ @@ -892,8 +892,6 @@ rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) epilogue_end = pc + PPC_MAX_EPILOGUE_INSTRUCTIONS * PPC_INSN_SIZE; if (epilogue_end > func_end) epilogue_end = func_end; - curfrm = get_current_frame (); - /* Scan forward until next 'blr'. */ for (scan_pc = pc; scan_pc < epilogue_end; scan_pc += PPC_INSN_SIZE) @@ -934,6 +932,15 @@ rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) return 0; } +/* Implementation of gdbarch_in_function_epilogue_p. */ + +static int +rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + return rs6000_in_function_epilogue_frame_p (get_current_frame (), + gdbarch, pc); +} + /* Get the ith function argument for the current function. */ static CORE_ADDR rs6000_fetch_pointer_argument (struct frame_info *frame, int argi, @@ -3339,6 +3346,89 @@ static const struct frame_unwind rs6000_frame_unwind = NULL, default_frame_sniffer }; + +static struct rs6000_frame_cache * +rs6000_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache) +{ + volatile struct gdb_exception ex; + struct rs6000_frame_cache *cache; + struct gdbarch *gdbarch = get_frame_arch (this_frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + CORE_ADDR sp; + + if (*this_cache) + return *this_cache; + + cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache); + (*this_cache) = cache; + cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); + + TRY_CATCH (ex, RETURN_MASK_ERROR) + { + /* At this point the stack looks as if we just entered the + function, and the return address is stored in LR. */ + CORE_ADDR sp, lr; + + sp = get_frame_register_unsigned (this_frame, gdbarch_sp_regnum (gdbarch)); + lr = get_frame_register_unsigned (this_frame, tdep->ppc_lr_regnum); + + cache->base = sp; + cache->initial_sp = sp; + + trad_frame_set_value (cache->saved_regs, + gdbarch_pc_regnum (gdbarch), lr); + } + if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); + + return cache; +} + +static void +rs6000_epilogue_frame_this_id (struct frame_info *this_frame, + void **this_cache, struct frame_id *this_id) +{ + CORE_ADDR pc; + struct rs6000_frame_cache *info = + rs6000_epilogue_frame_cache (this_frame, this_cache); + + pc = get_frame_func (this_frame); + if (info->base == 0) + (*this_id) = frame_id_build_unavailable_stack (pc); + else + (*this_id) = frame_id_build (info->base, pc); +} + +static struct value * +rs6000_epilogue_frame_prev_register (struct frame_info *this_frame, + void **this_cache, int regnum) +{ + struct rs6000_frame_cache *info = + rs6000_epilogue_frame_cache (this_frame, this_cache); + return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum); +} + +static int +rs6000_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 rs6000_in_function_epilogue_frame_p (this_frame, + get_frame_arch (this_frame), + get_frame_pc (this_frame)); + else + return 0; +} + +static const struct frame_unwind rs6000_epilogue_frame_unwind = +{ + NORMAL_FRAME, + default_frame_unwind_stop_reason, + rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register, + NULL, + rs6000_epilogue_frame_sniffer +}; static CORE_ADDR @@ -4154,6 +4244,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) case GDB_OSABI_NETBSD_ELF: case GDB_OSABI_UNKNOWN: set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc); + frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind); frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind); set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id); frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer); @@ -4162,6 +4253,7 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_believe_pcc_promotion (gdbarch, 1); set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc); + frame_unwind_append_unwinder (gdbarch, &rs6000_epilogue_frame_unwind); frame_unwind_append_unwinder (gdbarch, &rs6000_frame_unwind); set_gdbarch_dummy_id (gdbarch, rs6000_dummy_id); frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);