~ubuntu-branches/ubuntu/natty/eglibc/natty-security

« back to all changes in this revision

Viewing changes to sysdeps/unix/sparc/start.c

  • Committer: Bazaar Package Importer
  • Author(s): Aurelien Jarno
  • Date: 2009-05-05 09:54:14 UTC
  • Revision ID: james.westby@ubuntu.com-20090505095414-c45qsg9ixjheohru
ImportĀ upstreamĀ versionĀ 2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 1991,92,93,94,95,96,97,2004 Free Software Foundation, Inc.
 
2
   This file is part of the GNU C Library.
 
3
 
 
4
   The GNU C Library is free software; you can redistribute it and/or
 
5
   modify it under the terms of the GNU Lesser General Public
 
6
   License as published by the Free Software Foundation; either
 
7
   version 2.1 of the License, or (at your option) any later version.
 
8
 
 
9
   In addition to the permissions in the GNU Lesser General Public
 
10
   License, the Free Software Foundation gives you unlimited
 
11
   permission to link the compiled version of this file with other
 
12
   programs, and to distribute those programs without any restriction
 
13
   coming from the use of this file. (The GNU Lesser General Public
 
14
   License restrictions do apply in other respects; for example, they
 
15
   cover modification of the file, and distribution when not linked
 
16
   into another program.)
 
17
 
 
18
   Note that people who make modified versions of this file are not
 
19
   obligated to grant this special exception for their modified
 
20
   versions; it is their choice whether to do so. The GNU Lesser
 
21
   General Public License gives permission to release a modified
 
22
   version without this exception; this exception also makes it
 
23
   possible to release a modified version which carries forward this
 
24
   exception.
 
25
 
 
26
   The GNU C Library is distributed in the hope that it will be useful,
 
27
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
28
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
29
   Lesser General Public License for more details.
 
30
 
 
31
   You should have received a copy of the GNU Lesser General Public
 
32
   License along with the GNU C Library; if not, write to the Free
 
33
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 
34
   02111-1307 USA.  */
 
35
 
 
36
#include <errno.h>
 
37
#include <stdlib.h>
 
38
#include <unistd.h>
 
39
#include <fcntl.h>
 
40
 
 
41
#ifndef NO_SHLIB
 
42
#include <sys/exec.h>
 
43
#include <sys/types.h>
 
44
#include <sys/mman.h>
 
45
#include <link.h>
 
46
#include <syscall.h>
 
47
#endif
 
48
 
 
49
#if !defined (__GNUC__) || __GNUC__ < 2
 
50
  #error This file uses GNU C extensions; you must compile with GCC version 2.
 
51
#endif
 
52
 
 
53
/* The first piece of initialized data.  */
 
54
int __data_start = 0;
 
55
#ifdef HAVE_WEAK_SYMBOLS
 
56
weak_alias (__data_start, data_start)
 
57
#endif
 
58
 
 
59
extern void __libc_init (int argc, char **argv, char **envp) __THROW;
 
60
extern int main (int argc, char **argv, char **envp) __THROW;
 
61
 
 
62
register long int sp asm("%sp"), fp asm("%fp");
 
63
 
 
64
#ifndef NO_SHLIB
 
65
static void init_shlib (void) __THROW;
 
66
#endif
 
67
 
 
68
#ifndef NO_EXPLICIT_START
 
69
/* Declare _start with an explicit assembly symbol name of `start'
 
70
   (note no leading underscore).  This is the name Sun's crt0.o uses,
 
71
   and programs are often linked with `ld -e start'.  */
 
72
void _start (void) asm ("start");
 
73
#endif
 
74
 
 
75
void
 
76
_start (void)
 
77
{
 
78
  /* It is important that these be declared `register'.
 
79
     Otherwise, when compiled without optimization, they are put on the
 
80
     stack, which loses completely after we zero the FP.  */
 
81
  register int argc;
 
82
  register char **argv, **envp;
 
83
 
 
84
  /* Unwind the frame built when we entered the function.  */
 
85
  asm("restore");
 
86
 
 
87
  /* And clear the frame pointer.  */
 
88
  fp = 0;
 
89
 
 
90
  /* The argument info starts after one register
 
91
     window (64 bytes) past the SP.  */
 
92
  argc = ((int *) sp)[16];
 
93
  argv = (char **) &((int *) sp)[17];
 
94
  envp = &argv[argc + 1];
 
95
  __environ = envp;
 
96
 
 
97
#ifndef NO_SHLIB
 
98
  init_shlib ();
 
99
#endif
 
100
 
 
101
  /* Allocate 24 bytes of stack space for the register save area.  */
 
102
  sp -= 24;
 
103
  __libc_init (argc, argv, envp);
 
104
 
 
105
  exit (main (argc, argv, envp));
 
106
}
 
107
 
 
108
#ifndef NO_SHLIB
 
109
 
 
110
/* System calls for use by the bootstrap routine.
 
111
   These are defined here since the usual calls may be dynamically linked.  */
 
112
 
 
113
int syscall (int sysno, ...) asm ("init_syscall");
 
114
asm ("init_syscall:\n"
 
115
     "  clr %g1\n"
 
116
     "  ta 0\n"
 
117
     "  bcc 1f\n"
 
118
     "  sethi %hi(_errno), %g1\n"
 
119
     "  st %o0, [%g1 + %lo(_errno)]\n"
 
120
     "  sub %g0, 1, %o0\n"
 
121
     "1:retl\n"
 
122
     "  nop");
 
123
 
 
124
static void
 
125
init_shlib ()
 
126
{
 
127
  extern struct link_dynamic _DYNAMIC;
 
128
  int so, zf;
 
129
  caddr_t somap;
 
130
  caddr_t sodmap;
 
131
  caddr_t sobssmap;
 
132
  void (*ldstart) (int, int);
 
133
  struct exec soexec;
 
134
  struct
 
135
    {
 
136
      caddr_t crt_ba;
 
137
      int crt_dzfd;
 
138
      int crt_ldfd;
 
139
      struct link_dynamic *crt_dp;
 
140
      char **crt_ep;
 
141
      caddr_t crt_bp;
 
142
    } soarg;
 
143
 
 
144
  /* If not dynamically linked, do nothing.  */
 
145
  if (&_DYNAMIC == 0)
 
146
    return;
 
147
 
 
148
  /* Map in the dynamic linker.  */
 
149
  so = syscall (SYS_open, "/usr/lib/ld.so", O_RDONLY);
 
150
  if (syscall (SYS_read, so, &soexec, sizeof (soexec)) != sizeof (soexec)
 
151
      || soexec.a_magic != ZMAGIC)
 
152
    {
 
153
      static const char emsg[] = "crt0: no /usr/lib/ld.so\n";
 
154
 
 
155
      syscall (SYS_write, 2, emsg, sizeof (emsg) - 1);
 
156
      syscall (SYS_exit, 127);
 
157
    }
 
158
  somap = (caddr_t) syscall (SYS_mmap, 0,
 
159
                             soexec.a_text + soexec.a_data + soexec.a_bss,
 
160
                             PROT_READ | PROT_EXEC, _MAP_NEW | MAP_PRIVATE,
 
161
                             so, 0);
 
162
  sodmap = (caddr_t) syscall (SYS_mmap, somap + soexec.a_text, soexec.a_data,
 
163
                              PROT_READ | PROT_WRITE | PROT_EXEC,
 
164
                              _MAP_NEW | MAP_FIXED | MAP_PRIVATE,
 
165
                              so, soexec.a_text);
 
166
  zf = syscall (SYS_open, "/dev/zero", O_RDONLY);
 
167
  if (soexec.a_bss != 0)
 
168
    sobssmap = (caddr_t) syscall (SYS_mmap,
 
169
                                  somap + soexec.a_text + soexec.a_data,
 
170
                                  soexec.a_bss,
 
171
                                  PROT_READ | PROT_WRITE | PROT_EXEC,
 
172
                                  _MAP_NEW | MAP_FIXED | MAP_PRIVATE,
 
173
                                  zf, 0);
 
174
 
 
175
  /* Call the entry point of the dynamic linker.  */
 
176
  soarg.crt_ba = somap;
 
177
  soarg.crt_dzfd = zf;
 
178
  soarg.crt_ldfd = so;
 
179
  soarg.crt_dp = &_DYNAMIC;
 
180
  soarg.crt_ep = __environ;
 
181
  soarg.crt_bp = (caddr_t) &&retaddr;
 
182
 
 
183
  ldstart = (__typeof (ldstart)) (somap + soexec.a_entry);
 
184
  (*ldstart) (1, (char *) &soarg - (char *) sp);
 
185
 
 
186
 retaddr:
 
187
}
 
188
 
 
189
#endif