Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Joel Brobecker <brobecker@gnat.com>
To: Jim Blandy <jimb@redhat.com>
Cc: Daniel Jacobowitz <drow@mvista.com>,
	Eli Zaretskii <eliz@elta.co.il>,
	gdb-patches@sources.redhat.com
Subject: Re: [RFC/dwarf-2] Add support for included files
Date: Sat, 01 May 2004 01:14:00 -0000	[thread overview]
Message-ID: <20040501011418.GG16083@gnat.com> (raw)
In-Reply-To: <vt24qr2nz4j.fsf@zenia.home>

[-- Attachment #1: Type: text/plain, Size: 3813 bytes --]

> I actually have still more comments:

Jim, you'll be happy, your comments make the patch neater :-).
Once you get to know the data structures a little bit more
(I really should have studied them a little harder before working
on this), everything seems to be falling into place almost naturally...

Attached is a revised version of the patch, up to date as of now,
and incorporating all your comments, except one which I wasn't sure
about.

> - Rather than passing 'line_offset' by reference to read_partial_die,
>   could you add a line_offset field to 'struct partial_die_info, and have
>   read_partial_die set that?  That would seem more consistent with the
>   rest of what read_partial_die does.  Then
>   'dwarf2_build_include_psymtabs' should take a pointer to the CU die.

This brings a nice cleanup.

>   That's assuming Daniel doesn't see any problem enlarging
>   partial_die_info.  If he does, maybe we could add the fields to
>   'struct dwarf2_cu' instead: it's a little odd to have
>   'read_partial_die' set the cu's fields directly, but not horribly
>   so, as long as the die's tag is DW_TAG_compile_unit.

partial_die_info seems better suited to hold that information.
Hopefully Daniel won't object.

> - Is it really okay to pass NULL to dwarf_decode_lines for comp_dir?
>   Won't the filenames of the partial symbol tables be different from
>   those of the symbol tables?  To fix this, read_partial_die would
>   have to check for DW_AT_comp_dir attributes, too.

I don't think we need to worry about the comp_dir when building
the psymtabs for included files. The filename used for the psymtab
is the same as the filename used to build the symtab (checked it
by inspecting start_subfile() and end_symtab()). The only thing
we could gain from computing the comp_dir as well during that phase
is to compute the psymtab fullname. But then comp_dir is used
to set the symtab dirname, not to compute the fullname. So it doesn't
help improve the consistency between psymtab and symtab.

I think that part is fine...

... At least for now :-).

> - It seems to me the file_is_included array should be in struct
>   line_header, with add_file_name managing its allocation /
>   initialization in parallel with file_names.  It's already the case
>   that that structure is mutated by the act of processing the line
>   number program, so I don't see that it's a serious change to the
>   usage patterns of that structure type.

Good idea. I included it, and the code becomes one notch cleaner.

> - I'd rather see the call to dwarf2_build_include_psymtabs before the
>   assignment to info_ptr, not after.  Not that it matters much.

Done.

> - Thanks for fixing the comments on dwarf_decode_lines --- especially
>   the references to arguments that had been missing for some time now.

My pleasure :-).

2004-04-30  J. Brobecker  <brobecker@gnat.com>

        * dwarf2read.c (line_header): Add new included_p field in
        field file_names.
        (partial_die_info): New field has_stmt_list. New field line_offset.
        (dwarf2_create_include_psymtab): New function.
        (dwarf2_build_include_psymtabs): New function.
        (add_file_name): Add forward declaration. Initialize new field.
        (dwarf_decode_lines): Add new parameter. Enhance this procedure
        to be able to determine the list of files included by the
        given unit, and build their associated psymtabs.
        (dwarf2_build_psymtabs_hard): Build the psymtabs for the included
        files as well.
        (psymtab_to_symtab_1): Build the symtabs of all dependencies as well.
        (read_file_scope): Update call to dwarf_decode_lines.
        (read_partial_die): Handle DW_AT_stmt_list attributes.

Tested on x86-linux, no regression. Fixes the two sep.exp KFAILS.
OK to apply?

Thanks,
-- 
Joel

[-- Attachment #2: separate2.diff --]
[-- Type: text/plain, Size: 12133 bytes --]

Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.148
diff -u -p -r1.148 dwarf2read.c
--- dwarf2read.c	19 Apr 2004 18:20:50 -0000	1.148
+++ dwarf2read.c	1 May 2004 01:07:21 -0000
@@ -341,6 +341,7 @@ struct line_header
     unsigned int dir_index;
     unsigned int mod_time;
     unsigned int length;
+    int included_p; /* Non-zero if referenced by the Line Number Program.  */
   } *file_names;
 
   /* The start and end of the statement program following this
@@ -368,6 +369,7 @@ struct partial_die_info
     unsigned int is_declaration : 1;
     unsigned int has_type : 1;
     unsigned int has_specification : 1;
+    unsigned int has_stmt_list : 1;
     unsigned int has_pc_info : 1;
 
     /* Flag set if the SCOPE field of this structure has been
@@ -400,6 +402,9 @@ struct partial_die_info
        DW_AT_extension).  */
     unsigned int spec_offset;
 
+    /* If HAS_STMT_LIST, the offset of the Line Number Information data.  */
+    unsigned int line_offset;
+
     /* Pointers to this DIE's parent, first child, and next sibling,
        if any.  */
     struct partial_die_info *die_parent, *die_child, *die_sibling;
@@ -631,6 +636,13 @@ static void dwarf2_locate_sections (bfd 
 static void dwarf2_build_psymtabs_easy (struct objfile *, int);
 #endif
 
+static void dwarf2_create_include_psymtab (char *, struct partial_symtab *,
+                                           struct objfile *);
+
+static void dwarf2_build_include_psymtabs (struct dwarf2_cu *,
+                                           struct partial_die_info *,
+                                           struct partial_symtab *);
+
 static void dwarf2_build_psymtabs_hard (struct objfile *, int);
 
 static void scan_partial_symbols (struct partial_die_info *,
@@ -739,12 +751,15 @@ static struct die_info *die_specificatio
 
 static void free_line_header (struct line_header *lh);
 
+static void add_file_name (struct line_header *, char *, unsigned int,
+                           unsigned int, unsigned int);
+
 static struct line_header *(dwarf_decode_line_header
                             (unsigned int offset,
                              bfd *abfd, struct dwarf2_cu *cu));
 
 static void dwarf_decode_lines (struct line_header *, char *, bfd *,
-				struct dwarf2_cu *);
+				struct dwarf2_cu *, struct partial_symtab *);
 
 static void dwarf2_start_subfile (char *, char *);
 
@@ -1194,6 +1209,68 @@ partial_read_comp_unit_head (struct comp
   return info_ptr;
 }
 
+/* Allocate a new partial symtab for file named NAME and mark this new
+   partial symtab as being an include of PST.  */
+
+static void
+dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst,
+                               struct objfile *objfile)
+{
+  struct partial_symtab *subpst = allocate_psymtab (name, objfile);
+
+  subpst->section_offsets = pst->section_offsets;
+  subpst->textlow = 0;
+  subpst->texthigh = 0;
+
+  subpst->dependencies = (struct partial_symtab **)
+    obstack_alloc (&objfile->objfile_obstack,
+                   sizeof (struct partial_symtab *));
+  subpst->dependencies[0] = pst;
+  subpst->number_of_dependencies = 1;
+
+  subpst->globals_offset = 0;
+  subpst->n_global_syms = 0;
+  subpst->statics_offset = 0;
+  subpst->n_static_syms = 0;
+  subpst->symtab = NULL;
+  subpst->read_symtab = pst->read_symtab;
+  subpst->readin = 0;
+
+  /* No private part is necessary for include psymtabs.  This property
+     can be used to differentiate between such include psymtabs and
+     the regular ones.  If it ever happens that a regular psymtab can
+     legitimally have a NULL PST_PRIVATE part, then we'll have to add a
+     dedicated field for that in the dwarf2_pinfo structure.  */
+  PST_PRIVATE (subpst) = NULL;
+}
+
+/* Read the Line Number Program data and extract the list of files
+   included by the source file represented by PST.  Build an include
+   partial symtab for each of these included files.
+   
+   This procedure assumes that there *is* a Line Number Program in
+   the given CU.  Callers should check that PDI->HAS_STMT_LIST is set
+   before calling this procedure.  */
+
+static void
+dwarf2_build_include_psymtabs (struct dwarf2_cu *cu,
+                               struct partial_die_info *pdi,
+                               struct partial_symtab *pst)
+{
+  struct objfile *objfile = cu->objfile;
+  bfd *abfd = objfile->obfd;
+  struct line_header *lh;
+
+  lh = dwarf_decode_line_header (pdi->line_offset, abfd, cu);
+  if (lh == NULL)
+    return;  /* No linetable, so no includes.  */
+
+  dwarf_decode_lines (lh, NULL, abfd, cu, pst);
+
+  free_line_header (lh);
+}
+
+
 /* Build the partial symbol table by doing a quick pass through the
    .debug_info and .debug_abbrev sections.  */
 
@@ -1321,6 +1398,13 @@ dwarf2_build_psymtabs_hard (struct objfi
          also happen.) This happens in VxWorks.  */
       free_named_symtabs (pst->filename);
 
+      if (comp_unit_die.has_stmt_list)
+        {
+          /* Get the list of files included in the current compilation unit,
+             and build a psymtab for each of them.  */
+          dwarf2_build_include_psymtabs (&cu, &comp_unit_die, pst);
+        }
+
       info_ptr = beg_of_comp_unit + cu.header.length
                                   + cu.header.initial_length_size;
 
@@ -2006,6 +2090,32 @@ psymtab_to_symtab_1 (struct partial_symt
   struct cleanup *back_to;
   struct attribute *attr;
   CORE_ADDR baseaddr;
+  int i;
+
+  for (i = 0; i < pst->number_of_dependencies; i++)
+    if (!pst->dependencies[i]->readin)
+      {
+        /* Inform about additional files that need to be read in.  */
+        if (info_verbose)
+          {
+            fputs_filtered (" ", gdb_stdout);
+            wrap_here ("");
+            fputs_filtered ("and ", gdb_stdout);
+            wrap_here ("");
+            printf_filtered ("%s...", pst->dependencies[i]->filename);
+            wrap_here ("");     /* Flush output */
+            gdb_flush (gdb_stdout);
+          }
+        psymtab_to_symtab_1 (pst->dependencies[i]);
+      }
+
+  if (PST_PRIVATE (pst) == NULL)
+    {
+      /* It's an include file, no symbols to read for it.
+         Everything is in the parent symtab.  */
+      pst->readin = 1;
+      return;
+    }
 
   dwarf2_per_objfile = objfile_data (pst->objfile, dwarf2_objfile_data_key);
 
@@ -2294,7 +2404,7 @@ read_file_scope (struct die_info *die, s
         {
           make_cleanup ((make_cleanup_ftype *) free_line_header,
                         (void *) line_header);
-          dwarf_decode_lines (line_header, comp_dir, abfd, cu);
+          dwarf_decode_lines (line_header, comp_dir, abfd, cu, NULL);
         }
     }
 
@@ -4826,6 +4936,10 @@ read_partial_die (struct partial_die_inf
 	    part_die->sibling = dwarf2_per_objfile->info_buffer
 	      + dwarf2_get_ref_die_offset (&attr, cu);
 	  break;
+        case DW_AT_stmt_list:
+          part_die->has_stmt_list = 1;
+          part_die->line_offset = DW_UNSND (&attr);
+          break;
 	default:
 	  break;
 	}
@@ -5628,6 +5742,7 @@ add_file_name (struct line_header *lh,
   fe->dir_index = dir_index;
   fe->mod_time = mod_time;
   fe->length = length;
+  fe->included_p = 0;
 }
  
 
@@ -5785,13 +5900,23 @@ check_cu_functions (CORE_ADDR address, s
   return fn->lowpc;
 }
 
-/* Decode the line number information for the compilation unit whose
-   line number info is at OFFSET in the .debug_line section.
-   The compilation directory of the file is passed in COMP_DIR.  */
+/* Decode the Line Number Program (LNP) for the given line_header
+   structure and CU.  The actual information extracted and the type
+   of structures created from the LNP depends on the value of PST.
+
+   1. If PST is NULL, then this procedure uses the data from the program
+      to create all necessary symbol tables, and their linetables.
+      The compilation directory of the file is passed in COMP_DIR,
+      and must not be NULL.
+   
+   2. If PST is not NULL, this procedure reads the program to determine
+      the list of files included by the unit represented by PST, and
+      builds all the associated partial symbol tables.  In this case,
+      the value of COMP_DIR is ignored, and can thus be NULL.  */
 
 static void
 dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
-		    struct dwarf2_cu *cu)
+		    struct dwarf2_cu *cu, struct partial_symtab *pst)
 {
   char *line_ptr;
   char *line_end;
@@ -5799,6 +5924,7 @@ dwarf_decode_lines (struct line_header *
   unsigned char op_code, extended_op, adj_opcode;
   CORE_ADDR baseaddr;
   struct objfile *objfile = cu->objfile;
+  const int decode_for_pst_p = (pst != NULL);
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
@@ -5817,9 +5943,9 @@ dwarf_decode_lines (struct line_header *
       int basic_block = 0;
       int end_sequence = 0;
 
-      /* Start a subfile for the current file of the state machine.  */
-      if (lh->num_file_names >= file)
+      if (!decode_for_pst_p && lh->num_file_names >= file)
 	{
+          /* Start a subfile for the current file of the state machine.  */
 	  /* lh->include_dirs and lh->file_names are 0-based, but the
 	     directory and file name numbers in the statement program
 	     are 1-based.  */
@@ -5844,9 +5970,12 @@ dwarf_decode_lines (struct line_header *
 	      address += (adj_opcode / lh->line_range)
 		* lh->minimum_instruction_length;
 	      line += lh->line_base + (adj_opcode % lh->line_range);
-	      /* append row to matrix using current values */
-	      record_line (current_subfile, line, 
-	                   check_cu_functions (address, cu));
+              if (!decode_for_pst_p)
+                {
+	          /* append row to matrix using current values */
+	          record_line (current_subfile, line, 
+	                       check_cu_functions (address, cu));
+                }
 	      basic_block = 1;
 	    }
 	  else switch (op_code)
@@ -5859,7 +5988,8 @@ dwarf_decode_lines (struct line_header *
 		{
 		case DW_LNE_end_sequence:
 		  end_sequence = 1;
-		  record_line (current_subfile, 0, address);
+                  if (!decode_for_pst_p)
+		    record_line (current_subfile, 0, address);
 		  break;
 		case DW_LNE_set_address:
 		  address = read_address (abfd, line_ptr, cu, &bytes_read);
@@ -5892,8 +6022,9 @@ dwarf_decode_lines (struct line_header *
 		}
 	      break;
 	    case DW_LNS_copy:
-	      record_line (current_subfile, line, 
-	                   check_cu_functions (address, cu));
+              if (!decode_for_pst_p)
+	        record_line (current_subfile, line, 
+	                     check_cu_functions (address, cu));
 	      basic_block = 0;
 	      break;
 	    case DW_LNS_advance_pc:
@@ -5915,11 +6046,13 @@ dwarf_decode_lines (struct line_header *
                 file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
                 line_ptr += bytes_read;
                 fe = &lh->file_names[file - 1];
+                fe->included_p = 1;
                 if (fe->dir_index)
                   dir = lh->include_dirs[fe->dir_index - 1];
                 else
                   dir = comp_dir;
-                dwarf2_start_subfile (fe->name, dir);
+                if (!decode_for_pst_p)
+                  dwarf2_start_subfile (fe->name, dir);
               }
 	      break;
 	    case DW_LNS_set_column:
@@ -5956,6 +6089,22 @@ dwarf_decode_lines (struct line_header *
 	      }
 	    }
 	}
+    }
+
+  if (decode_for_pst_p)
+    {
+      int file_index;
+
+      /* Now that we're done scanning the Line Header Program, we can
+         create the psymtab of each included file.  */
+      for (file_index = 0; file_index < lh->num_file_names; file_index++)
+        if (lh->file_names[file_index].included_p == 1)
+          {
+            char *include_name = lh->file_names [file_index].name;
+    
+            if (strcmp (include_name, pst->filename) != 0)
+              dwarf2_create_include_psymtab (include_name, pst, objfile);
+          }
     }
 }
 

  reply	other threads:[~2004-05-01  1:14 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-04-07 16:05 Jim Blandy
2004-04-13  5:20 ` Joel Brobecker
2004-04-14 19:10   ` Jim Blandy
2004-04-15 22:13     ` Joel Brobecker
2004-04-16  4:24       ` Jim Blandy
2004-04-16  4:28         ` Joel Brobecker
2004-04-16 23:08         ` Joel Brobecker
2004-04-29 23:32           ` Jim Blandy
2004-05-01  1:14             ` Joel Brobecker [this message]
2004-05-01  4:57               ` Jim Blandy
2004-05-03 16:25                 ` Joel Brobecker
  -- strict thread matches above, loose matches on Subject: below --
2004-05-03 22:15 Andrew Pinski
2004-05-04  0:15 ` Joel Brobecker
2004-05-04  0:18   ` Andrew Pinski
2004-01-02  7:25 Joel Brobecker
2004-01-02 14:18 ` Daniel Jacobowitz
2004-01-03 14:42   ` Joel Brobecker
2004-01-03 16:34     ` Eli Zaretskii
2004-01-03 17:47       ` Joel Brobecker
2004-01-02 14:45 ` Eli Zaretskii
2004-01-05 16:18 ` Andrew Cagney
2004-01-05 19:17   ` Joel Brobecker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20040501011418.GG16083@gnat.com \
    --to=brobecker@gnat.com \
    --cc=drow@mvista.com \
    --cc=eliz@elta.co.il \
    --cc=gdb-patches@sources.redhat.com \
    --cc=jimb@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox