aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog28
-rw-r--r--gdb/buildsym.c17
-rw-r--r--gdb/buildsym.h3
-rw-r--r--gdb/dwarf2-frame.c83
-rw-r--r--gdb/dwarf2read.c10
-rw-r--r--gdb/symtab.h4
-rw-r--r--gdb/testsuite/ChangeLog14
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 <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>
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 <vladimir@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.
+
2006-01-04 Joel Brobecker <brobecker@adacore.com>
Make this testcase a bit more realistic. The current code