1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
/* $OpenBSD: crt0.c,v 1.11 2013/05/08 16:06:45 miod Exp $ */
/*
* Mach Operating System
* Copyright (c) 1991, 1992 Carnegie Mellon University
* Copyright (c) 1991, 1992 Omron Corporation
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation is hereby granted, provided that both the copyright
* notice and this permission notice appear in all copies of the
* software, derivative works or modified versions, and any portions
* thereof, and that both notices appear in supporting documentation.
*
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
*
* Carnegie Mellon requests users of this software to return to
*
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
* School of Computer Science
* Carnegie Mellon University
* Pittsburgh PA 15213-3890
*
* any improvements or extensions that they make and grant Carnegie Mellon
* the rights to redistribute these changes.
*/
/*
* When a program begins, r31 points to a structure passed by the kernel.
*
* This structure contains argc, the argv[] NULL-terminated array, and
* the envp[] NULL-terminated array.
*/
#include <sys/param.h>
#include <stdlib.h>
char **environ;
char *__progname = "";
char __progname_storage[NAME_MAX + 1];
#ifdef MCRT0
extern void monstartup(u_long, u_long);
extern void _mcleanup(void);
extern unsigned char _etext, _eprol;
#endif /* MCRT0 */
static inline char *_strrchr(const char *p, char ch);
__asm__ (
" .text\n"
" .align 3\n"
" .globl __start\n"
" .globl _start\n"
"__start:\n"
"_start:\n"
" or %r0, %r0, %r0\n" /* two nop because execution may */
" or %r0, %r0, %r0\n" /* skip up to two instructions */
/* see setregs() in the kernel */
/* for details. */
" ld %r2, %r31, 0\n" /* argc */
" addu %r3, %r31, 4\n" /* argv */
" lda %r4, %r3[%r2]\n"
" br.n ___start\n"
" addu %r4, %r4, 4\n" /* envp = argv + argc + 1 */
/* cleanup is %r5, zeroed in setregs() at the moment */
);
void
___start(int argc, char **argv, char **envp, void (*cleanup)(void))
{
char *s;
environ = envp;
if ((__progname = argv[0]) != NULL) { /* NULL ptr if argc = 0 */
if ((__progname = _strrchr(__progname, '/')) == NULL)
__progname = argv[0];
else
__progname++;
for (s = __progname_storage; *__progname &&
s < &__progname_storage[sizeof __progname_storage - 1]; )
*s++ = *__progname++;
*s = '\0';
__progname = __progname_storage;
}
if (cleanup)
atexit(cleanup);
#ifdef MCRT0
atexit(_mcleanup);
monstartup((u_long)&_eprol, (u_long)&_etext);
#endif
__init();
exit(main(argc, argv, environ));
}
static char *
_strrchr(const char *p, char ch)
{
char *save;
for (save = NULL;; ++p) {
if (*p == ch)
save = (char *)p;
if (!*p)
return(save);
}
}
#ifdef MCRT0
asm("\t.text\n_eprol:\n");
#endif
|