Skip to content

Commit

Permalink
FEAT: added libc-init support for Syllable and Darwin. Fixes long-sta…
Browse files Browse the repository at this point in the history
…nding issue #129.
  • Loading branch information
dockimbel committed Feb 26, 2012
1 parent 4d7a98f commit 21994a4
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 8 deletions.
41 changes: 39 additions & 2 deletions red-system/runtime/start.reds
Expand Up @@ -23,9 +23,46 @@ system: declare struct! [ ;-- trimmed down temporary system definition
#switch OS [ #switch OS [
Windows [] ;-- nothing to do, initialization occurs in DLL init entry point Windows [] ;-- nothing to do, initialization occurs in DLL init entry point
Syllable [ Syllable [

#import [LIBC-file cdecl [
libc-start: "__libc_start_main" [
main [function! []]
argv [pointer! [integer!]]
envp [pointer! [integer!]]
init [function! []]
finish [function! []]
stack-end [pointer! [integer!]]
]
]]

;; Clear the frame pointer. The SVR4 ELF/i386 ABI suggests this, to
;; mark the outermost frame.
system/stack/frame: as pointer! [integer!] 0

;; Extract arguments from the call stack (which was setup by the
;; kernel).
;; esp: dummy value
;; esp+4: **argv
***__argv: system/stack/top + 1
***__argv: as [pointer! [integer!]] ***__argv/value
;; esp+8: **envp
***__envp: system/stack/top + 2
***__envp: as [pointer! [integer!]] ***__envp/value

;; Before pushing arguments for `libc-start`, align the stack to a
;; 128-bit boundary, to prevent misaligned access penalities.
system/stack/top: as pointer! [integer!] (FFFFFFF0h and as integer! ***__argv)

;; The call to `libc-start` takes 6 4-byte arguments (passed on the
;; stack). To keep the stack 128-bit aligned even after the call, we
;; push some garbage.
push 0
push 0

;; Finally, call into libc's startup routine.
***__stack_end: system/stack/top
libc-start :***_start ***__argv ***__envp null null ***__stack_end
] ]
#default [ #default [ ;-- for SVR4 fully conforming UNIX platforms
#import [LIBC-file cdecl [ #import [LIBC-file cdecl [
libc-start: "__libc_start_main" [ libc-start: "__libc_start_main" [
main [function! []] main [function! []]
Expand Down
21 changes: 15 additions & 6 deletions red-system/runtime/syllable.reds
Expand Up @@ -34,11 +34,20 @@ Red/System [
;------------------------------------------- ;-------------------------------------------
;-- Retrieve command-line information from stack ;-- Retrieve command-line information from stack
;------------------------------------------- ;-------------------------------------------
pop ;-- dummy value
system/args-list: as str-array! pop ;-- &argv
system/env-vars: as str-array! pop ;-- &envp


***-on-start: func [/local c argv][ #either use-natives? = yes [
pop ;-- dummy value
system/args-list: as str-array! pop ;-- &argv
system/env-vars: as str-array! pop ;-- &envp

][
;-- the current stack is pointing to main(int argc, void **argv, void **envp) C layout
;-- we avoid the double indirection by reusing our variables from %start.reds
system/args-list: as str-array! ***__argv
system/env-vars: as str-array! ***__envp
]

***-get-argc: func [/local c argv][
argv: system/args-list argv: system/args-list
c: 0 c: 0
while [argv/item <> null][ while [argv/item <> null][
Expand All @@ -47,6 +56,6 @@ system/env-vars: as str-array! pop ;-- &envp
] ]
system/args-count: c system/args-count: c
] ]
***-on-start ***-get-argc

#include %POSIX.reds #include %POSIX.reds

0 comments on commit 21994a4

Please sign in to comment.