From 1bfdfae2ff97e3dc4868864f523d799d2b029d37 Mon Sep 17 00:00:00 2001
From: nitachra <Nitika.Achra@amd.com>
Date: Fri, 1 Oct 2021 01:11:24 +0530
Subject: [PATCH] Fix for the gdb.base/macscp.exp testcase failure with split
 dwarf.

Command used: make check RUNTESTFLAGS='CC_FOR_TARGET="clang -gdwarf-5 -gsplit-dwarf -fdebug-macro"'
			 TESTS="gdb.base/macscp.exp"

Before the patch:
Number of expected passes            234
Number of unexpected failures        65
Number of known failures             40

After the patch:
Number of expected passes            319
Number of unexpected failures        1
Number of known failures             19

Compiler used: clang 12.0.0

Clang is emitting both .debug_line and .debug_line.dwo sections and .debug
_macro.dwo is pointing to the .debug_line.dwo section(file index in the
.debug_macro.dwo is the index in the file_names array of .debug_line.dwo).
However, GDB is reading only .debug_line section. In this patch, I have added
the support for reading .debug_line.dwo section and added m_dwo_include
_dirs and m_dwo_file_names vectors in struct line_header to store the
directories and files respectively.
---
 gdb/dwarf2/line-header.c | 246 ++++++++++++++++++++++++++-------------
 gdb/dwarf2/line-header.h | 105 +++++++++++++----
 gdb/dwarf2/read.c        | 110 ++++++++++++++---
 gdb/macrotab.c           |   4 +-
 4 files changed, 341 insertions(+), 124 deletions(-)

diff --git a/gdb/dwarf2/line-header.c b/gdb/dwarf2/line-header.c
index 938e9fd55d4..621c1c69ae5 100644
--- a/gdb/dwarf2/line-header.c
+++ b/gdb/dwarf2/line-header.c
@@ -26,57 +26,88 @@
 #include "filenames.h"
 
 void
-line_header::add_include_dir (const char *include_dir)
+line_header::add_include_dir (const char *include_dir, bool is_dwo)
 {
   if (dwarf_line_debug >= 2)
     {
       size_t new_size;
-      if (version >= 5)
-	new_size = m_include_dirs.size ();
+      int include_dir_size = is_dwo ? m_dwo_include_dirs.size ():
+			     m_include_dirs.size ();
+      if ((is_dwo && dwo_version >= 5) || (!is_dwo && version >= 5))
+	new_size = include_dir_size;
       else
-	new_size = m_include_dirs.size () + 1;
+	new_size = include_dir_size + 1;
       fprintf_unfiltered (gdb_stdlog, "Adding dir %zu: %s\n",
 			  new_size, include_dir);
     }
-  m_include_dirs.push_back (include_dir);
+
+    if (is_dwo)
+      m_dwo_include_dirs.push_back (include_dir);
+    else
+      m_include_dirs.push_back (include_dir);
 }
 
 void
 line_header::add_file_name (const char *name,
 			    dir_index d_index,
 			    unsigned int mod_time,
-			    unsigned int length)
+			    unsigned int length,
+			    bool is_dwo)
 {
   if (dwarf_line_debug >= 2)
     {
       size_t new_size;
-      if (version >= 5)
-	new_size = file_names_size ();
+      bool file_name_size = is_dwo ? dwo_file_names_size ():
+			     file_names_size ();
+      if ((is_dwo && dwo_version >= 5) || (!is_dwo && version >= 5))
+	new_size = file_name_size;
       else
-	new_size = file_names_size () + 1;
+	new_size = file_name_size + 1;
       fprintf_unfiltered (gdb_stdlog, "Adding file %zu: %s\n",
 			  new_size, name);
     }
-  m_file_names.emplace_back (name, d_index, mod_time, length);
+
+    if (is_dwo)
+      m_dwo_file_names.emplace_back (name, d_index, mod_time, length);
+    else
+      m_file_names.emplace_back (name, d_index, mod_time, length);
 }
 
 gdb::unique_xmalloc_ptr<char>
 line_header::file_file_name (int file) const
 {
   /* Is the file number a valid index into the line header's file name
-     table?  Remember that file numbers start with one, not zero.  */
-  if (is_valid_file_index (file))
+     table?  First check in the .debug_line.dwo file table and then in
+     .debug_line table. Remember that file numbers start with one in
+     DWARFv4 and with zero in DWARFv5.  */
+  if (is_valid_dwo_file_index (file))
     {
-      const file_entry *fe = file_name_at (file);
+      const file_entry *fe = file_name_at (file, true);
 
       if (!IS_ABSOLUTE_PATH (fe->name))
-	{
-	  const char *dir = fe->include_dir (this);
-	  if (dir != NULL)
-	    return gdb::unique_xmalloc_ptr<char> (concat (dir, SLASH_STRING,
-							  fe->name,
-							  (char *) NULL));
-	}
+       {
+	 const char *dir = fe->include_dir (this, true);
+	 if (dir != NULL)
+	   return gdb::unique_xmalloc_ptr<char> (concat (dir, SLASH_STRING,
+							 fe->name,
+							 (char *) NULL));
+       }
+
+      return make_unique_xstrdup (fe->name);
+    }
+  else if (is_valid_file_index (file))
+    {
+      const file_entry *fe = file_name_at (file, false);
+
+      if (!IS_ABSOLUTE_PATH (fe->name))
+       {
+	 const char *dir = fe->include_dir (this, false);
+	 if (dir != NULL)
+	   return gdb::unique_xmalloc_ptr<char> (concat (dir, SLASH_STRING,
+							 fe->name,
+							 (char *) NULL));
+       }
+
       return make_unique_xstrdup (fe->name);
     }
   else
@@ -137,12 +168,13 @@ read_checked_initial_length_and_offset (bfd *abfd, const gdb_byte *buf,
 static void
 read_formatted_entries (dwarf2_per_objfile *per_objfile, bfd *abfd,
 			const gdb_byte **bufp, struct line_header *lh,
-			unsigned int offset_size,
+			unsigned int offset_size, bool is_dwo,
 			void (*callback) (struct line_header *lh,
 					  const char *name,
 					  dir_index d_index,
 					  unsigned int mod_time,
-					  unsigned int length))
+					  unsigned int length,
+					  bool is_dwo_section))
 {
   gdb_byte format_count, formati;
   ULONGEST data_count, datai;
@@ -257,7 +289,7 @@ read_formatted_entries (dwarf2_per_objfile *per_objfile, bfd *abfd,
 	    }
 	}
 
-      callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length);
+      callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length, is_dwo);
     }
 
   *bufp = buf;
@@ -265,11 +297,12 @@ read_formatted_entries (dwarf2_per_objfile *per_objfile, bfd *abfd,
 
 /* See line-header.h.  */
 
-line_header_up
+bool
 dwarf_decode_line_header  (sect_offset sect_off, bool is_dwz,
 			   dwarf2_per_objfile *per_objfile,
 			   struct dwarf2_section_info *section,
-			   const struct comp_unit_head *cu_header)
+			   const struct comp_unit_head *cu_header,
+			   line_header_up& lh, bool is_dwo)
 {
   const gdb_byte *line_ptr;
   unsigned int bytes_read, offset_size;
@@ -283,40 +316,61 @@ dwarf_decode_line_header  (sect_offset sect_off, bool is_dwz,
   if (to_underlying (sect_off) + 4 >= section->size)
     {
       dwarf2_statement_list_fits_in_line_number_section_complaint ();
-      return 0;
+      return false;
     }
 
-  line_header_up lh (new line_header ());
-
   lh->sect_off = sect_off;
   lh->offset_in_dwz = is_dwz;
 
   line_ptr = section->buffer + to_underlying (sect_off);
 
   /* Read in the header.  */
-  lh->total_length =
+  LONGEST total_length =
     read_checked_initial_length_and_offset (abfd, line_ptr, cu_header,
 					    &bytes_read, &offset_size);
-  line_ptr += bytes_read;
 
-  const gdb_byte *start_here = line_ptr;
+  line_ptr += bytes_read;
 
-  if (line_ptr + lh->total_length > (section->buffer + section->size))
+  if (line_ptr + total_length > (section->buffer + section->size))
     {
       dwarf2_statement_list_fits_in_line_number_section_complaint ();
-      return 0;
+      return false;
     }
-  lh->statement_program_end = start_here + lh->total_length;
-  lh->version = read_2_bytes (abfd, line_ptr);
-  line_ptr += 2;
-  if (lh->version > 5)
+
+  if (is_dwo)
     {
-      /* This is a version we don't understand.  The format could have
-	 changed in ways we don't handle properly so just punt.  */
-      complaint (_("unsupported version in .debug_line section"));
-      return NULL;
+      lh->dwo_total_length = total_length;
+      lh->dwo_version = read_2_bytes (abfd, line_ptr);
+
+      if (lh->dwo_version > 5)
+	{
+	  /* This is a version we don't understand.  The format could have
+	     changed in ways we don't handle properly so just punt.  */
+	  complaint (_("unsupported version in .debug_line.dwo section"));
+	  return false;
+	}
+
+      line_ptr += 2;
     }
-  if (lh->version >= 5)
+  else
+    {
+      lh->total_length = total_length;
+      const gdb_byte *start_here = line_ptr;
+      lh->statement_program_end = start_here + lh->total_length;
+      lh->version = read_2_bytes (abfd, line_ptr);
+
+      if (lh->version > 5)
+	{
+	  /* This is a version we don't understand.  The format could have
+	     changed in ways we don't handle properly so just punt.  */
+	  complaint (_("unsupported version in .debug_line section"));
+	  return false;
+	}
+
+      line_ptr += 2;
+    }
+
+  if ((is_dwo && lh->dwo_version >= 5) || (!is_dwo && lh->version >= 5))
     {
       gdb_byte segment_selector_size;
 
@@ -326,71 +380,103 @@ dwarf_decode_line_header  (sect_offset sect_off, bool is_dwz,
 
       segment_selector_size = read_1_byte (abfd, line_ptr);
       line_ptr += 1;
+
       if (segment_selector_size != 0)
 	{
 	  complaint (_("unsupported segment selector size %u "
 		       "in .debug_line section"),
 		     segment_selector_size);
-	  return NULL;
+	  return false;
 	}
     }
-  lh->header_length = read_offset (abfd, line_ptr, offset_size);
+
+  unsigned int header_length = read_offset (abfd, line_ptr, offset_size);
   line_ptr += offset_size;
-  lh->statement_program_start = line_ptr + lh->header_length;
-  lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
-  line_ptr += 1;
-  if (lh->version >= 4)
+
+  if (is_dwo)
     {
-      lh->maximum_ops_per_instruction = read_1_byte (abfd, line_ptr);
+      lh->dwo_header_length = header_length;
+      line_ptr += 1; /* Skip the minimum instruction length.  */
+      if (lh->dwo_version >= 4)
+	line_ptr += 1; /* Skip maximum ops per instruction.  */
+      line_ptr += 1; /* Skip default is stmt.  */
+      line_ptr += 2; /* Skip line base and line range.  */
+
+      /* Read the opcode base.  */
+      lh->dwo_opcode_base = read_1_byte (abfd, line_ptr);
       line_ptr += 1;
+      lh->dwo_standard_opcode_lengths.reset (new unsigned char[lh->dwo_opcode_base]);
+      lh->dwo_standard_opcode_lengths[0] = 1;  /* This should never be used anyway.  */
+
+      for (i = 1; i < lh->dwo_opcode_base; ++i)
+	{
+	  lh->dwo_standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
+	  line_ptr += 1;
+	}
     }
   else
-    lh->maximum_ops_per_instruction = 1;
-
-  if (lh->maximum_ops_per_instruction == 0)
     {
-      lh->maximum_ops_per_instruction = 1;
-      complaint (_("invalid maximum_ops_per_instruction "
-		   "in `.debug_line' section"));
-    }
+      lh->header_length = header_length;
+      lh->statement_program_start = line_ptr + lh->header_length;
+      lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
+      line_ptr += 1;
 
-  lh->default_is_stmt = read_1_byte (abfd, line_ptr);
-  line_ptr += 1;
-  lh->line_base = read_1_signed_byte (abfd, line_ptr);
-  line_ptr += 1;
-  lh->line_range = read_1_byte (abfd, line_ptr);
-  line_ptr += 1;
-  lh->opcode_base = read_1_byte (abfd, line_ptr);
-  line_ptr += 1;
-  lh->standard_opcode_lengths.reset (new unsigned char[lh->opcode_base]);
-
-  lh->standard_opcode_lengths[0] = 1;  /* This should never be used anyway.  */
-  for (i = 1; i < lh->opcode_base; ++i)
-    {
-      lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
+      if (lh->version >= 4)
+	{
+	  lh->maximum_ops_per_instruction = read_1_byte (abfd, line_ptr);
+	  line_ptr += 1;
+	}
+      else
+	{
+	  lh->maximum_ops_per_instruction = 1;
+	}
+
+      if (lh->maximum_ops_per_instruction == 0)
+	{
+	  lh->maximum_ops_per_instruction = 1;
+	  complaint (_("invalid maximum_ops_per_instruction "
+		       "in `.debug_line' section"));
+	}
+
+      lh->default_is_stmt = read_1_byte (abfd, line_ptr);
+      line_ptr += 1;
+      lh->line_base = read_1_signed_byte (abfd, line_ptr);
       line_ptr += 1;
+      lh->line_range = read_1_byte (abfd, line_ptr);
+      line_ptr += 1;
+
+      lh->opcode_base = read_1_byte (abfd, line_ptr);
+      line_ptr += 1;
+      lh->standard_opcode_lengths.reset (new unsigned char[lh->opcode_base]);
+      lh->standard_opcode_lengths[0] = 1;  /* This should never be used anyway.  */
+
+      for (i = 1; i < lh->opcode_base; ++i)
+	{
+	  lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
+	  line_ptr += 1;
+	}
     }
 
-  if (lh->version >= 5)
+  if ((is_dwo && lh->dwo_version >= 5) || (!is_dwo && lh->version >=5))
     {
       /* Read directory table.  */
       read_formatted_entries (per_objfile, abfd, &line_ptr, lh.get (),
-			      offset_size,
+			      offset_size, is_dwo,
 			      [] (struct line_header *header, const char *name,
 				  dir_index d_index, unsigned int mod_time,
-				  unsigned int length)
+				  unsigned int length, bool is_dwo_section)
 	{
-	  header->add_include_dir (name);
+	  header->add_include_dir (name, is_dwo_section);
 	});
 
       /* Read file name table.  */
       read_formatted_entries (per_objfile, abfd, &line_ptr, lh.get (),
-			      offset_size,
+			      offset_size, is_dwo,
 			      [] (struct line_header *header, const char *name,
 				  dir_index d_index, unsigned int mod_time,
-				  unsigned int length)
+				  unsigned int length, bool is_dwo_section)
 	{
-	  header->add_file_name (name, d_index, mod_time, length);
+	  header->add_file_name (name, d_index, mod_time, length, is_dwo_section);
 	});
     }
   else
@@ -399,7 +485,7 @@ dwarf_decode_line_header  (sect_offset sect_off, bool is_dwz,
       while ((cur_dir = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
 	{
 	  line_ptr += bytes_read;
-	  lh->add_include_dir (cur_dir);
+	  lh->add_include_dir (cur_dir, is_dwo);
 	}
       line_ptr += bytes_read;
 
@@ -417,7 +503,7 @@ dwarf_decode_line_header  (sect_offset sect_off, bool is_dwz,
 	  length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
 	  line_ptr += bytes_read;
 
-	  lh->add_file_name (cur_file, d_index, mod_time, length);
+	  lh->add_file_name (cur_file, d_index, mod_time, length, is_dwo);
 	}
       line_ptr += bytes_read;
     }
@@ -426,5 +512,5 @@ dwarf_decode_line_header  (sect_offset sect_off, bool is_dwz,
     complaint (_("line number info header doesn't "
 		 "fit in `.debug_line' section"));
 
-  return lh;
+  return true;
 }
diff --git a/gdb/dwarf2/line-header.h b/gdb/dwarf2/line-header.h
index 8fb44be56b2..48cf9a5b742 100644
--- a/gdb/dwarf2/line-header.h
+++ b/gdb/dwarf2/line-header.h
@@ -44,9 +44,12 @@ struct file_entry
       length (length_)
   {}
 
-  /* Return the include directory at D_INDEX stored in LH.  Returns
-     NULL if D_INDEX is out of bounds.  */
-  const char *include_dir (const line_header *lh) const;
+  /* Return the include directory at D_INDEX stored in m_include_dirs vector
+     in LH or in m_dwo_include_dirs vector in LH if IS_DWO is true. m_dwo_
+     include_dirs contains the include_directories entries of .debug_line.dwo
+     section whereas m_include_dirs contains the include_directories array
+     entries of .debug_line section. Returns NULL if D_INDEX is out of bounds.  */
+  const char *include_dir (const line_header *lh, bool is_dwo) const;
 
   /* The file name.  Note this is an observing pointer.  The memory is
      owned by debug_line_buffer.  */
@@ -75,25 +78,37 @@ struct line_header
     : offset_in_dwz {}
   {}
 
-  /* Add an entry to the include directory table.  */
-  void add_include_dir (const char *include_dir);
+  /* Add an entry to the m_include_dirs vector or to m_dwo_include_dirs vector
+     if IS_DWO is true.  */
+  void add_include_dir (const char *include_dir, bool is_dwo);
 
-  /* Add an entry to the file name table.  */
+  /* Add an entry to the m_file_names vector or to the m_dwo_file_names vector
+     if IS_DWO is true. m_dwo_file_names vector contains the file_names entries of
+     .debug_line.dwo section whereas m_file_names contains the file_names array
+     entries of .debug_line section.  */
   void add_file_name (const char *name, dir_index d_index,
-		      unsigned int mod_time, unsigned int length);
+		      unsigned int mod_time, unsigned int length, bool is_dwo);
 
-  /* Return the include dir at INDEX (0-based in DWARF 5 and 1-based before).
+  /* Return the include dir from m_include_dirs or from the m_dwo_include_dirs
+     if IS_DWO is true at INDEX (0-based in DWARF 5 and 1-based before).
      Returns NULL if INDEX is out of bounds.  */
-  const char *include_dir_at (dir_index index) const
+  const char *include_dir_at (dir_index index, bool is_dwo) const
   {
     int vec_index;
-    if (version >= 5)
+
+    if (is_dwo && m_dwo_include_dirs.empty())
+      is_dwo = false;
+
+    if ((is_dwo && dwo_version >= 5) || (!is_dwo && version >= 5))
       vec_index = index;
     else
       vec_index = index - 1;
-    if (vec_index < 0 || vec_index >= m_include_dirs.size ())
+    int include_dirs_size = is_dwo ? m_dwo_include_dirs.size () :
+			    m_include_dirs.size ();
+    if (vec_index < 0 || vec_index >= include_dirs_size)
       return NULL;
-    return m_include_dirs[vec_index];
+    return is_dwo ? m_dwo_include_dirs[vec_index] :
+		    m_include_dirs[vec_index];
   }
 
   bool is_valid_file_index (int file_index) const
@@ -103,25 +118,43 @@ struct line_header
     return 1 <= file_index && file_index <= file_names_size ();
   }
 
-  /* Return the file name at INDEX (0-based in DWARF 5 and 1-based before).
+  /* Returns true if the FILE_INDEX is a valid index in the file_names vector
+     of .debug_line.dwo section. */
+  bool is_valid_dwo_file_index (int file_index) const
+  {
+    if (dwo_version >= 5)
+      return 0 <= file_index && file_index < dwo_file_names_size ();
+    return 1 <= file_index && file_index <= dwo_file_names_size ();
+
+  }
+
+  /* Return the file name from m_file_names or from m_dwo_file_names vector
+     if IS_DWO is true at INDEX (0-based in DWARF 5 and 1-based before).
      Returns NULL if INDEX is out of bounds.  */
-  file_entry *file_name_at (file_name_index index)
+  file_entry *file_name_at (file_name_index index, bool is_dwo)
   {
     int vec_index;
-    if (version >= 5)
+
+    if (is_dwo && m_dwo_file_names.empty ())
+      is_dwo = false;
+
+    if ((is_dwo && dwo_version >= 5) || (!is_dwo && version >= 5))
       vec_index = index;
     else
       vec_index = index - 1;
-    if (vec_index < 0 || vec_index >= m_file_names.size ())
+    int file_names_size = is_dwo ? m_dwo_file_names.size ():
+			  m_file_names.size ();
+
+    if (vec_index < 0 || vec_index >= file_names_size)
       return NULL;
-    return &m_file_names[vec_index];
+    return is_dwo ? &m_dwo_file_names[vec_index] : &m_file_names[vec_index];
   }
 
   /* A const overload of the same.  */
-  const file_entry *file_name_at (file_name_index index) const
+  const file_entry *file_name_at (file_name_index index, bool is_dwo) const
   {
     line_header *lh = const_cast<line_header *> (this);
-    return lh->file_name_at (index);
+    return lh->file_name_at (index, is_dwo);
   }
 
   /* The indexes are 0-based in DWARF 5 and 1-based in DWARF 4. Therefore,
@@ -133,6 +166,12 @@ struct line_header
   const std::vector<file_entry> &file_names () const
   { return m_file_names; }
 
+  std::vector<file_entry> &dwo_file_names ()
+  { return m_dwo_file_names; }
+  /* A const overload of the same.  */
+  const std::vector<file_entry> &dwo_file_names () const
+  { return m_dwo_file_names; }
+
   /* Offset of line number information in .debug_line section.  */
   sect_offset sect_off {};
 
@@ -140,14 +179,18 @@ struct line_header
   unsigned offset_in_dwz : 1; /* Can't initialize bitfields in-class.  */
 
   unsigned int total_length {};
+  unsigned int dwo_total_length {};
   unsigned short version {};
+  unsigned short dwo_version {};
   unsigned int header_length {};
+  unsigned int dwo_header_length {};
   unsigned char minimum_instruction_length {};
   unsigned char maximum_ops_per_instruction {};
   unsigned char default_is_stmt {};
   int line_base {};
   unsigned char line_range {};
   unsigned char opcode_base {};
+  unsigned char dwo_opcode_base {};
 
   /* standard_opcode_lengths[i] is the number of operands for the
      standard opcode whose value is i.  This means that
@@ -155,9 +198,18 @@ struct line_header
      element is standard_opcode_lengths[opcode_base - 1].  */
   std::unique_ptr<unsigned char[]> standard_opcode_lengths;
 
+  /* dwo_standard_opcode_lengths[i] is the number of operands for the
+     standard opcode whose value is i.  This means that
+     dwo_standard_opcode_lengths[0] is unused, and the last meaningful
+     element is dwo_standard_opcode_lengths[dwo_opcode_base - 1].  */
+  std::unique_ptr<unsigned char[]> dwo_standard_opcode_lengths;
+
   int file_names_size () const
   { return m_file_names.size(); }
 
+  int dwo_file_names_size () const
+  { return m_dwo_file_names.size (); }
+
   /* The start and end of the statement program following this
      header.  These point into dwarf2_per_objfile->line_buffer.  */
   const gdb_byte *statement_program_start {}, *statement_program_end {};
@@ -173,19 +225,25 @@ struct line_header
      pointers.  The memory is owned by debug_line_buffer.  */
   std::vector<const char *> m_include_dirs;
 
+  /* The include_directories table from .debug_line.dwo section.  */
+  std::vector<const char *> m_dwo_include_dirs;
+
   /* The file_names table. This is private because the meaning of indexes
      differs among DWARF versions (The first valid index is 1 in DWARF 4 and
      before, and is 0 in DWARF 5 and later).  So the client should use
      file_name_at method for access.  */
   std::vector<file_entry> m_file_names;
+
+  /* The file_names table from .debug_line.dwo section.  */
+  std::vector<file_entry> m_dwo_file_names;
 };
 
 typedef std::unique_ptr<line_header> line_header_up;
 
 inline const char *
-file_entry::include_dir (const line_header *lh) const
+file_entry::include_dir (const line_header *lh, bool is_dwo) const
 {
-  return lh->include_dir_at (d_index);
+  return lh->include_dir_at (d_index, is_dwo);
 }
 
 /* Read the statement program header starting at SECT_OFF in SECTION.
@@ -196,8 +254,9 @@ file_entry::include_dir (const line_header *lh) const
    the returned object point into the dwarf line section buffer,
    and must not be freed.  */
 
-extern line_header_up dwarf_decode_line_header
+extern bool dwarf_decode_line_header
   (sect_offset sect_off, bool is_dwz, dwarf2_per_objfile *per_objfile,
-   struct dwarf2_section_info *section, const struct comp_unit_head *cu_header);
+   struct dwarf2_section_info *section, const struct comp_unit_head *cu_header,
+   line_header_up& lh, bool is_dwo);
 
 #endif /* DWARF2_LINE_HEADER_H */
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 10550336063..b9700f70e9c 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1544,7 +1544,7 @@ static const char *compute_include_file_name
      (const struct line_header *lh,
       const file_entry &fe,
       const file_and_directory &cu_info,
-      gdb::unique_xmalloc_ptr<char> *name_holder);
+      gdb::unique_xmalloc_ptr<char> *name_holder, bool is_dwo);
 
 static htab_up allocate_signatured_type_table ();
 
@@ -3027,7 +3027,19 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
 	{
 	  gdb::unique_xmalloc_ptr<char> name_holder;
 	  const char *include_name =
-	    compute_include_file_name (lh.get (), entry, fnd, &name_holder);
+	    compute_include_file_name (lh.get (), entry, fnd, &name_holder, false);
+	  if (include_name != nullptr)
+	    {
+	      include_name = per_objfile->objfile->intern (include_name);
+	      include_names.push_back (include_name);
+	    }
+	}
+
+      for (const auto &entry : lh->dwo_file_names ())
+	{
+	  gdb::unique_xmalloc_ptr<char> name_holder;
+	  const char *include_name =
+	    compute_include_file_name (lh.get (), entry, fnd, &name_holder, true);
 	  if (include_name != nullptr)
 	    {
 	      include_name = per_objfile->objfile->intern (include_name);
@@ -10753,7 +10765,7 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
 	{
 	  file_entry &fe = file_names[i];
 	  dwarf2_start_subfile (this, fe.name,
-				fe.include_dir (line_header));
+				fe.include_dir (line_header, false));
 	  buildsym_compunit *b = get_builder ();
 	  if (b->get_current_subfile ()->symtab == NULL)
 	    {
@@ -20722,7 +20734,7 @@ get_debug_line_section (struct dwarf2_cu *cu)
 }
 
 /* Read the statement program header starting at OFFSET in
-   .debug_line, or .debug_line.dwo.  Return a pointer
+   .debug_line and .debug_line.dwo.  Return a pointer
    to a struct line_header, allocated using xmalloc.
    Returns NULL if there is a problem reading the header, e.g., if it
    has a version we don't understand.
@@ -20735,21 +20747,48 @@ static line_header_up
 dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
 {
   struct dwarf2_section_info *section;
+  struct dwarf2_section_info *dwo_section = NULL;
   dwarf2_per_objfile *per_objfile = cu->per_objfile;
 
   section = get_debug_line_section (cu);
   section->read (per_objfile->objfile);
+
   if (section->buffer == NULL)
+  {
+    if (cu->dwo_unit && cu->per_cu->is_debug_types)
+      complaint (_("missing .debug_line.dwo section"));
+    else
+      complaint (_("missing .debug_line section"));
+    return 0;
+  }
+
+  line_header_up lh (new line_header ());
+
+  if (!dwarf_decode_line_header (sect_off, cu->per_cu->is_dwz,
+				 per_objfile, section,
+				 &cu->header, lh, false))
     {
-      if (cu->dwo_unit && cu->per_cu->is_debug_types)
-	complaint (_("missing .debug_line.dwo section"));
-      else
-	complaint (_("missing .debug_line section"));
       return 0;
     }
 
-  return dwarf_decode_line_header (sect_off, cu->per_cu->is_dwz,
-				   per_objfile, section, &cu->header);
+  if (cu->dwo_unit && !cu->per_cu->is_debug_types)
+    {
+      dwo_section = &cu->dwo_unit->dwo_file->sections.line;
+      dwo_section->read (per_objfile->objfile);
+    }
+
+  if (cu->dwo_unit && dwo_section && (dwo_section->buffer != NULL))
+    {
+      sect_offset dwo_sect_off = (sect_offset) 0;
+      if (!dwarf_decode_line_header (dwo_sect_off, cu->per_cu->is_dwz,
+				     per_objfile, dwo_section,
+				     &cu->header, lh, true))
+      {
+	return 0;
+      }
+    }
+
+  return lh;
 }
 
 /* Subroutine of dwarf_decode_lines to simplify it.
@@ -20762,12 +20801,20 @@ dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
 static const char *
 compute_include_file_name (const struct line_header *lh, const file_entry &fe,
 			   const file_and_directory &cu_info,
-			   gdb::unique_xmalloc_ptr<char> *name_holder)
+			   gdb::unique_xmalloc_ptr<char> *name_holder, bool is_dwo)
 {
   const char *include_name = fe.name;
   const char *include_name_to_compare = include_name;
+  const char *dir_name;
 
-  const char *dir_name = fe.include_dir (lh);
+  if (is_dwo)
+    {
+      dir_name = fe.include_dir (lh, true);
+    }
+  else
+    {
+      dir_name = fe.include_dir (lh, false);
+    }
 
   gdb::unique_xmalloc_ptr<char> hold_compare;
   if (!IS_ABSOLUTE_PATH (include_name)
@@ -20838,7 +20885,7 @@ class lnp_state_machine
   {
     /* lh->file_names is 0-based, but the file name numbers in the
        statement program are 1-based.  */
-    return m_line_header->file_name_at (m_file);
+    return m_line_header->file_name_at (m_file, false);
   }
 
   /* Record the line in the state machine.  END_SEQUENCE is true if
@@ -21012,7 +21059,7 @@ lnp_state_machine::handle_set_file (file_name_index file)
     dwarf2_debug_line_missing_file_complaint ();
   else if (m_record_lines_p)
     {
-      const char *dir = fe->include_dir (m_line_header);
+      const char *dir = fe->include_dir (m_line_header, false);
 
       m_last_subfile = m_cu->get_builder ()->get_current_subfile ();
       m_line_has_non_zero_discriminator = m_discriminator != 0;
@@ -21304,7 +21351,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
 	  const file_entry *fe = state_machine.current_file ();
 
 	  if (fe != NULL)
-	    dwarf2_start_subfile (cu, fe->name, fe->include_dir (lh));
+	    dwarf2_start_subfile (cu, fe->name, fe->include_dir (lh, false));
 	}
 
       /* Decode the table.  */
@@ -21369,7 +21416,7 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu,
 		    length =
 		      read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
 		    line_ptr += bytes_read;
-		    lh->add_file_name (cur_file, dindex, mod_time, length);
+		    lh->add_file_name (cur_file, dindex, mod_time, length, false);
 		  }
 		  break;
 		case DW_LNE_set_discriminator:
@@ -21526,7 +21573,20 @@ dwarf_decode_lines (struct line_header *lh, const file_and_directory &fnd,
 	  {
 	    gdb::unique_xmalloc_ptr<char> name_holder;
 	    const char *include_name =
-	      compute_include_file_name (lh, file_entry, fnd, &name_holder);
+	      compute_include_file_name (lh, file_entry, fnd, &name_holder, false);
+	    if (include_name != NULL)
+	      dwarf2_create_include_psymtab
+		(cu->per_objfile->per_bfd, include_name, pst,
+		 cu->per_objfile->per_bfd->partial_symtabs.get (),
+		 objfile->per_bfd);
+	  }
+
+      for (auto &file_entry : lh->dwo_file_names ())
+	if (file_entry.included_p)
+	  {
+	    gdb::unique_xmalloc_ptr<char> name_holder;
+	    const char *include_name =
+	      compute_include_file_name (lh, file_entry, fnd, &name_holder, true);
 	    if (include_name != NULL)
 	      dwarf2_create_include_psymtab
 		(cu->per_objfile->per_bfd, include_name, pst,
@@ -21544,7 +21604,19 @@ dwarf_decode_lines (struct line_header *lh, const file_and_directory &fnd,
 
       for (auto &fe : lh->file_names ())
 	{
-	  dwarf2_start_subfile (cu, fe.name, fe.include_dir (lh));
+	  dwarf2_start_subfile (cu, fe.name, fe.include_dir (lh, false));
+	  if (builder->get_current_subfile ()->symtab == NULL)
+	    {
+	      builder->get_current_subfile ()->symtab
+		= allocate_symtab (cust,
+				   builder->get_current_subfile ()->name);
+	    }
+	  fe.symtab = builder->get_current_subfile ()->symtab;
+	}
+
+      for (auto &fe : lh->dwo_file_names ())
+	{
+	  dwarf2_start_subfile (cu, fe.name, fe.include_dir (lh, true));
 	  if (builder->get_current_subfile ()->symtab == NULL)
 	    {
 	      builder->get_current_subfile ()->symtab
@@ -21760,7 +21832,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	  struct file_entry *fe;
 
 	  if (cu->line_header != NULL)
-	    fe = cu->line_header->file_name_at (file_index);
+	    fe = cu->line_header->file_name_at (file_index, (cu->dwo_unit != nullptr));
 	  else
 	    fe = NULL;
 
diff --git a/gdb/macrotab.c b/gdb/macrotab.c
index 7ca3f312d33..73a917541b6 100644
--- a/gdb/macrotab.c
+++ b/gdb/macrotab.c
@@ -238,7 +238,7 @@ compare_locations (struct macro_source_file *file1, int line1,
 
   /* If the two files are not the same, find their common ancestor in
      the #inclusion tree.  */
-  if (file1 != file2)
+  if (file1 != file2 || filename_cmp(file1->filename, file2->filename) != 0)
     {
       /* If one file is deeper than the other, walk up the #inclusion
 	 chain until the two files are at least at the same *depth*.
@@ -266,7 +266,7 @@ compare_locations (struct macro_source_file *file1, int line1,
 
       /* Now both file1 and file2 are at the same depth.  Walk toward
 	 the root of the tree until we find where the branches meet.  */
-      while (file1 != file2)
+      while (file1 != file2 || filename_cmp(file1->filename, file2->filename) != 0)
 	{
 	  line1 = file1->included_at_line;
 	  file1 = file1->included_by;
-- 
2.17.1

