137 lines
3.9 KiB
C
137 lines
3.9 KiB
C
/* Support for cris*-axis-linux-gnu and src/sim/cris simulator.
|
|
Copyright (C) 2000-2005, 2017, 2023 Axis Communications.
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Neither the name of Axis Communications nor the names of its
|
|
contributors may be used to endorse or promote products derived
|
|
from this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS
|
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS
|
|
COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE. */
|
|
|
|
#include "linunistd.h"
|
|
#include "newlib.h"
|
|
#include <stdlib.h>
|
|
|
|
#ifdef _HAVE_INITFINI_ARRAY
|
|
#define _init __libc_init_array
|
|
#define _fini __libc_fini_array
|
|
#endif
|
|
|
|
extern void exit (int) __attribute ((__noreturn__));
|
|
|
|
__asm__ (".syntax no_register_prefix");
|
|
|
|
#ifdef __ELF__
|
|
/* This simulator magic for an earlier simulator was supposed to be
|
|
found two bytes before _start. Let's keep it for sake of
|
|
compatibility. Trying to emit them with an ordinary const char[]
|
|
and attribute section makes gcc barf; it doesn't like having the
|
|
same section attribute for both code and data.
|
|
The code is supposed to cause a crash if someone jumps to 0. */
|
|
__asm__
|
|
(
|
|
" .section .startup,\"ax\",@progbits\n"
|
|
" .byte 55,55\n"
|
|
" move.d 0xbadacce5,r9\n"
|
|
" clear.d [r9]\n"
|
|
" setf\n"
|
|
" setf\n"
|
|
" .previous");
|
|
#endif
|
|
|
|
__asm__
|
|
(
|
|
#ifdef __AOUT__
|
|
" .text\n\t"
|
|
#elif defined (__ELF__)
|
|
" .section .startup,\"ax\",@progbits\n"
|
|
#endif
|
|
" .global __start\n"
|
|
"__start:\n"
|
|
/* SP must be set up by the simulator or the system. */
|
|
|
|
/* Find ARGC, ARGV and ENV. */
|
|
/* ARGC. */
|
|
" move.d [sp],r10\n"
|
|
|
|
/* ARGV. */
|
|
" move.d sp,r11\n"
|
|
" addq 4,r11\n"
|
|
|
|
/* ENVP. */
|
|
" move.d sp,r12\n"
|
|
" addi r10.d,r12\n"
|
|
" addq 8,r12\n"
|
|
|
|
/* Terminate R9 and R6; we don't have a "console_print_etrax" or system
|
|
call function. */
|
|
" clear.d r9\n"
|
|
" clear.d r6\n"
|
|
" move.d __start1,r13\n"
|
|
" jump r13\n"
|
|
" setf\n"
|
|
#ifndef __AOUT__
|
|
/* We rely on a.out not being in .data here. Quite fragile, but
|
|
covered by e.g. running the GCC test-suite for cris-unknown-aout. */
|
|
" .previous"
|
|
#endif
|
|
);
|
|
|
|
extern void _Libctors (void);
|
|
extern void _Libdtors (void);
|
|
|
|
extern void __init__start (void) __attribute ((weak));
|
|
extern void __aout__ctors (void) __attribute ((weak));
|
|
extern int main (int argc, char **argv, char **env);
|
|
|
|
static void start1 () __asm__ ("__start1") __attribute ((__used__));
|
|
static void
|
|
start1 (int argc, char **argv, char **env)
|
|
{
|
|
#ifdef __ELF__
|
|
/* For ELF systems, we call _init and register _fini with atexit. */
|
|
{
|
|
extern void _init (void);
|
|
extern void _fini (void);
|
|
_init ();
|
|
if (atexit (_fini) != 0)
|
|
exit (-1);
|
|
}
|
|
#else
|
|
/* Constructors which may get here through the ELF .init section, when
|
|
linking ELF and producing a.out. */
|
|
if (__init__start)
|
|
__init__start ();
|
|
|
|
if (__aout__ctors)
|
|
__aout__ctors ();
|
|
|
|
/* Call constructors in shared libraries. */
|
|
_Libctors ();
|
|
|
|
if (atexit (_Libdtors) != 0)
|
|
exit (-1);
|
|
#endif
|
|
|
|
/* Call the user program. */
|
|
exit (main (argc, argv, env));
|
|
}
|