{
    This file is part of the Free Pascal run time library.
    Copyright (c) 2009 by Pierre Muller,
    member of the Free Pascal development team.

    Program startup
    Adapted from code generated by gcc on opensolaris 2.11
    and sparc version in

    See the file COPYING.FPC, included in this distribution,
    for details about the copyright.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 **********************************************************************}


type
   TCdeclProcedure = procedure; cdecl;
function atexit(proc:TCdeclProcedure):longint;cdecl;external 'c' name 'atexit'{ @plt };
procedure C_exit;cdecl;external 'c' name 'exit';
procedure _exit;cdecl;external 'c' name '_exit';
//procedure _fini;cdecl;external 'c' name '_fini';
//procedure __fpstart;cdecl;external 'c' name '__fpstart'{ @plt };
//procedure __fsr;cdecl;external 'c' name '__fsr';
//procedure _init;cdecl;external 'c' name '_init';
procedure PascalMain;cdecl;external name 'PASCALMAIN';


{vars are not correctly transformed :(
var
  _DYNAMIC : longint; cvar; external;
  __Argv : pointer; cvar; external;
  environ : pointer; cvar; external;
  __get_exit_frame_monitor_ptr : pointer; cvar; external;
  __do_exit_code_ptr : pointer; cvar; external;
}

var
  _environ : pointer; cvar; external;

procedure _DYNAMIC;cdecl;external 'c' name '_DYNAMIC'; { should be weak }

procedure __Argv;cdecl;external 'c' name '__Argv';
//procedure environ;cdecl;external 'c' name 'environ';
//procedure __get_exit_frame_monitor_ptr;cdecl;external 'c' name '__get_exit_frame_monitor_ptr';
//procedure __do_exit_code_ptr;cdecl;external 'c' name '__do_exit_code_ptr';

{
(top-gdb) disas _start
Dump of assembler code for function _start:   }
procedure _start;assembler;nostackframe;public name '_start';
asm
   pushl  $0x0
   pushl  $0x0
   mov    %esp,%ebp
   mov    $_DYNAMIC,%eax
   test   %eax,%eax
   je     .Label1
   push   %edx
   call   atexit {@plt}
   add    $0x4,%esp
.Label1:
   (*
   push   _fini
   call   atexit {@plt}
   add    $0x4,%esp
   lea    __get_exit_frame_monitor_ptr,%eax
   mov    (%eax),%eax
   test   %eax,%eax
   je     .Label2
   lea    __do_exit_code_ptr,%eax
   mov    (%eax),%eax
   test   %eax,%eax
   je     .Label2
   push   %eax
   call   atexit {@plt}
   add    $0x4,%esp
   *)
.Label2:
   mov    0x8(%ebp),%eax
   mov    %eax,argc
   mov    _environ,%edx
   test   %edx,%edx
   jne    .Label3
   lea    0x10(%ebp,%eax,4),%edx
.Label3:
   movl   %edx,_environ
   movl   %edx,envp
   and    $0xfffffff0,%esp
   push   %edx
   lea    0xc(%ebp),%edx
   mov    %edx,argv
   push   %edx
   push   %eax
   //call   __fpstart {@plt}
   //call   __fsr
   //call   _init
   call   PASCALMAIN {was <main> }
   add    $0xc,%esp
   push   %eax
   push   %eax
   call   C_exit { was exit@plt }
   add    $0x4,%esp
   call   _exit {@plt}
   add    $0x4,%esp
   hlt
end;
