* symfile.h (struct dwarf2_debug_sections) <macro>: New field.
* dwarf2read.c (read_indirect_string_at_offset): New function. (read_indirect_string): Use it. (dwarf_decode_macro_bytes): New function, taken from dwarf_decode_macros. Handle DW_MACRO_GNU_*. (dwarf_decode_macros): Use it. handle DW_MACRO_GNU_*. (dwarf_parse_macro_header, skip_form_bytes, skip_unknown_opcode): New functions. (struct dwarf2_per_objfile) <macro>: New field. (dwarf2_elf_names): Add .debug_macro. (dwarf2_macros_too_long_complaint): Add 'section' argument. (dwarf2_locate_sections): Handle new section. (read_file_scope): Handle DW_AT_GNU_macros. (dwarf2_per_objfile_free): Unmap the .debug_macro section.
This commit is contained in:
parent
177bc8396e
commit
cf2c3c16d9
3 changed files with 483 additions and 156 deletions
|
@ -1,3 +1,20 @@
|
||||||
|
2011-07-26 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
* symfile.h (struct dwarf2_debug_sections) <macro>: New field.
|
||||||
|
* dwarf2read.c (read_indirect_string_at_offset): New function.
|
||||||
|
(read_indirect_string): Use it.
|
||||||
|
(dwarf_decode_macro_bytes): New function, taken from
|
||||||
|
dwarf_decode_macros. Handle DW_MACRO_GNU_*.
|
||||||
|
(dwarf_decode_macros): Use it. handle DW_MACRO_GNU_*.
|
||||||
|
(dwarf_parse_macro_header, skip_form_bytes, skip_unknown_opcode):
|
||||||
|
New functions.
|
||||||
|
(struct dwarf2_per_objfile) <macro>: New field.
|
||||||
|
(dwarf2_elf_names): Add .debug_macro.
|
||||||
|
(dwarf2_macros_too_long_complaint): Add 'section' argument.
|
||||||
|
(dwarf2_locate_sections): Handle new section.
|
||||||
|
(read_file_scope): Handle DW_AT_GNU_macros.
|
||||||
|
(dwarf2_per_objfile_free): Unmap the .debug_macro section.
|
||||||
|
|
||||||
2011-07-26 Paul Pluzhnikov <ppluzhnikov@google.com>
|
2011-07-26 Paul Pluzhnikov <ppluzhnikov@google.com>
|
||||||
|
|
||||||
* NEWS: Mention dcache configuration.
|
* NEWS: Mention dcache configuration.
|
||||||
|
|
583
gdb/dwarf2read.c
583
gdb/dwarf2read.c
|
@ -187,6 +187,7 @@ struct dwarf2_per_objfile
|
||||||
struct dwarf2_section_info line;
|
struct dwarf2_section_info line;
|
||||||
struct dwarf2_section_info loc;
|
struct dwarf2_section_info loc;
|
||||||
struct dwarf2_section_info macinfo;
|
struct dwarf2_section_info macinfo;
|
||||||
|
struct dwarf2_section_info macro;
|
||||||
struct dwarf2_section_info str;
|
struct dwarf2_section_info str;
|
||||||
struct dwarf2_section_info ranges;
|
struct dwarf2_section_info ranges;
|
||||||
struct dwarf2_section_info frame;
|
struct dwarf2_section_info frame;
|
||||||
|
@ -264,6 +265,7 @@ static const struct dwarf2_debug_sections dwarf2_elf_names = {
|
||||||
{ ".debug_line", ".zdebug_line" },
|
{ ".debug_line", ".zdebug_line" },
|
||||||
{ ".debug_loc", ".zdebug_loc" },
|
{ ".debug_loc", ".zdebug_loc" },
|
||||||
{ ".debug_macinfo", ".zdebug_macinfo" },
|
{ ".debug_macinfo", ".zdebug_macinfo" },
|
||||||
|
{ ".debug_macro", ".zdebug_macro" },
|
||||||
{ ".debug_str", ".zdebug_str" },
|
{ ".debug_str", ".zdebug_str" },
|
||||||
{ ".debug_ranges", ".zdebug_ranges" },
|
{ ".debug_ranges", ".zdebug_ranges" },
|
||||||
{ ".debug_types", ".zdebug_types" },
|
{ ".debug_types", ".zdebug_types" },
|
||||||
|
@ -858,10 +860,11 @@ dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dwarf2_macros_too_long_complaint (void)
|
dwarf2_macros_too_long_complaint (struct dwarf2_section_info *section)
|
||||||
{
|
{
|
||||||
complaint (&symfile_complaints,
|
complaint (&symfile_complaints,
|
||||||
_("macro info runs off end of `.debug_macinfo' section"));
|
_("macro info runs off end of `%s' section"),
|
||||||
|
section->asection->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1233,7 +1236,9 @@ static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR,
|
||||||
struct dwarf2_cu *);
|
struct dwarf2_cu *);
|
||||||
|
|
||||||
static void dwarf_decode_macros (struct line_header *, unsigned int,
|
static void dwarf_decode_macros (struct line_header *, unsigned int,
|
||||||
char *, bfd *, struct dwarf2_cu *);
|
char *, bfd *, struct dwarf2_cu *,
|
||||||
|
struct dwarf2_section_info *,
|
||||||
|
int);
|
||||||
|
|
||||||
static int attr_form_is_block (struct attribute *);
|
static int attr_form_is_block (struct attribute *);
|
||||||
|
|
||||||
|
@ -1438,6 +1443,11 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
|
||||||
dwarf2_per_objfile->macinfo.asection = sectp;
|
dwarf2_per_objfile->macinfo.asection = sectp;
|
||||||
dwarf2_per_objfile->macinfo.size = bfd_get_section_size (sectp);
|
dwarf2_per_objfile->macinfo.size = bfd_get_section_size (sectp);
|
||||||
}
|
}
|
||||||
|
else if (section_is_p (sectp->name, &names->macro))
|
||||||
|
{
|
||||||
|
dwarf2_per_objfile->macro.asection = sectp;
|
||||||
|
dwarf2_per_objfile->macro.size = bfd_get_section_size (sectp);
|
||||||
|
}
|
||||||
else if (section_is_p (sectp->name, &names->str))
|
else if (section_is_p (sectp->name, &names->str))
|
||||||
{
|
{
|
||||||
dwarf2_per_objfile->str.asection = sectp;
|
dwarf2_per_objfile->str.asection = sectp;
|
||||||
|
@ -5641,13 +5651,28 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||||
refers to information in the line number info statement program
|
refers to information in the line number info statement program
|
||||||
header, so we can only read it if we've read the header
|
header, so we can only read it if we've read the header
|
||||||
successfully. */
|
successfully. */
|
||||||
|
attr = dwarf2_attr (die, DW_AT_GNU_macros, cu);
|
||||||
|
if (attr && cu->line_header)
|
||||||
|
{
|
||||||
|
if (dwarf2_attr (die, DW_AT_macro_info, cu))
|
||||||
|
complaint (&symfile_complaints,
|
||||||
|
_("CU refers to both DW_AT_GNU_macros and DW_AT_macro_info"));
|
||||||
|
|
||||||
|
dwarf_decode_macros (cu->line_header, DW_UNSND (attr),
|
||||||
|
comp_dir, abfd, cu,
|
||||||
|
&dwarf2_per_objfile->macro, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
attr = dwarf2_attr (die, DW_AT_macro_info, cu);
|
attr = dwarf2_attr (die, DW_AT_macro_info, cu);
|
||||||
if (attr && cu->line_header)
|
if (attr && cu->line_header)
|
||||||
{
|
{
|
||||||
unsigned int macro_offset = DW_UNSND (attr);
|
unsigned int macro_offset = DW_UNSND (attr);
|
||||||
|
|
||||||
dwarf_decode_macros (cu->line_header, macro_offset,
|
dwarf_decode_macros (cu->line_header, macro_offset,
|
||||||
comp_dir, abfd, cu);
|
comp_dir, abfd, cu,
|
||||||
|
&dwarf2_per_objfile->macinfo, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
do_cleanups (back_to);
|
do_cleanups (back_to);
|
||||||
}
|
}
|
||||||
|
@ -10261,6 +10286,23 @@ read_direct_string (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
|
||||||
return (char *) buf;
|
return (char *) buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
read_indirect_string_at_offset (bfd *abfd, LONGEST str_offset)
|
||||||
|
{
|
||||||
|
dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->str);
|
||||||
|
if (dwarf2_per_objfile->str.buffer == NULL)
|
||||||
|
error (_("DW_FORM_strp used without .debug_str section [in module %s]"),
|
||||||
|
bfd_get_filename (abfd));
|
||||||
|
if (str_offset >= dwarf2_per_objfile->str.size)
|
||||||
|
error (_("DW_FORM_strp pointing outside of "
|
||||||
|
".debug_str section [in module %s]"),
|
||||||
|
bfd_get_filename (abfd));
|
||||||
|
gdb_assert (HOST_CHAR_BIT == 8);
|
||||||
|
if (dwarf2_per_objfile->str.buffer[str_offset] == '\0')
|
||||||
|
return NULL;
|
||||||
|
return (char *) (dwarf2_per_objfile->str.buffer + str_offset);
|
||||||
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
read_indirect_string (bfd *abfd, gdb_byte *buf,
|
read_indirect_string (bfd *abfd, gdb_byte *buf,
|
||||||
const struct comp_unit_head *cu_header,
|
const struct comp_unit_head *cu_header,
|
||||||
|
@ -10268,24 +10310,7 @@ read_indirect_string (bfd *abfd, gdb_byte *buf,
|
||||||
{
|
{
|
||||||
LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
|
LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
|
||||||
|
|
||||||
dwarf2_read_section (dwarf2_per_objfile->objfile, &dwarf2_per_objfile->str);
|
return read_indirect_string_at_offset (abfd, str_offset);
|
||||||
if (dwarf2_per_objfile->str.buffer == NULL)
|
|
||||||
{
|
|
||||||
error (_("DW_FORM_strp used without .debug_str section [in module %s]"),
|
|
||||||
bfd_get_filename (abfd));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (str_offset >= dwarf2_per_objfile->str.size)
|
|
||||||
{
|
|
||||||
error (_("DW_FORM_strp pointing outside of "
|
|
||||||
".debug_str section [in module %s]"),
|
|
||||||
bfd_get_filename (abfd));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
gdb_assert (HOST_CHAR_BIT == 8);
|
|
||||||
if (dwarf2_per_objfile->str.buffer[str_offset] == '\0')
|
|
||||||
return NULL;
|
|
||||||
return (char *) (dwarf2_per_objfile->str.buffer + str_offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long
|
static unsigned long
|
||||||
|
@ -14669,117 +14694,205 @@ parse_macro_definition (struct macro_source_file *file, int line,
|
||||||
dwarf2_macro_malformed_definition_complaint (body);
|
dwarf2_macro_malformed_definition_complaint (body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Skip some bytes from BYTES according to the form given in FORM.
|
||||||
|
Returns the new pointer. */
|
||||||
|
|
||||||
static void
|
static gdb_byte *
|
||||||
dwarf_decode_macros (struct line_header *lh, unsigned int offset,
|
skip_form_bytes (bfd *abfd, gdb_byte *bytes,
|
||||||
char *comp_dir, bfd *abfd,
|
enum dwarf_form form,
|
||||||
struct dwarf2_cu *cu)
|
unsigned int offset_size,
|
||||||
|
struct dwarf2_section_info *section)
|
||||||
{
|
{
|
||||||
gdb_byte *mac_ptr, *mac_end;
|
|
||||||
struct macro_source_file *current_file = 0;
|
|
||||||
enum dwarf_macinfo_record_type macinfo_type;
|
|
||||||
int at_commandline;
|
|
||||||
|
|
||||||
dwarf2_read_section (dwarf2_per_objfile->objfile,
|
|
||||||
&dwarf2_per_objfile->macinfo);
|
|
||||||
if (dwarf2_per_objfile->macinfo.buffer == NULL)
|
|
||||||
{
|
|
||||||
complaint (&symfile_complaints, _("missing .debug_macinfo section"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* First pass: Find the name of the base filename.
|
|
||||||
This filename is needed in order to process all macros whose definition
|
|
||||||
(or undefinition) comes from the command line. These macros are defined
|
|
||||||
before the first DW_MACINFO_start_file entry, and yet still need to be
|
|
||||||
associated to the base file.
|
|
||||||
|
|
||||||
To determine the base file name, we scan the macro definitions until we
|
|
||||||
reach the first DW_MACINFO_start_file entry. We then initialize
|
|
||||||
CURRENT_FILE accordingly so that any macro definition found before the
|
|
||||||
first DW_MACINFO_start_file can still be associated to the base file. */
|
|
||||||
|
|
||||||
mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
|
|
||||||
mac_end = dwarf2_per_objfile->macinfo.buffer
|
|
||||||
+ dwarf2_per_objfile->macinfo.size;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* Do we at least have room for a macinfo type byte? */
|
|
||||||
if (mac_ptr >= mac_end)
|
|
||||||
{
|
|
||||||
/* Complaint is printed during the second pass as GDB will probably
|
|
||||||
stop the first pass earlier upon finding
|
|
||||||
DW_MACINFO_start_file. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
macinfo_type = read_1_byte (abfd, mac_ptr);
|
|
||||||
mac_ptr++;
|
|
||||||
|
|
||||||
switch (macinfo_type)
|
|
||||||
{
|
|
||||||
/* A zero macinfo type indicates the end of the macro
|
|
||||||
information. */
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DW_MACINFO_define:
|
|
||||||
case DW_MACINFO_undef:
|
|
||||||
/* Only skip the data by MAC_PTR. */
|
|
||||||
{
|
|
||||||
unsigned int bytes_read;
|
unsigned int bytes_read;
|
||||||
|
|
||||||
read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
|
switch (form)
|
||||||
mac_ptr += bytes_read;
|
|
||||||
read_direct_string (abfd, mac_ptr, &bytes_read);
|
|
||||||
mac_ptr += bytes_read;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DW_MACINFO_start_file:
|
|
||||||
{
|
{
|
||||||
unsigned int bytes_read;
|
case DW_FORM_data1:
|
||||||
int line, file;
|
case DW_FORM_flag:
|
||||||
|
++bytes;
|
||||||
line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
|
|
||||||
mac_ptr += bytes_read;
|
|
||||||
file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
|
|
||||||
mac_ptr += bytes_read;
|
|
||||||
|
|
||||||
current_file = macro_start_file (file, line, current_file,
|
|
||||||
comp_dir, lh, cu->objfile);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_MACINFO_end_file:
|
case DW_FORM_data2:
|
||||||
/* No data to skip by MAC_PTR. */
|
bytes += 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_MACINFO_vendor_ext:
|
case DW_FORM_data4:
|
||||||
/* Only skip the data by MAC_PTR. */
|
bytes += 4;
|
||||||
{
|
break;
|
||||||
unsigned int bytes_read;
|
|
||||||
|
|
||||||
read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
|
case DW_FORM_data8:
|
||||||
mac_ptr += bytes_read;
|
bytes += 8;
|
||||||
read_direct_string (abfd, mac_ptr, &bytes_read);
|
break;
|
||||||
mac_ptr += bytes_read;
|
|
||||||
}
|
case DW_FORM_string:
|
||||||
|
read_direct_string (abfd, bytes, &bytes_read);
|
||||||
|
bytes += bytes_read;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_FORM_sec_offset:
|
||||||
|
case DW_FORM_strp:
|
||||||
|
bytes += offset_size;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_FORM_block:
|
||||||
|
bytes += read_unsigned_leb128 (abfd, bytes, &bytes_read);
|
||||||
|
bytes += bytes_read;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_FORM_block1:
|
||||||
|
bytes += 1 + read_1_byte (abfd, bytes);
|
||||||
|
break;
|
||||||
|
case DW_FORM_block2:
|
||||||
|
bytes += 2 + read_2_bytes (abfd, bytes);
|
||||||
|
break;
|
||||||
|
case DW_FORM_block4:
|
||||||
|
bytes += 4 + read_4_bytes (abfd, bytes);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_FORM_sdata:
|
||||||
|
case DW_FORM_udata:
|
||||||
|
bytes = skip_leb128 (abfd, bytes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
{
|
||||||
|
complain:
|
||||||
|
complaint (&symfile_complaints,
|
||||||
|
_("invalid form 0x%x in `%s'"),
|
||||||
|
form,
|
||||||
|
section->asection->name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (macinfo_type != 0 && current_file == NULL);
|
|
||||||
|
|
||||||
/* Second pass: Process all entries.
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
Use the AT_COMMAND_LINE flag to determine whether we are still processing
|
/* A helper for dwarf_decode_macros that handles skipping an unknown
|
||||||
command-line macro definitions/undefinitions. This flag is unset when we
|
opcode. Returns an updated pointer to the macro data buffer; or,
|
||||||
reach the first DW_MACINFO_start_file entry. */
|
on error, issues a complaint and returns NULL. */
|
||||||
|
|
||||||
mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
|
static gdb_byte *
|
||||||
|
skip_unknown_opcode (unsigned int opcode,
|
||||||
|
gdb_byte **opcode_definitions,
|
||||||
|
gdb_byte *mac_ptr,
|
||||||
|
bfd *abfd,
|
||||||
|
unsigned int offset_size,
|
||||||
|
struct dwarf2_section_info *section)
|
||||||
|
{
|
||||||
|
unsigned int bytes_read, i;
|
||||||
|
unsigned long arg;
|
||||||
|
gdb_byte *defn;
|
||||||
|
|
||||||
|
if (opcode_definitions[opcode] == NULL)
|
||||||
|
{
|
||||||
|
complaint (&symfile_complaints,
|
||||||
|
_("unrecognized DW_MACFINO opcode 0x%x"),
|
||||||
|
opcode);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
defn = opcode_definitions[opcode];
|
||||||
|
arg = read_unsigned_leb128 (abfd, defn, &bytes_read);
|
||||||
|
defn += bytes_read;
|
||||||
|
|
||||||
|
for (i = 0; i < arg; ++i)
|
||||||
|
{
|
||||||
|
mac_ptr = skip_form_bytes (abfd, mac_ptr, defn[i], offset_size, section);
|
||||||
|
if (mac_ptr == NULL)
|
||||||
|
{
|
||||||
|
/* skip_form_bytes already issued the complaint. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mac_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A helper function which parses the header of a macro section.
|
||||||
|
If the macro section is the extended (for now called "GNU") type,
|
||||||
|
then this updates *OFFSET_SIZE. Returns a pointer to just after
|
||||||
|
the header, or issues a complaint and returns NULL on error. */
|
||||||
|
|
||||||
|
static gdb_byte *
|
||||||
|
dwarf_parse_macro_header (gdb_byte **opcode_definitions,
|
||||||
|
bfd *abfd,
|
||||||
|
gdb_byte *mac_ptr,
|
||||||
|
unsigned int *offset_size,
|
||||||
|
int section_is_gnu)
|
||||||
|
{
|
||||||
|
memset (opcode_definitions, 0, 256 * sizeof (gdb_byte *));
|
||||||
|
|
||||||
|
if (section_is_gnu)
|
||||||
|
{
|
||||||
|
unsigned int version, flags;
|
||||||
|
|
||||||
|
version = read_2_bytes (abfd, mac_ptr);
|
||||||
|
if (version != 4)
|
||||||
|
{
|
||||||
|
complaint (&symfile_complaints,
|
||||||
|
_("unrecognized version `%d' in .debug_macro section"),
|
||||||
|
version);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
mac_ptr += 2;
|
||||||
|
|
||||||
|
flags = read_1_byte (abfd, mac_ptr);
|
||||||
|
++mac_ptr;
|
||||||
|
*offset_size = (flags & 1) ? 8 : 4;
|
||||||
|
|
||||||
|
if ((flags & 2) != 0)
|
||||||
|
/* We don't need the line table offset. */
|
||||||
|
mac_ptr += *offset_size;
|
||||||
|
|
||||||
|
/* Vendor opcode descriptions. */
|
||||||
|
if ((flags & 4) != 0)
|
||||||
|
{
|
||||||
|
unsigned int i, count;
|
||||||
|
|
||||||
|
count = read_1_byte (abfd, mac_ptr);
|
||||||
|
++mac_ptr;
|
||||||
|
for (i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
unsigned int opcode, bytes_read;
|
||||||
|
unsigned long arg;
|
||||||
|
|
||||||
|
opcode = read_1_byte (abfd, mac_ptr);
|
||||||
|
++mac_ptr;
|
||||||
|
opcode_definitions[opcode] = mac_ptr;
|
||||||
|
arg = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
|
||||||
|
mac_ptr += bytes_read;
|
||||||
|
mac_ptr += arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mac_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A helper for dwarf_decode_macros that handles the GNU extensions,
|
||||||
|
including DW_GNU_MACINFO_transparent_include. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
dwarf_decode_macro_bytes (bfd *abfd, gdb_byte *mac_ptr, gdb_byte *mac_end,
|
||||||
|
struct macro_source_file *current_file,
|
||||||
|
struct line_header *lh, char *comp_dir,
|
||||||
|
struct dwarf2_section_info *section,
|
||||||
|
int section_is_gnu,
|
||||||
|
unsigned int offset_size,
|
||||||
|
struct objfile *objfile)
|
||||||
|
{
|
||||||
|
enum dwarf_macro_record_type macinfo_type;
|
||||||
|
int at_commandline;
|
||||||
|
gdb_byte *opcode_definitions[256];
|
||||||
|
|
||||||
|
mac_ptr = dwarf_parse_macro_header (opcode_definitions, abfd, mac_ptr,
|
||||||
|
&offset_size, section_is_gnu);
|
||||||
|
if (mac_ptr == NULL)
|
||||||
|
{
|
||||||
|
/* We already issued a complaint. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Determines if GDB is still before first DW_MACINFO_start_file. If true
|
/* Determines if GDB is still before first DW_MACINFO_start_file. If true
|
||||||
GDB is still reading the definitions from command line. First
|
GDB is still reading the definitions from command line. First
|
||||||
|
@ -14795,13 +14908,15 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
|
||||||
/* Do we at least have room for a macinfo type byte? */
|
/* Do we at least have room for a macinfo type byte? */
|
||||||
if (mac_ptr >= mac_end)
|
if (mac_ptr >= mac_end)
|
||||||
{
|
{
|
||||||
dwarf2_macros_too_long_complaint ();
|
dwarf2_macros_too_long_complaint (section);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
macinfo_type = read_1_byte (abfd, mac_ptr);
|
macinfo_type = read_1_byte (abfd, mac_ptr);
|
||||||
mac_ptr++;
|
mac_ptr++;
|
||||||
|
|
||||||
|
/* Note that we rely on the fact that the corresponding GNU and
|
||||||
|
DWARF constants are the same. */
|
||||||
switch (macinfo_type)
|
switch (macinfo_type)
|
||||||
{
|
{
|
||||||
/* A zero macinfo type indicates the end of the macro
|
/* A zero macinfo type indicates the end of the macro
|
||||||
|
@ -14809,29 +14924,45 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_MACINFO_define:
|
case DW_MACRO_GNU_define:
|
||||||
case DW_MACINFO_undef:
|
case DW_MACRO_GNU_undef:
|
||||||
|
case DW_MACRO_GNU_define_indirect:
|
||||||
|
case DW_MACRO_GNU_undef_indirect:
|
||||||
{
|
{
|
||||||
unsigned int bytes_read;
|
unsigned int bytes_read;
|
||||||
int line;
|
int line;
|
||||||
char *body;
|
char *body;
|
||||||
|
int is_define;
|
||||||
|
|
||||||
line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
|
line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
|
||||||
mac_ptr += bytes_read;
|
mac_ptr += bytes_read;
|
||||||
|
|
||||||
|
if (macinfo_type == DW_MACRO_GNU_define
|
||||||
|
|| macinfo_type == DW_MACRO_GNU_undef)
|
||||||
|
{
|
||||||
body = read_direct_string (abfd, mac_ptr, &bytes_read);
|
body = read_direct_string (abfd, mac_ptr, &bytes_read);
|
||||||
mac_ptr += bytes_read;
|
mac_ptr += bytes_read;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LONGEST str_offset;
|
||||||
|
|
||||||
|
str_offset = read_offset_1 (abfd, mac_ptr, offset_size);
|
||||||
|
mac_ptr += offset_size;
|
||||||
|
|
||||||
|
body = read_indirect_string_at_offset (abfd, str_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
is_define = (macinfo_type == DW_MACRO_GNU_define
|
||||||
|
|| macinfo_type == DW_MACRO_GNU_define_indirect);
|
||||||
if (! current_file)
|
if (! current_file)
|
||||||
{
|
{
|
||||||
/* DWARF violation as no main source is present. */
|
/* DWARF violation as no main source is present. */
|
||||||
complaint (&symfile_complaints,
|
complaint (&symfile_complaints,
|
||||||
_("debug info with no main source gives macro %s "
|
_("debug info with no main source gives macro %s "
|
||||||
"on line %d: %s"),
|
"on line %d: %s"),
|
||||||
macinfo_type == DW_MACINFO_define ?
|
is_define ? _("definition") : _("undefinition"),
|
||||||
_("definition") :
|
line, body);
|
||||||
macinfo_type == DW_MACINFO_undef ?
|
|
||||||
_("undefinition") :
|
|
||||||
_("something-or-other"), line, body);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((line == 0 && !at_commandline)
|
if ((line == 0 && !at_commandline)
|
||||||
|
@ -14839,21 +14970,21 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
|
||||||
complaint (&symfile_complaints,
|
complaint (&symfile_complaints,
|
||||||
_("debug info gives %s macro %s with %s line %d: %s"),
|
_("debug info gives %s macro %s with %s line %d: %s"),
|
||||||
at_commandline ? _("command-line") : _("in-file"),
|
at_commandline ? _("command-line") : _("in-file"),
|
||||||
macinfo_type == DW_MACINFO_define ?
|
is_define ? _("definition") : _("undefinition"),
|
||||||
_("definition") :
|
|
||||||
macinfo_type == DW_MACINFO_undef ?
|
|
||||||
_("undefinition") :
|
|
||||||
_("something-or-other"),
|
|
||||||
line == 0 ? _("zero") : _("non-zero"), line, body);
|
line == 0 ? _("zero") : _("non-zero"), line, body);
|
||||||
|
|
||||||
if (macinfo_type == DW_MACINFO_define)
|
if (is_define)
|
||||||
parse_macro_definition (current_file, line, body);
|
parse_macro_definition (current_file, line, body);
|
||||||
else if (macinfo_type == DW_MACINFO_undef)
|
else
|
||||||
|
{
|
||||||
|
gdb_assert (macinfo_type == DW_MACRO_GNU_undef
|
||||||
|
|| macinfo_type == DW_MACRO_GNU_undef_indirect);
|
||||||
macro_undef (current_file, line, body);
|
macro_undef (current_file, line, body);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_MACINFO_start_file:
|
case DW_MACRO_GNU_start_file:
|
||||||
{
|
{
|
||||||
unsigned int bytes_read;
|
unsigned int bytes_read;
|
||||||
int line, file;
|
int line, file;
|
||||||
|
@ -14873,17 +15004,18 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
|
||||||
|
|
||||||
if (at_commandline)
|
if (at_commandline)
|
||||||
{
|
{
|
||||||
/* This DW_MACINFO_start_file was executed in the pass one. */
|
/* This DW_MACRO_GNU_start_file was executed in the
|
||||||
|
pass one. */
|
||||||
at_commandline = 0;
|
at_commandline = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
current_file = macro_start_file (file, line,
|
current_file = macro_start_file (file, line,
|
||||||
current_file, comp_dir,
|
current_file, comp_dir,
|
||||||
lh, cu->objfile);
|
lh, objfile);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_MACINFO_end_file:
|
case DW_MACRO_GNU_end_file:
|
||||||
if (! current_file)
|
if (! current_file)
|
||||||
complaint (&symfile_complaints,
|
complaint (&symfile_complaints,
|
||||||
_("macro debug info has an unmatched "
|
_("macro debug info has an unmatched "
|
||||||
|
@ -14893,7 +15025,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
|
||||||
current_file = current_file->included_by;
|
current_file = current_file->included_by;
|
||||||
if (! current_file)
|
if (! current_file)
|
||||||
{
|
{
|
||||||
enum dwarf_macinfo_record_type next_type;
|
enum dwarf_macro_record_type next_type;
|
||||||
|
|
||||||
/* GCC circa March 2002 doesn't produce the zero
|
/* GCC circa March 2002 doesn't produce the zero
|
||||||
type byte marking the end of the compilation
|
type byte marking the end of the compilation
|
||||||
|
@ -14903,7 +15035,7 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
|
||||||
/* Do we at least have room for a macinfo type byte? */
|
/* Do we at least have room for a macinfo type byte? */
|
||||||
if (mac_ptr >= mac_end)
|
if (mac_ptr >= mac_end)
|
||||||
{
|
{
|
||||||
dwarf2_macros_too_long_complaint ();
|
dwarf2_macros_too_long_complaint (section);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14920,7 +15052,24 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DW_MACRO_GNU_transparent_include:
|
||||||
|
{
|
||||||
|
LONGEST offset;
|
||||||
|
|
||||||
|
offset = read_offset_1 (abfd, mac_ptr, offset_size);
|
||||||
|
mac_ptr += offset_size;
|
||||||
|
|
||||||
|
dwarf_decode_macro_bytes (abfd,
|
||||||
|
section->buffer + offset,
|
||||||
|
mac_end, current_file,
|
||||||
|
lh, comp_dir,
|
||||||
|
section, section_is_gnu,
|
||||||
|
offset_size, objfile);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case DW_MACINFO_vendor_ext:
|
case DW_MACINFO_vendor_ext:
|
||||||
|
if (!section_is_gnu)
|
||||||
{
|
{
|
||||||
unsigned int bytes_read;
|
unsigned int bytes_read;
|
||||||
int constant;
|
int constant;
|
||||||
|
@ -14931,12 +15080,171 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
|
||||||
mac_ptr += bytes_read;
|
mac_ptr += bytes_read;
|
||||||
|
|
||||||
/* We don't recognize any vendor extensions. */
|
/* We don't recognize any vendor extensions. */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
default:
|
||||||
|
mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
|
||||||
|
mac_ptr, abfd, offset_size,
|
||||||
|
section);
|
||||||
|
if (mac_ptr == NULL)
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (macinfo_type != 0);
|
} while (macinfo_type != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dwarf_decode_macros (struct line_header *lh, unsigned int offset,
|
||||||
|
char *comp_dir, bfd *abfd,
|
||||||
|
struct dwarf2_cu *cu,
|
||||||
|
struct dwarf2_section_info *section,
|
||||||
|
int section_is_gnu)
|
||||||
|
{
|
||||||
|
gdb_byte *mac_ptr, *mac_end;
|
||||||
|
struct macro_source_file *current_file = 0;
|
||||||
|
enum dwarf_macro_record_type macinfo_type;
|
||||||
|
unsigned int offset_size = cu->header.offset_size;
|
||||||
|
gdb_byte *opcode_definitions[256];
|
||||||
|
|
||||||
|
dwarf2_read_section (dwarf2_per_objfile->objfile, section);
|
||||||
|
if (section->buffer == NULL)
|
||||||
|
{
|
||||||
|
complaint (&symfile_complaints, _("missing %s section"),
|
||||||
|
section->asection->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First pass: Find the name of the base filename.
|
||||||
|
This filename is needed in order to process all macros whose definition
|
||||||
|
(or undefinition) comes from the command line. These macros are defined
|
||||||
|
before the first DW_MACINFO_start_file entry, and yet still need to be
|
||||||
|
associated to the base file.
|
||||||
|
|
||||||
|
To determine the base file name, we scan the macro definitions until we
|
||||||
|
reach the first DW_MACINFO_start_file entry. We then initialize
|
||||||
|
CURRENT_FILE accordingly so that any macro definition found before the
|
||||||
|
first DW_MACINFO_start_file can still be associated to the base file. */
|
||||||
|
|
||||||
|
mac_ptr = section->buffer + offset;
|
||||||
|
mac_end = section->buffer + section->size;
|
||||||
|
|
||||||
|
mac_ptr = dwarf_parse_macro_header (opcode_definitions, abfd, mac_ptr,
|
||||||
|
&offset_size, section_is_gnu);
|
||||||
|
if (mac_ptr == NULL)
|
||||||
|
{
|
||||||
|
/* We already issued a complaint. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Do we at least have room for a macinfo type byte? */
|
||||||
|
if (mac_ptr >= mac_end)
|
||||||
|
{
|
||||||
|
/* Complaint is printed during the second pass as GDB will probably
|
||||||
|
stop the first pass earlier upon finding
|
||||||
|
DW_MACINFO_start_file. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
macinfo_type = read_1_byte (abfd, mac_ptr);
|
||||||
|
mac_ptr++;
|
||||||
|
|
||||||
|
/* Note that we rely on the fact that the corresponding GNU and
|
||||||
|
DWARF constants are the same. */
|
||||||
|
switch (macinfo_type)
|
||||||
|
{
|
||||||
|
/* A zero macinfo type indicates the end of the macro
|
||||||
|
information. */
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_MACRO_GNU_define:
|
||||||
|
case DW_MACRO_GNU_undef:
|
||||||
|
/* Only skip the data by MAC_PTR. */
|
||||||
|
{
|
||||||
|
unsigned int bytes_read;
|
||||||
|
|
||||||
|
read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
|
||||||
|
mac_ptr += bytes_read;
|
||||||
|
read_direct_string (abfd, mac_ptr, &bytes_read);
|
||||||
|
mac_ptr += bytes_read;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_MACRO_GNU_start_file:
|
||||||
|
{
|
||||||
|
unsigned int bytes_read;
|
||||||
|
int line, file;
|
||||||
|
|
||||||
|
line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
|
||||||
|
mac_ptr += bytes_read;
|
||||||
|
file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
|
||||||
|
mac_ptr += bytes_read;
|
||||||
|
|
||||||
|
current_file = macro_start_file (file, line, current_file,
|
||||||
|
comp_dir, lh, cu->objfile);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_MACRO_GNU_end_file:
|
||||||
|
/* No data to skip by MAC_PTR. */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_MACRO_GNU_define_indirect:
|
||||||
|
case DW_MACRO_GNU_undef_indirect:
|
||||||
|
{
|
||||||
|
unsigned int bytes_read;
|
||||||
|
|
||||||
|
read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
|
||||||
|
mac_ptr += bytes_read;
|
||||||
|
mac_ptr += offset_size;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_MACRO_GNU_transparent_include:
|
||||||
|
/* Note that, according to the spec, a transparent include
|
||||||
|
chain cannot call DW_MACRO_GNU_start_file. So, we can just
|
||||||
|
skip this opcode. */
|
||||||
|
mac_ptr += offset_size;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DW_MACINFO_vendor_ext:
|
||||||
|
/* Only skip the data by MAC_PTR. */
|
||||||
|
if (!section_is_gnu)
|
||||||
|
{
|
||||||
|
unsigned int bytes_read;
|
||||||
|
|
||||||
|
read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
|
||||||
|
mac_ptr += bytes_read;
|
||||||
|
read_direct_string (abfd, mac_ptr, &bytes_read);
|
||||||
|
mac_ptr += bytes_read;
|
||||||
|
}
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
default:
|
||||||
|
mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
|
||||||
|
mac_ptr, abfd, offset_size,
|
||||||
|
section);
|
||||||
|
if (mac_ptr == NULL)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (macinfo_type != 0 && current_file == NULL);
|
||||||
|
|
||||||
|
/* Second pass: Process all entries.
|
||||||
|
|
||||||
|
Use the AT_COMMAND_LINE flag to determine whether we are still processing
|
||||||
|
command-line macro definitions/undefinitions. This flag is unset when we
|
||||||
|
reach the first DW_MACINFO_start_file entry. */
|
||||||
|
|
||||||
|
dwarf_decode_macro_bytes (abfd, section->buffer + offset, mac_end,
|
||||||
|
current_file, lh, comp_dir, section, section_is_gnu,
|
||||||
|
offset_size, cu->objfile);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if the attribute's form is a DW_FORM_block*
|
/* Check if the attribute's form is a DW_FORM_block*
|
||||||
if so return true else false. */
|
if so return true else false. */
|
||||||
static int
|
static int
|
||||||
|
@ -15663,6 +15971,7 @@ dwarf2_per_objfile_free (struct objfile *objfile, void *d)
|
||||||
munmap_section_buffer (&data->line);
|
munmap_section_buffer (&data->line);
|
||||||
munmap_section_buffer (&data->loc);
|
munmap_section_buffer (&data->loc);
|
||||||
munmap_section_buffer (&data->macinfo);
|
munmap_section_buffer (&data->macinfo);
|
||||||
|
munmap_section_buffer (&data->macro);
|
||||||
munmap_section_buffer (&data->str);
|
munmap_section_buffer (&data->str);
|
||||||
munmap_section_buffer (&data->ranges);
|
munmap_section_buffer (&data->ranges);
|
||||||
munmap_section_buffer (&data->frame);
|
munmap_section_buffer (&data->frame);
|
||||||
|
|
|
@ -582,6 +582,7 @@ struct dwarf2_debug_sections {
|
||||||
struct dwarf2_section_names line;
|
struct dwarf2_section_names line;
|
||||||
struct dwarf2_section_names loc;
|
struct dwarf2_section_names loc;
|
||||||
struct dwarf2_section_names macinfo;
|
struct dwarf2_section_names macinfo;
|
||||||
|
struct dwarf2_section_names macro;
|
||||||
struct dwarf2_section_names str;
|
struct dwarf2_section_names str;
|
||||||
struct dwarf2_section_names ranges;
|
struct dwarf2_section_names ranges;
|
||||||
struct dwarf2_section_names types;
|
struct dwarf2_section_names types;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue