* 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.
This commit is contained in:
parent
2d0720d988
commit
303b6f5dea
7 changed files with 135 additions and 24 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue