start.inc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Michael Van Canneyt,
  4. member of the Free Pascal development team.
  5. Program startup
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. type
  13. TCdeclProcedure = procedure; cdecl;
  14. function atexit(proc:TCdeclProcedure):longint;cdecl;external 'c' name 'atexit';
  15. procedure _cleanup;cdecl;external 'c' name '_cleanup';
  16. procedure _DYNAMIC;cdecl;external 'c' name '_DYNAMIC';
  17. procedure __fpstart;cdecl;external 'c' name '__fpstart';
  18. procedure PascalMain;external name 'PASCALMAIN';
  19. procedure _start;assembler;nostackframe;public name '_start';
  20. asm
  21. // Terminate the stack frame
  22. mov %g0, %fp
  23. // Save current %sp to StackTopPtr
  24. mov %sp, %o2
  25. sethi %hi(StackTopPtr),%o1
  26. or %o1,%lo(StackTopPtr),%o1
  27. st %o2, [%o1]
  28. // Reserve space for functions to drop their arguments.
  29. sub %sp, 6*4, %sp
  30. // Extract the arguments and environment as encoded on the stack. The
  31. // argument info starts after one register window (16 words) past the SP.
  32. ld [%sp+22*4], %o2
  33. sethi %hi(argc),%o1
  34. or %o1,%lo(argc),%o1
  35. st %o2, [%o1]
  36. add %sp, 23*4, %o0
  37. sethi %hi(argv),%o1
  38. or %o1,%lo(argv),%o1
  39. st %o0, [%o1]
  40. // envp=(argc+1)*4+argv
  41. inc %o2
  42. sll %o2, 2, %o2
  43. add %o2, %o0, %o2
  44. sethi %hi(envp),%o1
  45. or %o1,%lo(envp),%o1
  46. st %o2, [%o1]
  47. // Check to see if there is an _cleanup() function linked in, and if
  48. // so, register it with atexit() as the last thing to be run by
  49. // atexit().
  50. sethi %hi(_cleanup), %o0
  51. or %o0, %lo(_cleanup), %o0
  52. cmp %o0,%g0
  53. be .L1
  54. nop
  55. call atexit
  56. nop
  57. .L1:
  58. // Now check to see if we have an _DYNAMIC table, and if so then
  59. // we need to register the function pointer previously in %edx, but
  60. // now conveniently saved on the stack as the argument to pass to
  61. // atexit().
  62. sethi %hi(_DYNAMIC), %o0
  63. or %o0, %lo(_DYNAMIC), %o0
  64. cmp %o0,%g0
  65. be .L2
  66. nop
  67. call atexit
  68. nop
  69. .L2:
  70. // Register _fini() with atexit(). We will take care of calling _init()
  71. // directly.
  72. //
  73. // sethi %hi(_fini), %o0
  74. // or %o0, %lo(_fini), %o0
  75. // call atexit
  76. // Call _init(argc, argv, environ), _fpstart(argc, argv, environ), and
  77. // main(argc, argv, environ).
  78. ld [%sp+22*4], %o0
  79. add %sp, 23*4, %o1
  80. add %o0, 1, %o2
  81. sll %o2, 2, %o2
  82. add %o2, %o1, %o2
  83. // call __fpstart
  84. // nop
  85. call PASCALMAIN
  86. nop
  87. // Die very horribly if exit returns
  88. unimp
  89. end;