home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / glibc-1.06 / sysdeps / unix / sparc / start.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-14  |  4.8 KB  |  179 lines

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