PATCH: dwarf2 EH for Darwin, revised
Stan Shebs
shebs@apple.com
Thu Sep 12 09:38:00 GMT 2002
Here is the all-singing all-dancing version of the Darwin EH bits
that takes jason and rth comments into account, adding a target hook
for zero-termination of frame info, but leaving the dwarf2asm macros
to be hookified later. Bootstrapped and tested on powerpc-apple-darwin
and i686-pc-linux, no regressions.
OK for trunk now?
Stan
2002-09-09 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.
(patch also attached in case of mail manglement - first day with
Moz 1.1 on OS X)
Index: config.gcc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config.gcc,v
retrieving revision 1.244
diff -p -r1.244 config.gcc
*** config.gcc 3 Sep 2002 20:21:32 -0000 1.244
--- config.gcc 12 Sep 2002 13:01:05 -0000
*************** i[34567]86-*-darwin*)
*** 980,985 ****
--- 980,986 ----
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
;;
*************** powerpc-*-darwin*)
*** 1946,1951 ****
--- 1947,1953 ----
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: crtstuff.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/crtstuff.c,v
retrieving revision 1.56
diff -p -r1.56 crtstuff.c
*** crtstuff.c 4 Jun 2002 02:55:28 -0000 1.56
--- crtstuff.c 12 Sep 2002 13:01:06 -0000
*************** __do_global_ctors (void)
*** 545,608 ****
#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 *);
#ifdef CRT_BEGIN
! static void __reg_frame_ctor (void) __attribute__ ((constructor));
static void
! __reg_frame_ctor (void)
{
! static struct object object;
! const struct section *eh_frame;
!
! eh_frame = getsectbynamefromheader (&_mh_execute_header,
! "__TEXT", "__eh_frame");
! __register_frame_info ((void *) eh_frame->addr, &object);
! }
! #elif defined(CRT_END)
! static void __dereg_frame_dtor (void) __attribute__ ((destructor));
static void
! __dereg_frame_dtor (void)
{
! const struct section *eh_frame;
! eh_frame = getsectbynamefromheader (&_mh_execute_header,
! "__TEXT", "__eh_frame");
! __deregister_frame_info ((void *) eh_frame->addr);
}
! /* Terminate the frame section with a final zero. */
! STATIC int __FRAME_END__[]
! __attribute__ ((unused, mode(SI), section(EH_FRAME_SECTION_NAME),
! aligned(4)))
! = { 0 };
#else /* ! CRT_BEGIN && ! CRT_END */
#error "One of CRT_BEGIN or CRT_END must be defined."
#endif
! #endif /* OBJECT_FORMAT_MACHO */
--- 545,624 ----
#else /* OBJECT_FORMAT_MACHO */
! /* 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
! /* 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
! unwind_dyld_add_image_hook (struct mach_header *mh,
! unsigned long vm_slide)
{
! unsigned long sz;
! char *fde;
! fde = getsectdatafromheader (mh, "__TEXT", "__eh_frame", &sz);
! if (fde)
! {
! struct object *ob = (struct object *) malloc (sizeof (struct
object));
! __register_frame_info (fde + vm_slide, ob);
! }
! }
static void
! unwind_dyld_remove_image_hook (struct mach_header *mh,
! unsigned long vm_slide)
{
! unsigned long sz;
! char *fde;
!
! fde = getsectdatafromheader (mh, "__TEXT", "__eh_frame", &sz);
! if (fde)
! __deregister_frame_info (fde + vm_slide);
}
! /* 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 */
Index: dwarf2asm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2asm.c,v
retrieving revision 1.27
diff -p -r1.27 dwarf2asm.c
*** dwarf2asm.c 4 Jun 2002 07:07:22 -0000 1.27
--- dwarf2asm.c 12 Sep 2002 13:01:06 -0000
*************** dw2_asm_output_delta VPARAMS ((int size,
*** 104,114 ****
VA_FIXEDARG (ap, const char *, lab2);
VA_FIXEDARG (ap, const char *, comment);
dw2_assemble_integer (size,
gen_rtx_MINUS (Pmode,
gen_rtx_SYMBOL_REF (Pmode, lab1),
gen_rtx_SYMBOL_REF (Pmode, lab2)));
!
if (flag_debug_asm && comment)
{
fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
--- 104,117 ----
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: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.385
diff -p -r1.385 dwarf2out.c
*** dwarf2out.c 8 Sep 2002 18:36:53 -0000 1.385
--- dwarf2out.c 12 Sep 2002 13:01:12 -0000
*************** output_call_frame_info (for_eh)
*** 2043,2052 ****
ASM_OUTPUT_LABEL (asm_out_file, l2);
}
! #ifndef EH_FRAME_SECTION_NAME
! if (for_eh)
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. */
--- 2043,2050 ----
ASM_OUTPUT_LABEL (asm_out_file, l2);
}
! if (for_eh && targetm.terminate_dw2_eh_frame_info)
dw2_asm_output_data (4, 0, "End of Table");
#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: target-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target-def.h,v
retrieving revision 1.33
diff -p -r1.33 target-def.h
*** target-def.h 8 Sep 2002 09:30:20 -0000 1.33
--- target-def.h 12 Sep 2002 13:01:12 -0000
*************** Foundation, 59 Temple Place - Suite 330,
*** 126,131 ****
--- 126,139 ----
#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
*************** Foundation, 59 Temple Place - Suite 330,
*** 266,272 ****
TARGET_HAVE_NAMED_SECTIONS, \
TARGET_HAVE_CTORS_DTORS, \
TARGET_HAVE_TLS, \
! TARGET_HAVE_SRODATA_SECTION \
}
#include "hooks.h"
--- 274,281 ----
TARGET_HAVE_NAMED_SECTIONS, \
TARGET_HAVE_CTORS_DTORS, \
TARGET_HAVE_TLS, \
! TARGET_HAVE_SRODATA_SECTION, \
! TARGET_TERMINATE_DW2_EH_FRAME_INFO \
}
#include "hooks.h"
Index: target.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/target.h,v
retrieving revision 1.35
diff -p -r1.35 target.h
*** target.h 7 Sep 2002 00:19:26 -0000 1.35
--- target.h 12 Sep 2002 13:01:12 -0000
*************** struct gcc_target
*** 269,274 ****
--- 269,277 ----
/* 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;
Index: doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.165
diff -p -r1.165 tm.texi
*** doc/tm.texi 9 Sep 2002 20:04:32 -0000 1.165
--- doc/tm.texi 12 Sep 2002 13:01:22 -0000
*************** is a function that outputs a standard GA
*** 7501,7506 ****
--- 7501,7513 ----
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
*************** to indicate the beginning of the text se
*** 8033,8038 ****
--- 8040,8061 ----
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{}
Index: config/darwin.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin.c,v
retrieving revision 1.26
diff -p -r1.26 darwin.c
*** config/darwin.c 21 Aug 2002 02:41:46 -0000 1.26
--- config/darwin.c 12 Sep 2002 13:01:23 -0000
*************** darwin_globalize_label (stream, name)
*** 1294,1298 ****
--- 1294,1327 ----
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: config/darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/darwin.h,v
retrieving revision 1.38
diff -p -r1.38 darwin.h
*** config/darwin.h 3 Sep 2002 20:09:18 -0000 1.38
--- config/darwin.h 12 Sep 2002 13:01:23 -0000
*************** Boston, MA 02111-1307, USA. */
*** 35,40 ****
--- 35,46 ----
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.) */
*************** Boston, MA 02111-1307, USA. */
*** 92,99 ****
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
! "%{pg:%{static:-lgcrt0.o}%{!static:-lgcrt1.o}} \
! %{!pg:%{static:-lcrt0.o}%{!static:-lcrt1.o}}"
#undef DOLLARS_IN_IDENTIFIERS
#define DOLLARS_IN_IDENTIFIERS 2
--- 98,109 ----
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
! "%{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
*************** SECTION_FUNCTION (machopic_picsymbol_stu
*** 425,431 ****
".picsymbol_stub", 0) \
SECTION_FUNCTION (darwin_exception_section, \
in_darwin_exception, \
! ".section __TEXT,__gcc_except_tab", 0) \
SECTION_FUNCTION (darwin_eh_frame_section, \
in_darwin_eh_frame, \
".section __TEXT,__eh_frame", 0) \
--- 435,441 ----
".picsymbol_stub", 0) \
SECTION_FUNCTION (darwin_exception_section, \
in_darwin_exception, \
! ".section __DATA,__gcc_except_tab", 0) \
SECTION_FUNCTION (darwin_eh_frame_section, \
in_darwin_eh_frame, \
".section __TEXT,__eh_frame", 0) \
*************** enum machopic_addr_class {
*** 597,603 ****
#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)
#define DARWIN_REGISTER_TARGET_PRAGMAS(PFILE) \
do { \
--- 607,620 ----
#undef ASM_PREFERRED_EH_DATA_FORMAT
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
! (((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 { \
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: eh-patch
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20020912/e056bce6/attachment.ksh>
More information about the Gcc-patches
mailing list