DWARF for Darwin!

Geoffrey Keating gkeating@apple.com
Fri Mar 17 00:27:00 GMT 2006


This patch implements full DWARF functionality for Darwin.

The previous DWARF had various problems involving linking, ranging
from 'doesn't link' to 'is slow'.  We've decided to avoid those
problems by declaring that DWARF does not participate in linking: no
DWARF appears in executables or other linked products.  The debugger
finds the DWARF in the .o files by using information placed in the
executable by the linker (at present, in the form of STABS entries in
the symbol table).  There is a utility that can take an executable,
find all the .o files, and create a separate file that is sufficient
to debug the executable without the .o files.

So, what this patch does is:
1. Change the DWARF segment names to be __DWARF, and add an attribute
that tells the linker to ignore them.  (You can still have the old
__DWARFA segment, and it will be linked into the final executable, but
the debugger doesn't support it any more.)
2. Ensure that there are no labels defined in DWARF sections after
assembly.
3. Arrange for those parts of the DWARF information that should be
offsets to the start of some section to be calculated at assembly time
using .set directives and subtraction; this can be done because the
DWARF never gets into the final executable and so no relocs are
necessary.  (This part accounts for most of the changes in the
patch).  This is necessary because in Mach-O, even in .o files,
addresses don't overlap, so we can't play the 'all DWARF sections
start at address 0' trick that ELF uses.

To work, this requires cctools-590.36, see
<http://gcc.gnu.org/ml/gcc/2006-03/msg00507.html>.

DWARF is not switched on by default, but only because people outside
Apple won't yet have a GDB that understands it.

Bootstrapped & tested on powerpc-darwin8.

-- 
- Geoffrey Keating <geoffk@apple.com>

===File ~/patches/gcc-darwin-dwarf-1.patch==================
2006-03-16  Geoffrey Keating  <geoffk@apple.com>

	* doc/tm.texi (SDB and DWARF): Add extra parameter to
	ASM_OUTPUT_DWARF_OFFSET.  Use @var to indicate metavariables.
	* dwarf2asm.h (dw2_asm_output_offset): Add section parameter.
	* dwarf2asm.c (dw2_asm_output_offset): Add base section parameter.
	Pass to ASM_OUTPUT_DWARF_OFFSET.
	* dwarf2out.c (debug_frame_section): New.
	(output_call_frame_info): Use debug_frame_section.  Pass it to
	dw2_asm_output_offset.
	(output_die): Pass appropriate section to dw2_asm_output_offset.
	(output_compilation_unit_header): Likewise.
	(output_pubnames): Likewise.
	(output_aranges): Likewise.
	(enum dw_val_class): Break dw_val_class_lbl_offset into
	dw_val_class_lineptr and dw_val_class_macptr.
	(add_AT_lbl_offset): Delete.
	(add_AT_lineptr): New.
	(add_AT_macptr): New.
	(AT_lbl): Expect a lineptr or macptr.
	(print_die): Handle dw_val_class_lineptr and dw_val_class_macptr.
	(attr_checksum): Likewise.
	(same_dw_val_p): Likewise.
	(size_of_die): Likewise.
	(value_format): Likewise.
	(output_die): Likewise.
	(dwarf2out_finish): Call add_AT_lineptr and add_AT_macptr instead of
	add_AT_lbl_offset.
	* config/i386/cygming.h (ASM_OUTPUT_DWARF_OFFSET): Add extra parameter.
	* config/i386/i386.c (x86_file_start): Call darwin_file_start.
	* config/darwin-protos.h (darwin_file_start): New.
	(darwin_asm_output_dwarf_offset): New.
	* config/ia64/ia64.h (ASM_OUTPUT_DWARF_OFFSET): Add extra parameter.
	* config/rs6000/rs6000.c (rs6000_darwin_file_start): Call
	darwin_file_start.
	* config/darwin.c (darwin_emit_unwind_label): Don't output label
	if not EH section; simplify.
	(darwin_file_start): New.
	(darwin_asm_output_dwarf_offset): New.
	* config/darwin.h (DEBUG_FRAME_SECTION): In __DWARF segment,
	mark as 'debug'.
	(DEBUG_INFO_SECTION): Likewise.
	(DEBUG_ABBREV_SECTION): Likewise.
	(DEBUG_ARANGES_SECTION): Likewise.
	(DEBUG_MACINFO_SECTION): Likewise.
	(DEBUG_LINE_SECTION): Likewise.
	(DEBUG_LOC_SECTION): Likewise.
	(DEBUG_PUBNAMES_SECTION): Likewise.
	(DEBUG_STR_SECTION): Likewise.
	(DEBUG_RANGES_SECTION): Likewise.
	(FRAME_BEGIN_LABEL): Must start with 'L' in debug section.
	(ASM_OUTPUT_DWARF_OFFSET): New.

Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 112129)
+++ doc/tm.texi	(working copy)
@@ -8424,18 +8424,18 @@
 
 @defmac ASM_OUTPUT_DWARF_DELTA (@var{stream}, @var{size}, @var{label1}, @var{label2})
 A C statement to issue assembly directives that create a difference
-between the two given labels, using an integer of the given size.
+@var{lab1} minus @var{lab2}, using an integer of the given @var{size}.
 @end defmac
 
-@defmac ASM_OUTPUT_DWARF_OFFSET (@var{stream}, @var{size}, @var{label})
+@defmac ASM_OUTPUT_DWARF_OFFSET (@var{stream}, @var{size}, @var{label}, @var{section})
 A C statement to issue assembly directives that create a
-section-relative reference to the given label, using an integer of the
-given size.
+section-relative reference to the given @var{label}, using an integer of the
+given @var{size}.  The label is known to be defined in the given @var{section}.
 @end defmac
 
 @defmac ASM_OUTPUT_DWARF_PCREL (@var{stream}, @var{size}, @var{label})
 A C statement to issue assembly directives that create a self-relative
-reference to the given label, using an integer of the given size.
+reference to the given @var{label}, using an integer of the given @var{size}.
 @end defmac
 
 @deftypefn {Target Hook} void TARGET_ASM_OUTPUT_DWARF_DTPREL (FILE *@var{FILE}, int @var{size}, rtx @var{x})
Index: dwarf2asm.c
===================================================================
--- dwarf2asm.c	(revision 112129)
+++ dwarf2asm.c	(working copy)
@@ -119,14 +119,15 @@
   va_end (ap);
 }
 
-/* Output a section-relative reference to a label.  In general this
-   can only be done for debugging symbols.  E.g. on most targets with
-   the GNU linker, this is accomplished with a direct reference and
-   the knowledge that the debugging section will be placed at VMA 0.
-   Some targets have special relocations for this that we must use.  */
+/* Output a section-relative reference to a LABEL, which was placed in
+   BASE.  In general this can only be done for debugging symbols.
+   E.g. on most targets with the GNU linker, this is accomplished with
+   a direct reference and the knowledge that the debugging section
+   will be placed at VMA 0.  Some targets have special relocations for
+   this that we must use.  */
 
 void
-dw2_asm_output_offset (int size, const char *label,
+dw2_asm_output_offset (int size, const char *label, section * base,
 		       const char *comment, ...)
 {
   va_list ap;
@@ -134,7 +135,7 @@
   va_start (ap, comment);
 
 #ifdef ASM_OUTPUT_DWARF_OFFSET
-  ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label);
+  ASM_OUTPUT_DWARF_OFFSET (asm_out_file, size, label, base);
 #else
   dw2_assemble_integer (size, gen_rtx_SYMBOL_REF (Pmode, label));
 #endif
Index: dwarf2asm.h
===================================================================
--- dwarf2asm.h	(revision 112129)
+++ dwarf2asm.h	(working copy)
@@ -1,5 +1,5 @@
 /* Dwarf2 assembler output helper routines.
-   Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -29,8 +29,9 @@
 				  const char *, ...)
      ATTRIBUTE_NULL_PRINTF_4;
 
-extern void dw2_asm_output_offset (int, const char *, const char *, ...)
-     ATTRIBUTE_NULL_PRINTF_3;
+extern void dw2_asm_output_offset (int, const char *, section *, 
+				   const char *, ...)
+     ATTRIBUTE_NULL_PRINTF_4;
 
 extern void dw2_asm_output_addr (int, const char *, const char *, ...)
      ATTRIBUTE_NULL_PRINTF_3;
Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 112129)
+++ dwarf2out.c	(working copy)
@@ -158,6 +158,7 @@
 static GTY(()) section *debug_pubnames_section;
 static GTY(()) section *debug_str_section;
 static GTY(()) section *debug_ranges_section;
+static GTY(()) section *debug_frame_section;
 
 /* How to start an assembler comment.  */
 #ifndef ASM_COMMENT_START
@@ -2212,7 +2213,7 @@
   if (for_eh)
     switch_to_eh_frame_section ();
   else
-    switch_to_section (get_section (DEBUG_FRAME_SECTION, SECTION_DEBUG, NULL));
+    switch_to_section (debug_frame_section);
 
   ASM_GENERATE_INTERNAL_LABEL (section_start_label, FRAME_BEGIN_LABEL, for_eh);
   ASM_OUTPUT_LABEL (asm_out_file, section_start_label);
@@ -2360,7 +2361,7 @@
 	dw2_asm_output_delta (4, l1, section_start_label, "FDE CIE offset");
       else
 	dw2_asm_output_offset (DWARF_OFFSET_SIZE, section_start_label,
-			       "FDE CIE offset");
+			       debug_frame_section, "FDE CIE offset");
 
       if (for_eh)
 	{
@@ -2655,8 +2656,9 @@
   dw_val_class_die_ref,
   dw_val_class_fde_ref,
   dw_val_class_lbl_id,
-  dw_val_class_lbl_offset,
-  dw_val_class_str
+  dw_val_class_lineptr,
+  dw_val_class_str,
+  dw_val_class_macptr
 };
 
 /* Describe a double word constant value.  */
@@ -3984,7 +3986,8 @@
 static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx);
 static inline rtx AT_addr (dw_attr_ref);
 static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *);
-static void add_AT_lbl_offset (dw_die_ref, enum dwarf_attribute, const char *);
+static void add_AT_lineptr (dw_die_ref, enum dwarf_attribute, const char *);
+static void add_AT_macptr (dw_die_ref, enum dwarf_attribute, const char *);
 static void add_AT_offset (dw_die_ref, enum dwarf_attribute,
 			   unsigned HOST_WIDE_INT);
 static void add_AT_range_list (dw_die_ref, enum dwarf_attribute,
@@ -5159,20 +5162,38 @@
   add_dwarf_attr (die, attr);
 }
 
-/* Add a section offset attribute value to a DIE.  */
+/* Add a section offset attribute value to a DIE, an offset into the
+   debug_line section.  */
 
 static inline void
-add_AT_lbl_offset (dw_die_ref die, enum dwarf_attribute attr_kind, const char *label)
+add_AT_lineptr (dw_die_ref die, enum dwarf_attribute attr_kind,
+		const char *label)
 {
   dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
 
   attr->dw_attr_next = NULL;
   attr->dw_attr = attr_kind;
-  attr->dw_attr_val.val_class = dw_val_class_lbl_offset;
+  attr->dw_attr_val.val_class = dw_val_class_lineptr;
   attr->dw_attr_val.v.val_lbl_id = xstrdup (label);
   add_dwarf_attr (die, attr);
 }
 
+/* Add a section offset attribute value to a DIE, an offset into the
+   debug_macinfo section.  */
+
+static inline void
+add_AT_macptr (dw_die_ref die, enum dwarf_attribute attr_kind,
+	       const char *label)
+{
+  dw_attr_ref attr = ggc_alloc (sizeof (dw_attr_node));
+
+  attr->dw_attr_next = NULL;
+  attr->dw_attr = attr_kind;
+  attr->dw_attr_val.val_class = dw_val_class_macptr;
+  attr->dw_attr_val.v.val_lbl_id = xstrdup (label);
+  add_dwarf_attr (die, attr);
+}
+
 /* Add an offset attribute value to a DIE.  */
 
 static inline void
@@ -5207,7 +5228,8 @@
 AT_lbl (dw_attr_ref a)
 {
   gcc_assert (a && (AT_class (a) == dw_val_class_lbl_id
-		    || AT_class (a) == dw_val_class_lbl_offset));
+		    || AT_class (a) == dw_val_class_lineptr
+		    || AT_class (a) == dw_val_class_macptr));
   return a->dw_attr_val.v.val_lbl_id;
 }
 
@@ -5723,7 +5745,8 @@
 	    fprintf (outfile, "die -> <null>");
 	  break;
 	case dw_val_class_lbl_id:
-	case dw_val_class_lbl_offset:
+	case dw_val_class_lineptr:
+	case dw_val_class_macptr:
 	  fprintf (outfile, "label: %s", AT_lbl (a));
 	  break;
 	case dw_val_class_str:
@@ -5937,7 +5960,8 @@
 
     case dw_val_class_fde_ref:
     case dw_val_class_lbl_id:
-    case dw_val_class_lbl_offset:
+    case dw_val_class_lineptr:
+    case dw_val_class_macptr:
       break;
 
     default:
@@ -6038,7 +6062,8 @@
 
     case dw_val_class_fde_ref:
     case dw_val_class_lbl_id:
-    case dw_val_class_lbl_offset:
+    case dw_val_class_lineptr:
+    case dw_val_class_macptr:
       return 1;
 
     default:
@@ -6612,7 +6637,8 @@
 	case dw_val_class_lbl_id:
 	  size += DWARF2_ADDR_SIZE;
 	  break;
-	case dw_val_class_lbl_offset:
+	case dw_val_class_lineptr:
+	case dw_val_class_macptr:
 	  size += DWARF_OFFSET_SIZE;
 	  break;
 	case dw_val_class_str:
@@ -6804,7 +6830,8 @@
       return DW_FORM_data;
     case dw_val_class_lbl_id:
       return DW_FORM_addr;
-    case dw_val_class_lbl_offset:
+    case dw_val_class_lineptr:
+    case dw_val_class_macptr:
       return DW_FORM_data;
     case dw_val_class_str:
       return AT_string_form (a);
@@ -7023,7 +7050,7 @@
 	    sprintf (p, "+" HOST_WIDE_INT_PRINT_HEX,
 		     a->dw_attr_val.v.val_offset);
 	    dw2_asm_output_offset (DWARF_OFFSET_SIZE, ranges_section_label,
-				   "%s", name);
+				   debug_ranges_section, "%s", name);
 	    *p = '\0';
 	  }
 	  break;
@@ -7105,7 +7132,8 @@
 	    char *sym = AT_loc_list (a)->ll_symbol;
 
 	    gcc_assert (sym);
-	    dw2_asm_output_offset (DWARF_OFFSET_SIZE, sym, "%s", name);
+	    dw2_asm_output_offset (DWARF_OFFSET_SIZE, sym, debug_loc_section,
+				   "%s", name);
 	  }
 	  break;
 
@@ -7115,7 +7143,8 @@
 	      char *sym = AT_ref (a)->die_symbol;
 
 	      gcc_assert (sym);
-	      dw2_asm_output_offset (DWARF2_ADDR_SIZE, sym, "%s", name);
+	      dw2_asm_output_offset (DWARF2_ADDR_SIZE, sym, debug_info_section,
+				     "%s", name);
 	    }
 	  else
 	    {
@@ -7131,7 +7160,8 @@
 
 	    ASM_GENERATE_INTERNAL_LABEL (l1, FDE_LABEL,
 					 a->dw_attr_val.v.val_fde_index * 2);
-	    dw2_asm_output_offset (DWARF_OFFSET_SIZE, l1, "%s", name);
+	    dw2_asm_output_offset (DWARF_OFFSET_SIZE, l1, debug_frame_section,
+				   "%s", name);
 	  }
 	  break;
 
@@ -7139,14 +7169,21 @@
 	  dw2_asm_output_addr (DWARF2_ADDR_SIZE, AT_lbl (a), "%s", name);
 	  break;
 
-	case dw_val_class_lbl_offset:
-	  dw2_asm_output_offset (DWARF_OFFSET_SIZE, AT_lbl (a), "%s", name);
+	case dw_val_class_lineptr:
+	  dw2_asm_output_offset (DWARF_OFFSET_SIZE, AT_lbl (a),
+				 debug_line_section, "%s", name);
 	  break;
 
+	case dw_val_class_macptr:
+	  dw2_asm_output_offset (DWARF_OFFSET_SIZE, AT_lbl (a),
+				 debug_macinfo_section, "%s", name);
+	  break;
+
 	case dw_val_class_str:
 	  if (AT_string_form (a) == DW_FORM_strp)
 	    dw2_asm_output_offset (DWARF_OFFSET_SIZE,
 				   a->dw_attr_val.v.val_str->label,
+				   debug_str_section,
 				   "%s: \"%s\"", name, AT_string (a));
 	  else
 	    dw2_asm_output_nstring (AT_string (a), -1, "%s", name);
@@ -7180,6 +7217,7 @@
 		       "Length of Compilation Unit Info");
   dw2_asm_output_data (2, DWARF_VERSION, "DWARF version number");
   dw2_asm_output_offset (DWARF_OFFSET_SIZE, abbrev_section_label,
+			 debug_abbrev_section,
 			 "Offset Into Abbrev. Section");
   dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)");
 }
@@ -7287,6 +7325,7 @@
 		       "Length of Public Names Info");
   dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version");
   dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_info_section_label,
+			 debug_info_section,
 			 "Offset of Compilation Unit Info");
   dw2_asm_output_data (DWARF_OFFSET_SIZE, next_die_offset,
 		       "Compilation Unit Length");
@@ -7345,6 +7384,7 @@
 		       "Length of Address Ranges Info");
   dw2_asm_output_data (2, DWARF_VERSION, "DWARF Version");
   dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_info_section_label,
+			 debug_info_section,
 			 "Offset of Compilation Unit Info");
   dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Size of Address");
   dw2_asm_output_data (1, 0, "Size of Segment Descriptor");
@@ -13732,6 +13772,8 @@
 				   DEBUG_STR_SECTION_FLAGS, NULL);
   debug_ranges_section = get_section (DEBUG_RANGES_SECTION,
 				      SECTION_DEBUG, NULL);
+  debug_frame_section = get_section (DEBUG_FRAME_SECTION,
+				     SECTION_DEBUG, NULL);
 
   ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
   ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label,
@@ -14142,11 +14184,11 @@
     }
 
   if (debug_info_level >= DINFO_LEVEL_NORMAL)
-    add_AT_lbl_offset (comp_unit_die, DW_AT_stmt_list,
-		       debug_line_section_label);
+    add_AT_lineptr (comp_unit_die, DW_AT_stmt_list,
+		    debug_line_section_label);
 
   if (debug_info_level >= DINFO_LEVEL_VERBOSE)
-    add_AT_lbl_offset (comp_unit_die, DW_AT_macro_info, macinfo_section_label);
+    add_AT_macptr (comp_unit_die, DW_AT_macro_info, macinfo_section_label);
 
   /* Output all of the compilation units.  We put the main one last so that
      the offsets are available to output_pubnames.  */
Index: config/i386/cygming.h
===================================================================
--- config/i386/cygming.h	(revision 112129)
+++ config/i386/cygming.h	(working copy)
@@ -37,13 +37,13 @@
 /* Use section relative relocations for debugging offsets.  Unlike
    other targets that fake this by putting the section VMA at 0, PE
    won't allow it.  */
-#define ASM_OUTPUT_DWARF_OFFSET(FILE, SIZE, LABEL)    \
-  do {                                                \
-    if (SIZE != 4)                                    \
-      abort ();                                       \
-                                                      \
-    fputs ("\t.secrel32\t", FILE);                    \
-    assemble_name (FILE, LABEL);                      \
+#define ASM_OUTPUT_DWARF_OFFSET(FILE, SIZE, LABEL, SECTION)	\
+  do {								\
+    if (SIZE != 4)						\
+      abort ();							\
+								\
+    fputs ("\t.secrel32\t", FILE);				\
+    assemble_name (FILE, LABEL);				\
   } while (0)
 #endif
 
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 112129)
+++ config/i386/i386.c	(working copy)
@@ -17457,6 +17457,9 @@
 x86_file_start (void)
 {
   default_file_start ();
+#if TARGET_MACHO
+  darwin_file_start ();
+#endif
   if (X86_FILE_START_VERSION_DIRECTIVE)
     fputs ("\t.version\t\"01.01\"\n", asm_out_file);
   if (X86_FILE_START_FLTUSED)
Index: config/darwin-protos.h
===================================================================
--- config/darwin-protos.h	(revision 112129)
+++ config/darwin-protos.h	(working copy)
@@ -66,6 +66,7 @@
 extern void darwin_pragma_options (struct cpp_reader *);
 extern void darwin_pragma_unused (struct cpp_reader *);
 
+extern void darwin_file_start (void);
 extern void darwin_file_end (void);
 
 extern void darwin_mark_decl_preserved (const char *);
@@ -78,6 +79,8 @@
 extern void darwin_assemble_visibility (tree, int);
 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 bool darwin_binds_local_p (tree);
 extern void darwin_cpp_builtins (struct cpp_reader *);
 extern void darwin_asm_output_anchor (rtx symbol);
Index: config/ia64/ia64.h
===================================================================
--- config/ia64/ia64.h	(revision 112129)
+++ config/ia64/ia64.h	(working copy)
@@ -1891,12 +1891,12 @@
 /* Use section-relative relocations for debugging offsets.  Unlike other
    targets that fake this by putting the section VMA at 0, IA-64 has
    proper relocations for them.  */
-#define ASM_OUTPUT_DWARF_OFFSET(FILE, SIZE, LABEL)	\
-  do {							\
-    fputs (integer_asm_op (SIZE, FALSE), FILE);		\
-    fputs ("@secrel(", FILE);				\
-    assemble_name (FILE, LABEL);			\
-    fputc (')', FILE);					\
+#define ASM_OUTPUT_DWARF_OFFSET(FILE, SIZE, LABEL, SECTION)	\
+  do {								\
+    fputs (integer_asm_op (SIZE, FALSE), FILE);			\
+    fputs ("@secrel(", FILE);					\
+    assemble_name (FILE, LABEL);				\
+    fputc (')', FILE);						\
   } while (0)
 
 /* Emit a PC-relative relocation.  */
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c	(revision 112129)
+++ config/rs6000/rs6000.c	(working copy)
@@ -18048,6 +18048,7 @@
   size_t i;
 
   rs6000_file_start ();
+  darwin_file_start ();
 
   /* Determine the argument to -mcpu=.  Default to G3 if not specified.  */
   for (i = 0; i < ARRAY_SIZE (rs6000_select); i++)
Index: config/darwin.c
===================================================================
--- config/darwin.c	(revision 112129)
+++ config/darwin.c	(working copy)
@@ -1328,32 +1328,17 @@
     ? DECL_ASSEMBLER_NAME (decl)
     : DECL_NAME (decl);
 
-  const char *prefix = user_label_prefix;
-
   const char *base = IDENTIFIER_POINTER (id);
-  unsigned int base_len = IDENTIFIER_LENGTH (id);
 
-  const char *suffix = ".eh";
-
-  int need_quotes = name_needs_quotes (base);
-  int quotes_len = need_quotes ? 2 : 0;
+  bool need_quotes = name_needs_quotes (base);
   char *lab;
 
   if (! for_eh)
-    suffix = ".eh1";
+    return;
 
-  lab = XNEWVEC (char, strlen (prefix)
-		 + base_len + strlen (suffix) + quotes_len + 1);
-  lab[0] = '\0';
+  lab = concat (need_quotes ? "\"" : "", user_label_prefix, base, ".eh",
+		need_quotes ? "\"" : "", NULL);
 
-  if (need_quotes)
-    strcat(lab, "\"");
-  strcat(lab, prefix);
-  strcat(lab, base);
-  strcat(lab, suffix);
-  if (need_quotes)
-    strcat(lab, "\"");
-
   if (TREE_PUBLIC (decl))
     fprintf (file, "\t%s %s\n",
 	     (DECL_VISIBILITY (decl) != VISIBILITY_HIDDEN
@@ -1457,7 +1442,64 @@
     fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
 }
 
+/* Output labels for the start of the DWARF sections if necessary.  */
 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_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);
+	}
+    }
+}
+
+/* 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
+   responsible for parsing the DWARF and updating the offsets.  */
+
+void
+darwin_asm_output_dwarf_offset (FILE *file, int size, const char * lab,
+				section *base)
+{
+  char sname[64];
+  int namelen;
+  
+  gcc_assert (base->common.flags & SECTION_NAMED);
+  gcc_assert (strncmp (base->named.name, "__DWARF,", 8) == 0);
+  gcc_assert (strchr (base->named.name + 8, ','));
+
+  namelen = strchr (base->named.name + 8, ',') - (base->named.name + 8);
+  sprintf (sname, "*Lsection%.*s", namelen, base->named.name + 8);
+  darwin_asm_output_dwarf_delta (file, size, lab, sname);
+}
+
+void
 darwin_file_end (void)
 {
   machopic_finish (asm_out_file);
Index: config/darwin.h
===================================================================
--- config/darwin.h	(revision 112129)
+++ config/darwin.h	(working copy)
@@ -360,16 +360,16 @@
 #define DWARF2_DEBUGGING_INFO
 #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
 
-#define DEBUG_FRAME_SECTION   "__DWARFA,__debug_frame,coalesced,no_toc+strip_static_syms"
-#define DEBUG_INFO_SECTION    "__DWARFA,__debug_info"
-#define DEBUG_ABBREV_SECTION  "__DWARFA,__debug_abbrev"
-#define DEBUG_ARANGES_SECTION "__DWARFA,__debug_aranges"
-#define DEBUG_MACINFO_SECTION "__DWARFA,__debug_macinfo"
-#define DEBUG_LINE_SECTION    "__DWARFA,__debug_line"
-#define DEBUG_LOC_SECTION     "__DWARFA,__debug_loc"
-#define DEBUG_PUBNAMES_SECTION        "__DWARFA,__debug_pubnames"
-#define DEBUG_STR_SECTION     "__DWARFA,__debug_str"
-#define DEBUG_RANGES_SECTION  "__DWARFA,__debug_ranges"
+#define DEBUG_FRAME_SECTION	"__DWARF,__debug_frame,regular,debug"
+#define DEBUG_INFO_SECTION	"__DWARF,__debug_info,regular,debug"
+#define DEBUG_ABBREV_SECTION	"__DWARF,__debug_abbrev,regular,debug"
+#define DEBUG_ARANGES_SECTION	"__DWARF,__debug_aranges,regular,debug"
+#define DEBUG_MACINFO_SECTION	"__DWARF,__debug_macinfo,regular,debug"
+#define DEBUG_LINE_SECTION	"__DWARF,__debug_line,regular,debug"
+#define DEBUG_LOC_SECTION	"__DWARF,__debug_loc,regular,debug"
+#define DEBUG_PUBNAMES_SECTION	"__DWARF,__debug_pubnames,regular,debug"
+#define DEBUG_STR_SECTION	"__DWARF,__debug_str,regular,debug"
+#define DEBUG_RANGES_SECTION	"__DWARF,__debug_ranges,regular,debug"
 
 /* When generating stabs debugging, use N_BINCL entries.  */
 
@@ -439,9 +439,11 @@
 #define TARGET_USES_WEAK_UNWIND_INFO 1
 
 /* We need to use a nonlocal label for the start of an EH frame: the
-   Darwin linker requires that a coalesced section start with a label. */
+   Darwin linker requires that a coalesced section start with a label. 
+   Unfortunately, it also requires that 'debug' sections don't contain
+   labels.  */
 #undef FRAME_BEGIN_LABEL
-#define FRAME_BEGIN_LABEL "EH_frame"
+#define FRAME_BEGIN_LABEL (for_eh ? "EH_frame" : "Lframe")
 
 /* Emit a label for the FDE corresponding to DECL.  EMPTY means
    emit a label for an empty FDE. */
@@ -798,6 +800,9 @@
 #define ASM_OUTPUT_DWARF_DELTA(FILE,SIZE,LABEL1,LABEL2)  \
   darwin_asm_output_dwarf_delta (FILE, SIZE, LABEL1, LABEL2)
 
+#define ASM_OUTPUT_DWARF_OFFSET(FILE,SIZE,LABEL,BASE)  \
+  darwin_asm_output_dwarf_offset (FILE, SIZE, LABEL, BASE)
+
 #define ASM_MAYBE_OUTPUT_ENCODED_ADDR_RTX(ASM_OUT_FILE, ENCODING, SIZE, ADDR, DONE)	\
       if (ENCODING == ASM_PREFERRED_EH_DATA_FORMAT (2, 1)) {				\
 	darwin_non_lazy_pcrel (ASM_OUT_FILE, ADDR);					\
============================================================



More information about the Gcc-patches mailing list