summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4>2002-09-13 03:44:54 +0000
committershebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4>2002-09-13 03:44:54 +0000
commita08b74c8bf89232cd59a439190b786dae8a87a5f (patch)
tree9d8b83093127fbc3b7a523ef893b097ff59eb9b5
parent9f6ef744447d2da6c300f71e8f22802d0064b1f5 (diff)
downloadgcc-a08b74c8bf89232cd59a439190b786dae8a87a5f.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@57089 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog26
-rw-r--r--gcc/config.gcc2
-rw-r--r--gcc/config/darwin.c29
-rw-r--r--gcc/config/darwin.h26
-rw-r--r--gcc/crtstuff.c100
-rw-r--r--gcc/doc/tm.texi23
-rw-r--r--gcc/dwarf2asm.c5
-rw-r--r--gcc/dwarf2out.c4
-rw-r--r--gcc/target-def.h11
-rw-r--r--gcc/target.h3
10 files changed, 177 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bad52cacec0..a5bdc1d0059 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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"
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 8e9498f0f6e..e7bdc166078 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -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
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index f1370b9d00a..670a57aa3d8 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -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"
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index ba7cb66cc22..0c327b93b30 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -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 { \
diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c
index 041c810f6f4..125e236ee9c 100644
--- a/gcc/crtstuff.c
+++ b/gcc/crtstuff.c
@@ -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 */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 0576d74d600..f324982cde4 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -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
diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c
index 6e6a5d02303..b80e7c3398f 100644
--- a/gcc/dwarf2asm.c
+++ b/gcc/dwarf2asm.c
@@ -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);
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 5757d247d71..f5503d48d65 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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. */
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 53b29a921e8..fbb75f0257f 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -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"
diff --git a/gcc/target.h b/gcc/target.h
index f68cfb13632..2cc950421ff 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -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;