diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5926b2eded2..d1a26c176c8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2001-08-03 Stephane Carrez + + * config/m68hc11/t-m68hc11-gas (T_CPPFLAGS): Add _ctor and _dtor. + * config/m68hc11/larith.asm (_exit): Split in several sub-sections + merged by linker script to get a final _exit(). + (__do_global_dtors): New for destructor handling in specific exit + section. + (__do_global_ctors): New for constructors in specific install section. + (__map_data_section): Map data sections before running constructors. + * config/m68hc11/m68hc11.h (INT_ASM_OP): Define to use .word. + (CTORS_SECTION_ASM_OP): Define to put in readonly section. + (DTORS_SECTION_ASM_OP): Likewise. + (CTORS_SECTION_FUNCTION): Define to force a reference to + __do_global_ctors. + (DTORS_SECTION_FUNCTION): Likewise for __do_global_dtors. + 2001-08-03 Daniel Berlin * ChangeLog: Fix date on previous ChangeLog entry for GCSE. diff --git a/gcc/config/m68hc11/larith.asm b/gcc/config/m68hc11/larith.asm index 5ff3e9a6bfc..4c24dccfa82 100644 --- a/gcc/config/m68hc11/larith.asm +++ b/gcc/config/m68hc11/larith.asm @@ -179,13 +179,26 @@ __premain: ;; ;; Exit operation. Just loop forever and wait for interrupts. ;; (no other place to go) +;; This operation is split in several pieces collected together by +;; the linker script. This allows to support destructors at the +;; exit stage while not impacting program sizes when there is no +;; destructors. ;; - .sect .text - .globl _exit +;; _exit: +;; *(.fini0) /* Beginning of finish code (_exit symbol). */ +;; *(.fini1) /* Place holder for applications. */ +;; *(.fini2) /* C++ destructors. */ +;; *(.fini3) /* Place holder for applications. */ +;; *(.fini4) /* Runtime exit. */ +;; + .sect .fini0,"ax",@progbits + .globl _exit .globl exit .weak exit exit: _exit: + + .sect .fini4,"ax",@progbits fatal: cli wai @@ -1035,7 +1048,7 @@ A_low_B_low: #ifdef L_map_data - .sect .install3,"ax",@progbits + .sect .install2,"ax",@progbits .globl __map_data_section __map_data_section: @@ -1063,7 +1076,7 @@ Done: #ifdef L_init_bss - .sect .install3,"ax",@progbits + .sect .install2,"ax",@progbits .globl __init_bss_section __init_bss_section: @@ -1083,7 +1096,58 @@ Loop: Done: #endif - + +#ifdef L_ctor + +; End of constructor table + .sect .install3,"ax",@progbits + .globl __do_global_ctors + +__do_global_ctors: + ; Start from the end - sizeof(void*) + ldx #__CTOR_END__-2 +ctors_loop: + cpx #__CTOR_LIST__ + blt ctors_done + pshx + ldx 0,x + jsr 0,x + pulx + dex + dex + bra ctors_loop +ctors_done: + +#endif + +#ifdef L_dtor + + .sect .fini3,"ax",@progbits + .globl __do_global_dtors + +;; +;; This piece of code is inserted in the _exit() code by the linker. +;; +__do_global_dtors: + pshb ; Save exit code + psha + ldx #__DTOR_LIST__ +dtors_loop: + cpx #__DTOR_END__ + bge dtors_done + pshx + ldx 0,x + jsr 0,x + pulx + inx + inx + bra dtors_loop +dtors_done: + pula ; Restore exit code + pulb + +#endif + ;----------------------------------------- ; end required gcclib code ;----------------------------------------- diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h index 3ce23b8ce56..777fb886b03 100644 --- a/gcc/config/m68hc11/m68hc11.h +++ b/gcc/config/m68hc11/m68hc11.h @@ -1580,6 +1580,52 @@ do { \ /* Output before uninitialized data. */ #define BSS_SECTION_ASM_OP ("\t.sect\t.bss") +/* This is the pseudo-op used to generate a reference to a specific + symbol in some section. It is only used in machine-specific + configuration files, typically only in ASM_OUTPUT_CONSTRUCTOR and + ASM_OUTPUT_DESTRUCTOR. This is the same for all known svr4 + assemblers, except those in targets that don't use 32-bit pointers. + Those should override INT_ASM_OP. Yes, the name of the macro is + misleading. */ +#undef INT_ASM_OP +#define INT_ASM_OP "\t.word\t" + +/* Define the pseudo-ops used to switch to the .ctors and .dtors sections. + + Same as config/elfos.h but don't mark these section SHF_WRITE since + there is no shared library problem. */ +#undef CTORS_SECTION_ASM_OP +#define CTORS_SECTION_ASM_OP "\t.section\t.ctors,\"a\"" + +#undef DTORS_SECTION_ASM_OP +#define DTORS_SECTION_ASM_OP "\t.section\t.dtors,\"a\"" + +#undef CTORS_SECTION_FUNCTION +#define CTORS_SECTION_FUNCTION \ +void \ +ctors_section () \ +{ \ + if (in_section != in_ctors) \ + { \ + fprintf (asm_out_file, "\t.globl\t__do_global_ctors\n"); \ + fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \ + in_section = in_ctors; \ + } \ +} + +#undef DTORS_SECTION_FUNCTION +#define DTORS_SECTION_FUNCTION \ +void \ +dtors_section () \ +{ \ + if (in_section != in_dtors) \ + { \ + fprintf (asm_out_file, "\t.globl\t__do_global_dtors\n"); \ + fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \ + in_section = in_dtors; \ + } \ +} + /* This is how to begin an assembly language file. Most svr4 assemblers want at least a .file directive to come first, and some want to see a .version directive come right after that. Here we just establish a default diff --git a/gcc/config/m68hc11/t-m68hc11-gas b/gcc/config/m68hc11/t-m68hc11-gas index a73fe893da5..7dd74456d57 100644 --- a/gcc/config/m68hc11/t-m68hc11-gas +++ b/gcc/config/m68hc11/t-m68hc11-gas @@ -24,7 +24,8 @@ LIB1ASMFUNCS = _mulsi3 \ _regs_d3_4 _regs_d5_6 _regs_d7_8 _regs_d9_16 _regs_d17_32 \ _premain __exit _abort _cleanup \ _adddi3 _subdi3 _notdi2 \ - _ashrhi3 _lshrhi3 _lshlhi3 _ashrqi3 _lshlqi3 _map_data _init_bss + _ashrhi3 _lshrhi3 _lshlhi3 _ashrqi3 _lshlqi3 _map_data _init_bss \ + _ctor _dtor TARGET_LIBGCC2_CFLAGS = -DUSE_GAS -DIN_GCC