diff options
-rw-r--r-- | ChangeLog.csl | 17 | ||||
-rw-r--r-- | gdb/buildsym.c | 17 | ||||
-rw-r--r-- | gdb/buildsym.h | 3 | ||||
-rw-r--r-- | gdb/dwarf2-frame.c | 60 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 10 | ||||
-rw-r--r-- | gdb/symtab.h | 4 |
6 files changed, 100 insertions, 11 deletions
diff --git a/ChangeLog.csl b/ChangeLog.csl index 3dfc1b32735..157182f9fcc 100644 --- a/ChangeLog.csl +++ b/ChangeLog.csl @@ -1,3 +1,20 @@ +2006-04-17 Daniel Jacobowitz <dan@codesourcery.com> + + * gdb/buildsym.c (start_subfile): Handle producer. + (record_producer): New function. + * gdb/buildsym.h (struct subfile): Include producer. + (record_producer): New prototype. + * gdb/dwarf2-frame.c (struct dwarf2_cie): Add version. + (struct dwarf2_frame_state): Add armcc_cfa_offsets_sf and + armcc_cfa_offsets_reversed. + (execute_cfa_program): Handle armcc_cfa_offsets_sf. + (dwarf2_frame_find_quirks): New function. + (dwarf2_frame_cache): Call it. Handle armcc_cfa_offsets_reversed. + (decode_frame_entry_1): Record the CIE version. + * gdb/dwarf2read.c (read_file_scope): Save the producer. + * gdb/symtab.h (struct symtab): Rename unused version member to + producer. + 2006-04-12 Daniel Jacobowitz <dan@codesourcery.com> * gdb/Makefile.in (ALLDEPFILES): Add solib-target.c. diff --git a/gdb/buildsym.c b/gdb/buildsym.c index d0143bc3f24..7908773708d 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -591,6 +591,9 @@ start_subfile (char *name, char *dirname) later via a call to record_debugformat. */ subfile->debugformat = NULL; + /* Similarly for the producer. */ + subfile->producer = NULL; + /* If the filename of this subfile ends in .C, then change the language of any pending subfiles from C to C++. We also accept any other C++ suffixes accepted by deduce_language_from_filename. */ @@ -999,6 +1002,12 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) &objfile->objfile_obstack); } + /* Similarly for the producer. */ + if (subfile->producer != NULL) + symtab->producer = obsavestring (subfile->producer, + strlen (subfile->producer), + &objfile->objfile_obstack); + /* All symtabs for the main file and the subfiles share a blockvector, so we need to clear primary for everything but the main file. */ @@ -1021,6 +1030,8 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section) { xfree ((void *) subfile->debugformat); } + if (subfile->producer != NULL) + xfree (subfile->producer); nextsub = subfile->next; xfree ((void *) subfile); @@ -1097,6 +1108,12 @@ record_debugformat (char *format) current_subfile->debugformat = savestring (format, strlen (format)); } +void +record_producer (const char *producer) +{ + current_subfile->producer = savestring (producer, strlen (producer)); +} + /* Merge the first symbol list SRCLIST into the second symbol list TARGETLIST by repeated calls to add_symbol_to_list(). This procedure "frees" each link of SRCLIST by adding it to the diff --git a/gdb/buildsym.h b/gdb/buildsym.h index 8b8ee89d22b..3b4fee68c3a 100644 --- a/gdb/buildsym.h +++ b/gdb/buildsym.h @@ -68,6 +68,7 @@ struct subfile struct linetable *line_vector; int line_vector_length; enum language language; + char *producer; char *debugformat; }; @@ -281,6 +282,8 @@ extern void record_pending_block (struct objfile *objfile, extern void record_debugformat (char *format); +extern void record_producer (const char *producer); + extern void merge_symbol_lists (struct pending **srclist, struct pending **targetlist); diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index 668500d26c9..4301dac5fb5 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -69,6 +69,9 @@ struct dwarf2_cie /* True if a 'z' augmentation existed. */ unsigned char saw_z_augmentation; + /* The version recorded in the CIE. */ + unsigned char version; + struct dwarf2_cie *next; }; @@ -130,6 +133,16 @@ struct dwarf2_frame_state LONGEST data_align; ULONGEST code_align; ULONGEST retaddr_column; + + /* Flags for known producer quirks. */ + + /* The ARM compilers, in DWARF2 mode, assume that DW_CFA_def_cfa + and DW_CFA_def_cfa_offset takes a factored offset. */ + int armcc_cfa_offsets_sf; + + /* The ARM compilers, in DWARF2 or DWARF3 mode, assume that + the CFA is defined as REG - OFFSET rather than REG + OFFSET. */ + int armcc_cfa_offsets_reversed; }; /* Store the length the expression for the CFA in the `cfa_reg' field, @@ -399,6 +412,10 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc)); case DW_CFA_def_cfa: insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg); insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); + + if (fs->armcc_cfa_offsets_sf) + utmp *= fs->data_align; + fs->cfa_offset = utmp; fs->cfa_how = CFA_REG_OFFSET; break; @@ -410,6 +427,10 @@ bad CFI data; mismatched DW_CFA_restore_state at 0x%s"), paddr (fs->pc)); case DW_CFA_def_cfa_offset: insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp); + + if (fs->armcc_cfa_offsets_sf) + utmp *= fs->data_align; + fs->cfa_offset = utmp; /* cfa_how deliberately not set. */ break; @@ -614,6 +635,36 @@ dwarf2_frame_signal_frame_p (struct gdbarch *gdbarch, return 0; return ops->signal_frame_p (gdbarch, next_frame); } + +static void +dwarf2_frame_find_quirks (struct dwarf2_frame_state *fs, + struct dwarf2_fde *fde) +{ + static const char *arm_idents[] = { + "ARM C Compiler, ADS", + "Thumb C Compiler, ADS", + "ARM C++ Compiler, ADS", + "Thumb C++ Compiler, ADS", + "ARM/Thumb C/C++ Compiler, RVCT" + }; + int i; + + struct symtab *s; + + s = find_pc_symtab (fs->pc); + if (s == NULL || s->producer == NULL) + return; + + for (i = 0; i < ARRAY_SIZE (arm_idents); i++) + if (strncmp (s->producer, arm_idents[i], strlen (arm_idents[i])) == 0) + { + if (fde->cie->version == 1) + fs->armcc_cfa_offsets_sf = 1; + + if (fde->cie->version == 1 || fde->cie->version == 3) + fs->armcc_cfa_offsets_reversed = 1; + } +} struct dwarf2_frame_cache @@ -680,6 +731,9 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache) fs->code_align = fde->cie->code_alignment_factor; fs->retaddr_column = fde->cie->return_address_register; + /* Check for "quirks" - known bugs in producers. */ + dwarf2_frame_find_quirks (fs, fde); + /* First decode all the insns in the CIE. */ execute_cfa_program (fde->cie->initial_instructions, fde->cie->end, next_frame, fs); @@ -696,7 +750,10 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache) { case CFA_REG_OFFSET: cache->cfa = read_reg (next_frame, fs->cfa_reg); - cache->cfa += fs->cfa_offset; + if (fs->armcc_cfa_offsets_reversed) + cache->cfa -= fs->cfa_offset; + else + cache->cfa += fs->cfa_offset; break; case CFA_EXP: @@ -1454,6 +1511,7 @@ decode_frame_entry_1 (struct comp_unit *unit, gdb_byte *start, int eh_frame_p) cie_version = read_1_byte (unit->abfd, buf); if (cie_version != 1 && cie_version != 3) return NULL; + cie->version = cie_version; buf += 1; /* Interpret the interesting bits of the augmentation. */ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 6fe9245f4a2..4bdf5e480cd 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -2779,16 +2779,9 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) attr = dwarf2_attr (die, DW_AT_producer, cu); if (attr) cu->producer = DW_STRING (attr); - + /* We assume that we're processing GCC output. */ processing_gcc_compilation = 2; -#if 0 - /* FIXME:Do something here. */ - if (dip->at_producer != NULL) - { - handle_producer (dip->at_producer); - } -#endif /* The compilation unit may be in a different language or objfile, zero out all remembered fundamental types. */ @@ -2796,6 +2789,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) start_symtab (name, comp_dir, lowpc); record_debugformat ("DWARF 2"); + record_producer (cu->producer); initialize_cu_func_list (cu); diff --git a/gdb/symtab.h b/gdb/symtab.h index 840478ad5db..763d61ee27d 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -846,9 +846,9 @@ struct symtab char *debugformat; - /* String of version information. May be zero. */ + /* String of producer version information. May be zero. */ - char *version; + char *producer; /* Full name of file as found by searching the source path. NULL if not yet known. */ |