From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27053 invoked by alias); 20 Apr 2002 07:31:47 -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 27046 invoked from network); 20 Apr 2002 07:31:45 -0000 Received: from unknown (HELO pizda.ninka.net) (216.101.162.242) by sources.redhat.com with SMTP; 20 Apr 2002 07:31:45 -0000 Received: from localhost (IDENT:davem@localhost.localdomain [127.0.0.1]) by pizda.ninka.net (8.9.3/8.9.3) with ESMTP id AAA10592 for ; Sat, 20 Apr 2002 00:23:04 -0700 Date: Sat, 20 Apr 2002 00:31:00 -0000 Message-Id: <20020420.002304.41086933.davem@redhat.com> To: gdb-patches@sources.redhat.com Subject: [RFA] Improve Sparc epilogue analysis From: "David S. Miller" Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2002-04/txt/msg00673.txt.bz2 Unlike other ports, Sparc only had a manual prologue discovery mechanism. Most other port have a manual prologue examiner, but they also first try to use line number information. To this end, we look for line number information (the first two ".loc" entries for a function have the same line number, the second one begins at the end of the prologue) and if found we use it. Else we just drop into the existing code. Also, in sparc_init_extra_frame_info we were using grotty code to find out if the save instruction in the prologue had executed yet. Firstly, this relied on the debugging info being there. Secondly such things need to be done within the prologue range only, and examine_prologue was created to figure this out. Due to a bug in dwarf2 gas up until a week ago, gas would eliminate these duplicate .loc entries used for prologue discovery by accident. For those of you playing at home: sparc32 sparc64 failures before 88 124 failures after 83 111 More to come. 2002-04-19 David S. Miller * sparc-tdep.c (examine_prologue): Put forward declaration before sparc_init_extra_frame_info. (sparc_init_extra_frame_info): Use it to determine if the save instruction has been executed yet instead of solely relying upon line number information. Some versions of gas delete duplicates. (examine_prologue): Use line number information to find end of prologue, if available. Else, use existing by-hand insn examination. --- sparc-tdep.c.~1~ Fri Apr 19 23:03:54 2002 +++ sparc-tdep.c Fri Apr 19 23:53:57 2002 @@ -279,6 +279,9 @@ struct frame_extra_info int sp_offset; }; +static CORE_ADDR examine_prologue (CORE_ADDR, int, struct frame_info *, + CORE_ADDR *); + /* Call this for each newly created frame. For SPARC, we need to calculate the bottom of the frame, and do some extra work if the prologue has been generated via the -mflat option to GCC. In @@ -393,25 +396,20 @@ sparc_init_extra_frame_info (int fromlea to the current value of the stack pointer and set the in_prologue flag. */ CORE_ADDR addr; - struct symtab_and_line sal; - sal = find_pc_line (prologue_start, 0); - if (sal.line == 0) /* no line info, use PC */ - prologue_end = fi->pc; - else if (sal.end < prologue_end) - prologue_end = sal.end; + prologue_end = examine_prologue (prologue_start, 0, NULL, NULL); if (fi->pc < prologue_end) { - for (addr = prologue_start; addr < fi->pc; addr += 4) + for (addr = fi->pc; addr < prologue_end; addr += 4) { insn = read_memory_integer (addr, 4); if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3c) break; /* SAVE seen, stop searching */ } - if (addr >= fi->pc) + if (addr < prologue_end) { fi->extra_info->in_prologue = 1; - fi->frame = read_register (SP_REGNUM); + fi->frame = read_sp (); } } } @@ -546,9 +544,6 @@ setup_arbitrary_frame (int argc, CORE_AD This routine should be more specific in its actions; making sure that it uses the same register in the initial prologue section. */ -static CORE_ADDR examine_prologue (CORE_ADDR, int, struct frame_info *, - CORE_ADDR *); - static CORE_ADDR examine_prologue (CORE_ADDR start_pc, int frameless_p, struct frame_info *fi, CORE_ADDR *saved_regs) @@ -557,7 +552,21 @@ examine_prologue (CORE_ADDR start_pc, in int dest = -1; CORE_ADDR pc = start_pc; int is_flat = 0; + struct symtab_and_line sal; + CORE_ADDR func_start, func_end; + + /* This is the preferred method, find the end of the prologue by + using the debugging information. */ + if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end)) + { + sal = find_pc_line (func_start, 0); + + if (sal.end < func_end + && start_pc <= sal.end) + return sal.end; + } + /* Oh well, examine the code by hand. */ insn = fetch_instruction (pc); /* Recognize the `sethi' insn and record its destination. */