diff options
-rw-r--r-- | gdb/ChangeLog | 13 | ||||
-rw-r--r-- | gdb/amd64-tdep.c | 61 | ||||
-rw-r--r-- | gdb/defs.h | 2 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 49 | ||||
-rw-r--r-- | gdb/symtab.h | 5 | ||||
-rw-r--r-- | gdb/utils.c | 44 |
6 files changed, 96 insertions, 78 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8b43992..75f96c3 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,16 @@ +2011-09-09 Jan Kratochvil <jan.kratochvil@redhat.com> + + 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. + 2011-09-09 Pedro Alves <pedro@codesourcery.com> * linux-nat.h (enum resume_kind): New. diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 14be776..8f686d1 100644 --- 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. */ @@ -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 *); diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index c79f2be..6b87d2a 100644 --- 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) diff --git a/gdb/symtab.h b/gdb/symtab.h index eb7c53b..41a0fd6 100644 --- 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. */ diff --git a/gdb/utils.c b/gdb/utils.c index a979cc4..21682d0 100644 --- 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; |