From 303b6f5dea757484ac8074bee1b4d5f7c897a997 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Thu, 4 Jan 2007 20:26:42 +0000 Subject: [PATCH] * buildsym.c (start_subfile): Handle producer. (record_producer): New function. * buildsym.h (struct subfile): Include producer. (record_producer): New prototype. * dwarf2-frame.c (struct dwarf2_cie): Add version and augmentation. (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. Record the augmentation. Skip armcc augmentations. * dwarf2read.c (read_file_scope): Save the producer. * symtab.h (struct symtab): Rename unused version member to producer. --- gdb/ChangeLog | 28 ++++++++++------- gdb/buildsym.c | 17 ++++++++++ gdb/buildsym.h | 3 ++ gdb/dwarf2-frame.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++-- gdb/dwarf2read.c | 10 ++---- gdb/symtab.h | 4 +-- gdb/testsuite/ChangeLog | 14 +++++++++ 7 files changed, 135 insertions(+), 24 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ed80928..029330a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,16 +1,20 @@ -2007-01-04 Vladimir Prus +2007-01-04 Daniel Jacobowitz - Implement specification of MI tests as comments - in C and C++ sources. - * lib/mi-support.exp (mi_autotest_data): New variable. - (mi_autotest_source): New variable. - (count_newlines, mi_prepare_inline_tests) - (mi_get_inline_test, mi_continue_to_line) - (mi_run_inline_test, mi_tbreak) - (mi_send_resuming_command, mi_wait_for_stop): New functions. - * gdb.mi/mi-var-cp.exp: Move most content to the C file. - Run inline tests. - * gdb.mi/mi-var-cp.cc: Define tests here. + * buildsym.c (start_subfile): Handle producer. + (record_producer): New function. + * buildsym.h (struct subfile): Include producer. + (record_producer): New prototype. + * dwarf2-frame.c (struct dwarf2_cie): Add version and augmentation. + (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. Record the + augmentation. Skip armcc augmentations. + * dwarf2read.c (read_file_scope): Save the producer. + * symtab.h (struct symtab): Rename unused version member to + producer. 2007-01-04 Daniel Jacobowitz diff --git a/gdb/buildsym.c b/gdb/buildsym.c index 2e946b9..ab6fff3 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -596,6 +596,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. */ @@ -1004,6 +1007,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. */ @@ -1026,6 +1035,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); @@ -1102,6 +1113,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 8b8ee89..3b4fee6 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 861e19d..2f3751b 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -64,6 +64,9 @@ struct dwarf2_cie gdb_byte *initial_instructions; gdb_byte *end; + /* Saved augmentation, in case it's needed later. */ + char *augmentation; + /* Encoding of addresses. */ gdb_byte encoding; @@ -73,6 +76,9 @@ struct dwarf2_cie /* True if an 'S' augmentation existed. */ unsigned char signal_frame; + /* The version recorded in the CIE. */ + unsigned char version; + struct dwarf2_cie *next; }; @@ -138,6 +144,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, may 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, @@ -430,6 +446,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; @@ -444,6 +464,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; @@ -715,6 +739,49 @@ dwarf2_frame_eh_frame_regnum (struct gdbarch *gdbarch, int regnum) return regnum; return ops->eh_frame_regnum (gdbarch, regnum); } + +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) + fs->armcc_cfa_offsets_reversed = 1; + + /* The reversed offset problem is present in some compilers + using DWARF3, but it was eventually fixed. Check the ARM + defined augmentations, which are in the format "armcc" followed + by a list of one-character options. The "+" option means + this problem is fixed (no quirk needed). If the armcc + augmentation is missing, the quirk is needed. */ + if (fde->cie->version == 3 + && (strncmp (fde->cie->augmentation, "armcc", 5) != 0 + || strchr (fde->cie->augmentation + 5, '+') == NULL)) + fs->armcc_cfa_offsets_reversed = 1; + + return; + } +} struct dwarf2_frame_cache @@ -781,6 +848,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, fde->eh_frame_p); @@ -798,7 +868,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: @@ -1584,12 +1657,18 @@ 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. */ - augmentation = (char *) buf; + cie->augmentation = augmentation = (char *) buf; buf += (strlen (augmentation) + 1); + /* Ignore armcc augmentations. We only use them for quirks, + and that doesn't happen until later. */ + if (strncmp (augmentation, "armcc", 5) == 0) + augmentation += strlen (augmentation); + /* The GCC 2.x "eh" augmentation has a pointer immediately following the augmentation string, so it must be handled first. */ diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 3dcf436..9059189 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -2803,16 +2803,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. */ @@ -2820,6 +2813,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 4a980c1..1d72c84 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. */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 9b4fe7e..b68951b 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2007-01-04 Vladimir Prus + + Implement specification of MI tests as comments + in C and C++ sources. + * lib/mi-support.exp (mi_autotest_data): New variable. + (mi_autotest_source): New variable. + (count_newlines, mi_prepare_inline_tests) + (mi_get_inline_test, mi_continue_to_line) + (mi_run_inline_test, mi_tbreak) + (mi_send_resuming_command, mi_wait_for_stop): New functions. + * gdb.mi/mi-var-cp.exp: Move most content to the C file. + Run inline tests. + * gdb.mi/mi-var-cp.cc: Define tests here. + 2006-01-04 Joel Brobecker Make this testcase a bit more realistic. The current code -- 2.7.4