Patchwork [darwin,debug] make debug section starts explicit.

login
register
mail settings
Submitter IainS
Date Oct. 28, 2010, 6:16 p.m.
Message ID <FF5C3451-84EB-4DE6-A603-173ED619C1C6@sandoe-acoustics.co.uk>
Download mbox | patch
Permalink /patch/69482/
State New
Headers show

Comments

IainS - Oct. 28, 2010, 6:16 p.m.
Hello,
On darwin  the order in which we emit sections from the assembler is  
the same as they are encountered in the source.
Currently, this means that when debug is enabled we have say text and  
data sections split by debug ones - whereas they would not be otherwise.

In addition, since debug offsets are local to their sections in darwin  
we need to emit a label at the start of each debug section.

---

I was investigating the possibility of making it such that all debug  
sections appeared at the end of asm files (and had a solution working  
a few months ago).
Apart from making it easier to compare asm between debug / non-debug  
cases, I was also pursuing the possibility of simplifying the object  
compares (which takes a moderate chunk of the bootstrap wall-clock  
time since it's done sequentially).

There is not sufficient time to get all the steps of this into stage 1  
(even with the extension).

However, the attached patch is the first step towards it - and gets  
rid of a kludge where we have to emit all the debug sections at the  
start of an asm file to satisfy the need for start labels.

I cc'd RTH - since we were discussing this in irc (although, I'm sure  
that there's every reason to have forgotten the conversation, it was  
some time ago :-) ).

this has been bootstrapped and tested numerous times over the last few  
months  (on *darwin* and x86-64-linux and cris-elf)
... re-tested on darwin and running on x86-64 ...

OK for trunk assuming re-test passes?
Iain


gcc:

	* doc/tm.texi (TARGET_ASM_OUTPUT_DWARF_SECTION_START_INFO): Hook
	documentation (auto-generated).
	* doc/tm.texi.in (TARGET_ASM_OUTPUT_DWARF_SECTION_START_INFO) New.
	* target.def (output_dwarf_section_start_info): New hook.
	* dwarf2out.c (dwarf2_start_section): New.
	(dwarf2out_init): Use dwarf2_start_section().
	(output_indirect_string): Only emit the section switch the first  
time, use dwarf2_start_section ().
	(dwarf2out_finish): use dwarf2_start_section ().
	* config/darwin-protos.h  
(darwin_asm_output_dwarf_section_start_info): New.
	* config/darwin.c (darwin_asm_output_dwarf_section_start_info): New.
	(darwin_file_start): Do not emit dwarf sections.
	* config/darwin.h (DEBUG_DCALL_SECTION): New.
	(DEBUG_VCALL_SECTION): New.
	(TARGET_ASM_OUTPUT_DWARF_SECTION_START_INFO): New.

gcc/testsuite:

	* g++.dg/debug/dwarf2/pubnames-1.C: Adjust since darwin no longer  
emits two section
	switches.
Richard Henderson - Oct. 29, 2010, 9:01 p.m.
On 10/28/2010 11:16 AM, IainS wrote:
>     * doc/tm.texi (TARGET_ASM_OUTPUT_DWARF_SECTION_START_INFO): Hook
>     documentation (auto-generated).

I think the hook is redundant with the support that we already
have for sections.

May I suggest instead that we create allow the section structures
for each of these debug sections to be overwritten.  Darwin can
then alter both the section name and notice the SECTION_DECLARED
bit in order to output that label.

This will involve moving declaration and initialization of
debug_info_section et al to the same place where we handle text_section.
That should be before TARGET_ASM_INIT_SECTIONS is invoked, where
darwin can install new section structures.


r~
IainS - Oct. 30, 2010, 8:07 a.m.
Hi Richard,
On 29 Oct 2010, at 22:01, Richard Henderson wrote:

> On 10/28/2010 11:16 AM, IainS wrote:
>>    * doc/tm.texi (TARGET_ASM_OUTPUT_DWARF_SECTION_START_INFO): Hook
>>    documentation (auto-generated).
>
> I think the hook is redundant with the support that we already
> have for sections.
>
> May I suggest instead that we create allow the section structures
> for each of these debug sections to be overwritten.  Darwin can
> then alter both the section name and notice the SECTION_DECLARED
> bit in order to output that label.
>
> This will involve moving declaration and initialization of
> debug_info_section et al to the same place where we handle  
> text_section.
> That should be before TARGET_ASM_INIT_SECTIONS is invoked, where
> darwin can install new section structures.

So, IIUC, we would catch dwarf debug sections and
..   install the darwin section name
..   install our own hook into the section (like we have with objc)  
and then use that to emit the section label on the first switch?

That seems a much better way (less prone to someone editing dwarf2out  
and forgetting to use dwarf2_section_start()).

Ah well, something to consider for 4.7 ;-) ...

.. there are higher priority things for this weekend.

thanks for reviewing,
Iain
Richard Henderson - Oct. 30, 2010, 6:03 p.m.
On 10/30/2010 01:07 AM, IainS wrote:
> Ah well, something to consider for 4.7 ;-) ...

This *is* a bug fix, isn't it?  If so, you don't have to
wait for stage1 to open up again.  You've got 2 months...


r~

Patch

Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 166029)
+++ gcc/doc/tm.texi	(working copy)
@@ -9442,6 +9442,10 @@  is used on some systems to avoid garbage collectin
 is referenced by a function.
 @end defmac
 
+@deftypefn {Target Hook} void TARGET_ASM_OUTPUT_DWARF_SECTION_START_INFO (FILE *@var{file}, section *@var{sect})
+If defined, this target hook is a function that emits any initialization needed at the start of each dwarf debug section (for example, a label).  The hook will be invoked once immediately after the first switch to the debug section @var{sect}.  Output should be written to  @var{file}.
+@end deftypefn
+
 @deftypefn {Target Hook} void TARGET_ASM_OUTPUT_DWARF_DTPREL (FILE *@var{file}, int @var{size}, rtx @var{x})
 If defined, this target hook is a function which outputs a DTP-relative
 reference to the given TLS symbol of the specified size.
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 166029)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -9414,6 +9414,8 @@  is used on some systems to avoid garbage collectin
 is referenced by a function.
 @end defmac
 
+@hook TARGET_ASM_OUTPUT_DWARF_SECTION_START_INFO
+
 @hook TARGET_ASM_OUTPUT_DWARF_DTPREL
 If defined, this target hook is a function which outputs a DTP-relative
 reference to the given TLS symbol of the specified size.
Index: gcc/target.def
===================================================================
--- gcc/target.def	(revision 166029)
+++ gcc/target.def	(working copy)
@@ -431,6 +431,15 @@  DEFHOOK
  void, (rtx x),
  default_asm_output_anchor)
 
+DEFHOOK
+(output_dwarf_section_start_info,
+ "If defined, this target hook is a function that emits any initialization\
+ needed at the start of each dwarf debug section (for example, a label).\
+  The hook will be invoked once immediately after the first switch to the\
+ debug section @var{sect}.  Output should be written to  @var{file}.",
+ void, (FILE *file, section *sect),
+ NULL)
+
 /* Output a DTP-relative reference to a TLS symbol.  */
 DEFHOOK
 (output_dwarf_dtprel,
Index: gcc/testsuite/g++.dg/debug/dwarf2/pubnames-1.C
===================================================================
--- gcc/testsuite/g++.dg/debug/dwarf2/pubnames-1.C	(revision 166029)
+++ gcc/testsuite/g++.dg/debug/dwarf2/pubnames-1.C	(working copy)
@@ -4,12 +4,7 @@ 
 // { dg-options "-g -dA -fno-merge-debug-strings" }
 //
 // There should be one debug_pubnames section generated.
-// On Darwin though, there is also a label pointing at the begining of the
-// debug_pubnames section. The assembly code of that label adds an occurence
-// of section declaration assembly. So on Darwin, we need to check for two
-// occurences of the debug_pubnames section declaration.
-// { dg-final { scan-assembler-times "\.section\[\t \]\[^\n\]*debug_pubnames" 1 { target { ! *-*-darwin* } } } }
-// { dg-final { scan-assembler-times "\.section\[\t \]\[^\n\]*debug_pubnames" 2 { target { *-*-darwin* } } } }
+// { dg-final { scan-assembler-times "\.section\[\t \]\[^\n\]*debug_pubnames" 1 } }
 //
 // Then check of the presence of the names we are interested in.
 // { dg-final { scan-assembler-times "\"main.0\"\[^\n\]*external name" 1 } }
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c	(revision 166029)
+++ gcc/dwarf2out.c	(working copy)
@@ -546,6 +546,25 @@  static struct dw_loc_descr_struct *mem_loc_descrip
 #define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG)
 #endif
 
+/* Start a dwarf debug section.
+   Allow the target the opportunity to initialize for this section.
+   If the section requires a start label emit this.  */
+
+static void
+dwarf2_start_section (section *sect, char *label)
+{
+  switch_to_section (sect);
+
+  /* If the target needs to initialize the use of this section.  */
+  if (targetm.asm_out.output_dwarf_section_start_info)
+    targetm.asm_out.output_dwarf_section_start_info 
+    		(asm_out_file, sect) ;
+
+  /* If we have section start label for local use, emit this.  */
+  if (label)
+    ASM_OUTPUT_LABEL (asm_out_file, label);
+}
+
 /* Hook used by __throw.  */
 
 rtx
@@ -3098,7 +3117,7 @@  switch_to_frame_table_section (int for_eh, bool ba
       if (!debug_frame_section)
 	debug_frame_section = get_section (DEBUG_FRAME_SECTION,
 					   SECTION_DEBUG, NULL);
-      switch_to_section (debug_frame_section);
+      dwarf2_start_section (debug_frame_section, NULL);
     }
 }
 
@@ -21811,19 +21830,16 @@  dwarf2out_init (const char *filename ATTRIBUTE_UNU
 			       DEBUG_LINE_SECTION_LABEL, 0);
   ASM_GENERATE_INTERNAL_LABEL (ranges_section_label,
 			       DEBUG_RANGES_SECTION_LABEL, 0);
-  switch_to_section (debug_abbrev_section);
-  ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label);
-  switch_to_section (debug_info_section);
-  ASM_OUTPUT_LABEL (asm_out_file, debug_info_section_label);
-  switch_to_section (debug_line_section);
-  ASM_OUTPUT_LABEL (asm_out_file, debug_line_section_label);
 
+  dwarf2_start_section (debug_abbrev_section, abbrev_section_label);
+  dwarf2_start_section (debug_info_section, debug_info_section_label);
+  dwarf2_start_section (debug_line_section, debug_line_section_label);
+
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
     {
-      switch_to_section (debug_macinfo_section);
       ASM_GENERATE_INTERNAL_LABEL (macinfo_section_label,
 				   DEBUG_MACINFO_SECTION_LABEL, 0);
-      ASM_OUTPUT_LABEL (asm_out_file, macinfo_section_label);
+      dwarf2_start_section (debug_macinfo_section, macinfo_section_label);
     }
 
   switch_to_section (text_section);
@@ -21860,7 +21876,12 @@  output_indirect_string (void **h, void *v ATTRIBUT
 
   if (node->label && node->refcount)
     {
-      switch_to_section (debug_str_section);
+      static bool done;
+      if (!done)
+	{
+	  dwarf2_start_section (debug_str_section, NULL);
+	  done = true;
+	}
       ASM_OUTPUT_LABEL (asm_out_file, node->label);
       assemble_string (node->str, strlen (node->str) + 1);
     }
@@ -23049,17 +23070,16 @@  dwarf2out_finish (const char *filename)
   if (have_location_lists)
     {
       /* Output the location lists info.  */
-      switch_to_section (debug_loc_section);
       ASM_GENERATE_INTERNAL_LABEL (loc_section_label,
 				   DEBUG_LOC_SECTION_LABEL, 0);
-      ASM_OUTPUT_LABEL (asm_out_file, loc_section_label);
+      dwarf2_start_section (debug_loc_section, loc_section_label);
       output_location_lists (die);
     }
 
   /* Output public names table if necessary.  */
   if (!VEC_empty (pubname_entry, pubname_table))
     {
-      switch_to_section (debug_pubnames_section);
+      dwarf2_start_section (debug_pubnames_section, NULL);
       output_pubnames (pubname_table);
     }
 
@@ -23069,19 +23089,20 @@  dwarf2out_finish (const char *filename)
      simply won't look for the section.  */
   if (!VEC_empty (pubname_entry, pubtype_table))
     {
-      switch_to_section (debug_pubtypes_section);
+      dwarf2_start_section (debug_pubtypes_section, NULL);
       output_pubnames (pubtype_table);
     }
 
   /* Output direct and virtual call tables if necessary.  */
   if (!VEC_empty (dcall_entry, dcall_table))
     {
-      switch_to_section (debug_dcall_section);
+      dwarf2_start_section (debug_dcall_section, NULL);
       output_dcall_table ();
     }
+
   if (!VEC_empty (vcall_entry, vcall_table))
     {
-      switch_to_section (debug_vcall_section);
+      dwarf2_start_section (debug_vcall_section, NULL);
       output_vcall_table ();
     }
 
@@ -23089,15 +23110,14 @@  dwarf2out_finish (const char *filename)
      table, so don't write it out if we don't have any.  */
   if (fde_table_in_use)
     {
-      switch_to_section (debug_aranges_section);
+      dwarf2_start_section (debug_aranges_section, NULL);
       output_aranges ();
     }
 
   /* Output ranges section if necessary.  */
   if (ranges_table_in_use)
     {
-      switch_to_section (debug_ranges_section);
-      ASM_OUTPUT_LABEL (asm_out_file, ranges_section_label);
+      dwarf2_start_section (debug_ranges_section, ranges_section_label);
       output_ranges ();
     }
 
Index: gcc/config/darwin-protos.h
===================================================================
--- gcc/config/darwin-protos.h	(revision 166029)
+++ gcc/config/darwin-protos.h	(working copy)
@@ -83,10 +83,14 @@  extern tree darwin_handle_weak_import_attribute (t
 extern void machopic_output_stub (FILE *, const char *, const char *);
 extern void darwin_globalize_label (FILE *, const char *);
 extern void darwin_assemble_visibility (tree, int);
+
+extern void darwin_asm_output_dwarf_section_start_info (FILE *file, 
+							section *sect);
 extern void darwin_asm_output_dwarf_delta (FILE *, int, const char *,
 					   const char *);
 extern void darwin_asm_output_dwarf_offset (FILE *, int, const char *,
 					    section *);
+
 extern void darwin_asm_declare_constant_name (FILE *, const char *,
 					      const_tree, HOST_WIDE_INT);
 extern bool darwin_binds_local_p (const_tree);
Index: gcc/config/darwin.c
===================================================================
--- gcc/config/darwin.c	(revision 166029)
+++ gcc/config/darwin.c	(working copy)
@@ -1675,6 +1675,26 @@  darwin_assemble_visibility (tree decl, int vis)
 	     "not supported in this configuration; ignored");
 }
 
+/* So that we can compute dwarf offsets within sections, we emit a known
+   section marker at the begining of the section.  This is distinct from
+   the ones emitted by dwarf2out.  The label is constructed by extracting
+   sectname from __DWARF,__sectname,...  The hook should be invoked
+   once, after the first switch to the section.  */
+   
+void
+darwin_asm_output_dwarf_section_start_info (FILE *file, section *sect)
+{
+  const char *dnam;
+  int namelen;
+  gcc_assert (sect && (sect->common.flags & (SECTION_NAMED|SECTION_DEBUG)));
+  dnam = ((struct named_section *)sect)->name;
+  gcc_assert (strncmp (dnam, "__DWARF,", 8) == 0);
+  gcc_assert (strchr (dnam + 8, ','));
+
+  namelen = strchr (dnam + 8, ',') - (dnam + 8);
+  fprintf (file, "Lsection%.*s:\n", namelen, dnam + 8);
+}
+
 /* Output a difference of two labels that will be an assembly time
    constant if the two labels are local.  (.long lab1-lab2 will be
    very different if lab1 is at the boundary between two sections; it
@@ -1703,49 +1723,6 @@  darwin_asm_output_dwarf_delta (FILE *file, int siz
     fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
 }
 
-/* Output labels for the start of the DWARF sections if necessary.
-   Initialize the stuff we need for LTO long section names support.  */
-void
-darwin_file_start (void)
-{
-  if (write_symbols == DWARF2_DEBUG)
-    {
-      static const char * const debugnames[] =
-	{
-	  DEBUG_FRAME_SECTION,
-	  DEBUG_INFO_SECTION,
-	  DEBUG_ABBREV_SECTION,
-	  DEBUG_ARANGES_SECTION,
-	  DEBUG_MACINFO_SECTION,
-	  DEBUG_LINE_SECTION,
-	  DEBUG_LOC_SECTION,
-	  DEBUG_PUBNAMES_SECTION,
-	  DEBUG_PUBTYPES_SECTION,
-	  DEBUG_STR_SECTION,
-	  DEBUG_RANGES_SECTION
-	};
-      size_t i;
-
-      for (i = 0; i < ARRAY_SIZE (debugnames); i++)
-	{
-	  int namelen;
-
-	  switch_to_section (get_section (debugnames[i], SECTION_DEBUG, NULL));
-
-	  gcc_assert (strncmp (debugnames[i], "__DWARF,", 8) == 0);
-	  gcc_assert (strchr (debugnames[i] + 8, ','));
-
-	  namelen = strchr (debugnames[i] + 8, ',') - (debugnames[i] + 8);
-	  fprintf (asm_out_file, "Lsection%.*s:\n", namelen, debugnames[i] + 8);
-	}
-    }
-
-  /* We fill this obstack with the complete section text for the lto section
-     names to write in darwin_file_end.  */
-  obstack_init (&lto_section_names_obstack);
-  lto_section_names_offset = 0;
-}
-
 /* Output an offset in a DWARF section on Darwin.  On Darwin, DWARF section
    offsets are not represented using relocs in .o files; either the
    section never leaves the .o file, or the linker or other tool is
@@ -1767,7 +1744,17 @@  darwin_asm_output_dwarf_offset (FILE *file, int si
   darwin_asm_output_dwarf_delta (file, size, lab, sname);
 }
 
+/* Initialize the stuff we need for LTO long section names support.  */
 void
+darwin_file_start (void)
+{
+  /* We fill this obstack with the complete section text for the lto section
+     names to write in darwin_file_end.  */
+  obstack_init (&lto_section_names_obstack);
+  lto_section_names_offset = 0;
+}
+
+void
 darwin_file_end (void)
 {
   const char *lto_section_names;
Index: gcc/config/darwin.h
===================================================================
--- gcc/config/darwin.h	(revision 166029)
+++ gcc/config/darwin.h	(working copy)
@@ -481,6 +481,8 @@  extern GTY(()) int darwin_ms_struct;
 #define DEBUG_PUBTYPES_SECTION	"__DWARF,__debug_pubtypes,regular,debug"
 #define DEBUG_STR_SECTION	"__DWARF,__debug_str,regular,debug"
 #define DEBUG_RANGES_SECTION	"__DWARF,__debug_ranges,regular,debug"
+#define DEBUG_DCALL_SECTION	"__DWARF,__debug_dcall,regular,debug"
+#define DEBUG_VCALL_SECTION	"__DWARF,__debug_vcall,regular,debug"
 
 #define TARGET_WANT_DEBUG_PUB_SECTIONS true
 
@@ -930,6 +932,12 @@  enum machopic_addr_class {
    ? (DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4) : \
      ((CODE) == 1 || (GLOBAL) == 0) ? DW_EH_PE_pcrel : DW_EH_PE_absptr)
 
+/* Darwin maintains local offsets per dwarf debug section in each object.
+   To support this, we need to provide a start label for each dwarf debug
+   section used.  */
+#define TARGET_ASM_OUTPUT_DWARF_SECTION_START_INFO \
+	darwin_asm_output_dwarf_section_start_info
+
 #define ASM_OUTPUT_DWARF_DELTA(FILE,SIZE,LABEL1,LABEL2)  \
   darwin_asm_output_dwarf_delta (FILE, SIZE, LABEL1, LABEL2)