* 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
|
* buildsym.c (start_subfile): Handle producer.
|
||||||
in C and C++ sources.
|
(record_producer): New function.
|
||||||
* lib/mi-support.exp (mi_autotest_data): New variable.
|
* buildsym.h (struct subfile): Include producer.
|
||||||
(mi_autotest_source): New variable.
|
(record_producer): New prototype.
|
||||||
(count_newlines, mi_prepare_inline_tests)
|
* dwarf2-frame.c (struct dwarf2_cie): Add version and augmentation.
|
||||||
(mi_get_inline_test, mi_continue_to_line)
|
(struct dwarf2_frame_state): Add armcc_cfa_offsets_sf and
|
||||||
(mi_run_inline_test, mi_tbreak)
|
armcc_cfa_offsets_reversed.
|
||||||
(mi_send_resuming_command, mi_wait_for_stop): New functions.
|
(execute_cfa_program): Handle armcc_cfa_offsets_sf.
|
||||||
* gdb.mi/mi-var-cp.exp: Move most content to the C file.
|
(dwarf2_frame_find_quirks): New function.
|
||||||
Run inline tests.
|
(dwarf2_frame_cache): Call it. Handle armcc_cfa_offsets_reversed.
|
||||||
* gdb.mi/mi-var-cp.cc: Define tests here.
|
(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>
|
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. */
|
later via a call to record_debugformat. */
|
||||||
subfile->debugformat = NULL;
|
subfile->debugformat = NULL;
|
||||||
|
|
||||||
|
/* Similarly for the producer. */
|
||||||
|
subfile->producer = NULL;
|
||||||
|
|
||||||
/* If the filename of this subfile ends in .C, then change the
|
/* If the filename of this subfile ends in .C, then change the
|
||||||
language of any pending subfiles from C to C++. We also accept
|
language of any pending subfiles from C to C++. We also accept
|
||||||
any other C++ suffixes accepted by deduce_language_from_filename. */
|
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);
|
&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
|
/* All symtabs for the main file and the subfiles share a
|
||||||
blockvector, so we need to clear primary for everything
|
blockvector, so we need to clear primary for everything
|
||||||
but the main file. */
|
but the main file. */
|
||||||
|
@ -1026,6 +1035,8 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
|
||||||
{
|
{
|
||||||
xfree ((void *) subfile->debugformat);
|
xfree ((void *) subfile->debugformat);
|
||||||
}
|
}
|
||||||
|
if (subfile->producer != NULL)
|
||||||
|
xfree (subfile->producer);
|
||||||
|
|
||||||
nextsub = subfile->next;
|
nextsub = subfile->next;
|
||||||
xfree ((void *) subfile);
|
xfree ((void *) subfile);
|
||||||
|
@ -1102,6 +1113,12 @@ record_debugformat (char *format)
|
||||||
current_subfile->debugformat = savestring (format, strlen (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
|
/* Merge the first symbol list SRCLIST into the second symbol list
|
||||||
TARGETLIST by repeated calls to add_symbol_to_list(). This
|
TARGETLIST by repeated calls to add_symbol_to_list(). This
|
||||||
procedure "frees" each link of SRCLIST by adding it to the
|
procedure "frees" each link of SRCLIST by adding it to the
|
||||||
|
|
|
@ -68,6 +68,7 @@ struct subfile
|
||||||
struct linetable *line_vector;
|
struct linetable *line_vector;
|
||||||
int line_vector_length;
|
int line_vector_length;
|
||||||
enum language language;
|
enum language language;
|
||||||
|
char *producer;
|
||||||
char *debugformat;
|
char *debugformat;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -281,6 +282,8 @@ extern void record_pending_block (struct objfile *objfile,
|
||||||
|
|
||||||
extern void record_debugformat (char *format);
|
extern void record_debugformat (char *format);
|
||||||
|
|
||||||
|
extern void record_producer (const char *producer);
|
||||||
|
|
||||||
extern void merge_symbol_lists (struct pending **srclist,
|
extern void merge_symbol_lists (struct pending **srclist,
|
||||||
struct pending **targetlist);
|
struct pending **targetlist);
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,9 @@ struct dwarf2_cie
|
||||||
gdb_byte *initial_instructions;
|
gdb_byte *initial_instructions;
|
||||||
gdb_byte *end;
|
gdb_byte *end;
|
||||||
|
|
||||||
|
/* Saved augmentation, in case it's needed later. */
|
||||||
|
char *augmentation;
|
||||||
|
|
||||||
/* Encoding of addresses. */
|
/* Encoding of addresses. */
|
||||||
gdb_byte encoding;
|
gdb_byte encoding;
|
||||||
|
|
||||||
|
@ -73,6 +76,9 @@ struct dwarf2_cie
|
||||||
/* True if an 'S' augmentation existed. */
|
/* True if an 'S' augmentation existed. */
|
||||||
unsigned char signal_frame;
|
unsigned char signal_frame;
|
||||||
|
|
||||||
|
/* The version recorded in the CIE. */
|
||||||
|
unsigned char version;
|
||||||
|
|
||||||
struct dwarf2_cie *next;
|
struct dwarf2_cie *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -138,6 +144,16 @@ struct dwarf2_frame_state
|
||||||
LONGEST data_align;
|
LONGEST data_align;
|
||||||
ULONGEST code_align;
|
ULONGEST code_align;
|
||||||
ULONGEST retaddr_column;
|
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,
|
/* 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:
|
case DW_CFA_def_cfa:
|
||||||
insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg);
|
insn_ptr = read_uleb128 (insn_ptr, insn_end, &fs->cfa_reg);
|
||||||
insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
|
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_offset = utmp;
|
||||||
fs->cfa_how = CFA_REG_OFFSET;
|
fs->cfa_how = CFA_REG_OFFSET;
|
||||||
break;
|
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:
|
case DW_CFA_def_cfa_offset:
|
||||||
insn_ptr = read_uleb128 (insn_ptr, insn_end, &utmp);
|
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_offset = utmp;
|
||||||
/* cfa_how deliberately not set. */
|
/* cfa_how deliberately not set. */
|
||||||
break;
|
break;
|
||||||
|
@ -715,6 +739,49 @@ dwarf2_frame_eh_frame_regnum (struct gdbarch *gdbarch, int regnum)
|
||||||
return regnum;
|
return regnum;
|
||||||
return ops->eh_frame_regnum (gdbarch, 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
|
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->code_align = fde->cie->code_alignment_factor;
|
||||||
fs->retaddr_column = fde->cie->return_address_register;
|
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. */
|
/* First decode all the insns in the CIE. */
|
||||||
execute_cfa_program (fde->cie->initial_instructions,
|
execute_cfa_program (fde->cie->initial_instructions,
|
||||||
fde->cie->end, next_frame, fs, fde->eh_frame_p);
|
fde->cie->end, next_frame, fs, fde->eh_frame_p);
|
||||||
|
@ -798,6 +868,9 @@ dwarf2_frame_cache (struct frame_info *next_frame, void **this_cache)
|
||||||
{
|
{
|
||||||
case CFA_REG_OFFSET:
|
case CFA_REG_OFFSET:
|
||||||
cache->cfa = read_reg (next_frame, fs->cfa_reg);
|
cache->cfa = read_reg (next_frame, fs->cfa_reg);
|
||||||
|
if (fs->armcc_cfa_offsets_reversed)
|
||||||
|
cache->cfa -= fs->cfa_offset;
|
||||||
|
else
|
||||||
cache->cfa += fs->cfa_offset;
|
cache->cfa += fs->cfa_offset;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -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);
|
cie_version = read_1_byte (unit->abfd, buf);
|
||||||
if (cie_version != 1 && cie_version != 3)
|
if (cie_version != 1 && cie_version != 3)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
cie->version = cie_version;
|
||||||
buf += 1;
|
buf += 1;
|
||||||
|
|
||||||
/* Interpret the interesting bits of the augmentation. */
|
/* Interpret the interesting bits of the augmentation. */
|
||||||
augmentation = (char *) buf;
|
cie->augmentation = augmentation = (char *) buf;
|
||||||
buf += (strlen (augmentation) + 1);
|
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
|
/* The GCC 2.x "eh" augmentation has a pointer immediately
|
||||||
following the augmentation string, so it must be handled
|
following the augmentation string, so it must be handled
|
||||||
first. */
|
first. */
|
||||||
|
|
|
@ -2806,13 +2806,6 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
|
|
||||||
/* We assume that we're processing GCC output. */
|
/* We assume that we're processing GCC output. */
|
||||||
processing_gcc_compilation = 2;
|
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,
|
/* The compilation unit may be in a different language or objfile,
|
||||||
zero out all remembered fundamental types. */
|
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);
|
start_symtab (name, comp_dir, lowpc);
|
||||||
record_debugformat ("DWARF 2");
|
record_debugformat ("DWARF 2");
|
||||||
|
record_producer (cu->producer);
|
||||||
|
|
||||||
initialize_cu_func_list (cu);
|
initialize_cu_func_list (cu);
|
||||||
|
|
||||||
|
|
|
@ -846,9 +846,9 @@ struct symtab
|
||||||
|
|
||||||
char *debugformat;
|
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.
|
/* Full name of file as found by searching the source path.
|
||||||
NULL if not yet known. */
|
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>
|
2006-01-04 Joel Brobecker <brobecker@adacore.com>
|
||||||
|
|
||||||
Make this testcase a bit more realistic. The current code
|
Make this testcase a bit more realistic. The current code
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue