-2007-01-04 Vladimir Prus <vladimir@codesourcery.com>
+2007-01-04 Daniel Jacobowitz <dan@codesourcery.com>
- 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 <dan@codesourcery.com>
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. */
&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. */
{
xfree ((void *) subfile->debugformat);
}
+ if (subfile->producer != NULL)
+ xfree (subfile->producer);
nextsub = subfile->next;
xfree ((void *) subfile);
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
gdb_byte *initial_instructions;
gdb_byte *end;
+ /* Saved augmentation, in case it's needed later. */
+ char *augmentation;
+
/* Encoding of addresses. */
gdb_byte encoding;
/* True if an 'S' augmentation existed. */
unsigned char signal_frame;
+ /* The version recorded in the CIE. */
+ unsigned char version;
+
struct dwarf2_cie *next;
};
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,
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;
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;
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;
+ }
+}
\f
struct dwarf2_frame_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);
{
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:
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. */