www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1999/08/17/11:13:08

Message-Id: <199908171505.PAA97176@out4.ibm.net>
From: "Mark E." <snowball3 AT bigfoot DOT com>
To: djgpp-workers AT delorie DOT com
Date: Tue, 17 Aug 1999 11:05:47 -0400
MIME-Version: 1.0
Subject: crtbegin.o and crtend.o
X-mailer: Pegasus Mail for Win32 (v3.11)
Reply-To: djgpp-workers AT delorie DOT com

Greetings,

Several folks have said recently and in the past that using gcc's crtbegin.o and 
crtend.o would be "a good thing". I agree, and for the past several days I've been 
working on getting crtbegin.o and crtend.o to work with DJGPP and today I succeeded. 
Making crt*.o work with DJGPP will require some changes in libc. However, these 
changes allow the current method of initializeing EH and of calling 'constructors' 
and 'destructors' to continue working for as long as neccessary. I'll send the GCC 
folks the patch to fix up crt*.o for DJGPP as soon as have time to generate the 
patch and write the ChangeLog. 

I'm not up on my x86 assembly, so my crt0.S may not be as efficient as it could be. 
BTW, the current crt0.S used spaces instead of tabs where it was patched initialize 
C++ EH.

*** src/libc/crt0/crt0.S.orig	Wed Aug 11 02:24:36 1999
--- src/libc/crt0/crt0.S	Tue Aug 17 10:59:34 1999
*************** use_stubinfo_stack_size:
*** 293,302 ****
  	movl	%eax, %esp
  
  	xorl	%ebp, %ebp
!         pushl   $_frame_struct
!         pushl   $_CRT0_EH_FRAME_BEGIN_
!         call    ___register_frame_info
!         addl    $8, %esp
  	call	___crt1_startup		/* run program */
  	jmp	exit
  
--- 293,307 ----
  	movl	%eax, %esp
  
  	xorl	%ebp, %ebp
! 	movl	gcc_init, %eax
! 	movl	gcc_init_end, %ecx
! 	cmpl	%eax, %ecx
! 	jne	call_crt1_startup
! 	pushl   $_frame_struct
! 	pushl   $_CRT0_EH_FRAME_BEGIN_
! 	call    ___register_frame_info
! 	addl    $8, %esp
! call_crt1_startup:
  	call	___crt1_startup		/* run program */
  	jmp	exit
  
*** src/libc/crt0/_main.c.orig	Fri Nov 24 21:06:58 1995
--- src/libc/crt0/_main.c	Tue Aug 17 10:55:24 1999
***************
*** 1,3 ****
--- 1,4 ----
+ /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  #include <libc/internal.h>
  #include <libc/bss.h>
***************
*** 5,10 ****
--- 6,13 ----
  typedef void (*FUNC)(void);
  extern FUNC djgpp_first_ctor[] __asm__("djgpp_first_ctor");
  extern FUNC djgpp_last_ctor[] __asm__("djgpp_last_ctor");
+ extern FUNC gcc_init __asm__("gcc_init");
+ extern FUNC gcc_init_end __asm__("gcc_init_end");
  
  void
  __main(void)
*************** __main(void)
*** 14,19 ****
    if (been_there_done_that == __bss_count)
      return;
    been_there_done_that = __bss_count;
!   for (i=0; i<djgpp_last_ctor-djgpp_first_ctor; i++)
!     djgpp_first_ctor[i]();
  }
--- 17,30 ----
    if (been_there_done_that == __bss_count)
      return;
    been_there_done_that = __bss_count;
! 
!   /* If the .init section isn't empty, then it contains the code that
!      calls the 'constructors' and initializes C++ exception handling.
!      Otherwise, the old method of calling the constructors is being used.  */
! 
!   if (gcc_init != gcc_init_end)
!     gcc_init();
!   else
!     for (i=0; i<djgpp_last_ctor-djgpp_first_ctor; i++)
!       djgpp_first_ctor[i]();
  }
*** src/libc/ansi/stdlib/exit.c.orig	Tue Jun 29 11:49:42 1999
--- src/libc/ansi/stdlib/exit.c	Tue Aug 17 10:57:28 1999
*************** void (*__FSEXT_exit_hook)(void) = NULL;
*** 21,26 ****
--- 21,28 ----
  typedef void (*FUNC)(void);
  extern FUNC djgpp_first_dtor[] __asm__("djgpp_first_dtor");
  extern FUNC djgpp_last_dtor[] __asm__("djgpp_last_dtor");
+ extern void gcc_fini() __asm__("gcc_fini");
+ extern void gcc_fini_end() __asm__("gcc_fini_end");
  
  void
  exit(int status)
*************** exit(int status)
*** 39,47 ****
    }
  
    /* Destructors should probably be called after functions registered
!      with atexit(), this is the way it happens in Linux anyway. */
!   for (i=0; i<djgpp_last_dtor-djgpp_first_dtor; i++)
!     djgpp_first_dtor[i]();
  
    /* Do this last so that everyone else may write to files
       during shutdown */
--- 41,55 ----
    }
  
    /* Destructors should probably be called after functions registered
!      with atexit(), this is the way it happens in Linux anyway.
!      If the .fini section isn't empty, then it contains the code for
!      executing the 'destructors' and finalizing C++ exception handling.  */
! 
!   if (&gcc_fini == &gcc_fini_end)
!     for (i=0; i<djgpp_last_dtor-djgpp_first_dtor; i++)
!       djgpp_first_dtor[i]();
!   else
!     gcc_fini();
  
    /* Do this last so that everyone else may write to files
       during shutdown */
*** lib/djgpp.djm	Fri Jul 30 03:50:40 1999
--- lib/djgpp.djl	Sun Aug 15 21:41:34 1999
*************** SECTIONS
*** 6,11 ****
--- 6,17 ----
      *(.text)
      *(.gnu.linkonce.t*)
      *(.gnu.linkonce.r*)
+     gcc_init = .;
+     *(.init)
+     gcc_init_end = .;
+     gcc_fini = .;
+     *(.fini)
+     gcc_fini_end = .;
      etext  =  . ; _etext = .;
      . = ALIGN(0x200);
    }
*************** SECTIONS
*** 19,28 ****
      *(.data)
      *(.gnu.linkonce.d*)
      *(.gcc_exc*)
-     ___EH_FRAME_BEGIN__ = . ;
      *(.eh_fram*)
-     ___EH_FRAME_END__ = . ;
-     LONG(0)
       edata  =  . ; _edata = .;
       . = ALIGN(0x200);
    }
--- 25,31 ----

--- 
Mark Elbrecht, snowball3 AT bigfoot DOT com
http://snowball.frogspace.net/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019