Move code to new file dwarf2/macro.c
authorTom Tromey <tom@tromey.com>
Thu, 26 Mar 2020 15:28:08 +0000 (09:28 -0600)
committerTom Tromey <tom@tromey.com>
Thu, 26 Mar 2020 15:28:15 +0000 (09:28 -0600)
This moves some more code out of dwarf2/read.c, introducing new files
dwarf2/macro.c and dwarf2/macro.h.

gdb/ChangeLog
2020-03-26  Tom Tromey  <tom@tromey.com>

* dwarf2/read.c (dwarf2_macro_malformed_definition_complaint)
(macro_start_file, consume_improper_spaces)
(parse_macro_definition, skip_form_bytes, skip_unknown_opcode)
(dwarf_parse_macro_header, dwarf_decode_macro_bytes)
(dwarf_decode_macros): Move to macro.c.
* dwarf2/macro.c: New file.
* dwarf2/macro.h: New file.
* Makefile.in (COMMON_SFILES): Add dwarf2/macro.c.

gdb/ChangeLog
gdb/Makefile.in
gdb/dwarf2/macro.c [new file with mode: 0644]
gdb/dwarf2/macro.h [new file with mode: 0644]
gdb/dwarf2/read.c

index 15e65eb2e02bc70eed6d36c64f7fe6791570b229..70b58f22455c948f3c2f642c07442f0792582507 100644 (file)
@@ -1,3 +1,14 @@
+2020-03-26  Tom Tromey  <tom@tromey.com>
+
+       * dwarf2/read.c (dwarf2_macro_malformed_definition_complaint)
+       (macro_start_file, consume_improper_spaces)
+       (parse_macro_definition, skip_form_bytes, skip_unknown_opcode)
+       (dwarf_parse_macro_header, dwarf_decode_macro_bytes)
+       (dwarf_decode_macros): Move to macro.c.
+       * dwarf2/macro.c: New file.
+       * dwarf2/macro.h: New file.
+       * Makefile.in (COMMON_SFILES): Add dwarf2/macro.c.
+
 2020-03-26  Tom Tromey  <tom@tromey.com>
 
        * dwarf2/section.h (struct dwarf2_section_info) <read_string>: New
index c9450ce7b52ce688b43d572aac5dd62a5dcef91d..f66affd3e5fe0015f0e41c78272aa3f2f4e80ada 100644 (file)
@@ -1013,6 +1013,7 @@ COMMON_SFILES = \
        dwarf2/leb.c \
        dwarf2/line-header.c \
        dwarf2/loc.c \
+       dwarf2/macro.c \
        dwarf2/read.c \
        dwarf2/section.c \
        eval.c \
diff --git a/gdb/dwarf2/macro.c b/gdb/dwarf2/macro.c
new file mode 100644 (file)
index 0000000..1f1cca8
--- /dev/null
@@ -0,0 +1,867 @@
+/* Read DWARF macro information
+
+   Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+   Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
+   Inc.  with support from Florida State University (under contract
+   with the Ada Joint Program Office), and Silicon Graphics, Inc.
+   Initial contribution by Brent Benson, Harris Computer Systems, Inc.,
+   based on Fred Fish's (Cygnus Support) implementation of DWARF 1
+   support.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "dwarf2/read.h"
+#include "dwarf2/leb.h"
+#include "dwarf2/expr.h"
+#include "dwarf2/line-header.h"
+#include "dwarf2/section.h"
+#include "dwarf2/macro.h"
+#include "dwarf2/dwz.h"
+#include "buildsym.h"
+#include "macrotab.h"
+#include "complaints.h"
+
+static void
+dwarf2_macro_malformed_definition_complaint (const char *arg1)
+{
+  complaint (_("macro debug info contains a "
+              "malformed macro definition:\n`%s'"),
+            arg1);
+}
+
+static struct macro_source_file *
+macro_start_file (buildsym_compunit *builder,
+                 int file, int line,
+                  struct macro_source_file *current_file,
+                  struct line_header *lh)
+{
+  /* File name relative to the compilation directory of this source file.  */
+  gdb::unique_xmalloc_ptr<char> file_name = lh->file_file_name (file);
+
+  if (! current_file)
+    {
+      /* Note: We don't create a macro table for this compilation unit
+        at all until we actually get a filename.  */
+      struct macro_table *macro_table = builder->get_macro_table ();
+
+      /* 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 (macro_table, file_name.get ());
+      macro_define_special (macro_table);
+    }
+  else
+    current_file = macro_include (current_file, line, file_name.get ());
+
+  return current_file;
+}
+
+static const char *
+consume_improper_spaces (const char *p, const char *body)
+{
+  if (*p == ' ')
+    {
+      complaint (_("macro definition contains spaces "
+                  "in formal argument list:\n`%s'"),
+                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;
+      std::string name (body, name_len);
+      const char *replacement;
+
+      if (*p == ' ')
+        replacement = body + name_len + 1;
+      else
+        {
+         dwarf2_macro_malformed_definition_complaint (body);
+          replacement = body + name_len;
+        }
+
+      macro_define_object (file, line, name.c_str (), replacement);
+    }
+  else if (*p == '(')
+    {
+      /* It's a function-like macro.  */
+      std::string name (body, p - body);
+      int argc = 0;
+      int argv_size = 1;
+      char **argv = XNEWVEC (char *, argv_size);
+
+      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)
+           dwarf2_macro_malformed_definition_complaint (body);
+          else
+            {
+              /* Make sure argv has room for the new argument.  */
+              if (argc >= argv_size)
+                {
+                  argv_size *= 2;
+                  argv = XRESIZEVEC (char *, argv, argv_size);
+                }
+
+              argv[argc++] = savestring (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.c_str (),
+                                   argc, (const char **) argv,
+                                   p + 1);
+          else if (*p == '\0')
+            {
+              /* Complain, but do define it.  */
+             dwarf2_macro_malformed_definition_complaint (body);
+              macro_define_function (file, line, name.c_str (),
+                                     argc, (const char **) argv,
+                                     p);
+            }
+          else
+            /* Just complain.  */
+           dwarf2_macro_malformed_definition_complaint (body);
+        }
+      else
+        /* Just complain.  */
+       dwarf2_macro_malformed_definition_complaint (body);
+
+      {
+        int i;
+
+        for (i = 0; i < argc; i++)
+          xfree (argv[i]);
+      }
+      xfree (argv);
+    }
+  else
+    dwarf2_macro_malformed_definition_complaint (body);
+}
+
+/* Skip some bytes from BYTES according to the form given in FORM.
+   Returns the new pointer.  */
+
+static const gdb_byte *
+skip_form_bytes (bfd *abfd, const gdb_byte *bytes, const gdb_byte *buffer_end,
+                enum dwarf_form form,
+                unsigned int offset_size,
+                struct dwarf2_section_info *section)
+{
+  unsigned int bytes_read;
+
+  switch (form)
+    {
+    case DW_FORM_data1:
+    case DW_FORM_flag:
+      ++bytes;
+      break;
+
+    case DW_FORM_data2:
+      bytes += 2;
+      break;
+
+    case DW_FORM_data4:
+      bytes += 4;
+      break;
+
+    case DW_FORM_data8:
+      bytes += 8;
+      break;
+
+    case DW_FORM_data16:
+      bytes += 16;
+      break;
+
+    case DW_FORM_string:
+      read_direct_string (abfd, bytes, &bytes_read);
+      bytes += bytes_read;
+      break;
+
+    case DW_FORM_sec_offset:
+    case DW_FORM_strp:
+    case DW_FORM_GNU_strp_alt:
+      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_addrx:
+    case DW_FORM_sdata:
+    case DW_FORM_strx:
+    case DW_FORM_udata:
+    case DW_FORM_GNU_addr_index:
+    case DW_FORM_GNU_str_index:
+      bytes = gdb_skip_leb128 (bytes, buffer_end);
+      if (bytes == NULL)
+       {
+         section->overflow_complaint ();
+         return NULL;
+       }
+      break;
+
+    case DW_FORM_implicit_const:
+      break;
+
+    default:
+      {
+       complaint (_("invalid form 0x%x in `%s'"),
+                  form, section->get_name ());
+       return NULL;
+      }
+    }
+
+  return bytes;
+}
+
+/* A helper for dwarf_decode_macros that handles skipping an unknown
+   opcode.  Returns an updated pointer to the macro data buffer; or,
+   on error, issues a complaint and returns NULL.  */
+
+static const gdb_byte *
+skip_unknown_opcode (unsigned int opcode,
+                    const gdb_byte **opcode_definitions,
+                    const gdb_byte *mac_ptr, const gdb_byte *mac_end,
+                    bfd *abfd,
+                    unsigned int offset_size,
+                    struct dwarf2_section_info *section)
+{
+  unsigned int bytes_read, i;
+  unsigned long arg;
+  const gdb_byte *defn;
+
+  if (opcode_definitions[opcode] == NULL)
+    {
+      complaint (_("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, mac_end,
+                                (enum dwarf_form) 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 const gdb_byte *
+dwarf_parse_macro_header (const gdb_byte **opcode_definitions,
+                         bfd *abfd,
+                         const 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 && version != 5)
+       {
+         complaint (_("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_MACRO_import.  */
+
+static void
+dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                         buildsym_compunit *builder,
+                         bfd *abfd,
+                         const gdb_byte *mac_ptr, const gdb_byte *mac_end,
+                         struct macro_source_file *current_file,
+                         struct line_header *lh,
+                         struct dwarf2_section_info *section,
+                         int section_is_gnu, int section_is_dwz,
+                         unsigned int offset_size,
+                         htab_t include_hash)
+{
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  enum dwarf_macro_record_type macinfo_type;
+  int at_commandline;
+  const 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
+     GDB is still reading the definitions from command line.  First
+     DW_MACINFO_start_file will need to be ignored as it was already executed
+     to create CURRENT_FILE for the main source holding also the command line
+     definitions.  On first met DW_MACINFO_start_file this flag is reset to
+     normally execute all the remaining DW_MACINFO_start_file macinfos.  */
+
+  at_commandline = 1;
+
+  do
+    {
+      /* Do we at least have room for a macinfo type byte?  */
+      if (mac_ptr >= mac_end)
+       {
+         section->overflow_complaint ();
+         break;
+       }
+
+      macinfo_type = (enum dwarf_macro_record_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.  */
+      DIAGNOSTIC_PUSH
+      DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
+      switch (macinfo_type)
+       {
+         /* A zero macinfo type indicates the end of the macro
+            information.  */
+       case 0:
+         break;
+
+        case DW_MACRO_define:
+        case DW_MACRO_undef:
+       case DW_MACRO_define_strp:
+       case DW_MACRO_undef_strp:
+       case DW_MACRO_define_sup:
+       case DW_MACRO_undef_sup:
+          {
+            unsigned int bytes_read;
+            int line;
+            const char *body;
+           int is_define;
+
+           line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+           mac_ptr += bytes_read;
+
+           if (macinfo_type == DW_MACRO_define
+               || macinfo_type == DW_MACRO_undef)
+             {
+               body = read_direct_string (abfd, mac_ptr, &bytes_read);
+               mac_ptr += bytes_read;
+             }
+           else
+             {
+               LONGEST str_offset;
+
+               str_offset = read_offset (abfd, mac_ptr, offset_size);
+               mac_ptr += offset_size;
+
+               if (macinfo_type == DW_MACRO_define_sup
+                   || macinfo_type == DW_MACRO_undef_sup
+                   || section_is_dwz)
+                 {
+                   struct dwz_file *dwz
+                     = dwarf2_get_dwz_file (dwarf2_per_objfile);
+
+                   body = dwz->read_string (objfile, str_offset);
+                 }
+               else
+                 body = (dwarf2_per_objfile->str.read_string
+                         (dwarf2_per_objfile->objfile,
+                          str_offset, "DW_FORM_strp"));
+             }
+
+           is_define = (macinfo_type == DW_MACRO_define
+                        || macinfo_type == DW_MACRO_define_strp
+                        || macinfo_type == DW_MACRO_define_sup);
+            if (! current_file)
+             {
+               /* DWARF violation as no main source is present.  */
+               complaint (_("debug info with no main source gives macro %s "
+                            "on line %d: %s"),
+                          is_define ? _("definition") : _("undefinition"),
+                          line, body);
+               break;
+             }
+           if ((line == 0 && !at_commandline)
+               || (line != 0 && at_commandline))
+             complaint (_("debug info gives %s macro %s with %s line %d: %s"),
+                        at_commandline ? _("command-line") : _("in-file"),
+                        is_define ? _("definition") : _("undefinition"),
+                        line == 0 ? _("zero") : _("non-zero"), line, body);
+
+           if (body == NULL)
+             {
+               /* Fedora's rpm-build's "debugedit" binary
+                  corrupted .debug_macro sections.
+
+                  For more info, see
+                  https://bugzilla.redhat.com/show_bug.cgi?id=1708786 */
+               complaint (_("debug info gives %s invalid macro %s "
+                            "without body (corrupted?) at line %d "
+                            "on file %s"),
+                          at_commandline ? _("command-line") : _("in-file"),
+                          is_define ? _("definition") : _("undefinition"),
+                          line, current_file->filename);
+             }
+           else if (is_define)
+             parse_macro_definition (current_file, line, body);
+           else
+             {
+               gdb_assert (macinfo_type == DW_MACRO_undef
+                           || macinfo_type == DW_MACRO_undef_strp
+                           || macinfo_type == DW_MACRO_undef_sup);
+               macro_undef (current_file, line, body);
+             }
+          }
+          break;
+
+        case DW_MACRO_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;
+
+           if ((line == 0 && !at_commandline)
+               || (line != 0 && at_commandline))
+             complaint (_("debug info gives source %d included "
+                          "from %s at %s line %d"),
+                        file, at_commandline ? _("command-line") : _("file"),
+                        line == 0 ? _("zero") : _("non-zero"), line);
+
+           if (at_commandline)
+             {
+               /* This DW_MACRO_start_file was executed in the
+                  pass one.  */
+               at_commandline = 0;
+             }
+           else
+             current_file = macro_start_file (builder, file, line,
+                                              current_file, lh);
+          }
+          break;
+
+        case DW_MACRO_end_file:
+          if (! current_file)
+           complaint (_("macro debug info has an unmatched "
+                        "`close_file' directive"));
+          else
+            {
+              current_file = current_file->included_by;
+              if (! current_file)
+                {
+                  enum dwarf_macro_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)
+                    {
+                     section->overflow_complaint ();
+                      return;
+                    }
+
+                  /* We don't increment mac_ptr here, so this is just
+                     a look-ahead.  */
+                  next_type
+                   = (enum dwarf_macro_record_type) read_1_byte (abfd,
+                                                                 mac_ptr);
+                  if (next_type != 0)
+                   complaint (_("no terminating 0-type entry for "
+                                "macros in `.debug_macinfo' section"));
+
+                  return;
+                }
+            }
+          break;
+
+       case DW_MACRO_import:
+       case DW_MACRO_import_sup:
+         {
+           LONGEST offset;
+           void **slot;
+           bfd *include_bfd = abfd;
+           struct dwarf2_section_info *include_section = section;
+           const gdb_byte *include_mac_end = mac_end;
+           int is_dwz = section_is_dwz;
+           const gdb_byte *new_mac_ptr;
+
+           offset = read_offset (abfd, mac_ptr, offset_size);
+           mac_ptr += offset_size;
+
+           if (macinfo_type == DW_MACRO_import_sup)
+             {
+               struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+
+               dwz->macro.read (objfile);
+
+               include_section = &dwz->macro;
+               include_bfd = include_section->get_bfd_owner ();
+               include_mac_end = dwz->macro.buffer + dwz->macro.size;
+               is_dwz = 1;
+             }
+
+           new_mac_ptr = include_section->buffer + offset;
+           slot = htab_find_slot (include_hash, new_mac_ptr, INSERT);
+
+           if (*slot != NULL)
+             {
+               /* This has actually happened; see
+                  http://sourceware.org/bugzilla/show_bug.cgi?id=13568.  */
+               complaint (_("recursive DW_MACRO_import in "
+                            ".debug_macro section"));
+             }
+           else
+             {
+               *slot = (void *) new_mac_ptr;
+
+               dwarf_decode_macro_bytes (dwarf2_per_objfile, builder,
+                                         include_bfd, new_mac_ptr,
+                                         include_mac_end, current_file, lh,
+                                         section, section_is_gnu, is_dwz,
+                                         offset_size, include_hash);
+
+               htab_remove_elt (include_hash, (void *) new_mac_ptr);
+             }
+         }
+         break;
+
+        case DW_MACINFO_vendor_ext:
+         if (!section_is_gnu)
+           {
+             unsigned int bytes_read;
+
+             /* This reads the constant, but since we don't recognize
+                any vendor extensions, we ignore it.  */
+             read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+             mac_ptr += bytes_read;
+             read_direct_string (abfd, mac_ptr, &bytes_read);
+             mac_ptr += bytes_read;
+
+             /* We don't recognize any vendor extensions.  */
+             break;
+           }
+         /* FALLTHROUGH */
+
+       default:
+         mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
+                                        mac_ptr, mac_end, abfd, offset_size,
+                                        section);
+         if (mac_ptr == NULL)
+           return;
+         break;
+        }
+      DIAGNOSTIC_POP
+    } while (macinfo_type != 0);
+}
+
+void
+dwarf_decode_macros (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                    buildsym_compunit *builder, dwarf2_section_info *section,
+                    struct line_header *lh, unsigned int offset_size,
+                    unsigned int offset, int section_is_gnu)
+{
+  bfd *abfd;
+  const gdb_byte *mac_ptr, *mac_end;
+  struct macro_source_file *current_file = 0;
+  enum dwarf_macro_record_type macinfo_type;
+  const gdb_byte *opcode_definitions[256];
+  void **slot;
+
+  abfd = section->get_bfd_owner ();
+
+  /* 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 = (enum dwarf_macro_record_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.  */
+      DIAGNOSTIC_PUSH
+      DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
+      switch (macinfo_type)
+        {
+          /* A zero macinfo type indicates the end of the macro
+             information.  */
+        case 0:
+         break;
+
+       case DW_MACRO_define:
+       case DW_MACRO_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_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 (builder, file, line,
+                                            current_file, lh);
+         }
+         break;
+
+       case DW_MACRO_end_file:
+         /* No data to skip by MAC_PTR.  */
+         break;
+
+       case DW_MACRO_define_strp:
+       case DW_MACRO_undef_strp:
+       case DW_MACRO_define_sup:
+       case DW_MACRO_undef_sup:
+         {
+           unsigned int bytes_read;
+
+           read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
+           mac_ptr += bytes_read;
+           mac_ptr += offset_size;
+         }
+         break;
+
+       case DW_MACRO_import:
+       case DW_MACRO_import_sup:
+         /* Note that, according to the spec, a transparent include
+            chain cannot call DW_MACRO_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, mac_end, abfd, offset_size,
+                                        section);
+         if (mac_ptr == NULL)
+           return;
+         break;
+       }
+      DIAGNOSTIC_POP
+    } 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.  */
+
+  htab_up include_hash (htab_create_alloc (1, htab_hash_pointer,
+                                          htab_eq_pointer,
+                                          NULL, xcalloc, xfree));
+  mac_ptr = section->buffer + offset;
+  slot = htab_find_slot (include_hash.get (), mac_ptr, INSERT);
+  *slot = (void *) mac_ptr;
+  dwarf_decode_macro_bytes (dwarf2_per_objfile, builder,
+                           abfd, mac_ptr, mac_end,
+                           current_file, lh, section,
+                           section_is_gnu, 0, offset_size,
+                           include_hash.get ());
+}
diff --git a/gdb/dwarf2/macro.h b/gdb/dwarf2/macro.h
new file mode 100644 (file)
index 0000000..3937c55
--- /dev/null
@@ -0,0 +1,33 @@
+/* DWARF macro support for GDB.
+
+   Copyright (C) 2003-2020 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_DWARF2_MACRO_H
+#define GDB_DWARF2_MACRO_H
+
+struct buildsym_compunit;
+
+extern void dwarf_decode_macros (struct dwarf2_per_objfile *dwarf2_per_objfile,
+                                buildsym_compunit *builder,
+                                dwarf2_section_info *section,
+                                struct line_header *lh,
+                                unsigned int offset_size,
+                                unsigned int offset,
+                                int section_is_gnu);
+
+#endif /* GDB_DWARF2_MACRO_H */
index fab5b94f0a79ce373e59de9979879de3ac7d76ba..29f3aeb7e70d276bddf59de2efd738bbea29b269 100644 (file)
@@ -38,6 +38,7 @@
 #include "dwarf2/leb.h"
 #include "dwarf2/line-header.h"
 #include "dwarf2/dwz.h"
+#include "dwarf2/macro.h"
 #include "bfd.h"
 #include "elf-bfd.h"
 #include "symtab.h"
@@ -48,7 +49,6 @@
 #include "demangle.h"
 #include "gdb-demangle.h"
 #include "filenames.h" /* for DOSish file names */
-#include "macrotab.h"
 #include "language.h"
 #include "complaints.h"
 #include "dwarf2/expr.h"
@@ -1710,14 +1710,6 @@ dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
             arg1, arg2, arg3);
 }
 
-static void
-dwarf2_macro_malformed_definition_complaint (const char *arg1)
-{
-  complaint (_("macro debug info contains a "
-              "malformed macro definition:\n`%s'"),
-            arg1);
-}
-
 static void
 dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2)
 {
@@ -23040,828 +23032,8 @@ dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs)
 }
 
 \f
-/* Macro support.  */
-
-static struct macro_source_file *
-macro_start_file (buildsym_compunit *builder,
-                 int file, int line,
-                  struct macro_source_file *current_file,
-                  struct line_header *lh)
-{
-  /* File name relative to the compilation directory of this source file.  */
-  gdb::unique_xmalloc_ptr<char> file_name = lh->file_file_name (file);
-
-  if (! current_file)
-    {
-      /* Note: We don't create a macro table for this compilation unit
-        at all until we actually get a filename.  */
-      struct macro_table *macro_table = builder->get_macro_table ();
-
-      /* 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 (macro_table, file_name.get ());
-      macro_define_special (macro_table);
-    }
-  else
-    current_file = macro_include (current_file, line, file_name.get ());
-
-  return current_file;
-}
-
-static const char *
-consume_improper_spaces (const char *p, const char *body)
-{
-  if (*p == ' ')
-    {
-      complaint (_("macro definition contains spaces "
-                  "in formal argument list:\n`%s'"),
-                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;
-      std::string name (body, name_len);
-      const char *replacement;
-
-      if (*p == ' ')
-        replacement = body + name_len + 1;
-      else
-        {
-         dwarf2_macro_malformed_definition_complaint (body);
-          replacement = body + name_len;
-        }
-
-      macro_define_object (file, line, name.c_str (), replacement);
-    }
-  else if (*p == '(')
-    {
-      /* It's a function-like macro.  */
-      std::string name (body, p - body);
-      int argc = 0;
-      int argv_size = 1;
-      char **argv = XNEWVEC (char *, argv_size);
-
-      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)
-           dwarf2_macro_malformed_definition_complaint (body);
-          else
-            {
-              /* Make sure argv has room for the new argument.  */
-              if (argc >= argv_size)
-                {
-                  argv_size *= 2;
-                  argv = XRESIZEVEC (char *, argv, argv_size);
-                }
-
-              argv[argc++] = savestring (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.c_str (),
-                                   argc, (const char **) argv,
-                                   p + 1);
-          else if (*p == '\0')
-            {
-              /* Complain, but do define it.  */
-             dwarf2_macro_malformed_definition_complaint (body);
-              macro_define_function (file, line, name.c_str (),
-                                     argc, (const char **) argv,
-                                     p);
-            }
-          else
-            /* Just complain.  */
-           dwarf2_macro_malformed_definition_complaint (body);
-        }
-      else
-        /* Just complain.  */
-       dwarf2_macro_malformed_definition_complaint (body);
-
-      {
-        int i;
-
-        for (i = 0; i < argc; i++)
-          xfree (argv[i]);
-      }
-      xfree (argv);
-    }
-  else
-    dwarf2_macro_malformed_definition_complaint (body);
-}
-
-/* Skip some bytes from BYTES according to the form given in FORM.
-   Returns the new pointer.  */
-
-static const gdb_byte *
-skip_form_bytes (bfd *abfd, const gdb_byte *bytes, const gdb_byte *buffer_end,
-                enum dwarf_form form,
-                unsigned int offset_size,
-                struct dwarf2_section_info *section)
-{
-  unsigned int bytes_read;
-
-  switch (form)
-    {
-    case DW_FORM_data1:
-    case DW_FORM_flag:
-      ++bytes;
-      break;
-
-    case DW_FORM_data2:
-      bytes += 2;
-      break;
-
-    case DW_FORM_data4:
-      bytes += 4;
-      break;
-
-    case DW_FORM_data8:
-      bytes += 8;
-      break;
-
-    case DW_FORM_data16:
-      bytes += 16;
-      break;
-
-    case DW_FORM_string:
-      read_direct_string (abfd, bytes, &bytes_read);
-      bytes += bytes_read;
-      break;
-
-    case DW_FORM_sec_offset:
-    case DW_FORM_strp:
-    case DW_FORM_GNU_strp_alt:
-      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_addrx:
-    case DW_FORM_sdata:
-    case DW_FORM_strx:
-    case DW_FORM_udata:
-    case DW_FORM_GNU_addr_index:
-    case DW_FORM_GNU_str_index:
-      bytes = gdb_skip_leb128 (bytes, buffer_end);
-      if (bytes == NULL)
-       {
-         section->overflow_complaint ();
-         return NULL;
-       }
-      break;
-
-    case DW_FORM_implicit_const:
-      break;
-
-    default:
-      {
-       complaint (_("invalid form 0x%x in `%s'"),
-                  form, section->get_name ());
-       return NULL;
-      }
-    }
-
-  return bytes;
-}
-
-/* A helper for dwarf_decode_macros that handles skipping an unknown
-   opcode.  Returns an updated pointer to the macro data buffer; or,
-   on error, issues a complaint and returns NULL.  */
-
-static const gdb_byte *
-skip_unknown_opcode (unsigned int opcode,
-                    const gdb_byte **opcode_definitions,
-                    const gdb_byte *mac_ptr, const gdb_byte *mac_end,
-                    bfd *abfd,
-                    unsigned int offset_size,
-                    struct dwarf2_section_info *section)
-{
-  unsigned int bytes_read, i;
-  unsigned long arg;
-  const gdb_byte *defn;
-
-  if (opcode_definitions[opcode] == NULL)
-    {
-      complaint (_("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, mac_end,
-                                (enum dwarf_form) 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 const gdb_byte *
-dwarf_parse_macro_header (const gdb_byte **opcode_definitions,
-                         bfd *abfd,
-                         const 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 && version != 5)
-       {
-         complaint (_("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_MACRO_import.  */
-
-static void
-dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
-                         buildsym_compunit *builder,
-                         bfd *abfd,
-                         const gdb_byte *mac_ptr, const gdb_byte *mac_end,
-                         struct macro_source_file *current_file,
-                         struct line_header *lh,
-                         struct dwarf2_section_info *section,
-                         int section_is_gnu, int section_is_dwz,
-                         unsigned int offset_size,
-                         htab_t include_hash)
-{
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
-  enum dwarf_macro_record_type macinfo_type;
-  int at_commandline;
-  const 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
-     GDB is still reading the definitions from command line.  First
-     DW_MACINFO_start_file will need to be ignored as it was already executed
-     to create CURRENT_FILE for the main source holding also the command line
-     definitions.  On first met DW_MACINFO_start_file this flag is reset to
-     normally execute all the remaining DW_MACINFO_start_file macinfos.  */
-
-  at_commandline = 1;
-
-  do
-    {
-      /* Do we at least have room for a macinfo type byte?  */
-      if (mac_ptr >= mac_end)
-       {
-         section->overflow_complaint ();
-         break;
-       }
-
-      macinfo_type = (enum dwarf_macro_record_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.  */
-      DIAGNOSTIC_PUSH
-      DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
-      switch (macinfo_type)
-       {
-         /* A zero macinfo type indicates the end of the macro
-            information.  */
-       case 0:
-         break;
-
-        case DW_MACRO_define:
-        case DW_MACRO_undef:
-       case DW_MACRO_define_strp:
-       case DW_MACRO_undef_strp:
-       case DW_MACRO_define_sup:
-       case DW_MACRO_undef_sup:
-          {
-            unsigned int bytes_read;
-            int line;
-            const char *body;
-           int is_define;
-
-           line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-           mac_ptr += bytes_read;
-
-           if (macinfo_type == DW_MACRO_define
-               || macinfo_type == DW_MACRO_undef)
-             {
-               body = read_direct_string (abfd, mac_ptr, &bytes_read);
-               mac_ptr += bytes_read;
-             }
-           else
-             {
-               LONGEST str_offset;
-
-               str_offset = read_offset (abfd, mac_ptr, offset_size);
-               mac_ptr += offset_size;
-
-               if (macinfo_type == DW_MACRO_define_sup
-                   || macinfo_type == DW_MACRO_undef_sup
-                   || section_is_dwz)
-                 {
-                   struct dwz_file *dwz
-                     = dwarf2_get_dwz_file (dwarf2_per_objfile);
-
-                   body = dwz->read_string (objfile, str_offset);
-                 }
-               else
-                 body = read_indirect_string_at_offset (dwarf2_per_objfile,
-                                                        str_offset);
-             }
-
-           is_define = (macinfo_type == DW_MACRO_define
-                        || macinfo_type == DW_MACRO_define_strp
-                        || macinfo_type == DW_MACRO_define_sup);
-            if (! current_file)
-             {
-               /* DWARF violation as no main source is present.  */
-               complaint (_("debug info with no main source gives macro %s "
-                            "on line %d: %s"),
-                          is_define ? _("definition") : _("undefinition"),
-                          line, body);
-               break;
-             }
-           if ((line == 0 && !at_commandline)
-               || (line != 0 && at_commandline))
-             complaint (_("debug info gives %s macro %s with %s line %d: %s"),
-                        at_commandline ? _("command-line") : _("in-file"),
-                        is_define ? _("definition") : _("undefinition"),
-                        line == 0 ? _("zero") : _("non-zero"), line, body);
-
-           if (body == NULL)
-             {
-               /* Fedora's rpm-build's "debugedit" binary
-                  corrupted .debug_macro sections.
-
-                  For more info, see
-                  https://bugzilla.redhat.com/show_bug.cgi?id=1708786 */
-               complaint (_("debug info gives %s invalid macro %s "
-                            "without body (corrupted?) at line %d "
-                            "on file %s"),
-                          at_commandline ? _("command-line") : _("in-file"),
-                          is_define ? _("definition") : _("undefinition"),
-                          line, current_file->filename);
-             }
-           else if (is_define)
-             parse_macro_definition (current_file, line, body);
-           else
-             {
-               gdb_assert (macinfo_type == DW_MACRO_undef
-                           || macinfo_type == DW_MACRO_undef_strp
-                           || macinfo_type == DW_MACRO_undef_sup);
-               macro_undef (current_file, line, body);
-             }
-          }
-          break;
-
-        case DW_MACRO_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;
-
-           if ((line == 0 && !at_commandline)
-               || (line != 0 && at_commandline))
-             complaint (_("debug info gives source %d included "
-                          "from %s at %s line %d"),
-                        file, at_commandline ? _("command-line") : _("file"),
-                        line == 0 ? _("zero") : _("non-zero"), line);
-
-           if (at_commandline)
-             {
-               /* This DW_MACRO_start_file was executed in the
-                  pass one.  */
-               at_commandline = 0;
-             }
-           else
-             current_file = macro_start_file (builder, file, line,
-                                              current_file, lh);
-          }
-          break;
-
-        case DW_MACRO_end_file:
-          if (! current_file)
-           complaint (_("macro debug info has an unmatched "
-                        "`close_file' directive"));
-          else
-            {
-              current_file = current_file->included_by;
-              if (! current_file)
-                {
-                  enum dwarf_macro_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)
-                    {
-                     section->overflow_complaint ();
-                      return;
-                    }
-
-                  /* We don't increment mac_ptr here, so this is just
-                     a look-ahead.  */
-                  next_type
-                   = (enum dwarf_macro_record_type) read_1_byte (abfd,
-                                                                 mac_ptr);
-                  if (next_type != 0)
-                   complaint (_("no terminating 0-type entry for "
-                                "macros in `.debug_macinfo' section"));
-
-                  return;
-                }
-            }
-          break;
-
-       case DW_MACRO_import:
-       case DW_MACRO_import_sup:
-         {
-           LONGEST offset;
-           void **slot;
-           bfd *include_bfd = abfd;
-           struct dwarf2_section_info *include_section = section;
-           const gdb_byte *include_mac_end = mac_end;
-           int is_dwz = section_is_dwz;
-           const gdb_byte *new_mac_ptr;
-
-           offset = read_offset (abfd, mac_ptr, offset_size);
-           mac_ptr += offset_size;
-
-           if (macinfo_type == DW_MACRO_import_sup)
-             {
-               struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
-
-               dwz->macro.read (objfile);
-
-               include_section = &dwz->macro;
-               include_bfd = include_section->get_bfd_owner ();
-               include_mac_end = dwz->macro.buffer + dwz->macro.size;
-               is_dwz = 1;
-             }
 
-           new_mac_ptr = include_section->buffer + offset;
-           slot = htab_find_slot (include_hash, new_mac_ptr, INSERT);
-
-           if (*slot != NULL)
-             {
-               /* This has actually happened; see
-                  http://sourceware.org/bugzilla/show_bug.cgi?id=13568.  */
-               complaint (_("recursive DW_MACRO_import in "
-                            ".debug_macro section"));
-             }
-           else
-             {
-               *slot = (void *) new_mac_ptr;
-
-               dwarf_decode_macro_bytes (dwarf2_per_objfile, builder,
-                                         include_bfd, new_mac_ptr,
-                                         include_mac_end, current_file, lh,
-                                         section, section_is_gnu, is_dwz,
-                                         offset_size, include_hash);
-
-               htab_remove_elt (include_hash, (void *) new_mac_ptr);
-             }
-         }
-         break;
-
-        case DW_MACINFO_vendor_ext:
-         if (!section_is_gnu)
-           {
-             unsigned int bytes_read;
-
-             /* This reads the constant, but since we don't recognize
-                any vendor extensions, we ignore it.  */
-             read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-             mac_ptr += bytes_read;
-             read_direct_string (abfd, mac_ptr, &bytes_read);
-             mac_ptr += bytes_read;
-
-             /* We don't recognize any vendor extensions.  */
-             break;
-           }
-         /* FALLTHROUGH */
-
-       default:
-         mac_ptr = skip_unknown_opcode (macinfo_type, opcode_definitions,
-                                        mac_ptr, mac_end, abfd, offset_size,
-                                        section);
-         if (mac_ptr == NULL)
-           return;
-         break;
-        }
-      DIAGNOSTIC_POP
-    } while (macinfo_type != 0);
-}
-
-static void
-dwarf_decode_macros (struct dwarf2_per_objfile *dwarf2_per_objfile,
-                    buildsym_compunit *builder, dwarf2_section_info *section,
-                    struct line_header *lh, unsigned int offset_size,
-                    unsigned int offset, int section_is_gnu)
-{
-  bfd *abfd;
-  const gdb_byte *mac_ptr, *mac_end;
-  struct macro_source_file *current_file = 0;
-  enum dwarf_macro_record_type macinfo_type;
-  const gdb_byte *opcode_definitions[256];
-  void **slot;
-
-  abfd = section->get_bfd_owner ();
-
-  /* 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 = (enum dwarf_macro_record_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.  */
-      DIAGNOSTIC_PUSH
-      DIAGNOSTIC_IGNORE_SWITCH_DIFFERENT_ENUM_TYPES
-      switch (macinfo_type)
-        {
-          /* A zero macinfo type indicates the end of the macro
-             information.  */
-        case 0:
-         break;
-
-       case DW_MACRO_define:
-       case DW_MACRO_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_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 (builder, file, line,
-                                            current_file, lh);
-         }
-         break;
-
-       case DW_MACRO_end_file:
-         /* No data to skip by MAC_PTR.  */
-         break;
-
-       case DW_MACRO_define_strp:
-       case DW_MACRO_undef_strp:
-       case DW_MACRO_define_sup:
-       case DW_MACRO_undef_sup:
-         {
-           unsigned int bytes_read;
-
-           read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-           mac_ptr += bytes_read;
-           mac_ptr += offset_size;
-         }
-         break;
-
-       case DW_MACRO_import:
-       case DW_MACRO_import_sup:
-         /* Note that, according to the spec, a transparent include
-            chain cannot call DW_MACRO_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, mac_end, abfd, offset_size,
-                                        section);
-         if (mac_ptr == NULL)
-           return;
-         break;
-       }
-      DIAGNOSTIC_POP
-    } 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.  */
-
-  htab_up include_hash (htab_create_alloc (1, htab_hash_pointer,
-                                          htab_eq_pointer,
-                                          NULL, xcalloc, xfree));
-  mac_ptr = section->buffer + offset;
-  slot = htab_find_slot (include_hash.get (), mac_ptr, INSERT);
-  *slot = (void *) mac_ptr;
-  dwarf_decode_macro_bytes (dwarf2_per_objfile, builder,
-                           abfd, mac_ptr, mac_end,
-                           current_file, lh, section,
-                           section_is_gnu, 0, offset_size,
-                           include_hash.get ());
-}
+/* Macro support.  */
 
 /* An overload of dwarf_decode_macros that finds the correct section
    and ensures it is read in before calling the other overload.  */