This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH]: Fix C++ static constructors/destructors for HC11/HC12


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
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]