/* * crt0.S -- startup file for m68k-coff * * Copyright (c) 1995, 1996, 1998, 2001 Cygnus Support * * The authors hereby grant permission to use, copy, modify, distribute, * and license this software and its documentation for any purpose, provided * that existing copyright notices are retained in all copies and that this * notice is included verbatim in any distributions. No written agreement, * license, or royalty fee is required for any of the authorized uses. * Modifications to this software may be copyrighted by their authors * and need not follow the licensing terms described here, provided that * the new terms are clearly indicated on the first page of each file where * they apply. */ #include "asm.h" .title "crt0.S for m68k-coff" #define STACKSIZE 0x4000 /* * Define an empty environment. */ .data .align 2 SYM (environ): .long 0 .align 2 .text /* * These symbols are defined in C code, so they need to always be * named with SYM because of the difference between object file formats. */ /* These are defined in C code. */ .extern SYM (main) .extern SYM (exit) .extern SYM (atexit) .extern SYM(__do_global_dtors) /* * These values are set in the linker script, so they must be * explicitly named here without SYM. */ .extern __stack .extern __bss_start .extern _end /* * set things up so the application will run. This *must* be called start. */ .global SYM (start) SYM (start): /* See if user supplied their own stack (__stack != 0). If not, then * default to using the value of %sp as set by the ROM monitor. */ movel IMM(__stack), a0 cmpl IMM(0), a0 jbeq 1f movel a0, sp 1: /* set up initial stack frame */ link a6, IMM(-8) /* * zero out the bss section. */ movel IMM(__bss_start), d1 movel IMM(_end), d0 cmpl d0, d1 jbeq 3f movl d1, a0 subl d1, d0 subql IMM(1), d0 2: clrb (a0)+ #if !defined(__mcoldfire__) && !defined(__mcf5200__) dbra d0, 2b clrw d0 subql IMM(1), d0 jbcc 2b #else subql IMM(1), d0 jbpl 2b #endif 3: /* * call the main routine from the application to get it going. * main (argc, argv, environ) * we pass argv as a pointer to NULL. */ #ifdef ADD_DTORS /* put __do_global_dtors in the atexit list so the destructors get run */ movel IMM (SYM(__do_global_dtors)),(sp) PICCALL SYM (atexit) #endif movel IMM (__FINI_SECTION__),(sp) PICCALL SYM (atexit) PICCALL __INIT_SECTION__ pea 0 PICPEA SYM (environ),a0 pea sp@(4) pea 0 PICCALL SYM (main) movel d0, sp@- /* * drop down into exit incase the user doesn't. This should drop * control back to the ROM monitor, if there is one. This calls the * exit() from the C library so the C++ tables get cleaned up right. */ PICCALL SYM (exit)