Permalink
Browse files

FEAT: added libc-init support for Syllable and Darwin. Fixes long-sta…

…nding issue #129.
  • Loading branch information...
1 parent 4d7a98f commit 21994a41a22411ecb5ad22bcb4f658069551b4f4 @dockimbel dockimbel committed Feb 26, 2012
Showing with 54 additions and 8 deletions.
  1. +39 −2 red-system/runtime/start.reds
  2. +15 −6 red-system/runtime/syllable.reds
@@ -23,9 +23,46 @@ system: declare struct! [ ;-- trimmed down temporary system definition
#switch OS [
Windows [] ;-- nothing to do, initialization occurs in DLL init entry point
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 [
libc-start: "__libc_start_main" [
main [function! []]
@@ -34,11 +34,20 @@ Red/System [
;-------------------------------------------
;-- 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
c: 0
while [argv/item <> null][
@@ -47,6 +56,6 @@ system/env-vars: as str-array! pop ;-- &envp
]
system/args-count: c
]
-***-on-start
-
+***-get-argc
+
#include %POSIX.reds

0 comments on commit 21994a4

Please sign in to comment.