diff options
author | shebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-13 03:44:54 +0000 |
---|---|---|
committer | shebs <shebs@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-09-13 03:44:54 +0000 |
commit | a08b74c8bf89232cd59a439190b786dae8a87a5f (patch) | |
tree | 9d8b83093127fbc3b7a523ef893b097ff59eb9b5 | |
parent | 9f6ef744447d2da6c300f71e8f22802d0064b1f5 (diff) | |
download | gcc-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/ChangeLog | 26 | ||||
-rw-r--r-- | gcc/config.gcc | 2 | ||||
-rw-r--r-- | gcc/config/darwin.c | 29 | ||||
-rw-r--r-- | gcc/config/darwin.h | 26 | ||||
-rw-r--r-- | gcc/crtstuff.c | 100 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 23 | ||||
-rw-r--r-- | gcc/dwarf2asm.c | 5 | ||||
-rw-r--r-- | gcc/dwarf2out.c | 4 | ||||
-rw-r--r-- | gcc/target-def.h | 11 | ||||
-rw-r--r-- | gcc/target.h | 3 |
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; |