This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: Fix C++ static constructors/destructors for HC11/HC12
- To: gcc-patches at gcc dot gnu dot org
- Subject: [PATCH]: Fix C++ static constructors/destructors for HC11/HC12
- From: Stephane Carrez <Stephane dot Carrez at worldnet dot fr>
- Date: Fri, 03 Aug 2001 23:07:24 +0200
Hi!
The C++ static constructor and destructors are not handled correctly for
HC11/HC12. The following patch fixes that:
- The pointer in the ctor/dtor table must be 2-byte wide (.word)
- The startup file must handle them. This is done within a .install3
section that is merged by the linker script in the startup code
(after data is initialized). The constructor code is linked
only when there is some constructors (by forcing the __do_global_ctors
symbol to be undefined).
- The destructors are handled by specific .fini[0-4] section.
.fini0 defines _exit symbol; .fini3 contains the __do_global_dtors;
it is present only when there are destructors; .fini4 contains the
real exit code. These .fini[04] sections are merged by specific linker
script.
- The __do_global_dtors/ctors are part of libgcc and the symbols are
forced to be undefined each time a ctor or dtor table is generated.
This way, the ctor or dtor management is present only when necessary.
I've committed this patch on mainline and 3_0 branch.
Stephane
2001-08-03 Stephane Carrez <Stephane.Carrez@worldnet.fr>
* 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.
Index: config/m68hc11/larith.asm
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/larith.asm,v
retrieving revision 1.5
diff -u -p -r1.5 larith.asm
--- larith.asm 2001/05/17 03:16:01 1.5
+++ larith.asm 2001/08/03 20:43:51
@@ -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
;-----------------------------------------
Index: config/m68hc11/m68hc11.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/m68hc11.h,v
retrieving revision 1.18
diff -u -p -r1.18 m68hc11.h
--- m68hc11.h 2001/07/09 06:10:03 1.18
+++ m68hc11.h 2001/08/03 20:43:53
@@ -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
Index: config/m68hc11/t-m68hc11-gas
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/m68hc11/t-m68hc11-gas,v
retrieving revision 1.4
diff -u -p -r1.4 t-m68hc11-gas
--- t-m68hc11-gas 2001/05/17 03:16:01 1.4
+++ t-m68hc11-gas 2001/08/03 20:43:53
@@ -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