+
+\f
+/* 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;
+ }
+ }
+}
+
+/* Check if the attribute's form is a DW_FORM_block*
+ if so return true else false. */
+static int
+attr_form_is_block (struct attribute *attr)
+{
+ return (attr == NULL ? 0 :
+ attr->form == DW_FORM_block1
+ || attr->form == DW_FORM_block2
+ || attr->form == DW_FORM_block4
+ || attr->form == DW_FORM_block);
+}