Teach the Dwarf 2 reader to read macro information.

* dwarf2read.c: #include "macrotab.h".
(dwarf_macinfo_buffer): New variable.
(struct dwarf2_pinfo): New members: dwarf_macinfo_buffer, and
dwarf_macinfo_size.
(DWARF_MACINFO_BUFFER, DWARF_MACINFO_SIZE): New macros.
(dwarf2_missing_macinfo_section, dwarf2_macros_too_long,
dwarf2_macros_not_terminated, dwarf2_macro_outside_file,
dwarf2_macro_unmatched_end_file, dwarf2_macro_malformed_definition,
dwarf2_macro_spaces_in_definition): New complaints.
(dwarf2_has_info): Initialize dwarf_macinfo_offset.
(dwarf2_build_psymtabs): Read the .dwarf_macinfo section.
(dwarf2_build_psymtabs_hard): Record the buffer and its size in
the partial symbol table.
(psymtab_to_symtab_1): Set the macinfo buffer and size globals
from what's recorded in the partial symbol table.
(read_file_scope): If the compilation unit has a
`DW_AT_macro_info' attribute, read its macro information.
* Makefile.in (dwarf2read.o): Depend on macrotab.h.
This commit is contained in:
Jim Blandy 2002-05-16 21:00:14 +00:00
parent 2f53fe6c16
commit 2e2761252b
3 changed files with 469 additions and 3 deletions

View File

@ -1,3 +1,25 @@
2002-05-16 Jim Blandy <jimb@redhat.com>
Teach the Dwarf 2 reader to read macro information.
* dwarf2read.c: #include "macrotab.h".
(dwarf_macinfo_buffer): New variable.
(struct dwarf2_pinfo): New members: dwarf_macinfo_buffer, and
dwarf_macinfo_size.
(DWARF_MACINFO_BUFFER, DWARF_MACINFO_SIZE): New macros.
(dwarf2_missing_macinfo_section, dwarf2_macros_too_long,
dwarf2_macros_not_terminated, dwarf2_macro_outside_file,
dwarf2_macro_unmatched_end_file, dwarf2_macro_malformed_definition,
dwarf2_macro_spaces_in_definition): New complaints.
(dwarf2_has_info): Initialize dwarf_macinfo_offset.
(dwarf2_build_psymtabs): Read the .dwarf_macinfo section.
(dwarf2_build_psymtabs_hard): Record the buffer and its size in
the partial symbol table.
(psymtab_to_symtab_1): Set the macinfo buffer and size globals
from what's recorded in the partial symbol table.
(read_file_scope): If the compilation unit has a
`DW_AT_macro_info' attribute, read its macro information.
* Makefile.in (dwarf2read.o): Depend on macrotab.h.
2002-05-16 Daniel Jacobowitz <drow@mvista.com>
Fix PR gdb/546

View File

@ -1426,7 +1426,7 @@ dwarfread.o: dwarfread.c $(bfd_h) $(buildsym_h) $(complaints_h) $(defs_h) \
dwarf2read.o: dwarf2read.c $(bfd_h) $(buildsym_h) $(defs_h) \
$(expression_h) $(gdbtypes_h) $(language_h) $(objfiles_h) \
$(symfile_h) $(symtab_h) $(gdb_string_h)
$(symfile_h) $(symtab_h) $(gdb_string_h) $(macrotab_h)
elfread.o: elfread.c $(bfd_h) $(buildsym_h) $(complaints_h) $(defs_h) \
$(gdb_stabs_h) $(objfiles_h) $(symfile_h) $(symtab_h) $(gdb_string_h) \

View File

@ -37,6 +37,7 @@
#include "demangle.h"
#include "expression.h"
#include "filenames.h" /* for DOSish file names */
#include "macrotab.h"
#include "language.h"
#include "complaints.h"
@ -350,6 +351,7 @@ static char *dwarf_info_buffer;
static char *dwarf_abbrev_buffer;
static char *dwarf_line_buffer;
static char *dwarf_str_buffer;
static char *dwarf_macinfo_buffer;
/* A zeroed version of a partial die for initialization purposes. */
static struct partial_die_info zeroed_partial_die;
@ -443,6 +445,15 @@ struct dwarf2_pinfo
/* Size of dwarf string section for the objfile. */
unsigned int dwarf_str_size;
/* Pointer to start of dwarf macro buffer for the objfile. */
char *dwarf_macinfo_buffer;
/* Size of dwarf macinfo section for the objfile. */
unsigned int dwarf_macinfo_size;
};
#define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
@ -454,6 +465,8 @@ struct dwarf2_pinfo
#define DWARF_LINE_SIZE(p) (PST_PRIVATE(p)->dwarf_line_size)
#define DWARF_STR_BUFFER(p) (PST_PRIVATE(p)->dwarf_str_buffer)
#define DWARF_STR_SIZE(p) (PST_PRIVATE(p)->dwarf_str_size)
#define DWARF_MACINFO_BUFFER(p) (PST_PRIVATE(p)->dwarf_macinfo_buffer)
#define DWARF_MACINFO_SIZE(p) (PST_PRIVATE(p)->dwarf_macinfo_size)
/* Maintain an array of referenced fundamental types for the current
compilation unit being read. For DWARF version 1, we have to construct
@ -617,6 +630,34 @@ static struct complaint dwarf2_line_header_too_long =
{
"line number info header doesn't fit in `.debug_line' section", 0, 0
};
static struct complaint dwarf2_missing_macinfo_section =
{
"missing .debug_macinfo section", 0, 0
};
static struct complaint dwarf2_macros_too_long =
{
"macro info runs off end of `.debug_macinfo' section", 0, 0
};
static struct complaint dwarf2_macros_not_terminated =
{
"no terminating 0-type entry for macros in `.debug_macinfo' section", 0, 0
};
static struct complaint dwarf2_macro_outside_file =
{
"debug info gives macro %s outside of any file: %s", 0, 0
};
static struct complaint dwarf2_macro_unmatched_end_file =
{
"macro debug info has an unmatched `close_file' directive", 0, 0
};
static struct complaint dwarf2_macro_malformed_definition =
{
"macro debug info contains a malformed macro definition:\n`%s'", 0, 0
};
static struct complaint dwarf2_macro_spaces_in_definition =
{
"macro definition contains spaces in formal argument list:\n`%s'", 0, 0
};
/* local function prototypes */
@ -862,15 +903,23 @@ static void initialize_cu_func_list (void);
static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR);
static void dwarf_decode_macros (struct line_header *, unsigned int,
char *, bfd *, const struct comp_unit_head *,
struct objfile *);
/* Try to locate the sections we need for DWARF 2 debugging
information and return true if we have enough to do something. */
int
dwarf2_has_info (bfd *abfd)
{
dwarf_info_offset = dwarf_abbrev_offset = dwarf_line_offset = 0;
dwarf_info_offset = 0;
dwarf_abbrev_offset = 0;
dwarf_line_offset = 0;
dwarf_str_offset = 0;
dwarf_frame_offset = dwarf_eh_frame_offset = 0;
dwarf_macinfo_offset = 0;
dwarf_frame_offset = 0;
dwarf_eh_frame_offset = 0;
bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
if (dwarf_info_offset && dwarf_abbrev_offset)
{
@ -966,6 +1015,13 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
else
dwarf_str_buffer = NULL;
if (dwarf_macinfo_offset)
dwarf_macinfo_buffer = dwarf2_read_section (objfile,
dwarf_macinfo_offset,
dwarf_macinfo_size);
else
dwarf_macinfo_buffer = NULL;
if (mainline
|| (objfile->global_psymbols.size == 0
&& objfile->static_psymbols.size == 0))
@ -1174,6 +1230,8 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
DWARF_LINE_SIZE (pst) = dwarf_line_size;
DWARF_STR_BUFFER (pst) = dwarf_str_buffer;
DWARF_STR_SIZE (pst) = dwarf_str_size;
DWARF_MACINFO_BUFFER (pst) = dwarf_macinfo_buffer;
DWARF_MACINFO_SIZE (pst) = dwarf_macinfo_size;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
/* Store the function that reads in the rest of the symbol table */
@ -1476,6 +1534,8 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
dwarf_line_size = DWARF_LINE_SIZE (pst);
dwarf_str_buffer = DWARF_STR_BUFFER (pst);
dwarf_str_size = DWARF_STR_SIZE (pst);
dwarf_macinfo_buffer = DWARF_MACINFO_BUFFER (pst);
dwarf_macinfo_size = DWARF_MACINFO_SIZE (pst);
baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
cu_header_offset = offset;
info_ptr = dwarf_info_buffer + offset;
@ -1738,6 +1798,17 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
}
}
/* Decode macro information, if present. Dwarf 2 macro information
refers to information in the line number info statement program
header, so we can only read it if we've read the header
successfully. */
attr = dwarf_attr (die, DW_AT_macro_info);
if (attr)
{
unsigned int macro_offset = DW_UNSND (attr);
dwarf_decode_macros (line_header, macro_offset,
comp_dir, abfd, cu_header, objfile);
}
do_cleanups (back_to);
}
@ -6367,3 +6438,376 @@ dwarf_alloc_die (void)
memset (die, 0, sizeof (struct die_info));
return (die);
}
/* Macro support. */
/* Return the full name of file number I in *LH's file name table.
Use COMP_DIR as the name of the current directory of the
compilation. The result is allocated using xmalloc; the caller is
responsible for freeing it. */
static char *
file_full_name (int file, struct line_header *lh, const char *comp_dir)
{
struct file_entry *fe = &lh->file_names[file - 1];
if (IS_ABSOLUTE_PATH (fe->name))
return xstrdup (fe->name);
else
{
const char *dir;
int dir_len;
char *full_name;
if (fe->dir_index)
dir = lh->include_dirs[fe->dir_index - 1];
else
dir = comp_dir;
if (dir)
{
dir_len = strlen (dir);
full_name = xmalloc (dir_len + 1 + strlen (fe->name) + 1);
strcpy (full_name, dir);
full_name[dir_len] = '/';
strcpy (full_name + dir_len + 1, fe->name);
return full_name;
}
else
return xstrdup (fe->name);
}
}
static struct macro_source_file *
macro_start_file (int file, int line,
struct macro_source_file *current_file,
const char *comp_dir,
struct line_header *lh, struct objfile *objfile)
{
/* The full name of this source file. */
char *full_name = file_full_name (file, lh, comp_dir);
/* We don't create a macro table for this compilation unit
at all until we actually get a filename. */
if (! pending_macros)
pending_macros = new_macro_table (&objfile->symbol_obstack,
&objfile->macro_cache);
if (! current_file)
/* If we have no current file, then this must be the start_file
directive for the compilation unit's main source file. */
current_file = macro_set_main (pending_macros, full_name);
else
current_file = macro_include (current_file, line, full_name);
xfree (full_name);
return current_file;
}
/* Copy the LEN characters at BUF to a xmalloc'ed block of memory,
followed by a null byte. */
static char *
copy_string (const char *buf, int len)
{
char *s = xmalloc (len + 1);
memcpy (s, buf, len);
s[len] = '\0';
return s;
}
static const char *
consume_improper_spaces (const char *p, const char *body)
{
if (*p == ' ')
{
complain (&dwarf2_macro_spaces_in_definition, body);
while (*p == ' ')
p++;
}
return p;
}
static void
parse_macro_definition (struct macro_source_file *file, int line,
const char *body)
{
const char *p;
/* The body string takes one of two forms. For object-like macro
definitions, it should be:
<macro name> " " <definition>
For function-like macro definitions, it should be:
<macro name> "() " <definition>
or
<macro name> "(" <arg name> ( "," <arg name> ) * ") " <definition>
Spaces may appear only where explicitly indicated, and in the
<definition>.
The Dwarf 2 spec says that an object-like macro's name is always
followed by a space, but versions of GCC around March 2002 omit
the space when the macro's definition is the empty string.
The Dwarf 2 spec says that there should be no spaces between the
formal arguments in a function-like macro's formal argument list,
but versions of GCC around March 2002 include spaces after the
commas. */
/* Find the extent of the macro name. The macro name is terminated
by either a space or null character (for an object-like macro) or
an opening paren (for a function-like macro). */
for (p = body; *p; p++)
if (*p == ' ' || *p == '(')
break;
if (*p == ' ' || *p == '\0')
{
/* It's an object-like macro. */
int name_len = p - body;
char *name = copy_string (body, name_len);
const char *replacement;
if (*p == ' ')
replacement = body + name_len + 1;
else
{
complain (&dwarf2_macro_malformed_definition, body);
replacement = body + name_len;
}
macro_define_object (file, line, name, replacement);
xfree (name);
}
else if (*p == '(')
{
/* It's a function-like macro. */
char *name = copy_string (body, p - body);
int argc = 0;
int argv_size = 1;
char **argv = xmalloc (argv_size * sizeof (*argv));
p++;
p = consume_improper_spaces (p, body);
/* Parse the formal argument list. */
while (*p && *p != ')')
{
/* Find the extent of the current argument name. */
const char *arg_start = p;
while (*p && *p != ',' && *p != ')' && *p != ' ')
p++;
if (! *p || p == arg_start)
complain (&dwarf2_macro_malformed_definition,
body);
else
{
/* Make sure argv has room for the new argument. */
if (argc >= argv_size)
{
argv_size *= 2;
argv = xrealloc (argv, argv_size * sizeof (*argv));
}
argv[argc++] = copy_string (arg_start, p - arg_start);
}
p = consume_improper_spaces (p, body);
/* Consume the comma, if present. */
if (*p == ',')
{
p++;
p = consume_improper_spaces (p, body);
}
}
if (*p == ')')
{
p++;
if (*p == ' ')
/* Perfectly formed definition, no complaints. */
macro_define_function (file, line, name,
argc, (const char **) argv,
p + 1);
else if (*p == '\0')
{
/* Complain, but do define it. */
complain (&dwarf2_macro_malformed_definition, body);
macro_define_function (file, line, name,
argc, (const char **) argv,
p);
}
else
/* Just complain. */
complain (&dwarf2_macro_malformed_definition, body);
}
else
/* Just complain. */
complain (&dwarf2_macro_malformed_definition, body);
xfree (name);
{
int i;
for (i = 0; i < argc; i++)
xfree (argv[i]);
}
xfree (argv);
}
else
complain (&dwarf2_macro_malformed_definition, body);
}
static void
dwarf_decode_macros (struct line_header *lh, unsigned int offset,
char *comp_dir, bfd *abfd,
const struct comp_unit_head *cu_header,
struct objfile *objfile)
{
char *mac_ptr, *mac_end;
struct macro_source_file *current_file = 0;
if (dwarf_macinfo_buffer == NULL)
{
complain (&dwarf2_missing_macinfo_section);
return;
}
mac_ptr = dwarf_macinfo_buffer + offset;
mac_end = dwarf_macinfo_buffer + dwarf_macinfo_size;
for (;;)
{
enum dwarf_macinfo_record_type macinfo_type;
/* Do we at least have room for a macinfo type byte? */
if (mac_ptr >= mac_end)
{
complain (&dwarf2_macros_too_long);
return;
}
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:
return;
case DW_MACINFO_define:
case DW_MACINFO_undef:
{
int bytes_read;
int line;
char *body;
line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
mac_ptr += bytes_read;
body = read_string (abfd, mac_ptr, &bytes_read);
mac_ptr += bytes_read;
if (! current_file)
complain (&dwarf2_macro_outside_file,
macinfo_type == DW_MACINFO_define ? "definition" :
macinfo_type == DW_MACINFO_undef ? "undefinition" :
"something-or-other",
body);
else
{
if (macinfo_type == DW_MACINFO_define)
parse_macro_definition (current_file, line, body);
else if (macinfo_type == DW_MACINFO_undef)
macro_undef (current_file, line, body);
}
}
break;
case DW_MACINFO_start_file:
{
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, objfile);
}
break;
case DW_MACINFO_end_file:
if (! current_file)
complain (&dwarf2_macro_unmatched_end_file);
else
{
current_file = current_file->included_by;
if (! current_file)
{
enum dwarf_macinfo_record_type next_type;
/* GCC circa March 2002 doesn't produce the zero
type byte marking the end of the compilation
unit. Complain if it's not there, but exit no
matter what. */
/* Do we at least have room for a macinfo type byte? */
if (mac_ptr >= mac_end)
{
complain (&dwarf2_macros_too_long);
return;
}
/* We don't increment mac_ptr here, so this is just
a look-ahead. */
next_type = read_1_byte (abfd, mac_ptr);
if (next_type != 0)
complain (&dwarf2_macros_not_terminated);
return;
}
}
break;
case DW_MACINFO_vendor_ext:
{
int bytes_read;
int constant;
char *string;
constant = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
mac_ptr += bytes_read;
string = read_string (abfd, mac_ptr, &bytes_read);
mac_ptr += bytes_read;
/* We don't recognize any vendor extensions. */
}
break;
}
}
}