; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Process management library. Linux part
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


; This procedure switches the program in PER_LINUX32_3GB personality, because of
; some conflicts with StrLib handles that are placed in the number space above
; $c0000000.
;
; It is usually the first of the initialization procedures.

if defined options.Force3GB & options.Force3GB

proc ___SwitchLinuxTo3GB
begin
        OutputValue "Stack top address: $", esp, 16, 8

        cmp     esp, $c0000000
        jb      .finish                 ; the system is 32bit

        mov     eax, sys_personality
        mov     ebx, -1
        int     $80

        OutputValue "Initial personality: $", eax, 16, 8

        test    eax, ADDR_LIMIT_3GB
        jnz     .finish                         ; everything is OK.

; set the needed personality

        DebugMsg "Switch to 3GB address space."

        mov     eax, sys_personality
        mov     ebx, PER_LINUX32_3GB
        int     $80

; and restart the process

        mov     eax, [esp+4]          ; argument count
        mov     ebx, [esp+8]          ; the first argument is the name of the program.
        lea     ecx, [esp+8]          ; the arguments list.
        lea     edx, [ecx+4*eax+4]    ; the environment list.

        mov     eax, sys_execve
        int     $80

   ; !!! THIS PROC EXITS ONLY IF EVERYTHING IS OK !!!
   ; if something gone wrong, it comes here and stops!

        int3

.finish:

        DebugMsg "The program switched to 3GB address space."
        return
endp
end if




; Terminate current thread
; Returns: eax = 0
body Terminate
begin
        mov     eax, sys_exit
        mov     ebx, [.exit_code]
        int     $80
        return
endp


; Terminate all process threads
body TerminateAll
begin
        mov     eax, sys_exit_group
        mov     ebx, [.exit_code]
        int     $80
        return
endp


body GetCmdArguments
begin
        push    ecx edx esi

        mov     esi, [_ptrEnvironment]

        mov     ecx, [esi]
        add     esi, 4

        stdcall CreateArray, 4
        mov     edx, eax
        jecxz   .array_ok

        stdcall AddArrayItems, eax, ecx

.array_ok:
        push    edx
        jecxz   .arg_ok

        lea     edx, [edx+TArray.array]

.loop:
        lodsd
        stdcall StrDupMem, eax
        mov     [edx], eax
        add     edx, 4
        loop    .loop

.arg_ok:
        pop     eax
        pop     esi edx ecx
        return
endp


match =LinuxThreads, LinuxThreads {
  define LinuxThreads posix
}

match =native, LinuxThreads {
  include '_process_native.asm'
}

match =posix, LinuxThreads {
  include '_process_posix.asm'
}




