target.h (struct gcc_target): New field terminate_dw2_eh_frame_info.
authorStan Shebs <shebs@apple.com>
Fri, 13 Sep 2002 03:44:54 +0000 (03:44 +0000)
committerStan Shebs <shebs@gcc.gnu.org>
Fri, 13 Sep 2002 03:44:54 +0000 (03:44 +0000)
        * target.h (struct gcc_target): New field
        terminate_dw2_eh_frame_info.
        * target-def.h (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Define.
        (TARGET_INITIALIZER): Add it.
        * dwarf2out.c (output_call_frame_info): Use target hook.
        * dwarf2asm.c (dw2_asm_output_delta): Use macro
        ASM_OUTPUT_DWARF_DELTA if defined.
        * doc/tm.texi (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Document.
        (ASM_OUTPUT_DWARF_DELTA): Ditto.
        (ASM_OUTPUT_DWARF_OFFSET): Ditto.
        (ASM_OUTPUT_DWARF_PCREL): Ditto.
        * config.gcc (i[34567]86-*-darwin*): Define extra_parts.
        (powerpc-*-darwin*): Ditto.
        * crtstuff.c [OBJECT_FORMAT_MACHO]: Update the Mach-O bits
        to work correctly for Darwin.
        * config/darwin.h (OBJECT_FORMAT_MACHO): Define.
        (STARTFILE_SPEC): Add crtbegin.o.
        (ENDFILE_SPEC): Define.
        (EXTRA_SECTION_FUNCTIONS): Put gcc_except_tab in data segment.
        (ASM_PREFERRED_EH_DATA_FORMAT): Handle more cases.
        (ASM_OUTPUT_DWARF_DELTA): Define.
        (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Define.
        * config/darwin.c (darwin_asm_output_dwarf_delta): New function.

From-SVN: r57089

gcc/ChangeLog
gcc/config.gcc
gcc/config/darwin.c
gcc/config/darwin.h
gcc/crtstuff.c
gcc/doc/tm.texi
gcc/dwarf2asm.c
gcc/dwarf2out.c
gcc/target-def.h
gcc/target.h

index bad52cacec0d8dcf18fcfd90b8f2deabac18c82b..a5bdc1d005962ff16a226d9931ff729f770de5a6 100644 (file)
@@ -1,3 +1,29 @@
+2002-09-12  Stan Shebs  <shebs@apple.com>
+
+       * target.h (struct gcc_target): New field
+       terminate_dw2_eh_frame_info.
+       * target-def.h (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Define.
+       (TARGET_INITIALIZER): Add it.
+       * dwarf2out.c (output_call_frame_info): Use target hook.
+       * dwarf2asm.c (dw2_asm_output_delta): Use macro
+       ASM_OUTPUT_DWARF_DELTA if defined.
+       * doc/tm.texi (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Document.
+       (ASM_OUTPUT_DWARF_DELTA): Ditto.
+       (ASM_OUTPUT_DWARF_OFFSET): Ditto.
+       (ASM_OUTPUT_DWARF_PCREL): Ditto.
+       * config.gcc (i[34567]86-*-darwin*): Define extra_parts.
+       (powerpc-*-darwin*): Ditto.
+       * crtstuff.c [OBJECT_FORMAT_MACHO]: Update the Mach-O bits
+       to work correctly for Darwin.
+       * config/darwin.h (OBJECT_FORMAT_MACHO): Define.
+       (STARTFILE_SPEC): Add crtbegin.o.
+       (ENDFILE_SPEC): Define.
+       (EXTRA_SECTION_FUNCTIONS): Put gcc_except_tab in data segment.
+       (ASM_PREFERRED_EH_DATA_FORMAT): Handle more cases.
+       (ASM_OUTPUT_DWARF_DELTA): Define.
+       (TARGET_TERMINATE_DW2_EH_FRAME_INFO): Define.
+       * config/darwin.c (darwin_asm_output_dwarf_delta): New function.
+
 2002-09-13  Alan Modra  <amodra@bigpond.net.au>
 
        * config/rs6000/rs6000.c (rs6000_emit_load_toc_table): Remove "if"
index 8e9498f0f6e92eed0d82a06bb10a1c976523a5ee..e7bdc16607846da0481f68ee5f447a06b3d255e0 100644 (file)
@@ -980,6 +980,7 @@ i[34567]86-*-darwin*)
        target_gtfiles="\$(srcdir)/config/darwin.c"
        c_target_objs="darwin-c.o"
        cxx_target_objs="darwin-c.o"
+       extra_parts="crtbegin.o crtend.o"
        # Darwin linker does collect2 functionality
        use_collect2=no
        ;;
@@ -1946,6 +1947,7 @@ powerpc-*-darwin*)
        target_gtfiles="\$(srcdir)/config/darwin.c"
        c_target_objs="darwin-c.o"
        cxx_target_objs="darwin-c.o"
+       extra_parts="crtbegin.o crtend.o"
        # Darwin linker does collect2 functionality
        use_collect2=no
        extra_headers=altivec.h
index f1370b9d00a7e87cc6cd15d4b48063dbfb1d381f..670a57aa3d86580864385f1cd563120c291c5a4d 100644 (file)
@@ -1275,5 +1275,34 @@ darwin_globalize_label (stream, name)
     default_globalize_label (stream, name);
 }
 
+/* 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
+   will be relocated according to the second section, not the first,
+   so one ends up with a difference between labels in different
+   sections, which is bad in the dwarf2 eh context for instance.)  */
+
+static int darwin_dwarf_label_counter;
+
+void
+darwin_asm_output_dwarf_delta (file, size, lab1, lab2)
+     FILE *file;
+     int size ATTRIBUTE_UNUSED;
+     const char *lab1, *lab2;
+{
+  const char *p = lab1 + (lab1[0] == '*');
+  int islocaldiff = (p[0] == 'L');
+
+  if (islocaldiff)
+    fprintf (file, "\t.set L$set$%d,", darwin_dwarf_label_counter);
+  else
+    fprintf (file, "\t%s\t", ".long");
+  assemble_name (file, lab1);
+  fprintf (file, "-");
+  assemble_name (file, lab2);
+  if (islocaldiff)
+    fprintf (file, "\n\t.long L$set$%d", darwin_dwarf_label_counter++);
+}
+
 #include "gt-darwin.h"
 
index ba7cb66cc22609b7d6ecf51db4ee1c1c7fd3f8d4..0c327b93b3071152063af1b528c2e6aa0ce8a20c 100644 (file)
@@ -35,6 +35,12 @@ Boston, MA 02111-1307, USA.  */
    leave it undefined and expect system builders to set configure args
    correctly.  */
 
+/* One of Darwin's NeXT legacies is the Mach-O format, which is partly
+   like a.out and partly like COFF, with additional features like
+   multi-architecture binary support.  */
+
+#define OBJECT_FORMAT_MACHO
+
 /* Suppress g++ attempt to link in the math library automatically.
    (Some Darwin versions have a libm, but they seem to cause problems
    for C++ executables.)  */
@@ -92,8 +98,12 @@ Boston, MA 02111-1307, USA.  */
 
 #undef STARTFILE_SPEC
 #define STARTFILE_SPEC  \
-  "%{pg:%{static:-lgcrt0.o}%{!static:-lgcrt1.o}} \
-    %{!pg:%{static:-lcrt0.o}%{!static:-lcrt1.o}}"
+  "%{pg:%{static:-lgcrt0.o}%{!static:-lgcrt1.o -lcrtbegin.o}} \
+    %{!pg:%{static:-lcrt0.o}%{!static:-lcrt1.o -lcrtbegin.o}}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC \
+  "-lcrtend.o"
 
 #undef DOLLARS_IN_IDENTIFIERS
 #define DOLLARS_IN_IDENTIFIERS 2
@@ -131,7 +141,6 @@ do { text_section ();                                                       \
 #define TARGET_ASM_CONSTRUCTOR  machopic_asm_out_constructor
 #define TARGET_ASM_DESTRUCTOR   machopic_asm_out_destructor
 
-
 /* Don't output a .file directive.  That is only used by the assembler for
    error reporting.  */
 
@@ -425,7 +434,7 @@ SECTION_FUNCTION (machopic_picsymbol_stub_section,  \
                ".picsymbol_stub", 0)                   \
 SECTION_FUNCTION (darwin_exception_section,            \
                in_darwin_exception,                    \
-               ".section __TEXT,__gcc_except_tab", 0)  \
+               ".section __DATA,__gcc_except_tab", 0)  \
 SECTION_FUNCTION (darwin_eh_frame_section,             \
                in_darwin_eh_frame,                     \
                ".section __TEXT,__eh_frame", 0)        \
@@ -597,7 +606,14 @@ enum machopic_addr_class {
   
 #undef ASM_PREFERRED_EH_DATA_FORMAT
 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL)  \
-  (((CODE) == 1 || (GLOBAL) == 0) ? DW_EH_PE_pcrel : DW_EH_PE_absptr)
+  (((CODE) == 2 && (GLOBAL) == 1) \
+   ? (DW_EH_PE_pcrel | DW_EH_PE_indirect) : \
+     ((CODE) == 1 || (GLOBAL) == 0) ? DW_EH_PE_pcrel : DW_EH_PE_absptr)
+
+#define ASM_OUTPUT_DWARF_DELTA(FILE,SIZE,LABEL1,LABEL2)  \
+  darwin_asm_output_dwarf_delta (FILE, SIZE, LABEL1, LABEL2)
+
+#define TARGET_TERMINATE_DW2_EH_FRAME_INFO false
 
 #define DARWIN_REGISTER_TARGET_PRAGMAS(PFILE)                          \
   do {                                                                 \
index 041c810f6f453d197e6d764e14619ac78f8eae9f..125e236ee9c6cea6241fa7717de8aa0bff969b25 100644 (file)
@@ -545,64 +545,80 @@ __do_global_ctors (void)
 
 #else  /* OBJECT_FORMAT_MACHO */
 
-/* For Mach-O format executables, we assume that the system's runtime is
-   smart enough to handle constructors and destructors, but doesn't have
-   an init section (if it can't even handle constructors/destructors
-   you should be using INVOKE__main, not crtstuff). All we need to do
-   is install/deinstall the frame information for exceptions. We do this
-   by putting a constructor in crtbegin.o and a destructor in crtend.o.
-
-   crtend.o also puts in the terminating zero in the frame information
-   segment.  */
-
-/* The crtstuff for other object formats use the symbol __EH_FRAME_BEGIN__
-   to figure out the start of the exception frame, but here we use
-   getsectbynamefromheader to find this value. Either method would work,
-   but this method avoids creating any global symbols, which seems
-   cleaner.  */
-
-#include <mach-o/ldsyms.h>
-extern const struct section *
-  getsectbynamefromheader (const struct mach_header *,
-                          const char *, const char *);
+/* Crt stuff for Mach-O (NeXT and Darwin).
+
+   The theory of this is that each dynamically-loadable module,
+   including the main program itself, must have been positioned by
+   dyld before any frame info can be registered.  So we set up the
+   registration functions as dyld hooks, using a "preregistration"
+   function that is called directly from the system crt1.o.  */
 
 #ifdef CRT_BEGIN
 
-static void __reg_frame_ctor (void) __attribute__ ((constructor));
+/* Homemade decls substituting for getsect.h and dyld.h, so cross
+   compilation works.  */
+struct mach_header;
+extern char *getsectdatafromheader (struct mach_header *, const char *,
+                                   const char *, unsigned long *);
+extern void _dyld_register_func_for_add_image
+  (void (*) (struct mach_header *, unsigned long));
+extern void _dyld_register_func_for_remove_image
+  (void (*) (struct mach_header *, unsigned long));
+
+extern void __darwin_gcc3_preregister_frame_info (void);
 
 static void
-__reg_frame_ctor (void)
+unwind_dyld_add_image_hook (struct mach_header *mh,
+                           unsigned long vm_slide)
 {
-  static struct object object;
-  const struct section *eh_frame;
+  unsigned long sz;
+  char *fde;
 
-  eh_frame = getsectbynamefromheader (&_mh_execute_header,
-                                     "__TEXT", "__eh_frame");
-  __register_frame_info ((void *) eh_frame->addr, &object);
-}
-
-#elif defined(CRT_END)
+  fde = getsectdatafromheader (mh, "__TEXT", "__eh_frame", &sz);
+  if (fde)
+    {
+      struct object *ob = (struct object *) malloc (sizeof (struct object));
 
-static void __dereg_frame_dtor (void) __attribute__ ((destructor));
+      __register_frame_info (fde + vm_slide, ob);
+    }
+}
 
 static void
-__dereg_frame_dtor (void)
+unwind_dyld_remove_image_hook (struct mach_header *mh,
+                              unsigned long vm_slide)
 {
-  const struct section *eh_frame;
+  unsigned long sz;
+  char *fde;
+
+  fde = getsectdatafromheader (mh, "__TEXT", "__eh_frame", &sz);
 
-  eh_frame = getsectbynamefromheader (&_mh_execute_header,
-                                     "__TEXT", "__eh_frame");
-  __deregister_frame_info ((void *) eh_frame->addr);
+  if (fde)
+    __deregister_frame_info (fde + vm_slide);
 }
 
-/* Terminate the frame section with a final zero.  */
-STATIC int __FRAME_END__[]
-     __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME),
-                    aligned(4)))
-     = { 0 };
+/* Call this routine from the system crt1.o.  The call is standard in
+   Darwin 6.x (Mac OS X 10.2) and later; for earlier systems, you
+   would need to modify crt.c in the Csu project.  (This isn't great,
+   but other alternatives run afoul of linker semantics.  This
+   function is declared as common and tested before being called, so
+   that programs compiled by older GCCs still link and run.)  */
+
+void
+__darwin_gcc3_preregister_frame_info ()
+{
+  _dyld_register_func_for_add_image (unwind_dyld_add_image_hook);
+  _dyld_register_func_for_remove_image (unwind_dyld_remove_image_hook);
+}
+
+#elif defined(CRT_END) /* ! CRT_BEGIN */
+
+/* Install a single zero word at the end of the __eh_frame section.  */
+
+asm (".section __TEXT,__eh_frame");
+asm (".long 0");
 
 #else /* ! CRT_BEGIN && ! CRT_END */
 #error "One of CRT_BEGIN or CRT_END must be defined."
 #endif
 
-#endif /* OBJECT_FORMAT_MACHO */
+#endif  /* OBJECT_FORMAT_MACHO  */
index 0576d74d60090b6ef9a6ebfef01ae33f1cd3b1fc..f324982cde4bed758c0937b5dc9d2f6bca07798e 100644 (file)
@@ -7501,6 +7501,13 @@ is a function that outputs a standard GAS section directive, if
 directive followed by a synthetic label.
 @end deftypefn
 
+@deftypevar {Target Hook} bool TARGET_TERMINATE_DW2_EH_FRAME_INFO
+Contains the value true if the target should add a zero word onto the
+end of a Dwarf-2 frame info section when used for exception handling.
+Default value is false if @code{EH_FRAME_SECTION_NAME} is defined, and
+true otherwise.
+@end deftypevar
+
 @node Alignment Output
 @subsection Assembler Commands for Alignment
 
@@ -8034,6 +8041,22 @@ Define this macro to be a nonzero value if the assembler can generate Dwarf 2
 line debug info sections.  This will result in much more compact line number
 tables, and hence is desirable if it works.
 
+@findex ASM_OUTPUT_DWARF_DELTA
+@item 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.
+
+@findex ASM_OUTPUT_DWARF_OFFSET
+@item ASM_OUTPUT_DWARF_OFFSET (@var{stream}, @var{size}, @var{label})
+A C statement to issue assembly directives that create a
+section-relative reference to the given label, using an integer of the
+given size.
+
+@findex ASM_OUTPUT_DWARF_PCREL
+@item 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.
+
 @findex PUT_SDB_@dots{}
 @item PUT_SDB_@dots{}
 Define these macros to override the assembler syntax for the special
index 6e6a5d02303da785ee835ce691bf5d8852055c47..b80e7c3398f7fcd1e3008cdcb631e529550c8c09 100644 (file)
@@ -104,11 +104,14 @@ dw2_asm_output_delta VPARAMS ((int size, const char *lab1, const char *lab2,
   VA_FIXEDARG (ap, const char *, lab2);
   VA_FIXEDARG (ap, const char *, comment);
 
+#ifdef ASM_OUTPUT_DWARF_DELTA
+  ASM_OUTPUT_DWARF_DELTA (asm_out_file, size, lab1, lab2);
+#else
   dw2_assemble_integer (size,
                        gen_rtx_MINUS (Pmode,
                                       gen_rtx_SYMBOL_REF (Pmode, lab1),
                                       gen_rtx_SYMBOL_REF (Pmode, lab2)));
-
+#endif
   if (flag_debug_asm && comment)
     {
       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
index 5757d247d71ab5b74a4c3a7c92f715d711d6d1f0..f5503d48d653e56d4800aa7b95f33fdbbdecf595 100644 (file)
@@ -2043,10 +2043,8 @@ output_call_frame_info (for_eh)
       ASM_OUTPUT_LABEL (asm_out_file, l2);
     }
 
-#ifndef EH_FRAME_SECTION_NAME
-  if (for_eh)
+  if (for_eh && targetm.terminate_dw2_eh_frame_info)
     dw2_asm_output_data (4, 0, "End of Table");
-#endif
 #ifdef MIPS_DEBUGGING_INFO
   /* Work around Irix 6 assembler bug whereby labels at the end of a section
      get a value of 0.  Putting .align 0 after the label fixes it.  */
index 53b29a921e81c9bd1158159a24ea5d4392e63375..fbb75f0257f0447bf7ab9f4552d1382d83ac09d1 100644 (file)
@@ -126,6 +126,14 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 #define TARGET_HAVE_SRODATA_SECTION false
 #endif
 
+#ifndef TARGET_TERMINATE_DW2_EH_FRAME_INFO
+#ifdef EH_FRAME_SECTION_NAME
+#define TARGET_TERMINATE_DW2_EH_FRAME_INFO false
+#else
+#define TARGET_TERMINATE_DW2_EH_FRAME_INFO true
+#endif
+#endif
+
 #ifndef TARGET_ASM_EXCEPTION_SECTION
 #define TARGET_ASM_EXCEPTION_SECTION default_exception_section
 #endif
@@ -266,7 +274,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   TARGET_HAVE_NAMED_SECTIONS,                  \
   TARGET_HAVE_CTORS_DTORS,                     \
   TARGET_HAVE_TLS,                             \
-  TARGET_HAVE_SRODATA_SECTION                  \
+  TARGET_HAVE_SRODATA_SECTION,                 \
+  TARGET_TERMINATE_DW2_EH_FRAME_INFO           \
 }
 
 #include "hooks.h"
index f68cfb13632f0848fc10bc5ae34ed17b1fcf1a3e..2cc950421ffeb6c33ad5e5d891a3e24a08c49abf 100644 (file)
@@ -269,6 +269,9 @@ struct gcc_target
 
   /* True if a small readonly data section is supported.  */
   bool have_srodata_section;
+
+  /* True if EH frame info sections should be zero-terminated.  */
+  bool terminate_dw2_eh_frame_info;
 };
 
 extern struct gcc_target targetm;