target.h (struct gcc_target): New field terminate_dw2_eh_frame_info.
* 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
This commit is contained in:
parent
20b71b177f
commit
7606e68f7b
10 changed files with 176 additions and 51 deletions
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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 { \
|
||||
|
|
|
@ -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.
|
||||
/* Crt stuff for Mach-O (NeXT and Darwin).
|
||||
|
||||
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 *);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(CRT_END)
|
||||
|
||||
static void __dereg_frame_dtor (void) __attribute__ ((destructor));
|
||||
|
||||
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;
|
||||
|
||||
eh_frame = getsectbynamefromheader (&_mh_execute_header,
|
||||
"__TEXT", "__eh_frame");
|
||||
__deregister_frame_info ((void *) eh_frame->addr);
|
||||
fde = getsectdatafromheader (mh, "__TEXT", "__eh_frame", &sz);
|
||||
|
||||
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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue