This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

FYI: implement new DWARF macro proposal


I'm checking this in.

Jakub recently wrote a spec and implementation for a new representation
of the data currently in .debug_macinfo.  This new representation takes
much less space the old one.  Jakub's code is now in GCC trunk.

This patch implements the new format for gdb.

Built and regtested by the buildbot.  I also tested macscp.exp and
lineinc.exp using the new compiler.

Tom

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.

diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 64325cb..505f576 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -187,6 +187,7 @@ struct dwarf2_per_objfile
   struct dwarf2_section_info line;
   struct dwarf2_section_info loc;
   struct dwarf2_section_info macinfo;
+  struct dwarf2_section_info macro;
   struct dwarf2_section_info str;
   struct dwarf2_section_info ranges;
   struct dwarf2_section_info frame;
@@ -264,6 +265,7 @@ static const struct dwarf2_debug_sections dwarf2_elf_names = {
   { ".debug_line", ".zdebug_line" },
   { ".debug_loc", ".zdebug_loc" },
   { ".debug_macinfo", ".zdebug_macinfo" },
+  { ".debug_macro", ".zdebug_macro" },
   { ".debug_str", ".zdebug_str" },
   { ".debug_ranges", ".zdebug_ranges" },
   { ".debug_types", ".zdebug_types" },
@@ -858,10 +860,11 @@ dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
 }
 
 static void
-dwarf2_macros_too_long_complaint (void)
+dwarf2_macros_too_long_complaint (struct dwarf2_section_info *section)
 {
   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
@@ -1233,7 +1236,9 @@ static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR,
 				 struct dwarf2_cu *);
 
 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 *);
 
@@ -1438,6 +1443,11 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *vnames)
       dwarf2_per_objfile->macinfo.asection = 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))
     {
       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
      header, so we can only read it if we've read the header
      successfully.  */
-  attr = dwarf2_attr (die, DW_AT_macro_info, cu);
+  attr = dwarf2_attr (die, DW_AT_GNU_macros, cu);
   if (attr && cu->line_header)
     {
-      unsigned int macro_offset = DW_UNSND (attr);
+      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);
+      if (attr && cu->line_header)
+	{
+	  unsigned int macro_offset = DW_UNSND (attr);
 
-      dwarf_decode_macros (cu->line_header, macro_offset,
-                           comp_dir, abfd, cu);
+	  dwarf_decode_macros (cu->line_header, macro_offset,
+			       comp_dir, abfd, cu,
+			       &dwarf2_per_objfile->macinfo, 0);
+	}
     }
   do_cleanups (back_to);
 }
@@ -10262,32 +10287,32 @@ read_direct_string (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
 }
 
 static char *
-read_indirect_string (bfd *abfd, gdb_byte *buf,
-		      const struct comp_unit_head *cu_header,
-		      unsigned int *bytes_read_ptr)
+read_indirect_string_at_offset (bfd *abfd, LONGEST str_offset)
 {
-  LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
-
   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));
-      return 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));
-      return NULL;
-    }
+    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 *
+read_indirect_string (bfd *abfd, gdb_byte *buf,
+		      const struct comp_unit_head *cu_header,
+		      unsigned int *bytes_read_ptr)
+{
+  LONGEST str_offset = read_offset (abfd, buf, cu_header, bytes_read_ptr);
+
+  return read_indirect_string_at_offset (abfd, str_offset);
+}
+
 static unsigned long
 read_unsigned_leb128 (bfd *abfd, gdb_byte *buf, unsigned int *bytes_read_ptr)
 {
@@ -14669,117 +14694,205 @@ parse_macro_definition (struct macro_source_file *file, int line,
     dwarf2_macro_malformed_definition_complaint (body);
 }
 
+/* Skip some bytes from BYTES according to the form given in FORM.
+   Returns the new pointer.  */
 
-static void
-dwarf_decode_macros (struct line_header *lh, unsigned int offset,
-                     char *comp_dir, bfd *abfd,
-                     struct dwarf2_cu *cu)
+static gdb_byte *
+skip_form_bytes (bfd *abfd, gdb_byte *bytes,
+		 enum dwarf_form form,
+		 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;
+  unsigned int bytes_read;
 
-  dwarf2_read_section (dwarf2_per_objfile->objfile,
-		       &dwarf2_per_objfile->macinfo);
-  if (dwarf2_per_objfile->macinfo.buffer == NULL)
+  switch (form)
     {
-      complaint (&symfile_complaints, _("missing .debug_macinfo section"));
-      return;
+    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_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;
+
+    default:
+      {
+      complain:
+	complaint (&symfile_complaints,
+		   _("invalid form 0x%x in `%s'"),
+		   form,
+		   section->asection->name);
+	return NULL;
+      }
     }
 
-  /* 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.
+  return bytes;
+}
 
-     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.  */
+/* 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.  */
 
-  mac_ptr = dwarf2_per_objfile->macinfo.buffer + offset;
-  mac_end = dwarf2_per_objfile->macinfo.buffer
-    + dwarf2_per_objfile->macinfo.size;
+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;
 
-  do
+  if (opcode_definitions[opcode] == NULL)
     {
-      /* 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;
-        }
+      complaint (&symfile_complaints,
+		 _("unrecognized DW_MACFINO opcode 0x%x"),
+		 opcode);
+      return NULL;
+    }
 
-      macinfo_type = read_1_byte (abfd, mac_ptr);
-      mac_ptr++;
+  defn = opcode_definitions[opcode];
+  arg = read_unsigned_leb128 (abfd, defn, &bytes_read);
+  defn += bytes_read;
 
-      switch (macinfo_type)
-        {
-          /* A zero macinfo type indicates the end of the macro
-             information.  */
-        case 0:
-	  break;
+  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;
+	}
+    }
 
-	case DW_MACINFO_define:
-	case DW_MACINFO_undef:
-	  /* Only skip the data by MAC_PTR.  */
-	  {
-	    unsigned int bytes_read;
+  return mac_ptr;
+}
 
-	    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;
+/* 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.  */
 
-	case DW_MACINFO_start_file:
-	  {
-	    unsigned int bytes_read;
-	    int line, file;
+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 *));
 
-	    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 (section_is_gnu)
+    {
+      unsigned int version, flags;
 
-	    current_file = macro_start_file (file, line, current_file,
-					     comp_dir, lh, cu->objfile);
-	  }
-	  break;
+      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;
 
-	case DW_MACINFO_end_file:
-	  /* No data to skip by MAC_PTR.  */
-	  break;
+      flags = read_1_byte (abfd, mac_ptr);
+      ++mac_ptr;
+      *offset_size = (flags & 1) ? 8 : 4;
 
-	case DW_MACINFO_vendor_ext:
-	  /* Only skip the data by MAC_PTR.  */
-	  {
-	    unsigned int bytes_read;
+      if ((flags & 2) != 0)
+	/* We don't need the line table offset.  */
+	mac_ptr += *offset_size;
 
-	    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;
+      /* Vendor opcode descriptions.  */
+      if ((flags & 4) != 0)
+	{
+	  unsigned int i, count;
 
-	default:
-	  break;
+	  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;
+	    }
 	}
-    } while (macinfo_type != 0 && current_file == NULL);
+    }
 
-  /* Second pass: Process all entries.
+  return mac_ptr;
+}
 
-     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.  */
+/* 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 = dwarf2_per_objfile->macinfo.buffer + offset;
+  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
@@ -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?  */
       if (mac_ptr >= mac_end)
 	{
-	  dwarf2_macros_too_long_complaint ();
+	  dwarf2_macros_too_long_complaint (section);
 	  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
@@ -14809,29 +14924,45 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 	case 0:
 	  break;
 
-        case DW_MACINFO_define:
-        case DW_MACINFO_undef:
+        case DW_MACRO_GNU_define:
+        case DW_MACRO_GNU_undef:
+	case DW_MACRO_GNU_define_indirect:
+	case DW_MACRO_GNU_undef_indirect:
           {
             unsigned int bytes_read;
             int line;
             char *body;
+	    int is_define;
 
-            line = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-            mac_ptr += bytes_read;
-            body = read_direct_string (abfd, mac_ptr, &bytes_read);
-            mac_ptr += bytes_read;
+	    line = read_unsigned_leb128 (abfd, 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);
+		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)
 	      {
 		/* DWARF violation as no main source is present.  */
 		complaint (&symfile_complaints,
 			   _("debug info with no main source gives macro %s "
 			     "on line %d: %s"),
-			   macinfo_type == DW_MACINFO_define ?
-			     _("definition") :
-			       macinfo_type == DW_MACINFO_undef ?
-				 _("undefinition") :
-				 _("something-or-other"), line, body);
+			   is_define ? _("definition") : _("undefinition"),
+			   line, body);
 		break;
 	      }
 	    if ((line == 0 && !at_commandline)
@@ -14839,21 +14970,21 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 	      complaint (&symfile_complaints,
 			 _("debug info gives %s macro %s with %s line %d: %s"),
 			 at_commandline ? _("command-line") : _("in-file"),
-			 macinfo_type == DW_MACINFO_define ?
-			   _("definition") :
-			     macinfo_type == DW_MACINFO_undef ?
-			       _("undefinition") :
-			       _("something-or-other"),
+			 is_define ? _("definition") : _("undefinition"),
 			 line == 0 ? _("zero") : _("non-zero"), line, body);
 
-	    if (macinfo_type == DW_MACINFO_define)
+	    if (is_define)
 	      parse_macro_definition (current_file, line, body);
-	    else if (macinfo_type == DW_MACINFO_undef)
-	      macro_undef (current_file, line, body);
+	    else
+	      {
+		gdb_assert (macinfo_type == DW_MACRO_GNU_undef
+			    || macinfo_type == DW_MACRO_GNU_undef_indirect);
+		macro_undef (current_file, line, body);
+	      }
           }
           break;
 
-        case DW_MACINFO_start_file:
+        case DW_MACRO_GNU_start_file:
           {
             unsigned int bytes_read;
             int line, file;
@@ -14873,17 +15004,18 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
 
 	    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;
 	      }
 	    else
 	      current_file = macro_start_file (file, line,
 					       current_file, comp_dir,
-					       lh, cu->objfile);
+					       lh, objfile);
           }
           break;
 
-        case DW_MACINFO_end_file:
+        case DW_MACRO_GNU_end_file:
           if (! current_file)
 	    complaint (&symfile_complaints,
 		       _("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;
               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
                      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?  */
                   if (mac_ptr >= mac_end)
                     {
-		      dwarf2_macros_too_long_complaint ();
+		      dwarf2_macros_too_long_complaint (section);
                       return;
                     }
 
@@ -14920,23 +15052,199 @@ dwarf_decode_macros (struct line_header *lh, unsigned int offset,
             }
           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:
-          {
-            unsigned int bytes_read;
-            int constant;
+	  if (!section_is_gnu)
+	    {
+	      unsigned int bytes_read;
+	      int constant;
 
-            constant = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
-            mac_ptr += bytes_read;
-            read_direct_string (abfd, mac_ptr, &bytes_read);
-            mac_ptr += bytes_read;
+	      constant = 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;
+	      /* 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;
         }
     } 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*
    if so return true else false.  */
 static int
@@ -15663,6 +15971,7 @@ dwarf2_per_objfile_free (struct objfile *objfile, void *d)
   munmap_section_buffer (&data->line);
   munmap_section_buffer (&data->loc);
   munmap_section_buffer (&data->macinfo);
+  munmap_section_buffer (&data->macro);
   munmap_section_buffer (&data->str);
   munmap_section_buffer (&data->ranges);
   munmap_section_buffer (&data->frame);
diff --git a/gdb/symfile.h b/gdb/symfile.h
index cc65a14..eb5beaa 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -582,6 +582,7 @@ struct dwarf2_debug_sections {
   struct dwarf2_section_names line;
   struct dwarf2_section_names loc;
   struct dwarf2_section_names macinfo;
+  struct dwarf2_section_names macro;
   struct dwarf2_section_names str;
   struct dwarf2_section_names ranges;
   struct dwarf2_section_names types;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]