From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 28736 invoked by alias); 8 Sep 2011 18:22:55 -0000 Received: (qmail 28337 invoked by uid 22791); 8 Sep 2011 18:22:50 -0000 X-SWARE-Spam-Status: No, hits=-6.7 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_GD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 08 Sep 2011 18:22:31 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p88IMVgo024241 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 8 Sep 2011 14:22:31 -0400 Received: from host1.jankratochvil.net (ovpn-116-38.ams2.redhat.com [10.36.116.38]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p88IMTL2013289 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 8 Sep 2011 14:22:30 -0400 Received: from host1.jankratochvil.net (localhost [127.0.0.1]) by host1.jankratochvil.net (8.14.4/8.14.4) with ESMTP id p88IMS3Y025667; Thu, 8 Sep 2011 20:22:28 +0200 Received: (from jkratoch@localhost) by host1.jankratochvil.net (8.14.4/8.14.4/Submit) id p88IMRhC025666; Thu, 8 Sep 2011 20:22:27 +0200 Date: Thu, 08 Sep 2011 19:13:00 -0000 From: Jan Kratochvil To: Doug Evans Cc: gdb-patches@sourceware.org Subject: Re: [patch] workaround gcc46: prologue skip skips too far (PR 12435) #2 Message-ID: <20110908182227.GA25597@host1.jankratochvil.net> References: <20110722215821.GA3433@host1.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) 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: 2011-09/txt/msg00149.txt.bz2 On Thu, 08 Sep 2011 19:15:59 +0200, Doug Evans wrote: > These kinds of functions tend to grow and grow and become hard to maintain. > IWBN if all this new code is about a specific issue then tuck it away > in its own function. I agree it is a good improvement. > > +  /* At least GCC 4.6.0 and 4.6.1 can produce invalid false prologue and marker > > +     on amd64.  This flag is set independently of the symtab arch.  */ > > + > > +  unsigned amd64_prologue_line_bug : 1; > > I can hear the screams of pushback if a random net person wanted to > check in anything architecture specific to the architecture > independent part of gdb. :-) That is a good comment. There is also symtab->producer, not just cu->producer so it is not needed at all. I will check it in. Thanks, Jan gdb/ 2011-09-08 Jan Kratochvil Code cleanup. * amd64-tdep.c (amd64_skip_prologue): Move the XMM code to ... (amd64_skip_xmm_prologue): ... this new function. Describe its parameters. No longer use amd64_prologue_line_bug. * defs.h (producer_is_gcc_ge_4): New declaration. * dwarf2read.c (producer_is_gcc_ge_4): Move to utils.c. (process_full_comp_unit): Update its caller. Remove amd64_prologue_line_bug initialization. * symtab.h (struct symtab): Remove field amd64_prologue_line_bug. * utils.c (producer_is_gcc_ge_4): Moved here from dwarf2read.c. --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -1910,43 +1910,37 @@ amd64_analyze_prologue (struct gdbarch *gdbarch, return pc; } -/* Return PC of first real instruction. */ +/* Work around false termination of prologue - GCC PR debug/48827. + + START_PC is the first instruction of a function, PC is its minimal already + determined advanced address. Function returns PC if it has nothing to do. + + 84 c0 test %al,%al + 74 23 je after + <-- here is 0 lines advance - the false prologue end marker. + 0f 29 85 70 ff ff ff movaps %xmm0,-0x90(%rbp) + 0f 29 4d 80 movaps %xmm1,-0x80(%rbp) + 0f 29 55 90 movaps %xmm2,-0x70(%rbp) + 0f 29 5d a0 movaps %xmm3,-0x60(%rbp) + 0f 29 65 b0 movaps %xmm4,-0x50(%rbp) + 0f 29 6d c0 movaps %xmm5,-0x40(%rbp) + 0f 29 75 d0 movaps %xmm6,-0x30(%rbp) + 0f 29 7d e0 movaps %xmm7,-0x20(%rbp) + after: */ static CORE_ADDR -amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) +amd64_skip_xmm_prologue (CORE_ADDR pc, CORE_ADDR start_pc) { - struct amd64_frame_cache cache; - CORE_ADDR pc; struct symtab_and_line start_pc_sal, next_sal; gdb_byte buf[4 + 8 * 7]; int offset, xmmreg; - amd64_init_frame_cache (&cache); - pc = amd64_analyze_prologue (gdbarch, start_pc, 0xffffffffffffffffLL, - &cache); - if (cache.frameless_p) - return start_pc; - - /* GCC PR debug/48827 produced false prologue end: - 84 c0 test %al,%al - 74 23 je after - <-- here is 0 lines advance - the false prologue end marker. - 0f 29 85 70 ff ff ff movaps %xmm0,-0x90(%rbp) - 0f 29 4d 80 movaps %xmm1,-0x80(%rbp) - 0f 29 55 90 movaps %xmm2,-0x70(%rbp) - 0f 29 5d a0 movaps %xmm3,-0x60(%rbp) - 0f 29 65 b0 movaps %xmm4,-0x50(%rbp) - 0f 29 6d c0 movaps %xmm5,-0x40(%rbp) - 0f 29 75 d0 movaps %xmm6,-0x30(%rbp) - 0f 29 7d e0 movaps %xmm7,-0x20(%rbp) - after: */ - if (pc == start_pc) return pc; start_pc_sal = find_pc_sect_line (start_pc, NULL, 0); if (start_pc_sal.symtab == NULL - || !start_pc_sal.symtab->amd64_prologue_line_bug + || producer_is_gcc_ge_4 (start_pc_sal.symtab->producer) < 6 || start_pc_sal.pc != start_pc || pc >= start_pc_sal.end) return pc; @@ -1993,6 +1987,23 @@ amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) return next_sal.end; } + +/* Return PC of first real instruction. */ + +static CORE_ADDR +amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) +{ + struct amd64_frame_cache cache; + CORE_ADDR pc; + + amd64_init_frame_cache (&cache); + pc = amd64_analyze_prologue (gdbarch, start_pc, 0xffffffffffffffffLL, + &cache); + if (cache.frameless_p) + return start_pc; + + return amd64_skip_xmm_prologue (pc, start_pc); +} /* Normal frames. */ --- a/gdb/defs.h +++ b/gdb/defs.h @@ -431,6 +431,8 @@ extern int parse_pid_to_attach (char *args); extern struct cleanup *make_bpstat_clear_actions_cleanup (void); +extern int producer_is_gcc_ge_4 (const char *producer); + /* From demangle.c */ extern void set_demangling_style (char *); --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -4723,50 +4723,6 @@ compute_delayed_physnames (struct dwarf2_cu *cu) } } -/* Check for GCC >= 4.x. Return minor version (x) of 4.x in such case. If it - is not GCC or it is GCC older than 4.x return -1. If it is GCC 5.x or - higher return INT_MAX. */ - -static int -producer_is_gcc_ge_4 (struct dwarf2_cu *cu) -{ - const char *cs; - int major, minor; - - if (cu->producer == NULL) - { - /* For unknown compilers expect their behavior is not compliant. For GCC - this case can also happen for -gdwarf-4 type units supported since - gcc-4.5. */ - - return -1; - } - - /* Skip any identifier after "GNU " - such as "C++" or "Java". */ - - if (strncmp (cu->producer, "GNU ", strlen ("GNU ")) != 0) - { - /* For non-GCC compilers expect their behavior is not compliant. */ - - return -1; - } - cs = &cu->producer[strlen ("GNU ")]; - while (*cs && !isdigit (*cs)) - cs++; - if (sscanf (cs, "%d.%d", &major, &minor) != 2) - { - /* Not recognized as GCC. */ - - return -1; - } - - if (major < 4) - return -1; - if (major > 4) - return INT_MAX; - return minor; -} - /* Generate full symbol information for PST and CU, whose DIEs have already been loaded into memory. */ @@ -4806,7 +4762,7 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) if (symtab != NULL) { - int gcc_4_minor = producer_is_gcc_ge_4 (cu); + int gcc_4_minor = producer_is_gcc_ge_4 (cu->producer); /* Set symtab language to language from DW_AT_language. If the compilation is from a C file generated by language preprocessors, do @@ -4829,9 +4785,6 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu) if (gcc_4_minor >= 5) symtab->epilogue_unwind_valid = 1; - - if (gcc_4_minor >= 6) - symtab->amd64_prologue_line_bug = 1; } if (dwarf2_per_objfile->using_index) --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -784,11 +784,6 @@ struct symtab unsigned int epilogue_unwind_valid : 1; - /* At least GCC 4.6.0 and 4.6.1 can produce invalid false prologue and marker - on amd64. This flag is set independently of the symtab arch. */ - - unsigned amd64_prologue_line_bug : 1; - /* The macro table for this symtab. Like the blockvector, this may be shared between different symtabs --- and normally is for all the symtabs in a given compilation unit. */ --- a/gdb/utils.c +++ b/gdb/utils.c @@ -3691,6 +3691,50 @@ make_bpstat_clear_actions_cleanup (void) return make_cleanup (do_bpstat_clear_actions_cleanup, NULL); } +/* Check for GCC >= 4.x according to the symtab->producer string. Return minor + version (x) of 4.x in such case. If it is not GCC or it is GCC older than + 4.x return -1. If it is GCC 5.x or higher return INT_MAX. */ + +int +producer_is_gcc_ge_4 (const char *producer) +{ + const char *cs; + int major, minor; + + if (producer == NULL) + { + /* For unknown compilers expect their behavior is not compliant. For GCC + this case can also happen for -gdwarf-4 type units supported since + gcc-4.5. */ + + return -1; + } + + /* Skip any identifier after "GNU " - such as "C++" or "Java". */ + + if (strncmp (producer, "GNU ", strlen ("GNU ")) != 0) + { + /* For non-GCC compilers expect their behavior is not compliant. */ + + return -1; + } + cs = &producer[strlen ("GNU ")]; + while (*cs && !isdigit (*cs)) + cs++; + if (sscanf (cs, "%d.%d", &major, &minor) != 2) + { + /* Not recognized as GCC. */ + + return -1; + } + + if (major < 4) + return -1; + if (major > 4) + return INT_MAX; + return minor; +} + /* Provide a prototype to silence -Wmissing-prototypes. */ extern initialize_file_ftype _initialize_utils;