Procházet zdrojové kódy

Merge branch 'master' into 'master'

# Conflicts:
#   src/stdio/src/default.rs
Tom Almeida před 6 roky
rodič
revize
a2dc22123f
100 změnil soubory, kde provedl 2581 přidání a 163 odebrání
  1. 27 0
      .gitlab-ci.yml
  2. 91 70
      Cargo.lock
  3. 9 2
      Cargo.toml
  4. 4 2
      Makefile
  5. 14 0
      include/assert.h
  6. 47 0
      include/bits/exec.h
  7. 195 0
      include/bits/inttypes.h
  8. 1 0
      include/bits/stdio.h
  9. 11 0
      include/bits/sys/stat.h
  10. 2 0
      include/complex.h
  11. 1 0
      include/math.h
  12. 67 0
      include/setjmp.h
  13. 66 0
      include/stdint.h
  14. 1 1
      ralloc
  15. 1 1
      rust-toolchain
  16. 12 4
      src/crt0/src/lib.rs
  17. 1 1
      src/fenv/cbindgen.toml
  18. 14 0
      src/inttypes/Cargo.toml
  19. 11 0
      src/inttypes/build.rs
  20. 7 0
      src/inttypes/cbindgen.toml
  21. 74 0
      src/inttypes/src/lib.rs
  22. 28 4
      src/lib.rs
  23. 3 0
      src/platform/Cargo.toml
  24. 8 1
      src/platform/src/lib.rs
  25. 8 0
      src/platform/src/linux/mod.rs
  26. 54 0
      src/platform/src/redox/mod.rs
  27. 4 0
      src/setjmp/Cargo.toml
  28. 6 0
      src/setjmp/src/impl/README.md
  29. 24 0
      src/setjmp/src/impl/aarch64/longjmp.s
  30. 24 0
      src/setjmp/src/impl/aarch64/setjmp.s
  31. 43 0
      src/setjmp/src/impl/arm/longjmp.s
  32. 45 0
      src/setjmp/src/impl/arm/setjmp.s
  33. 2 0
      src/setjmp/src/impl/bin/.gitignore
  34. 20 0
      src/setjmp/src/impl/i386/longjmp.s
  35. 23 0
      src/setjmp/src/impl/i386/setjmp.s
  36. 14 0
      src/setjmp/src/impl/m68k/longjmp.s
  37. 18 0
      src/setjmp/src/impl/m68k/setjmp.s
  38. 29 0
      src/setjmp/src/impl/microblaze/longjmp.s
  39. 32 0
      src/setjmp/src/impl/microblaze/setjmp.s
  40. 40 0
      src/setjmp/src/impl/mips/longjmp.S
  41. 39 0
      src/setjmp/src/impl/mips/setjmp.S
  42. 37 0
      src/setjmp/src/impl/mips64/longjmp.S
  43. 34 0
      src/setjmp/src/impl/mips64/setjmp.S
  44. 36 0
      src/setjmp/src/impl/mipsn32/longjmp.S
  45. 34 0
      src/setjmp/src/impl/mipsn32/setjmp.S
  46. 25 0
      src/setjmp/src/impl/or1k/longjmp.s
  47. 27 0
      src/setjmp/src/impl/or1k/setjmp.s
  48. 69 0
      src/setjmp/src/impl/powerpc/longjmp.S
  49. 63 0
      src/setjmp/src/impl/powerpc/setjmp.S
  50. 81 0
      src/setjmp/src/impl/powerpc64/longjmp.s
  51. 89 0
      src/setjmp/src/impl/powerpc64/setjmp.s
  52. 23 0
      src/setjmp/src/impl/s390x/longjmp.s
  53. 25 0
      src/setjmp/src/impl/s390x/setjmp.s
  54. 28 0
      src/setjmp/src/impl/sh/longjmp.S
  55. 32 0
      src/setjmp/src/impl/sh/setjmp.S
  56. 22 0
      src/setjmp/src/impl/x32/longjmp.s
  57. 22 0
      src/setjmp/src/impl/x32/setjmp.s
  58. 22 0
      src/setjmp/src/impl/x86_64/longjmp.s
  59. 22 0
      src/setjmp/src/impl/x86_64/setjmp.s
  60. 33 0
      src/setjmp/src/lib.rs
  61. 4 0
      src/signal/src/lib.rs
  62. 59 15
      src/stdio/src/default.rs
  63. 2 1
      src/stdlib/Cargo.toml
  64. 77 13
      src/stdlib/src/lib.rs
  65. 1 0
      src/sys_stat/cbindgen.toml
  66. 28 28
      src/sys_stat/src/lib.rs
  67. 1 0
      src/sys_time/cbindgen.toml
  68. 11 0
      src/sys_utsname/Cargo.toml
  69. 11 0
      src/sys_utsname/build.rs
  70. 5 0
      src/sys_utsname/cbindgen.toml
  71. 28 0
      src/sys_utsname/src/lib.rs
  72. 1 1
      src/time/src/constants.rs
  73. 1 0
      src/unistd/Cargo.toml
  74. 2 1
      src/unistd/cbindgen.toml
  75. 0 1
      src/unistd/src/getopt.rs
  76. 66 9
      src/unistd/src/lib.rs
  77. 394 0
      src/wchar/src/lib.rs
  78. 6 2
      tests/.gitignore
  79. 9 5
      tests/Makefile
  80. 14 0
      tests/assert.c
  81. 8 0
      tests/exec.c
  82. 0 0
      tests/expected/asctime.stderr
  83. 0 0
      tests/expected/asctime.stdout
  84. 0 0
      tests/expected/assert.stderr
  85. 1 0
      tests/expected/assert.stdout
  86. 0 0
      tests/expected/getc_unget.stderr
  87. 1 0
      tests/expected/getc_unget.stdout
  88. 0 0
      tests/expected/gmtime.stderr
  89. 0 0
      tests/expected/gmtime.stdout
  90. 0 1
      tests/expected/link.stderr
  91. 1 0
      tests/expected/printf.stdout
  92. 0 0
      tests/expected/rename.stderr
  93. 0 0
      tests/expected/rename.stdout
  94. 0 0
      tests/expected/setjmp.stderr
  95. 2 0
      tests/expected/setjmp.stdout
  96. 0 0
      tests/expected/stdio/all.stderr
  97. 3 0
      tests/expected/stdio/all.stdout
  98. 0 0
      tests/expected/stdio/freopen.stderr
  99. 1 0
      tests/expected/stdio/freopen.stdout
  100. 0 0
      tests/expected/stdio/fwrite.stderr

+ 27 - 0
.gitlab-ci.yml

@@ -0,0 +1,27 @@
+image: "rust:latest"
+
+before_script:
+    - git submodule update --init --recursive
+    - rustup toolchain add nightly
+    - rustup target add x86_64-unknown-redox --toolchain nightly
+    - rustup show      # Print version info for debugging
+
+build:linux:
+    script:
+        - make all
+
+#build:redox:
+#    script:
+#        - make all
+
+test:linux:
+    script:
+        - make test
+
+fmt:
+    script:
+        - rustup component add rustfmt-preview
+        - ./fmt.sh -- --check
+
+# TODO: Set up a docker image with a redox vm that would allow to
+#   run things like tests under redox

+ 91 - 70
Cargo.lock

@@ -3,22 +3,22 @@ name = "ansi_term"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "atty"
-version = "0.2.8"
+version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "bitflags"
-version = "1.0.1"
+version = "1.0.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -27,22 +27,22 @@ version = "0.5.2"
 dependencies = [
  "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
  "standalone-syn 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "cc"
-version = "1.0.9"
+version = "1.0.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "cfg-if"
-version = "0.1.2"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -51,18 +51,18 @@ version = "2.31.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "compiler_builtins"
 version = "0.1.0"
-source = "git+https://github.com/rust-lang-nursery/compiler-builtins.git#2a2f6d96c8dc578d2474742f14c9bab0b36b0408"
+source = "git+https://github.com/rust-lang-nursery/compiler-builtins.git#6eb8f8d710c5d77b0914bec56f68336ad3f06aac"
 
 [[package]]
 name = "crt0"
@@ -122,7 +122,7 @@ name = "fuchsia-zircon"
 version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -148,6 +148,17 @@ dependencies = [
  "sys_socket 0.1.0",
 ]
 
+[[package]]
+name = "inttypes"
+version = "0.1.0"
+dependencies = [
+ "cbindgen 0.5.2",
+ "ctype 0.1.0",
+ "errno 0.1.0",
+ "platform 0.1.0",
+ "stdlib 0.1.0",
+]
+
 [[package]]
 name = "itoa"
 version = "0.4.1"
@@ -155,7 +166,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libc"
-version = "0.2.40"
+version = "0.2.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -171,15 +182,15 @@ name = "log"
 version = "0.3.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "log"
-version = "0.4.1"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -189,16 +200,11 @@ dependencies = [
  "in_h 0.1.0",
 ]
 
-[[package]]
-name = "num-traits"
-version = "0.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "platform"
 version = "0.1.0"
 dependencies = [
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "sc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -227,7 +233,7 @@ dependencies = [
 name = "ralloc_shim"
 version = "0.1.1"
 dependencies = [
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "sc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -237,26 +243,26 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rand"
-version = "0.5.0-pre.0"
-source = "git+https://github.com/rust-lang-nursery/rand/#1960f833c0ca54c75badd11c5af397c677f92584"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rand_core 0.1.0-pre.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rand_core"
-version = "0.1.0-pre.0"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "redox_syscall"
-version = "0.1.37"
+version = "0.1.40"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -264,14 +270,14 @@ name = "redox_termios"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "relibc"
 version = "0.1.0"
 dependencies = [
- "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.1.0 (git+https://github.com/rust-lang-nursery/compiler-builtins.git)",
  "ctype 0.1.0",
  "errno 0.1.0",
@@ -279,10 +285,12 @@ dependencies = [
  "fenv 0.1.0",
  "float 0.1.0",
  "grp 0.1.0",
+ "inttypes 0.1.0",
  "locale 0.1.0",
  "netinet 0.1.0",
  "platform 0.1.0",
  "semaphore 0.1.0",
+ "setjmp 0.1.0",
  "signal 0.1.0",
  "stdio 0.1.0",
  "stdlib 0.1.0",
@@ -292,6 +300,7 @@ dependencies = [
  "sys_socket 0.1.0",
  "sys_stat 0.1.0",
  "sys_time 0.1.0",
+ "sys_utsname 0.1.0",
  "sys_wait 0.1.0",
  "time 0.1.0",
  "unistd 0.1.0",
@@ -300,10 +309,10 @@ dependencies = [
 
 [[package]]
 name = "remove_dir_all"
-version = "0.5.0"
+version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -321,7 +330,7 @@ dependencies = [
 
 [[package]]
 name = "serde"
-version = "1.0.36"
+version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -348,15 +357,18 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.13"
+version = "1.0.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "setjmp"
+version = "0.1.0"
+
 [[package]]
 name = "signal"
 version = "0.1.0"
@@ -405,7 +417,8 @@ dependencies = [
  "errno 0.1.0",
  "platform 0.1.0",
  "ralloc 1.0.0",
- "rand 0.5.0-pre.0 (git+https://github.com/rust-lang-nursery/rand/)",
+ "rand 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.0",
 ]
 
 [[package]]
@@ -482,6 +495,14 @@ dependencies = [
  "platform 0.1.0",
 ]
 
+[[package]]
+name = "sys_utsname"
+version = "0.1.0"
+dependencies = [
+ "cbindgen 0.5.2",
+ "platform 0.1.0",
+]
+
 [[package]]
 name = "sys_wait"
 version = "0.1.0"
@@ -497,7 +518,7 @@ version = "0.3.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -505,8 +526,8 @@ name = "termion"
 version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -515,7 +536,7 @@ name = "textwrap"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -529,10 +550,10 @@ dependencies = [
 
 [[package]]
 name = "toml"
-version = "0.4.5"
+version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "serde 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -542,7 +563,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "unicode-width"
-version = "0.1.4"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -563,6 +584,7 @@ dependencies = [
  "platform 0.1.0",
  "stdio 0.1.0",
  "string 0.1.0",
+ "sys_utsname 0.1.0",
 ]
 
 [[package]]
@@ -576,12 +598,12 @@ dependencies = [
 name = "va_list-helper"
 version = "0.0.2"
 dependencies = [
- "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "vec_map"
-version = "0.8.0"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -594,7 +616,7 @@ dependencies = [
 
 [[package]]
 name = "winapi"
-version = "0.3.4"
+version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -613,33 +635,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [metadata]
 "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
-"checksum atty 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "af80143d6f7608d746df1520709e5d141c96f240b0e62b0aa41bdfb53374d9d4"
-"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
-"checksum cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2b4911e4bdcb4100c7680e7e854ff38e23f1b34d4d9e079efae3da2801341ffc"
-"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
+"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1"
+"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
+"checksum cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "49ec142f5768efb5b7622aebc3fdbdbb8950a4b9ba996393cb76ef7466e8747d"
+"checksum cfg-if 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "405216fd8fe65f718daa7102ea808a946b6ce40c742998fbfd3463645552de18"
 "checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
 "checksum compiler_builtins 0.1.0 (git+https://github.com/rust-lang-nursery/compiler-builtins.git)" = "<none>"
 "checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
 "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 "checksum itoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c069bbec61e1ca5a596166e55dfe4773ff745c3d16b700013bcaff9a6df2c682"
-"checksum libc 0.2.40 (registry+https://github.com/rust-lang/crates.io-index)" = "6fd41f331ac7c5b8ac259b8bf82c75c0fb2e469bbf37d2becbba9a6a2221965b"
+"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
 "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
-"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
-"checksum num-traits 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dee092fcdf725aee04dd7da1d21debff559237d49ef1cb3e69bcb8ece44c7364"
+"checksum log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6fddaa003a65722a7fb9e26b0ce95921fe4ba590542ced664d8ce2fa26f9f3ac"
 "checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0"
 "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
 "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
-"checksum rand 0.5.0-pre.0 (git+https://github.com/rust-lang-nursery/rand/)" = "<none>"
-"checksum rand_core 0.1.0-pre.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2362a41734390a5953cfbf12dbb74b4573137f7ba9dad344bba804ea4355f23a"
-"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
+"checksum rand 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d0d9f869af32e387d9e0f2bdb64326b8ac84c81d5e55459d0bc7526b0fdb3671"
+"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
+"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
 "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
-"checksum remove_dir_all 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfc5b3ce5d5ea144bb04ebd093a9e14e9765bcfec866aecda9b6dec43b3d1e24"
+"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
 "checksum sc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4ebbb026ba4a707c25caec2db5ef59ad8b41f7ad77cad06257e06229c891f376"
-"checksum serde 1.0.36 (registry+https://github.com/rust-lang/crates.io-index)" = "c70142ae874a42c70e03c63c6a49abe2ea0079b090bf6e136e99252fc1974bd6"
+"checksum serde 1.0.66 (registry+https://github.com/rust-lang/crates.io-index)" = "e9a2d9a9ac5120e0f768801ca2b58ad6eec929dc9d1d616c162f208869c2ce95"
 "checksum serde_derive 1.0.21 (registry+https://github.com/rust-lang/crates.io-index)" = "652bc323d694dc925829725ec6c890156d8e70ae5202919869cb00fe2eff3788"
 "checksum serde_derive_internals 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "32f1926285523b2db55df263d2aa4eb69ddcfa7a7eade6430323637866b513ab"
-"checksum serde_json 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "5c508584d9913df116b91505eec55610a2f5b16e9ed793c46e4d0152872b3e74"
+"checksum serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "84b8035cabe9b35878adec8ac5fe03d5f6bc97ff6edd7ccb96b44c1276ba390e"
 "checksum standalone-quote 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dcedac1d6d98e7e9d1d6e628f5635af9566688ae5f6cea70a3976f495ae8d839"
 "checksum standalone-syn 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "115808f5187c07c23cb93eee49d542fae54c6e8285d3a24c6ff683fcde9243db"
 "checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550"
@@ -648,12 +669,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
 "checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
-"checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e"
+"checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9"
 "checksum unborrow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e92e959f029e4f8ee25d70d15ab58d2b46f98a17bc238b9265ff0c26f6f3d67f"
-"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
+"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
 "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
 "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
-"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
-"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
+"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
+"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd"
 "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

+ 9 - 2
Cargo.toml

@@ -11,19 +11,20 @@ crate-type = ["staticlib"]
 members = ["src/crt0"]
 
 [build-dependencies]
-cc = "1.0"
+cc = "1.0.17"
 
 [dependencies]
-compiler_builtins = { git = "https://github.com/rust-lang-nursery/compiler-builtins.git", default-features = false }
 ctype = { path = "src/ctype" }
 errno = { path = "src/errno" }
 fcntl = { path = "src/fcntl" }
 fenv = { path = "src/fenv" }
 float = { path = "src/float" }
 grp = { path = "src/grp" }
+inttypes = { path = "src/inttypes" }
 locale = { path = "src/locale" }
 netinet = { path = "src/netinet" }
 platform = { path = "src/platform" }
+setjmp = { path = "src/setjmp" }
 semaphore = { path = "src/semaphore" }
 signal = { path = "src/signal" }
 stdio = { path = "src/stdio" }
@@ -34,11 +35,17 @@ sys_resource = { path = "src/sys_resource" }
 sys_socket = { path = "src/sys_socket" }
 sys_stat = { path = "src/sys_stat" }
 sys_time = { path = "src/sys_time" }
+sys_utsname = { path = "src/sys_utsname" }
 sys_wait = { path = "src/sys_wait" }
 time = { path = "src/time" }
 unistd = { path = "src/unistd" }
 wctype = { path = "src/wctype" }
 
+[dependencies.compiler_builtins]
+git = "https://github.com/rust-lang-nursery/compiler-builtins.git"
+default-features = false
+features = ["no-lang-items", "mangled-names"]
+
 [profile.dev]
 panic = "abort"
 

+ 4 - 2
Makefile

@@ -38,6 +38,8 @@ install: all
 	cp -rv "target/include"/* "$(DESTDIR)/include"
 	cp -v "$(BUILD)/debug/libc.a" "$(DESTDIR)/lib"
 	cp -v "$(BUILD)/debug/crt0.o" "$(DESTDIR)/lib"
+	cp -rv "openlibm/include"/* "$(DESTDIR)/include"
+	cp -rv "openlibm/src"/*.h "$(DESTDIR)/include"
 	cp -v "$(BUILD)/openlibm/libopenlibm.a" "$(DESTDIR)/lib/libm.a"
 
 libc: $(BUILD)/debug/libc.a $(BUILD)/debug/crt0.o
@@ -52,7 +54,7 @@ $(BUILD)/debug/libc.a: $(SRC)
 	touch $@
 
 $(BUILD)/debug/crt0.o: $(SRC)
-	cargo rustc --manifest-path src/crt0/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@
+	CARGO_INCREMENTAL=0 cargo --verbose --verbose rustc --manifest-path src/crt0/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@
 	touch $@
 
 $(BUILD)/release/libc.a: $(SRC)
@@ -60,7 +62,7 @@ $(BUILD)/release/libc.a: $(SRC)
 	touch $@
 
 $(BUILD)/release/crt0.o: $(SRC)
-	cargo rustc --release --manifest-path src/crt0/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@
+	CARGO_INCREMENTAL=0 cargo rustc --release --manifest-path src/crt0/Cargo.toml $(CARGOFLAGS) -- --emit obj=$@
 	touch $@
 
 $(BUILD)/openlibm: openlibm

+ 14 - 0
include/assert.h

@@ -0,0 +1,14 @@
+#ifndef _ASSERT_H
+#define _ASSERT_H
+
+#ifdef NDEBUG
+# define assert(cond)
+#else
+# include <stdio.h>
+# define assert(cond) if (!(cond)) { \
+    fprintf(stderr, "%s: %s:%d: Assertion `%s` failed.\n", __func__, __FILE__, __LINE__, #cond); \
+    abort(); \
+    }
+#endif
+
+#endif

+ 47 - 0
include/bits/exec.h

@@ -0,0 +1,47 @@
+#ifndef _BITS_EXEC_H
+#define _BITS_EXEC_H
+
+int execl(const char *path, const char* argv0, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, argv0);
+	for (argc = 1; va_arg(ap, const char*); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		va_start(ap, argv0);
+		argv[0] = (char *)argv0;
+		for (i = 1; i < argc; i++) {
+			argv[i] = va_arg(ap, char *);
+		}
+		argv[i] = NULL;
+		va_end(ap);
+		return execv(path, argv);
+	}
+}
+
+int execle(const char *path, const char* argv0, ...)
+{
+	int argc;
+	va_list ap;
+	va_start(ap, argv0);
+	for (argc = 1; va_arg(ap, const char *); argc++);
+	va_end(ap);
+	{
+		int i;
+		char *argv[argc+1];
+		char **envp;
+		va_start(ap, argv0);
+		argv[0] = (char *)argv0;
+		for (i = 1; i <= argc; i++) {
+			argv[i] = va_arg(ap, char *);
+		}
+		envp = va_arg(ap, char **);
+		va_end(ap);
+		return execve(path, argv, envp);
+	}
+}
+
+#endif

+ 195 - 0
include/bits/inttypes.h

@@ -0,0 +1,195 @@
+#ifndef _BITS_INTTYPE_H
+#define _BITS_INTTYPE_H
+
+#define PRId8  "hhd"
+#define PRId16 "hd"
+#define PRId32 "ld"
+#define PRId64 "Ld"
+
+#define PRIdLEAST8  "hhd"
+#define PRIdLEAST16 "hd"
+#define PRIdLEAST32 "ld"
+#define PRIdLEAST64 "Ld"
+
+#define PRIdFAST8  "hhd"
+#define PRIdFAST16 "hd"
+#define PRIdFAST32 "ld"
+#define PRIdFAST64 "Ld"
+
+#define PRIi8  "hhi"
+#define PRIi16 "hi"
+#define PRIi32 "li"
+#define PRIi64 "Li"
+
+#define PRIiLEAST8  "hhi"
+#define PRIiLEAST16 "hi"
+#define PRIiLEAST32 "li"
+#define PRIiLEAST64 "Li"
+
+#define PRIiFAST8  "hhi"
+#define PRIiFAST16 "hi"
+#define PRIiFAST32 "li"
+#define PRIiFAST64 "Li"
+
+#define PRIo8  "hho"
+#define PRIo16 "ho"
+#define PRIo32 "lo"
+#define PRIo64 "Lo"
+
+#define PRIoLEAST8  "hho"
+#define PRIoLEAST16 "ho"
+#define PRIoLEAST32 "lo"
+#define PRIoLEAST64 "Lo"
+
+#define PRIoFAST8  "hho"
+#define PRIoFAST16 "ho"
+#define PRIoFAST32 "lo"
+#define PRIoFAST64 "Lo"
+
+#define PRIu8  "hhu"
+#define PRIu16 "hu"
+#define PRIu32 "lu"
+#define PRIu64 "Lu"
+
+#define PRIuLEAST8  "hhu"
+#define PRIuLEAST16 "hu"
+#define PRIuLEAST32 "lu"
+#define PRIuLEAST64 "Lu"
+
+#define PRIuFAST8  "hhu"
+#define PRIuFAST16 "hu"
+#define PRIuFAST32 "lu"
+#define PRIuFAST64 "Lu"
+
+#define PRIx8  "hhx"
+#define PRIx16 "hx"
+#define PRIx32 "lx"
+#define PRIx64 "Lx"
+
+#define PRIxLEAST8  "hhx"
+#define PRIxLEAST16 "hx"
+#define PRIxLEAST32 "lx"
+#define PRIxLEAST64 "Lx"
+
+#define PRIxFAST8  "hhx"
+#define PRIxFAST16 "hx"
+#define PRIxFAST32 "lx"
+#define PRIxFAST64 "Lx"
+
+#define PRIX8  "hhX"
+#define PRIX16 "hX"
+#define PRIX32 "lX"
+#define PRIX64 "LX"
+
+#define PRIXLEAST8  "hhX"
+#define PRIXLEAST16 "hX"
+#define PRIXLEAST32 "lX"
+#define PRIXLEAST64 "LX"
+
+#define PRIXFAST8  "hhX"
+#define PRIXFAST16 "hX"
+#define PRIXFAST32 "lX"
+#define PRIXFAST64 "LX"
+
+#define PRIdMAX "jd"
+#define PRIiMAX "ji"
+#define PRIoMAX "jo"
+#define PRIuMAX "ju"
+#define PRIxMAX "jx"
+#define PRIXMAX "jX"
+
+#define PRIdPTR "td"
+#define PRIiPTR "ti"
+#define PRIoPTR "to"
+#define PRIuPTR "tu"
+#define PRIxPTR "tx"
+#define PRIXPTR "tX"
+
+#define SCNd8  "hhd"
+#define SCNd16 "hd"
+#define SCNd32 "ld"
+#define SCNd64 "Ld"
+
+#define SCNdLEAST8  "hhd"
+#define SCNdLEAST16 "hd"
+#define SCNdLEAST32 "ld"
+#define SCNdLEAST64 "Ld"
+
+#define SCNdFAST8  "hhd"
+#define SCNdFAST16 "hd"
+#define SCNdFAST32 "ld"
+#define SCNdFAST64 "Ld"
+
+#define SCNi8  "hhi"
+#define SCNi16 "hi"
+#define SCNi32 "li"
+#define SCNi64 "Li"
+
+#define SCNiLEAST8  "hhi"
+#define SCNiLEAST16 "hi"
+#define SCNiLEAST32 "li"
+#define SCNiLEAST64 "Li"
+
+#define SCNiFAST8  "hhi"
+#define SCNiFAST16 "hi"
+#define SCNiFAST32 "li"
+#define SCNiFAST64 "Li"
+
+#define SCNo8  "hho"
+#define SCNo16 "ho"
+#define SCNo32 "lo"
+#define SCNo64 "Lo"
+
+#define SCNoLEAST8  "hho"
+#define SCNoLEAST16 "ho"
+#define SCNoLEAST32 "lo"
+#define SCNoLEAST64 "Lo"
+
+#define SCNoFAST8  "hho"
+#define SCNoFAST16 "ho"
+#define SCNoFAST32 "lo"
+#define SCNoFAST64 "Lo"
+
+#define SCNu8  "hhu"
+#define SCNu16 "hu"
+#define SCNu32 "lu"
+#define SCNu64 "Lu"
+
+#define SCNuLEAST8  "hhu"
+#define SCNuLEAST16 "hu"
+#define SCNuLEAST32 "lu"
+#define SCNuLEAST64 "Lu"
+
+#define SCNuFAST8  "hhu"
+#define SCNuFAST16 "hu"
+#define SCNuFAST32 "lu"
+#define SCNuFAST64 "Lu"
+
+#define SCNx8  "hhx"
+#define SCNx16 "hx"
+#define SCNx32 "lx"
+#define SCNx64 "Lx"
+
+#define SCNxLEAST8  "hhx"
+#define SCNxLEAST16 "hx"
+#define SCNxLEAST32 "lx"
+#define SCNxLEAST64 "Lx"
+
+#define SCNxFAST8  "hhx"
+#define SCNxFAST16 "hx"
+#define SCNxFAST32 "lx"
+#define SCNxFAST64 "Lx"
+
+#define SCNdMAX "jd"
+#define SCNiMAX "ji"
+#define SCNoMAX "jo"
+#define SCNuMAX "ju"
+#define SCNxMAX "jx"
+
+#define SCNdPTR "td"
+#define SCNiPTR "ti"
+#define SCNoPTR "to"
+#define SCNuPTR "tu"
+#define SCNxPTR "tx"
+
+#endif

+ 1 - 0
include/bits/stdio.h

@@ -2,6 +2,7 @@
 #define _BITS_STDIO_H
 
 #define EOF (-1)
+#define BUFSIZ 1024
 #define stdin __stdin()
 #define stdout __stdout()
 #define stderr __stderr()

+ 11 - 0
include/bits/sys/stat.h

@@ -0,0 +1,11 @@
+#ifndef _BITS_STAT_H
+#define _BITS_STAT_H
+
+#define S_ISDIR(mode) mode & S_IFMT == S_IFDIR
+#define S_ISCHR(mode) mode & S_IFMT == S_IFCHR
+#define S_ISBLK(mode) mode & S_IFMT == S_IFBLK
+#define S_ISREG(mode) mode & S_IFMT == S_IFREG
+#define S_ISIFO(mode) mode & S_IFMT == S_IFIFO
+#define S_ISLNK(mode) mode & S_IFMT == S_IFLNK
+
+#endif

+ 2 - 0
include/complex.h

@@ -0,0 +1,2 @@
+#define OPENLIBM_USE_HOST_FENV_H 1
+#include <openlibm.h>

+ 1 - 0
include/math.h

@@ -1 +1,2 @@
+#define OPENLIBM_USE_HOST_FENV_H 1
 #include <openlibm.h>

+ 67 - 0
include/setjmp.h

@@ -0,0 +1,67 @@
+#ifndef _SETJMP_H
+#define _SETJMP_H
+
+#ifdef __arch64__
+typedef unsigned long jmp_buf[22];
+#endif
+
+#ifdef __arm__
+typedef unsigned long long jmp_buf[32];
+#endif
+
+#ifdef __i386__
+typedef unsigned long jmp_buf[6];
+#endif
+
+#ifdef __m68k__
+typedef unsigned long jmp_buf[39];
+#endif
+
+#ifdef __microblaze__
+typedef unsigned long jmp_buf[18];
+#endif
+
+#ifdef __mips__
+typedef unsigned long long jmp_buf[13];
+#endif
+
+#ifdef __mips64__
+typedef unsigned long long jmp_buf[23];
+#endif
+
+#ifdef __mipsn32__
+typedef unsigned long long jmp_buf[23];
+#endif
+
+#ifdef __or1k__
+typedef unsigned long jmp_buf[13];
+#endif
+
+#ifdef __powerpc__
+typedef unsigned long long jmp_buf[56];
+#endif
+
+#ifdef __powerpc64__
+typedef uint128_t jmp_buf[32];
+#endif
+
+#ifdef __s390x__
+typedef unsigned long jmp_buf[18];
+#endif
+
+#ifdef __sh__
+typedef unsigned long jmp_buf[15];
+#endif
+
+#ifdef __x32__
+typedef unsigned long long jmp_buf[8];
+#endif
+
+#ifdef __x86_64__
+typedef unsigned long jmp_buf[8];
+#endif
+
+int setjmp(jmp_buf buf);
+void longjmp(jmp_buf buf, int value);
+
+#endif /* _SETJMP_H */

+ 66 - 0
include/stdint.h

@@ -6,41 +6,105 @@
 #define INT8_MAX 0x7F
 typedef signed char int8_t;
 
+#define INT_LEAST8_MIN -0x80
+#define INT_LEAST8_MAX 0x7F
+typedef signed char int_least8_t;
+
+#define INT_FAST8_MIN -0x80
+#define INT_FAST8_MAX 0x7F
+typedef signed char int_fast8_t;
+
 #define UINT8_C(value) ((uint8_t) value ## U)
 #define UINT8_MIN 0x00
 #define UINT8_MAX 0xFF
 typedef unsigned char uint8_t;
 
+#define UINT_LEAST8_MIN 0x00
+#define UINT_LEAST8_MAX 0xFF
+typedef unsigned char uint_least8_t;
+
+#define UINT_FAST8_MIN 0x00
+#define UINT_FAST8_MAX 0xFF
+typedef unsigned char uint_fast8_t;
+
 #define INT16_C(value) value
 #define INT16_MIN -0x8000
 #define INT16_MAX 0x7FFF
 typedef signed short int16_t;
 
+#define INT_LEAST16_MIN -0x8000
+#define INT_LEAST16_MAX 0x7FFF
+typedef signed short int_least16_t;
+
+#define INT_FAST16_MIN -0x8000
+#define INT_FAST16_MAX 0x7FFF
+typedef signed short int_fast16_t;
+
 #define UINT16_C(value) value ## U
 #define UINT16_MIN 0x0000
 #define UINT16_MAX 0xFFFF
 typedef unsigned short uint16_t;
 
+#define UINT_LEAST16_MIN 0x0000
+#define UINT_LEAST16_MAX 0xFFFF
+typedef unsigned short uint_least16_t;
+
+#define UINT_FAST16_MIN 0x0000
+#define UINT_FAST16_MAX 0xFFFF
+typedef unsigned short uint_fast16_t;
+
 #define INT32_C(value) value ## L
 #define INT32_MIN -0x80000000
 #define INT32_MAX 0x7FFFFFFF
 typedef signed long int32_t;
 
+#define INT_LEAST32_MIN -0x80000000
+#define INT_LEAST32_MAX 0x7FFFFFFF
+typedef signed long int_least32_t;
+
+#define INT_FAST32_MIN -0x80000000
+#define INT_FAST32_MAX 0x7FFFFFFF
+typedef signed long int_fast32_t;
+
 #define UINT32_C(value) value ## UL
 #define UINT32_MIN 0x00000000
 #define UINT32_MAX 0xFFFFFFFF
 typedef unsigned long uint32_t;
 
+#define UINT_LEAST32_MIN 0x00000000
+#define UINT_LEAST32_MAX 0xFFFFFFFF
+typedef unsigned long uint_least32_t;
+
+#define UINT_FAST32_MIN 0x00000000
+#define UINT_FAST32_MAX 0xFFFFFFFF
+typedef unsigned long uint_fast32_t;
+
 #define INT64_C(value) value ## LL
 #define INT64_MIN -0x8000000000000000
 #define INT64_MAX 0x7FFFFFFFFFFFFFFF
 typedef signed long long int64_t;
 
+#define INT_LEAST64_MIN -0x8000000000000000
+#define INT_LEAST64_MAX 0x7FFFFFFFFFFFFFFF
+typedef signed long long int_least64_t;
+
+#define INT_FAST64_MIN -0x8000000000000000
+#define INT_FAST64_MAX 0x7FFFFFFFFFFFFFFF
+typedef signed long long int_fast64_t;
+
 #define UINT64_C(value) value ## ULL
 #define UINT64_MIN 0x0000000000000000
 #define UINT64_MAX 0xFFFFFFFFFFFFFFFF
 typedef unsigned long long uint64_t;
 
+#define UINT_LEAST64_MIN 0x0000000000000000
+#define UINT_LEAST64_MAX 0xFFFFFFFFFFFFFFFF
+typedef unsigned long long uint_least64_t;
+
+#define UINT_FAST64_MIN 0x0000000000000000
+#define UINT_FAST64_MAX 0xFFFFFFFFFFFFFFFF
+typedef unsigned long long uint_fast64_t;
+
 #define INTMAX_C(value) value ## LL
 #define INTMAX_MIN INT64_MIN
 #define INTMAX_MAX INT64_MAX
@@ -61,4 +125,6 @@ typedef uint64_t uintptr_t;
 
 #define SIZE_MAX UINT64_MAX
 
+typedef long sig_atomic_t;
+
 #endif /* _STDINT_H */

+ 1 - 1
ralloc

@@ -1 +1 @@
-Subproject commit 2d8d44970eb5bb2ecc55f5ced8a33f21ed9407f4
+Subproject commit 867c809039aef77dbce22e98b1009b8995dfa868

+ 1 - 1
rust-toolchain

@@ -1 +1 @@
-nightly-2018-03-04
+nightly-2018-06-19

+ 12 - 4
src/crt0/src/lib.rs

@@ -2,8 +2,9 @@
 
 #![no_std]
 #![feature(asm)]
-#![feature(lang_items)]
+#![feature(linkage)]
 #![feature(naked_functions)]
+#![feature(panic_implementation)]
 
 extern crate platform;
 
@@ -59,7 +60,14 @@ pub unsafe extern "C" fn _start_rust(sp: &'static Stack) -> ! {
     platform::exit(main(argc, argv));
 }
 
-#[lang = "panic_fmt"]
-pub extern "C" fn rust_begin_unwind(_fmt: ::core::fmt::Arguments, _file: &str, _line: u32) -> ! {
-    loop {}
+#[panic_implementation]
+#[linkage = "weak"]
+#[no_mangle]
+pub extern "C" fn rust_begin_unwind(pi: &::core::panic::PanicInfo) -> ! {
+    use core::fmt::Write;
+
+    let mut w = platform::FileWriter(2);
+    let _ = w.write_fmt(format_args!("RELIBC CRT0 PANIC: {}\n", pi));
+
+    platform::exit(1);
 }

+ 1 - 1
src/fenv/cbindgen.toml

@@ -1,4 +1,4 @@
-sys_includes = ["sys/types.h"]
+sys_includes = ["stdint.h", "sys/types.h"]
 include_guard = "_FENV_H"
 language = "C"
 

+ 14 - 0
src/inttypes/Cargo.toml

@@ -0,0 +1,14 @@
+[package]
+name = "inttypes"
+version = "0.1.0"
+authors = ["jD91mZM2 <me@krake.one>"]
+build = "build.rs"
+
+[build-dependencies]
+cbindgen = { path = "../../cbindgen" }
+
+[dependencies]
+ctype = { path = "../ctype" }
+errno = { path = "../errno" }
+platform = { path = "../platform" }
+stdlib = { path = "../stdlib" }

+ 11 - 0
src/inttypes/build.rs

@@ -0,0 +1,11 @@
+extern crate cbindgen;
+
+use std::{env, fs};
+
+fn main() {
+    let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
+    fs::create_dir_all("../../target/include").expect("failed to create include directory");
+    cbindgen::generate(crate_dir)
+        .expect("failed to generate bindings")
+        .write_to_file("../../target/include/inttypes.h");
+}

+ 7 - 0
src/inttypes/cbindgen.toml

@@ -0,0 +1,7 @@
+sys_includes = ["stdint.h"]
+include_guard = "_INTTYPES_H"
+trailer = "#include <bits/inttypes.h>"
+language = "C"
+
+[enum]
+prefix_with_name = true

+ 74 - 0
src/inttypes/src/lib.rs

@@ -0,0 +1,74 @@
+#[macro_use] extern crate stdlib;
+extern crate ctype;
+extern crate errno;
+extern crate platform;
+
+use errno::*;
+use platform::types::*;
+
+#[no_mangle]
+pub extern "C" fn imaxabs(i: intmax_t) -> intmax_t {
+    i.abs()
+}
+
+#[no_mangle]
+#[repr(C)]
+pub struct intmaxdiv_t {
+    quot: intmax_t,
+    rem: intmax_t
+}
+
+#[no_mangle]
+pub extern "C" fn imaxdiv(i: intmax_t, j: intmax_t) -> intmaxdiv_t {
+    intmaxdiv_t {
+        quot: i / j,
+        rem: i % j
+    }
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn strtoimax(s: *const c_char,
+                                   endptr: *mut *mut c_char,
+                                   base: c_int)
+                                   -> intmax_t {
+    use stdlib::*;
+    strto_impl!(
+        intmax_t,
+        false,
+        intmax_t::max_value(),
+        intmax_t::min_value(),
+        s,
+        endptr,
+        base
+    )
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn strtoumax(s: *const c_char,
+                                   endptr: *mut *mut c_char,
+                                   base: c_int)
+                                   -> uintmax_t {
+    use stdlib::*;
+    strto_impl!(
+        uintmax_t,
+        false,
+        uintmax_t::max_value(),
+        uintmax_t::min_value(),
+        s,
+        endptr,
+        base
+    )
+}
+
+#[allow(unused)]
+#[no_mangle]
+pub extern "C" fn wcstoimax(nptr: *const wchar_t, endptr: *mut *mut wchar_t,
+                  base: c_int) -> intmax_t {
+    unimplemented!();
+}
+#[allow(unused)]
+#[no_mangle]
+pub extern "C" fn wcstoumax(nptr: *const wchar_t, endptr: *mut *mut wchar_t,
+                  base: c_int) -> uintmax_t {
+    unimplemented!();
+}

+ 28 - 4
src/lib.rs

@@ -1,7 +1,9 @@
 #![no_std]
 #![feature(lang_items)]
+#![feature(linkage)]
+#![feature(panic_implementation)]
 
-extern crate compiler_builtins;
+//extern crate compiler_builtins;
 extern crate platform;
 
 pub extern crate ctype;
@@ -13,6 +15,8 @@ pub extern crate grp;
 pub extern crate locale;
 pub extern crate netinet;
 pub extern crate semaphore;
+pub extern crate setjmp;
+pub extern crate signal;
 pub extern crate stdio;
 pub extern crate stdlib;
 pub extern crate string;
@@ -21,27 +25,47 @@ pub extern crate sys_resource;
 pub extern crate sys_socket;
 pub extern crate sys_stat;
 pub extern crate sys_time;
+pub extern crate sys_utsname;
 pub extern crate sys_wait;
 pub extern crate time;
 pub extern crate unistd;
 pub extern crate wctype;
 
+#[cfg(not(test))]
+#[panic_implementation]
+#[linkage = "weak"]
+#[no_mangle]
+pub extern "C" fn rust_begin_unwind(pi: &::core::panic::PanicInfo) -> ! {
+    use core::fmt::Write;
+
+    let mut w = platform::FileWriter(2);
+    let _ = w.write_fmt(format_args!("RELIBC PANIC: {}\n", pi));
+
+    platform::exit(1);
+}
+
+#[cfg(not(test))]
 #[lang = "eh_personality"]
 #[no_mangle]
+#[linkage = "weak"]
 pub extern "C" fn rust_eh_personality() {}
 
-#[lang = "panic_fmt"]
+#[cfg(not(test))]
+#[lang = "oom"]
+#[linkage = "weak"]
 #[no_mangle]
-pub extern "C" fn rust_begin_unwind(fmt: ::core::fmt::Arguments, file: &str, line: u32) -> ! {
+pub extern fn rust_oom(layout: ::core::alloc::Layout) -> ! {
     use core::fmt::Write;
 
     let mut w = platform::FileWriter(2);
-    let _ = w.write_fmt(format_args!("{}:{}: {}\n", file, line, fmt));
+    let _ = w.write_fmt(format_args!("RELIBC OOM: {} bytes aligned to {} bytes\n", layout.size(), layout.align()));
 
     platform::exit(1);
 }
 
+#[cfg(not(test))]
 #[allow(non_snake_case)]
+#[linkage = "weak"]
 #[no_mangle]
 pub extern "C" fn _Unwind_Resume() -> ! {
     use core::fmt::Write;

+ 3 - 0
src/platform/Cargo.toml

@@ -8,3 +8,6 @@ sc = "0.2"
 
 [target.'cfg(target_os = "redox")'.dependencies]
 redox_syscall = "0.1"
+
+[dependencies]
+ralloc = { path = "../../ralloc" }

+ 8 - 1
src/platform/src/lib.rs

@@ -2,6 +2,8 @@
 
 #![no_std]
 #![allow(non_camel_case_types)]
+#![feature(alloc)]
+#![feature(global_allocator)]
 //TODO #![feature(thread_local)]
 
 #[cfg(all(not(feature = "no_std"), target_os = "linux"))]
@@ -10,7 +12,7 @@ extern crate sc;
 
 #[cfg(all(not(feature = "no_std"), target_os = "redox"))]
 #[macro_use]
-extern crate syscall;
+pub extern crate syscall;
 
 pub use sys::*;
 
@@ -22,12 +24,17 @@ mod sys;
 #[path = "redox/mod.rs"]
 mod sys;
 
+extern crate alloc;
+extern crate ralloc;
+
 pub mod types;
 
 use core::fmt;
 
 use types::*;
 
+#[global_allocator]
+static ALLOCATOR: ralloc::Allocator = ralloc::Allocator;
 //TODO #[thread_local]
 #[allow(non_upper_case_globals)]
 #[no_mangle]

+ 8 - 0
src/platform/src/linux/mod.rs

@@ -54,6 +54,10 @@ pub fn dup2(fildes: c_int, fildes2: c_int) -> c_int {
     e(unsafe { syscall!(DUP3, fildes, fildes2, 0) }) as c_int
 }
 
+pub fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
+    e(unsafe { syscall!(EXECVE, path, argv, envp) }) as c_int
+}
+
 pub fn exit(status: c_int) -> ! {
     unsafe {
         syscall!(EXIT, status);
@@ -198,6 +202,10 @@ pub fn stat(file: *const c_char, buf: *mut stat) -> c_int {
     e(unsafe { syscall!(NEWFSTATAT, AT_FDCWD, file, buf, 0) }) as c_int
 }
 
+pub fn uname(utsname: usize) -> c_int {
+    e(unsafe { syscall!(UNAME, utsname, 0) }) as c_int
+}
+
 pub fn unlink(path: *const c_char) -> c_int {
     e(unsafe { syscall!(UNLINKAT, AT_FDCWD, path, 0) }) as c_int
 }

+ 54 - 0
src/platform/src/redox/mod.rs

@@ -1,5 +1,7 @@
 use core::ptr;
 use core::slice;
+use core::mem;
+use alloc::Vec;
 use syscall;
 use syscall::flag::*;
 use syscall::data::TimeSpec as redox_timespec;
@@ -66,6 +68,58 @@ pub fn dup2(fd1: c_int, fd2: c_int) -> c_int {
     e(syscall::dup2(fd1 as usize, fd2 as usize, &[])) as c_int
 }
 
+pub fn execve(path: *const c_char, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
+    unsafe {
+        let mut env = envp;
+        while !(*env).is_null() {
+            let slice = c_str(*env);
+            // Should always contain a =, but worth checking
+            if let Some(sep) = slice.iter().position(|&c| c == b'=') {
+                // If the environment variable has no name, do not attempt
+                // to add it to the env.
+                if sep > 0 {
+                    let mut path = b"env:".to_vec();
+                    path.extend_from_slice(&slice[..sep]);
+                    match syscall::open(&path, O_WRONLY | O_CREAT) {
+                        Ok(fd) => {
+                            // If the environment variable has no value, there
+                            // is no need to write anything to the env scheme.
+                            if sep + 1 < slice.len() {
+                                let n = match syscall::write(fd, &slice[sep + 1..]) {
+                                    Ok(n) => n,
+                                    err => {
+                                        return e(err) as c_int;
+                                    }
+                                };
+                            }
+                            // Cleanup after adding the variable.
+                            match syscall::close(fd) {
+                                Ok(_) => (),
+                                err => {
+                                    return e(err) as c_int;
+                                }
+                            }
+                        }
+                        err => {
+                            return e(err) as c_int;
+                        }
+                    }
+                }
+            }
+            env = env.offset(1);
+        }
+
+        let mut args: Vec<[usize; 2]> = Vec::new();
+        let mut arg = argv;
+        while !(*arg).is_null() {
+            args.push([*arg as usize, c_str(*arg).len()]);
+            arg = arg.offset(1);
+        }
+
+        e(syscall::execve(c_str(path), &args)) as c_int
+    }
+}
+
 pub fn exit(status: c_int) -> ! {
     let _ = syscall::exit(status as usize);
     loop {}

+ 4 - 0
src/setjmp/Cargo.toml

@@ -0,0 +1,4 @@
+[package]
+name = "setjmp"
+version = "0.1.0"
+authors = ["Jeremy Soller <jackpot51@gmail.com>"]

+ 6 - 0
src/setjmp/src/impl/README.md

@@ -0,0 +1,6 @@
+# setjmp implementation
+
+All this code belongs to [musl libc](https://www.musl-libc.org/).
+They own it. All rights go to them.
+Huge thanks to them for doing this tedious per-arch assembly work!
+We will reuse this awesome effort :)

+ 24 - 0
src/setjmp/src/impl/aarch64/longjmp.s

@@ -0,0 +1,24 @@
+.global _longjmp
+.global longjmp
+.type _longjmp,%function
+.type longjmp,%function
+_longjmp:
+longjmp:
+	// IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers
+	ldp x19, x20, [x0,#0]
+	ldp x21, x22, [x0,#16]
+	ldp x23, x24, [x0,#32]
+	ldp x25, x26, [x0,#48]
+	ldp x27, x28, [x0,#64]
+	ldp x29, x30, [x0,#80]
+	ldr x2, [x0,#104]
+	mov sp, x2
+	ldp d8 , d9, [x0,#112]
+	ldp d10, d11, [x0,#128]
+	ldp d12, d13, [x0,#144]
+	ldp d14, d15, [x0,#160]
+
+	mov x0, x1
+	cbnz x1, 1f
+	mov x0, #1
+1:	br x30

+ 24 - 0
src/setjmp/src/impl/aarch64/setjmp.s

@@ -0,0 +1,24 @@
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	// IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers
+	stp x19, x20, [x0,#0]
+	stp x21, x22, [x0,#16]
+	stp x23, x24, [x0,#32]
+	stp x25, x26, [x0,#48]
+	stp x27, x28, [x0,#64]
+	stp x29, x30, [x0,#80]
+	mov x2, sp
+	str x2, [x0,#104]
+	stp  d8,  d9, [x0,#112]
+	stp d10, d11, [x0,#128]
+	stp d12, d13, [x0,#144]
+	stp d14, d15, [x0,#160]
+	mov x0, #0
+	ret

+ 43 - 0
src/setjmp/src/impl/arm/longjmp.s

@@ -0,0 +1,43 @@
+.syntax unified
+.global _longjmp
+.global longjmp
+.type _longjmp,%function
+.type longjmp,%function
+_longjmp:
+longjmp:
+	mov ip,r0
+	movs r0,r1
+	moveq r0,#1
+	ldmia ip!, {v1,v2,v3,v4,v5,v6,sl,fp}
+	ldmia ip!, {r2,lr}
+	mov sp,r2
+
+	adr r1,1f
+	ldr r2,1f
+	ldr r1,[r1,r2]
+
+	tst r1,#0x260
+	beq 3f
+	tst r1,#0x20
+	beq 2f
+	ldc p2, cr4, [ip], #48
+2:	tst r1,#0x40
+	beq 2f
+	.fpu vfp
+	vldmia ip!, {d8-d15}
+	.fpu softvfp
+	.eabi_attribute 10, 0
+	.eabi_attribute 27, 0
+2:	tst r1,#0x200
+	beq 3f
+	ldcl p1, cr10, [ip], #8
+	ldcl p1, cr11, [ip], #8
+	ldcl p1, cr12, [ip], #8
+	ldcl p1, cr13, [ip], #8
+	ldcl p1, cr14, [ip], #8
+	ldcl p1, cr15, [ip], #8
+3:	bx lr
+
+.hidden __hwcap
+.align 2
+1:	.word __hwcap-1b

+ 45 - 0
src/setjmp/src/impl/arm/setjmp.s

@@ -0,0 +1,45 @@
+.syntax unified
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,%function
+.type _setjmp,%function
+.type setjmp,%function
+__setjmp:
+_setjmp:
+setjmp:
+	mov ip,r0
+	stmia ip!,{v1,v2,v3,v4,v5,v6,sl,fp}
+	mov r2,sp
+	stmia ip!,{r2,lr}
+	mov r0,#0
+
+	adr r1,1f
+	ldr r2,1f
+	ldr r1,[r1,r2]
+
+	tst r1,#0x260
+	beq 3f
+	tst r1,#0x20
+	beq 2f
+	stc p2, cr4, [ip], #48
+2:	tst r1,#0x40
+	beq 2f
+	.fpu vfp
+	vstmia ip!, {d8-d15}
+	.fpu softvfp
+	.eabi_attribute 10, 0
+	.eabi_attribute 27, 0
+2:	tst r1,#0x200
+	beq 3f
+	stcl p1, cr10, [ip], #8
+	stcl p1, cr11, [ip], #8
+	stcl p1, cr12, [ip], #8
+	stcl p1, cr13, [ip], #8
+	stcl p1, cr14, [ip], #8
+	stcl p1, cr15, [ip], #8
+3:	bx lr
+
+.hidden __hwcap
+.align 2
+1:	.word __hwcap-1b

+ 2 - 0
src/setjmp/src/impl/bin/.gitignore

@@ -0,0 +1,2 @@
+*
+!.gitignore

+ 20 - 0
src/setjmp/src/impl/i386/longjmp.s

@@ -0,0 +1,20 @@
+.global _longjmp
+.global longjmp
+.type _longjmp,@function
+.type longjmp,@function
+_longjmp:
+longjmp:
+	mov  4(%esp),%edx
+	mov  8(%esp),%eax
+	test    %eax,%eax
+	jnz 1f
+	inc     %eax
+1:
+	mov   (%edx),%ebx
+	mov  4(%edx),%esi
+	mov  8(%edx),%edi
+	mov 12(%edx),%ebp
+	mov 16(%edx),%ecx
+	mov     %ecx,%esp
+	mov 20(%edx),%ecx
+	jmp *%ecx

+ 23 - 0
src/setjmp/src/impl/i386/setjmp.s

@@ -0,0 +1,23 @@
+.global ___setjmp
+.hidden ___setjmp
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	mov 4(%esp), %eax
+	mov    %ebx, (%eax)
+	mov    %esi, 4(%eax)
+	mov    %edi, 8(%eax)
+	mov    %ebp, 12(%eax)
+	lea 4(%esp), %ecx
+	mov    %ecx, 16(%eax)
+	mov  (%esp), %ecx
+	mov    %ecx, 20(%eax)
+	xor    %eax, %eax
+	ret

+ 14 - 0
src/setjmp/src/impl/m68k/longjmp.s

@@ -0,0 +1,14 @@
+.global _longjmp
+.global longjmp
+.type _longjmp,@function
+.type longjmp,@function
+_longjmp:
+longjmp:
+	movea.l 4(%sp),%a0
+	move.l 8(%sp),%d0
+	bne 1f
+	move.l #1,%d0
+1:	movem.l (%a0),%d2-%d7/%a2-%a7
+	fmovem.x 52(%a0),%fp2-%fp7
+	move.l 48(%a0),(%sp)
+	rts

+ 18 - 0
src/setjmp/src/impl/m68k/setjmp.s

@@ -0,0 +1,18 @@
+.global ___setjmp
+.hidden ___setjmp
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	movea.l 4(%sp),%a0
+	movem.l %d2-%d7/%a2-%a7,(%a0)
+	move.l (%sp),48(%a0)
+	fmovem.x %fp2-%fp7,52(%a0)
+	clr.l %d0
+	rts

+ 29 - 0
src/setjmp/src/impl/microblaze/longjmp.s

@@ -0,0 +1,29 @@
+.global _longjmp
+.global longjmp
+.type   _longjmp,@function
+.type   longjmp,@function
+_longjmp:
+longjmp:
+	addi    r3, r6, 0
+	bnei    r3, 1f
+	addi    r3, r3, 1
+1:      lwi     r1,  r5, 0
+	lwi     r15, r5, 4
+	lwi     r2,  r5, 8
+	lwi     r13, r5, 12
+	lwi     r18, r5, 16
+	lwi     r19, r5, 20
+	lwi     r20, r5, 24
+	lwi     r21, r5, 28
+	lwi     r22, r5, 32
+	lwi     r23, r5, 36
+	lwi     r24, r5, 40
+	lwi     r25, r5, 44
+	lwi     r26, r5, 48
+	lwi     r27, r5, 52
+	lwi     r28, r5, 56
+	lwi     r29, r5, 60
+	lwi     r30, r5, 64
+	lwi     r31, r5, 68
+	rtsd    r15, 8
+	nop

+ 32 - 0
src/setjmp/src/impl/microblaze/setjmp.s

@@ -0,0 +1,32 @@
+.global ___setjmp
+.hidden ___setjmp
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	swi     r1,  r5, 0
+	swi     r15, r5, 4
+	swi     r2,  r5, 8
+	swi     r13, r5, 12
+	swi     r18, r5, 16
+	swi     r19, r5, 20
+	swi     r20, r5, 24
+	swi     r21, r5, 28
+	swi     r22, r5, 32
+	swi     r23, r5, 36
+	swi     r24, r5, 40
+	swi     r25, r5, 44
+	swi     r26, r5, 48
+	swi     r27, r5, 52
+	swi     r28, r5, 56
+	swi     r29, r5, 60
+	swi     r30, r5, 64
+	swi     r31, r5, 68
+	rtsd    r15, 8
+	ori     r3, r0, 0

+ 40 - 0
src/setjmp/src/impl/mips/longjmp.S

@@ -0,0 +1,40 @@
+.set noreorder
+
+.global _longjmp
+.global longjmp
+.type   _longjmp,@function
+.type   longjmp,@function
+_longjmp:
+longjmp:
+	move    $2, $5
+	bne     $2, $0, 1f
+	nop
+	addu    $2, $2, 1
+1:
+#ifndef __mips_soft_float
+	lwc1    $20, 56($4)
+	lwc1    $21, 60($4)
+	lwc1    $22, 64($4)
+	lwc1    $23, 68($4)
+	lwc1    $24, 72($4)
+	lwc1    $25, 76($4)
+	lwc1    $26, 80($4)
+	lwc1    $27, 84($4)
+	lwc1    $28, 88($4)
+	lwc1    $29, 92($4)
+	lwc1    $30, 96($4)
+	lwc1    $31, 100($4)
+#endif
+	lw      $ra,  0($4)
+	lw      $sp,  4($4)
+	lw      $16,  8($4)
+	lw      $17, 12($4)
+	lw      $18, 16($4)
+	lw      $19, 20($4)
+	lw      $20, 24($4)
+	lw      $21, 28($4)
+	lw      $22, 32($4)
+	lw      $23, 36($4)
+	lw      $30, 40($4)
+	jr      $ra
+	lw      $28, 44($4)

+ 39 - 0
src/setjmp/src/impl/mips/setjmp.S

@@ -0,0 +1,39 @@
+.set noreorder
+
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type   __setjmp,@function
+.type   _setjmp,@function
+.type   setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	sw      $ra,  0($4)
+	sw      $sp,  4($4)
+	sw      $16,  8($4)
+	sw      $17, 12($4)
+	sw      $18, 16($4)
+	sw      $19, 20($4)
+	sw      $20, 24($4)
+	sw      $21, 28($4)
+	sw      $22, 32($4)
+	sw      $23, 36($4)
+	sw      $30, 40($4)
+	sw      $28, 44($4)
+#ifndef __mips_soft_float
+	swc1    $20, 56($4)
+	swc1    $21, 60($4)
+	swc1    $22, 64($4)
+	swc1    $23, 68($4)
+	swc1    $24, 72($4)
+	swc1    $25, 76($4)
+	swc1    $26, 80($4)
+	swc1    $27, 84($4)
+	swc1    $28, 88($4)
+	swc1    $29, 92($4)
+	swc1    $30, 96($4)
+	swc1    $31, 100($4)
+#endif
+	jr      $ra
+	li      $2, 0

+ 37 - 0
src/setjmp/src/impl/mips64/longjmp.S

@@ -0,0 +1,37 @@
+.set	noreorder
+.global	_longjmp
+.global	longjmp
+.type	_longjmp,@function
+.type	longjmp,@function
+_longjmp:
+longjmp:
+	move	$2, $5
+
+	bne	$2, $0, 1f
+	nop
+	daddu	$2, $2, 1
+1:
+#ifndef __mips_soft_float
+	ldc1	$24, 96($4)
+	ldc1	$25, 104($4)
+	ldc1	$26, 112($4)
+	ldc1	$27, 120($4)
+	ldc1	$28, 128($4)
+	ldc1	$29, 136($4)
+	ldc1	$30, 144($4)
+	ldc1	$31, 152($4)
+#endif
+	ld	$ra, 0($4)
+	ld	$sp, 8($4)
+	ld	$gp, 16($4)
+	ld	$16, 24($4)
+	ld	$17, 32($4)
+	ld	$18, 40($4)
+	ld	$19, 48($4)
+	ld	$20, 56($4)
+	ld	$21, 64($4)
+	ld	$22, 72($4)
+	ld	$23, 80($4)
+	ld	$30, 88($4)
+	jr	$ra
+	nop

+ 34 - 0
src/setjmp/src/impl/mips64/setjmp.S

@@ -0,0 +1,34 @@
+.set	noreorder
+.global	__setjmp
+.global	_setjmp
+.global	setjmp
+.type	__setjmp,@function
+.type	_setjmp,@function
+.type	setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	sd	$ra, 0($4)
+	sd	$sp, 8($4)
+	sd	$gp, 16($4)
+	sd	$16, 24($4)
+	sd	$17, 32($4)
+	sd	$18, 40($4)
+	sd	$19, 48($4)
+	sd	$20, 56($4)
+	sd	$21, 64($4)
+	sd	$22, 72($4)
+	sd	$23, 80($4)
+	sd	$30, 88($4)
+#ifndef __mips_soft_float
+	sdc1	$24, 96($4)
+	sdc1	$25, 104($4)
+	sdc1	$26, 112($4)
+	sdc1	$27, 120($4)
+	sdc1	$28, 128($4)
+	sdc1	$29, 136($4)
+	sdc1	$30, 144($4)
+	sdc1	$31, 152($4)
+#endif
+	jr	$ra
+	li	$2, 0

+ 36 - 0
src/setjmp/src/impl/mipsn32/longjmp.S

@@ -0,0 +1,36 @@
+.set	noreorder
+.global	_longjmp
+.global	longjmp
+.type	_longjmp,@function
+.type	longjmp,@function
+_longjmp:
+longjmp:
+	move	$2, $5
+	bne	$2, $0, 1f
+	nop
+	addu	$2, $2, 1
+1:
+#ifndef __mips_soft_float
+	ldc1	$24, 96($4)
+	ldc1	$25, 104($4)
+	ldc1	$26, 112($4)
+	ldc1	$27, 120($4)
+	ldc1	$28, 128($4)
+	ldc1	$29, 136($4)
+	ldc1	$30, 144($4)
+	ldc1	$31, 152($4)
+#endif
+	ld	$ra, 0($4)
+	ld	$sp, 8($4)
+	ld	$gp, 16($4)
+	ld	$16, 24($4)
+	ld	$17, 32($4)
+	ld	$18, 40($4)
+	ld	$19, 48($4)
+	ld	$20, 56($4)
+	ld	$21, 64($4)
+	ld	$22, 72($4)
+	ld	$23, 80($4)
+	ld	$30, 88($4)
+	jr	$ra
+	nop

+ 34 - 0
src/setjmp/src/impl/mipsn32/setjmp.S

@@ -0,0 +1,34 @@
+.set	noreorder
+.global	__setjmp
+.global	_setjmp
+.global	setjmp
+.type	__setjmp,@function
+.type	_setjmp,@function
+.type	setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	sd	$ra, 0($4)
+	sd	$sp, 8($4)
+	sd	$gp, 16($4)
+	sd	$16, 24($4)
+	sd	$17, 32($4)
+	sd	$18, 40($4)
+	sd	$19, 48($4)
+	sd	$20, 56($4)
+	sd	$21, 64($4)
+	sd	$22, 72($4)
+	sd	$23, 80($4)
+	sd	$30, 88($4)
+#ifndef __mips_soft_float
+	sdc1	$24, 96($4)
+	sdc1	$25, 104($4)
+	sdc1	$26, 112($4)
+	sdc1	$27, 120($4)
+	sdc1	$28, 128($4)
+	sdc1	$29, 136($4)
+	sdc1	$30, 144($4)
+	sdc1	$31, 152($4)
+#endif
+	jr	$ra
+	li	$2, 0

+ 25 - 0
src/setjmp/src/impl/or1k/longjmp.s

@@ -0,0 +1,25 @@
+.global _longjmp
+.global longjmp
+.type   _longjmp,@function
+.type   longjmp,@function
+_longjmp:
+longjmp:
+	l.sfeqi	r4, 0
+	l.bnf	1f
+	 l.addi	r11, r4,0
+	l.ori	r11, r0, 1
+1:	l.lwz	r1, 0(r3)
+	l.lwz	r2, 4(r3)
+	l.lwz	r9, 8(r3)
+	l.lwz	r10, 12(r3)
+	l.lwz	r14, 16(r3)
+	l.lwz	r16, 20(r3)
+	l.lwz	r18, 24(r3)
+	l.lwz	r20, 28(r3)
+	l.lwz	r22, 32(r3)
+	l.lwz	r24, 36(r3)
+	l.lwz	r26, 40(r3)
+	l.lwz	r28, 44(r3)
+	l.lwz	r30, 48(r3)
+	l.jr	r9
+	 l.nop

+ 27 - 0
src/setjmp/src/impl/or1k/setjmp.s

@@ -0,0 +1,27 @@
+.global ___setjmp
+.hidden ___setjmp
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	l.sw	0(r3), r1
+	l.sw	4(r3), r2
+	l.sw	8(r3), r9
+	l.sw	12(r3), r10
+	l.sw	16(r3), r14
+	l.sw	20(r3), r16
+	l.sw	24(r3), r18
+	l.sw	28(r3), r20
+	l.sw	32(r3), r22
+	l.sw	36(r3), r24
+	l.sw	40(r3), r26
+	l.sw	44(r3), r28
+	l.sw	48(r3), r30
+	l.jr	r9
+	 l.ori	r11,r0,0

+ 69 - 0
src/setjmp/src/impl/powerpc/longjmp.S

@@ -0,0 +1,69 @@
+	.global _longjmp
+	.global longjmp
+	.type   _longjmp,@function
+	.type   longjmp,@function
+_longjmp:
+longjmp:
+	/*
+	 * void longjmp(jmp_buf env, int val);
+	 * put val into return register and restore the env saved in setjmp
+	 * if val(r4) is 0, put 1 there.
+	 */
+	/* 0) move old return address into r0 */
+	lwz 0, 0(3)
+	/* 1) put it into link reg */
+	mtlr 0
+	/* 2 ) restore stack ptr */
+	lwz 1, 4(3)
+	/* 3) restore control reg */
+	lwz 0, 8(3)
+	mtcr 0
+	/* 4) restore r14-r31 */
+	lwz 14, 12(3)
+	lwz 15, 16(3)
+	lwz 16, 20(3)
+	lwz 17, 24(3)
+	lwz 18, 28(3)
+	lwz 19, 32(3)
+	lwz 20, 36(3)
+	lwz 21, 40(3)
+	lwz 22, 44(3)
+	lwz 23, 48(3)
+	lwz 24, 52(3)
+	lwz 25, 56(3)
+	lwz 26, 60(3)
+	lwz 27, 64(3)
+	lwz 28, 68(3)
+	lwz 29, 72(3)
+	lwz 30, 76(3)
+	lwz 31, 80(3)
+#ifndef _SOFT_FLOAT
+	lfd 14,88(3)
+	lfd 15,96(3)
+	lfd 16,104(3)
+	lfd 17,112(3)
+	lfd 18,120(3)
+	lfd 19,128(3)
+	lfd 20,136(3)
+	lfd 21,144(3)
+	lfd 22,152(3)
+	lfd 23,160(3)
+	lfd 24,168(3)
+	lfd 25,176(3)
+	lfd 26,184(3)
+	lfd 27,192(3)
+	lfd 28,200(3)
+	lfd 29,208(3)
+	lfd 30,216(3)
+	lfd 31,224(3)
+#endif
+	/* 5) put val into return reg r3 */
+	mr 3, 4
+
+	/* 6) check if return value is 0, make it 1 in that case */
+	cmpwi cr7, 4, 0
+	bne cr7, 1f
+	li 3, 1
+1:
+	blr
+

+ 63 - 0
src/setjmp/src/impl/powerpc/setjmp.S

@@ -0,0 +1,63 @@
+	.global ___setjmp
+	.hidden ___setjmp
+	.global __setjmp
+	.global _setjmp
+	.global setjmp
+	.type   __setjmp,@function
+	.type   _setjmp,@function
+	.type   setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	/* 0) store IP int 0, then into the jmpbuf pointed to by r3 (first arg) */
+	mflr 0
+	stw 0, 0(3)
+	/* 1) store reg1 (SP) */
+	stw 1, 4(3)
+	/* 2) store cr */
+	mfcr 0
+	stw 0, 8(3)
+	/* 3) store r14-31 */
+	stw 14, 12(3)
+	stw 15, 16(3)
+	stw 16, 20(3)
+	stw 17, 24(3)
+	stw 18, 28(3)
+	stw 19, 32(3)
+	stw 20, 36(3)
+	stw 21, 40(3)
+	stw 22, 44(3)
+	stw 23, 48(3)
+	stw 24, 52(3)
+	stw 25, 56(3)
+	stw 26, 60(3)
+	stw 27, 64(3)
+	stw 28, 68(3)
+	stw 29, 72(3)
+	stw 30, 76(3)
+	stw 31, 80(3)
+#ifndef _SOFT_FLOAT
+	stfd 14,88(3)
+	stfd 15,96(3)
+	stfd 16,104(3)
+	stfd 17,112(3)
+	stfd 18,120(3)
+	stfd 19,128(3)
+	stfd 20,136(3)
+	stfd 21,144(3)
+	stfd 22,152(3)
+	stfd 23,160(3)
+	stfd 24,168(3)
+	stfd 25,176(3)
+	stfd 26,184(3)
+	stfd 27,192(3)
+	stfd 28,200(3)
+	stfd 29,208(3)
+	stfd 30,216(3)
+	stfd 31,224(3)
+#endif
+	/* 4) set return value to 0 */
+	li 3, 0
+	/* 5) return */
+	blr

+ 81 - 0
src/setjmp/src/impl/powerpc64/longjmp.s

@@ -0,0 +1,81 @@
+	.global _longjmp
+	.global longjmp
+	.type   _longjmp,@function
+	.type   longjmp,@function
+_longjmp:
+longjmp:
+	# 0) move old return address into the link register
+	ld   0,  0*8(3)
+	mtlr 0
+	# 1) restore cr
+	ld   0,  1*8(3)
+	mtcr 0
+	# 2) restore SP
+	ld   1,  2*8(3)
+	# 3) restore TOC into both r2 and the caller's stack.
+	#    Which location is required depends on whether setjmp was called
+	#    locally or non-locally, but it's always safe to restore to both.
+	ld   2,  3*8(3)
+	std  2,   24(1)
+	# 4) restore r14-r31
+	ld  14,  4*8(3)
+	ld  15,  5*8(3)
+	ld  16,  6*8(3)
+	ld  17,  7*8(3)
+	ld  18,  8*8(3)
+	ld  19,  9*8(3)
+	ld  20, 10*8(3)
+	ld  21, 11*8(3)
+	ld  22, 12*8(3)
+	ld  23, 13*8(3)
+	ld  24, 14*8(3)
+	ld  25, 15*8(3)
+	ld  26, 16*8(3)
+	ld  27, 17*8(3)
+	ld  28, 18*8(3)
+	ld  29, 19*8(3)
+	ld  30, 20*8(3)
+	ld  31, 21*8(3)
+	# 5) restore floating point registers f14-f31
+	lfd 14, 22*8(3)
+	lfd 15, 23*8(3)
+	lfd 16, 24*8(3)
+	lfd 17, 25*8(3)
+	lfd 18, 26*8(3)
+	lfd 19, 27*8(3)
+	lfd 20, 28*8(3)
+	lfd 21, 29*8(3)
+	lfd 22, 30*8(3)
+	lfd 23, 31*8(3)
+	lfd 24, 32*8(3)
+	lfd 25, 33*8(3)
+	lfd 26, 34*8(3)
+	lfd 27, 35*8(3)
+	lfd 28, 36*8(3)
+	lfd 29, 37*8(3)
+	lfd 30, 38*8(3)
+	lfd 31, 39*8(3)
+
+	# 6) restore vector registers v20-v31
+	addi 3, 3, 40*8
+	lvx 20, 0, 3 ; addi 3, 3, 16
+	lvx 21, 0, 3 ; addi 3, 3, 16
+	lvx 22, 0, 3 ; addi 3, 3, 16
+	lvx 23, 0, 3 ; addi 3, 3, 16
+	lvx 24, 0, 3 ; addi 3, 3, 16
+	lvx 25, 0, 3 ; addi 3, 3, 16
+	lvx 26, 0, 3 ; addi 3, 3, 16
+	lvx 27, 0, 3 ; addi 3, 3, 16
+	lvx 28, 0, 3 ; addi 3, 3, 16
+	lvx 29, 0, 3 ; addi 3, 3, 16
+	lvx 30, 0, 3 ; addi 3, 3, 16
+	lvx 31, 0, 3
+
+	# 7) return r4 ? r4 : 1
+	mr    3,   4
+	cmpwi cr7, 4, 0
+	bne   cr7, 1f
+	li    3,   1
+1:
+	blr
+

+ 89 - 0
src/setjmp/src/impl/powerpc64/setjmp.s

@@ -0,0 +1,89 @@
+	.global __setjmp
+	.global _setjmp
+	.global setjmp
+	.type   __setjmp,@function
+	.type   _setjmp,@function
+	.type   setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	ld 5, 24(1)   # load from the TOC slot in the caller's stack frame
+	b __setjmp_toc
+
+	.localentry __setjmp,.-__setjmp
+	.localentry _setjmp,.-_setjmp
+	.localentry setjmp,.-setjmp
+	mr 5, 2
+
+	.global __setjmp_toc
+	.hidden __setjmp_toc
+	# same as normal setjmp, except TOC pointer to save is provided in r5.
+	# r4 would normally be the 2nd parameter, but we're using r5 to simplify calling from sigsetjmp.
+	# solves the problem of knowing whether to save the TOC pointer from r2 or the caller's stack frame.
+__setjmp_toc:
+	# 0) store IP into 0, then into the jmpbuf pointed to by r3 (first arg)
+	mflr  0
+	std   0,  0*8(3)
+	# 1) store cr
+	mfcr  0
+	std   0,  1*8(3)
+	# 2) store SP and TOC
+	std   1,  2*8(3)
+	std   5,  3*8(3)
+	# 3) store r14-31
+	std  14,  4*8(3)
+	std  15,  5*8(3)
+	std  16,  6*8(3)
+	std  17,  7*8(3)
+	std  18,  8*8(3)
+	std  19,  9*8(3)
+	std  20, 10*8(3)
+	std  21, 11*8(3)
+	std  22, 12*8(3)
+	std  23, 13*8(3)
+	std  24, 14*8(3)
+	std  25, 15*8(3)
+	std  26, 16*8(3)
+	std  27, 17*8(3)
+	std  28, 18*8(3)
+	std  29, 19*8(3)
+	std  30, 20*8(3)
+	std  31, 21*8(3)
+	# 4) store floating point registers f14-f31
+	stfd 14, 22*8(3)
+	stfd 15, 23*8(3)
+	stfd 16, 24*8(3)
+	stfd 17, 25*8(3)
+	stfd 18, 26*8(3)
+	stfd 19, 27*8(3)
+	stfd 20, 28*8(3)
+	stfd 21, 29*8(3)
+	stfd 22, 30*8(3)
+	stfd 23, 31*8(3)
+	stfd 24, 32*8(3)
+	stfd 25, 33*8(3)
+	stfd 26, 34*8(3)
+	stfd 27, 35*8(3)
+	stfd 28, 36*8(3)
+	stfd 29, 37*8(3)
+	stfd 30, 38*8(3)
+	stfd 31, 39*8(3)
+
+	# 5) store vector registers v20-v31
+	addi  3, 3, 40*8
+	stvx 20, 0, 3 ; addi 3, 3, 16
+	stvx 21, 0, 3 ; addi 3, 3, 16
+	stvx 22, 0, 3 ; addi 3, 3, 16
+	stvx 23, 0, 3 ; addi 3, 3, 16
+	stvx 24, 0, 3 ; addi 3, 3, 16
+	stvx 25, 0, 3 ; addi 3, 3, 16
+	stvx 26, 0, 3 ; addi 3, 3, 16
+	stvx 27, 0, 3 ; addi 3, 3, 16
+	stvx 28, 0, 3 ; addi 3, 3, 16
+	stvx 29, 0, 3 ; addi 3, 3, 16
+	stvx 30, 0, 3 ; addi 3, 3, 16
+	stvx 31, 0, 3
+
+	# 6) return 0
+	li 3, 0
+	blr

+ 23 - 0
src/setjmp/src/impl/s390x/longjmp.s

@@ -0,0 +1,23 @@
+	.global _longjmp
+	.global longjmp
+	.type   _longjmp,@function
+	.type   longjmp,@function
+_longjmp:
+longjmp:
+
+1:
+	lmg %r6, %r15, 0(%r2)
+
+	ld  %f8, 10*8(%r2)
+	ld  %f9, 11*8(%r2)
+	ld %f10, 12*8(%r2)
+	ld %f11, 13*8(%r2)
+	ld %f12, 14*8(%r2)
+	ld %f13, 15*8(%r2)
+	ld %f14, 16*8(%r2)
+	ld %f15, 17*8(%r2)
+
+	ltgr %r2, %r3
+	bnzr %r14
+	lhi  %r2, 1
+	br   %r14

+ 25 - 0
src/setjmp/src/impl/s390x/setjmp.s

@@ -0,0 +1,25 @@
+	.global ___setjmp
+	.hidden ___setjmp
+	.global __setjmp
+	.global _setjmp
+	.global setjmp
+	.type   __setjmp,@function
+	.type   _setjmp,@function
+	.type   setjmp,@function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+	stmg %r6, %r15, 0(%r2)
+
+	std  %f8,  10*8(%r2)
+	std  %f9,  11*8(%r2)
+	std  %f10, 12*8(%r2)
+	std  %f11, 13*8(%r2)
+	std  %f12, 14*8(%r2)
+	std  %f13, 15*8(%r2)
+	std  %f14, 16*8(%r2)
+	std  %f15, 17*8(%r2)
+
+	lghi %r2, 0
+	br   %r14

+ 28 - 0
src/setjmp/src/impl/sh/longjmp.S

@@ -0,0 +1,28 @@
+.global _longjmp
+.global longjmp
+.type   _longjmp, @function
+.type   longjmp,  @function
+_longjmp:
+longjmp:
+	mov.l  @r4+, r8
+	mov.l  @r4+, r9
+	mov.l  @r4+, r10
+	mov.l  @r4+, r11
+	mov.l  @r4+, r12
+	mov.l  @r4+, r13
+	mov.l  @r4+, r14
+	mov.l  @r4+, r15
+	lds.l  @r4+, pr
+#if __SH_FPU_ANY__ || __SH4__
+	fmov.s @r4+, fr12
+	fmov.s @r4+, fr13
+	fmov.s @r4+, fr14
+	fmov.s @r4+, fr15
+#endif
+
+	tst  r5, r5
+	movt r0
+	add  r5, r0
+
+	rts
+	 nop

+ 32 - 0
src/setjmp/src/impl/sh/setjmp.S

@@ -0,0 +1,32 @@
+.global ___setjmp
+.hidden ___setjmp
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type   __setjmp, @function
+.type   _setjmp,  @function
+.type   setjmp,   @function
+___setjmp:
+__setjmp:
+_setjmp:
+setjmp:
+#if __SH_FPU_ANY__ || __SH4__
+	add   #52, r4
+	fmov.s fr15, @-r4
+	fmov.s fr14, @-r4
+	fmov.s fr13, @-r4
+	fmov.s fr12, @-r4
+#else
+	add   #36, r4
+#endif
+	sts.l  pr,   @-r4
+	mov.l  r15,  @-r4
+	mov.l  r14,  @-r4
+	mov.l  r13,  @-r4
+	mov.l  r12,  @-r4
+	mov.l  r11,  @-r4
+	mov.l  r10,  @-r4
+	mov.l  r9,   @-r4
+	mov.l  r8,   @-r4
+	rts
+	 mov  #0, r0

+ 22 - 0
src/setjmp/src/impl/x32/longjmp.s

@@ -0,0 +1,22 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.global _longjmp
+.global longjmp
+.type _longjmp,@function
+.type longjmp,@function
+_longjmp:
+longjmp:
+	mov %rsi,%rax           /* val will be longjmp return */
+	test %rax,%rax
+	jnz 1f
+	inc %rax                /* if val==0, val=1 per longjmp semantics */
+1:
+	mov (%rdi),%rbx         /* rdi is the jmp_buf, restore regs from it */
+	mov 8(%rdi),%rbp
+	mov 16(%rdi),%r12
+	mov 24(%rdi),%r13
+	mov 32(%rdi),%r14
+	mov 40(%rdi),%r15
+	mov 48(%rdi),%rdx       /* this ends up being the stack pointer */
+	mov %rdx,%rsp
+	mov 56(%rdi),%rdx       /* this is the instruction pointer */
+	jmp *%rdx               /* goto saved address without altering rsp */

+ 22 - 0
src/setjmp/src/impl/x32/setjmp.s

@@ -0,0 +1,22 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	mov %rbx,(%rdi)         /* rdi is jmp_buf, move registers onto it */
+	mov %rbp,8(%rdi)
+	mov %r12,16(%rdi)
+	mov %r13,24(%rdi)
+	mov %r14,32(%rdi)
+	mov %r15,40(%rdi)
+	lea 8(%rsp),%rdx        /* this is our rsp WITHOUT current ret addr */
+	mov %rdx,48(%rdi)
+	mov (%rsp),%rdx         /* save return addr ptr for new rip */
+	mov %rdx,56(%rdi)
+	xor %rax,%rax           /* always return 0 */
+	ret

+ 22 - 0
src/setjmp/src/impl/x86_64/longjmp.s

@@ -0,0 +1,22 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.global _longjmp
+.global longjmp
+.type _longjmp,@function
+.type longjmp,@function
+_longjmp:
+longjmp:
+	mov %rsi,%rax           /* val will be longjmp return */
+	test %rax,%rax
+	jnz 1f
+	inc %rax                /* if val==0, val=1 per longjmp semantics */
+1:
+	mov (%rdi),%rbx         /* rdi is the jmp_buf, restore regs from it */
+	mov 8(%rdi),%rbp
+	mov 16(%rdi),%r12
+	mov 24(%rdi),%r13
+	mov 32(%rdi),%r14
+	mov 40(%rdi),%r15
+	mov 48(%rdi),%rdx       /* this ends up being the stack pointer */
+	mov %rdx,%rsp
+	mov 56(%rdi),%rdx       /* this is the instruction pointer */
+	jmp *%rdx               /* goto saved address without altering rsp */

+ 22 - 0
src/setjmp/src/impl/x86_64/setjmp.s

@@ -0,0 +1,22 @@
+/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
+.global __setjmp
+.global _setjmp
+.global setjmp
+.type __setjmp,@function
+.type _setjmp,@function
+.type setjmp,@function
+__setjmp:
+_setjmp:
+setjmp:
+	mov %rbx,(%rdi)         /* rdi is jmp_buf, move registers onto it */
+	mov %rbp,8(%rdi)
+	mov %r12,16(%rdi)
+	mov %r13,24(%rdi)
+	mov %r14,32(%rdi)
+	mov %r15,40(%rdi)
+	lea 8(%rsp),%rdx        /* this is our rsp WITHOUT current ret addr */
+	mov %rdx,48(%rdi)
+	mov (%rsp),%rdx         /* save return addr ptr for new rip */
+	mov %rdx,56(%rdi)
+	xor %rax,%rax           /* always return 0 */
+	ret

+ 33 - 0
src/setjmp/src/lib.rs

@@ -0,0 +1,33 @@
+//! setjmp implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/setjmp.h.html
+
+#![no_std]
+#![feature(global_asm)]
+
+macro_rules! platform_specific {
+    ($($arch:expr,$ext:expr;)+) => {
+        $(
+            #[cfg(target_arch = $arch)]
+            global_asm!(include_str!(concat!("impl/", $arch, "/setjmp.", $ext)));
+            #[cfg(target_arch = $arch)]
+            global_asm!(include_str!(concat!("impl/", $arch, "/longjmp.", $ext)));
+        )+
+    }
+}
+
+platform_specific! {
+    "aarch64","s";
+    "arm","s";
+    "i386","s";
+    "m68k","s";
+    "microblaze","s";
+    "mips","S";
+    "mips64","S";
+    "mipsn32","S";
+    "or1k","s";
+    "powerpc","S";
+    "powerpc64","s";
+    "s390x","s";
+    "sh","S";
+    "x32","s";
+    "x86_64","s";
+}

+ 4 - 0
src/signal/src/lib.rs

@@ -12,6 +12,10 @@ pub mod sys;
 #[path = "redox.rs"]
 pub mod sys;
 
+pub const SIG_BLOCK:   c_int = 0;
+pub const SIG_UNBLOCK: c_int = 1;
+pub const SIG_SETMASK: c_int = 2;
+
 pub use sys::*;
 
 use platform::types::*;

+ 59 - 15
src/stdio/src/default.rs

@@ -1,32 +1,76 @@
-use core::cell::UnsafeCell;
 use core::sync::atomic::AtomicBool;
 use super::{constants, BUFSIZ, FILE, UNGET};
 
-struct GlobalFile(UnsafeCell<FILE>);
-impl GlobalFile {
-    const fn new(file: FILE) -> Self {
-        GlobalFile(UnsafeCell::new(file))
-    }
-    fn get(&self) -> *mut FILE {
-        self.0.get()
-    }
-}
-// statics need to be Sync
-unsafe impl Sync for GlobalFile {}
+#[allow(non_upper_case_globals)]
+static mut default_stdin_buf: [u8; BUFSIZ as usize + UNGET] = [0; BUFSIZ as usize + UNGET];
+
+#[allow(non_upper_case_globals)]
+static mut default_stdin: FILE = FILE {
+    flags: constants::F_PERM | constants::F_NOWR | constants::F_BADJ,
+    rpos: ptr::null_mut(),
+    rend: ptr::null_mut(),
+    wend: ptr::null_mut(),
+    wpos: ptr::null_mut(),
+    wbase: ptr::null_mut(),
+    fd: 0,
+    buf: unsafe { &mut default_stdin_buf as *mut [u8] as *mut u8 },
+    buf_size: BUFSIZ as usize,
+    buf_char: -1,
+    unget: UNGET,
+    lock: AtomicBool::new(false),
+};
+
+#[allow(non_upper_case_globals)]
+static mut default_stdout_buf: [u8; BUFSIZ as usize] = [0; BUFSIZ as usize];
+
+#[allow(non_upper_case_globals)]
+static mut default_stdout: FILE = FILE {
+    flags: constants::F_PERM | constants::F_NORD | constants::F_BADJ,
+    rpos: ptr::null_mut(),
+    rend: ptr::null_mut(),
+    wend: ptr::null_mut(),
+    wpos: ptr::null_mut(),
+    wbase: ptr::null_mut(),
+    fd: 1,
+    buf: unsafe { &mut default_stdout_buf } as *mut [u8] as *mut u8,
+    buf_size: BUFSIZ as usize,
+    buf_char: b'\n' as i8,
+    unget: 0,
+    lock: AtomicBool::new(false),
+};
+
+#[allow(non_upper_case_globals)]
+static mut default_stderr_buf: [u8; BUFSIZ as usize] = [0; BUFSIZ as usize];
+
+#[allow(non_upper_case_globals)]
+static mut default_stderr: FILE = FILE {
+    flags: constants::F_PERM | constants::F_NORD | constants::F_BADJ,
+    rpos: ptr::null_mut(),
+    rend: ptr::null_mut(),
+    wend: ptr::null_mut(),
+    wpos: ptr::null_mut(),
+    wbase: ptr::null_mut(),
+    fd: 2,
+    buf: unsafe { &mut default_stderr_buf } as *mut [u8] as *mut u8,
+    buf_size: BUFSIZ as usize,
+    buf_char: -1,
+    unget: 0,
+    lock: AtomicBool::new(false),
+};
 
 #[no_mangle]
 pub extern "C" fn __stdin() -> *mut FILE {
-    unsafe { default_stdin.get() }
+    unsafe { &mut default_stdin }
 }
 
 #[no_mangle]
 pub extern "C" fn __stdout() -> *mut FILE {
-    unsafe { default_stdout.get() }
+    unsafe { &mut default_stdout }
 }
 
 #[no_mangle]
 pub extern "C" fn __stderr() -> *mut FILE {
-    unsafe { default_stderr.get() }
+    unsafe { &mut default_stderr }
 }
 
 lazy_static! {

+ 2 - 1
src/stdlib/Cargo.toml

@@ -12,4 +12,5 @@ platform = { path = "../platform" }
 ralloc = { path = "../../ralloc", default-features = false }
 ctype = { path = "../ctype" }
 errno = { path = "../errno" }
-rand = { git = "https://github.com/rust-lang-nursery/rand/", default-features = false }
+rand = { version = "0.5.2", default-features = false }
+time = { path = "../time" }

+ 77 - 13
src/stdlib/src/lib.rs

@@ -2,16 +2,19 @@
 
 #![no_std]
 #![feature(core_intrinsics)]
-#![feature(global_allocator)]
 
 extern crate ctype;
 extern crate errno;
 extern crate platform;
 extern crate ralloc;
 extern crate rand;
+extern crate time;
 
 use core::{ptr, str};
-use rand::{Rng, SeedableRng, XorShiftRng};
+use rand::{Rng, SeedableRng}; 
+use rand::rngs::JitterRng;
+use rand::prng::XorShiftRng;
+use rand::distributions::Alphanumeric;
 
 use errno::*;
 use platform::types::*;
@@ -364,9 +367,65 @@ pub extern "C" fn mbtowc(pwc: *mut wchar_t, s: *const c_char, n: size_t) -> c_in
 
 #[no_mangle]
 pub extern "C" fn mktemp(name: *mut c_char) -> *mut c_char {
-    unimplemented!();
+    use core::slice;
+    use core::iter;
+    use core::mem;
+    extern "C" {
+        fn strlen(s: *const c_char) -> size_t;
+    }
+    let len = unsafe { strlen(name) };
+    if len < 6 {
+        unsafe { platform::errno = errno::EINVAL };
+        unsafe { *name = 0 };
+        return name;
+    }
+    for i in len-6..len {
+        if unsafe { *name.offset(i as isize) } != b'X' as c_char {
+            unsafe { platform::errno = errno::EINVAL };
+            unsafe { *name = 0 };
+            return name;
+        }
+    }
+
+    let mut rng = JitterRng::new_with_timer(get_nstime);
+    rng.test_timer();
+
+    let mut retries = 100;
+    loop {
+        let mut char_iter = iter::repeat(())
+        .map(|()| rng.sample(Alphanumeric))
+        .take(6);
+        unsafe {
+            for (i,c) in char_iter.enumerate() {
+                *name.offset(len as isize - i as isize - 1) = c as c_char
+            }
+        }
+
+        unsafe {
+            let mut st: stat = mem::uninitialized();
+            if platform::stat(name, &mut st) != 0 {
+                if platform::errno != ENOENT { *name = 0; }
+                return name;
+            }
+            mem::forget(st);
+        }
+        retries = retries -1;
+        if retries == 0 { break; }
+    }
+    unsafe { platform::errno = EEXIST };
+    unsafe { *name = 0 };
+    name
+}
+
+fn get_nstime() -> u64 {
+    use core::mem;
+    use time::constants::CLOCK_MONOTONIC;
+    let mut ts: timespec = unsafe { mem::uninitialized() };
+    platform::clock_gettime(CLOCK_MONOTONIC, &mut ts); 
+    unsafe { ts.tv_nsec as u64 }
 }
 
+
 #[no_mangle]
 pub extern "C" fn mkstemp(name: *mut c_char) -> c_int {
     unimplemented!();
@@ -412,10 +471,10 @@ pub extern "C" fn qsort(
 #[no_mangle]
 pub unsafe extern "C" fn rand() -> c_int {
     match RNG {
-        Some(ref mut rng) => rng.gen_range::<c_int>(0, RAND_MAX),
+        Some(ref mut rng) => rng.gen_range(0, RAND_MAX),
         None => {
             let mut rng = XorShiftRng::from_seed([1; 16]);
-            let ret = rng.gen_range::<c_int>(0, RAND_MAX);
+            let ret = rng.gen_range(0, RAND_MAX);
             RNG = Some(rng);
             ret
         }
@@ -498,7 +557,7 @@ pub unsafe extern "C" fn strtod(s: *const c_char, endptr: *mut *mut c_char) -> c
     }
 }
 
-fn is_positive(ch: c_char) -> Option<(bool, isize)> {
+pub fn is_positive(ch: c_char) -> Option<(bool, isize)> {
     match ch {
         0 => None,
         ch if ch == b'+' as c_char => Some((true, 1)),
@@ -507,7 +566,7 @@ fn is_positive(ch: c_char) -> Option<(bool, isize)> {
     }
 }
 
-fn detect_base(s: *const c_char) -> Option<(c_int, isize)> {
+pub fn detect_base(s: *const c_char) -> Option<(c_int, isize)> {
     let first = unsafe { *s } as u8;
     match first {
         0 => None,
@@ -526,7 +585,7 @@ fn detect_base(s: *const c_char) -> Option<(c_int, isize)> {
     }
 }
 
-unsafe fn convert_octal(s: *const c_char) -> Option<(c_ulong, isize, bool)> {
+pub unsafe fn convert_octal(s: *const c_char) -> Option<(c_ulong, isize, bool)> {
     if *s != 0 && *s == b'0' as c_char {
         if let Some((val, idx, overflow)) = convert_integer(s.offset(1), 8) {
             Some((val, idx + 1, overflow))
@@ -539,7 +598,7 @@ unsafe fn convert_octal(s: *const c_char) -> Option<(c_ulong, isize, bool)> {
     }
 }
 
-unsafe fn convert_hex(s: *const c_char) -> Option<(c_ulong, isize, bool)> {
+pub unsafe fn convert_hex(s: *const c_char) -> Option<(c_ulong, isize, bool)> {
     if (*s != 0 && *s == b'0' as c_char)
         && (*s.offset(1) != 0 && (*s.offset(1) == b'x' as c_char || *s.offset(1) == b'X' as c_char))
     {
@@ -549,7 +608,7 @@ unsafe fn convert_hex(s: *const c_char) -> Option<(c_ulong, isize, bool)> {
     }
 }
 
-fn convert_integer(s: *const c_char, base: c_int) -> Option<(c_ulong, isize, bool)> {
+pub fn convert_integer(s: *const c_char, base: c_int) -> Option<(c_ulong, isize, bool)> {
     // -1 means the character is invalid
     #[cfg_attr(rustfmt, rustfmt_skip)]
     const LOOKUP_TABLE: [c_long; 256] = [
@@ -603,6 +662,7 @@ fn convert_integer(s: *const c_char, base: c_int) -> Option<(c_ulong, isize, boo
     }
 }
 
+#[macro_export]
 macro_rules! strto_impl {
     (
         $rettype:ty,
@@ -620,7 +680,11 @@ macro_rules! strto_impl {
 
         let set_endptr = |idx: isize| {
             if !$endptr.is_null() {
-                *$endptr = $s.offset(idx);
+                // This is stupid, but apparently strto* functions want
+                // const input but mut output, yet the man page says
+                // "stores the address of the first invalid character in *endptr"
+                // so obviously it doesn't want us to clone it.
+                *$endptr = $s.offset(idx) as *mut _;
             }
         };
 
@@ -712,7 +776,7 @@ macro_rules! strto_impl {
 
 #[no_mangle]
 pub unsafe extern "C" fn strtoul(s: *const c_char,
-                                 endptr: *mut *const c_char,
+                                 endptr: *mut *mut c_char,
                                  base: c_int)
                                  -> c_ulong {
     strto_impl!(
@@ -728,7 +792,7 @@ pub unsafe extern "C" fn strtoul(s: *const c_char,
 
 #[no_mangle]
 pub unsafe extern "C" fn strtol(s: *const c_char,
-                                endptr: *mut *const c_char,
+                                endptr: *mut *mut c_char,
                                 base: c_int)
                                 -> c_long {
     strto_impl!(

+ 1 - 0
src/sys_stat/cbindgen.toml

@@ -1,5 +1,6 @@
 sys_includes = ["sys/types.h"]
 include_guard = "_SYS_STAT_H"
+trailer = "#include <bits/sys/stat.h>"
 language = "C"
 style = "Tag"
 

+ 28 - 28
src/sys_stat/src/lib.rs

@@ -6,31 +6,31 @@ extern crate platform;
 
 use platform::types::*;
 
-pub const S_IFMT: c_int = 00170000;
-pub const S_IFBLK: c_int = 0060000;
-pub const S_IFCHR: c_int = 0020000;
-pub const S_IFIFO: c_int = 0010000;
-pub const S_IFREG: c_int = 0100000;
-pub const S_IFDIR: c_int = 0040000;
-pub const S_IFLNK: c_int = 0120000;
-
-pub const S_IRWXU: c_int = 00700;
-pub const S_IRUSR: c_int = 00400;
-pub const S_IWUSR: c_int = 00200;
-pub const S_IXUSR: c_int = 00100;
-
-pub const S_IRWXG: c_int = 00070;
-pub const S_IRGRP: c_int = 00040;
-pub const S_IWGRP: c_int = 00020;
-pub const S_IXGRP: c_int = 00010;
-
-pub const S_IRWXO: c_int = 00007;
-pub const S_IROTH: c_int = 00004;
-pub const S_IWOTH: c_int = 00002;
-pub const S_IXOTH: c_int = 00001;
-pub const S_ISUID: c_int = 04000;
-pub const S_ISGID: c_int = 02000;
-pub const S_ISVTX: c_int = 01000;
+pub const S_IFMT: c_int = 0o0170000;
+pub const S_IFBLK: c_int = 0o060000;
+pub const S_IFCHR: c_int = 0o020000;
+pub const S_IFIFO: c_int = 0o010000;
+pub const S_IFREG: c_int = 0o100000;
+pub const S_IFDIR: c_int = 0o040000;
+pub const S_IFLNK: c_int = 0o120000;
+
+pub const S_IRWXU: c_int = 0o0700;
+pub const S_IRUSR: c_int = 0o0400;
+pub const S_IWUSR: c_int = 0o0200;
+pub const S_IXUSR: c_int = 0o0100;
+
+pub const S_IRWXG: c_int = 0o0070;
+pub const S_IRGRP: c_int = 0o0040;
+pub const S_IWGRP: c_int = 0o0020;
+pub const S_IXGRP: c_int = 0o0010;
+
+pub const S_IRWXO: c_int = 0o0007;
+pub const S_IROTH: c_int = 0o0004;
+pub const S_IWOTH: c_int = 0o0002;
+pub const S_IXOTH: c_int = 0o0001;
+pub const S_ISUID: c_int = 0o4000;
+pub const S_ISGID: c_int = 0o2000;
+pub const S_ISVTX: c_int = 0o1000;
 
 #[repr(C)]
 pub struct stat {
@@ -43,9 +43,9 @@ pub struct stat {
     pub st_rdev: dev_t,
     pub st_size: off_t,
     pub st_blksize: blksize_t,
-    pub st_atim: time_t,
-    pub st_mtim: time_t,
-    pub st_ctim: time_t,
+    pub st_atime: time_t,
+    pub st_mtime: time_t,
+    pub st_ctime: time_t,
     pub st_blocks: blkcnt_t,
 }
 

+ 1 - 0
src/sys_time/cbindgen.toml

@@ -1,6 +1,7 @@
 sys_includes = ["sys/types.h"]
 include_guard = "_SYS_TIME_H"
 language = "C"
+style = "Both"
 
 [enum]
 prefix_with_name = true

+ 11 - 0
src/sys_utsname/Cargo.toml

@@ -0,0 +1,11 @@
+[package]
+name = "sys_utsname"
+version = "0.1.0"
+authors = ["jD91mZM2 <me@krake.one>"]
+build = "build.rs"
+
+[build-dependencies]
+cbindgen = { path = "../../cbindgen" }
+
+[dependencies]
+platform = { path = "../platform" }

+ 11 - 0
src/sys_utsname/build.rs

@@ -0,0 +1,11 @@
+extern crate cbindgen;
+
+use std::{env, fs};
+
+fn main() {
+    let crate_dir = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
+    fs::create_dir_all("../../target/include").expect("failed to create include directory");
+    cbindgen::generate(crate_dir)
+        .expect("failed to generate bindings")
+        .write_to_file("../../target/include/sys/utsname.h");
+}

+ 5 - 0
src/sys_utsname/cbindgen.toml

@@ -0,0 +1,5 @@
+include_guard = "_SYS_UTSNAME_H"
+language = "C"
+
+[enum]
+prefix_with_name = true

+ 28 - 0
src/sys_utsname/src/lib.rs

@@ -0,0 +1,28 @@
+//! sys/utsname implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/sysutsname.h.html
+
+#![no_std]
+#![cfg(target_os = "linux")]
+
+extern crate platform;
+
+use core::ptr;
+use platform::types::*;
+
+const LENGTH: usize = 65;
+
+#[allow(non_camel_case)]
+#[no_mangle]
+#[repr(C)]
+pub struct utsname {
+    pub sysname:    [c_char; LENGTH],
+    pub nodename:   [c_char; LENGTH],
+    pub release:    [c_char; LENGTH],
+    pub version:    [c_char; LENGTH],
+    pub machine:    [c_char; LENGTH],
+    pub domainname: [c_char; LENGTH]
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn uname(uts: *mut utsname) -> c_int {
+    platform::uname(uts as usize)
+}

+ 1 - 1
src/time/src/constants.rs

@@ -44,7 +44,7 @@ pub(crate) const MON_NAMES: [&str; 12] = [
 ];
 
 pub(crate) const CLOCK_REALTIME: clockid_t = 0;
-pub(crate) const CLOCK_MONOTONIC: clockid_t = 1;
+pub const CLOCK_MONOTONIC: clockid_t = 1;
 pub(crate) const CLOCK_PROCESS_CPUTIME_ID: clockid_t = 2;
 pub(crate) const CLOCK_THREAD_CPUTIME_ID: clockid_t = 3;
 

+ 1 - 0
src/unistd/Cargo.toml

@@ -11,3 +11,4 @@ cbindgen = { path = "../../cbindgen" }
 platform = { path = "../platform" }
 stdio = { path = "../stdio" }
 string = { path = "../string" }
+sys_utsname = { path = "../sys_utsname" }

+ 2 - 1
src/unistd/cbindgen.toml

@@ -1,5 +1,6 @@
-sys_includes = ["stddef.h", "stdint.h", "sys/types.h"]
+sys_includes = ["stddef.h", "stdint.h", "sys/types.h", "stdarg.h", "bits/exec.h"]
 include_guard = "_UNISTD_H"
+trailer = "#include <bits/fcntl.h>"
 language = "C"
 
 [enum]

+ 0 - 1
src/unistd/src/getopt.rs

@@ -1,7 +1,6 @@
 //! getopt implementation for Redox, following http://pubs.opengroup.org/onlinepubs/009695399/functions/getopt.html
 
 use super::platform::types::*;
-use super::platform;
 use super::stdio;
 use super::string;
 use core::ptr;

+ 66 - 9
src/unistd/src/lib.rs

@@ -5,9 +5,11 @@
 extern crate platform;
 extern crate stdio;
 extern crate string;
+extern crate sys_utsname;
 
 pub use platform::types::*;
 pub use getopt::*;
+
 use core::ptr;
 
 mod getopt;
@@ -30,6 +32,9 @@ pub const STDIN_FILENO: c_int = 0;
 pub const STDOUT_FILENO: c_int = 1;
 pub const STDERR_FILENO: c_int = 2;
 
+#[no_mangle]
+pub static mut environ: *const *mut c_char = 0 as *const *mut c_char;
+
 #[no_mangle]
 pub extern "C" fn _exit(status: c_int) {
     platform::exit(status)
@@ -96,23 +101,27 @@ pub extern "C" fn encrypt(block: [c_char; 64], edflag: c_int) {
 }
 
 // #[no_mangle]
-// pub extern "C" fn execl(path: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int {
+// pub extern "C" fn execl(path: *const c_char, args: *const *mut c_char) -> c_int {
 //     unimplemented!();
 // }
-//
+
 // #[no_mangle]
-// pub extern "C" fn execle(path: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int {
+// pub extern "C" fn execle(
+//   path: *const c_char,
+//   args: *const *mut c_char,
+//   envp: *const *mut c_char,
+// ) -> c_int {
 //     unimplemented!();
 // }
-//
+
 // #[no_mangle]
-// pub extern "C" fn execlp(file: *const c_char, arg0: *const c_char /* TODO: , mut args: ... */) -> c_int {
+// pub extern "C" fn execlp(file: *const c_char, args: *const *mut c_char) -> c_int {
 //     unimplemented!();
 // }
 
 #[no_mangle]
 pub extern "C" fn execv(path: *const c_char, argv: *const *mut c_char) -> c_int {
-    unimplemented!();
+    unsafe { execve(path, argv, environ) }
 }
 
 #[no_mangle]
@@ -121,7 +130,7 @@ pub extern "C" fn execve(
     argv: *const *mut c_char,
     envp: *const *mut c_char,
 ) -> c_int {
-    unimplemented!();
+    platform::execve(path, argv, envp)
 }
 
 #[no_mangle]
@@ -199,6 +208,54 @@ pub extern "C" fn gethostid() -> c_long {
     unimplemented!();
 }
 
+#[no_mangle]
+pub unsafe extern "C" fn gethostname(mut name: *mut c_char, len: size_t) -> c_int {
+    #[cfg(target_os = "linux")] {
+        use core::mem;
+
+        // len only needs to be mutable on linux
+        let mut len = len;
+
+        let mut uts: sys_utsname::utsname = mem::uninitialized();
+        let err = sys_utsname::uname(&mut uts);
+        if err < 0 {
+            mem::forget(uts);
+            return err;
+        }
+        for c in uts.nodename.iter() {
+            if len == 0 { break; }
+            len -= 1;
+
+            *name = *c;
+
+            if *name == 0 {
+                // We do want to copy the zero also, so we check this after the copying.
+                break;
+            }
+
+            name = name.offset(1);
+        }
+        0
+    }
+    #[cfg(target_os = "redox")] {
+        use platform::{FileReader, Read};
+        use platform::syscall::flag::*;
+
+        let fd = platform::open("/etc/hostname\0",as_ptr(), 0, O_RDONLY);
+        if fd < 0 {
+            return fd;
+        }
+        let reader = FileReader(fd);
+        for _ in 0..len {
+            if !reader.read_u8(&mut *name) {
+                *name = 0;
+                break;
+            }
+            name = name.offset(1);
+        }
+    }
+}
+
 #[no_mangle]
 pub extern "C" fn getlogin() -> *mut c_char {
     unimplemented!();
@@ -347,7 +404,7 @@ pub extern "C" fn sbrk(incr: intptr_t) -> *mut c_void {
 
 #[no_mangle]
 pub extern "C" fn setgid(gid: gid_t) -> c_int {
-    unimplemented!();
+    platform::setregid(gid, gid)
 }
 
 #[no_mangle]
@@ -377,7 +434,7 @@ pub extern "C" fn setsid() -> pid_t {
 
 #[no_mangle]
 pub extern "C" fn setuid(uid: uid_t) -> c_int {
-    unimplemented!();
+    platform::setreuid(uid, uid)
 }
 
 #[no_mangle]

+ 394 - 0
src/wchar/src/lib.rs

@@ -0,0 +1,394 @@
+//! wchar implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/string.h.html
+
+#![no_std]
+
+extern crate errno;
+extern crate platform;
+extern crate stdlib;
+extern crate string;
+extern crate time;
+
+use platform::types::*;
+use errno::*;
+use time::*;
+use core::cmp;
+use core::usize;
+use core::ptr;
+use core::mem;
+use string::*;
+
+pub type wint_t = i32;
+
+#[repr(C)]
+pub struct mbstate_t {
+    pub mbs_count: c_int,
+    pub mbs_length: c_int,
+    pub mbs_wch: wint_t,
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn btowc(c: c_int) -> wint_t {
+    //Check for EOF
+    if c == -1 {
+        return -1;
+    }
+
+    let uc = c as u8;
+    let c = uc as c_char;
+    let mut ps: mbstate_t = mbstate_t {
+        mbs_count: 0,
+        mbs_length: 0,
+        mbs_wch: 0,
+    };
+    let mut wc: wchar_t = 0;
+    let saved_errno = platform::errno;
+    let status = mbrtowc(&mut wc, &c as (*const c_char), 1, &mut ps);
+    if status == usize::max_value() || status == usize::max_value() - 1 {
+        platform::errno = saved_errno;
+        return platform::errno;
+    }
+    return wc as wint_t;
+}
+
+#[no_mangle]
+pub extern "C" fn getwchar() -> wint_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn mbsinit(ps: *const mbstate_t) -> c_int {
+    if ps.is_null() || (*ps).mbs_count == 0 {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn mbrlen(s: *const c_char, n: usize, ps: *mut mbstate_t) -> usize {
+    static mut internal: mbstate_t = mbstate_t {
+        mbs_count: 0,
+        mbs_length: 0,
+        mbs_wch: 0,
+    };
+    return mbrtowc(ptr::null_mut(), s, n, &mut internal);
+}
+
+//Only works for utf8!
+#[no_mangle]
+pub unsafe extern "C" fn mbrtowc(
+    pwc: *mut wchar_t,
+    s: *const c_char,
+    n: usize,
+    ps: *mut mbstate_t,
+) -> usize {
+    static mut internal: mbstate_t = mbstate_t {
+        mbs_count: 0,
+        mbs_length: 0,
+        mbs_wch: 0,
+    };
+
+    if ps.is_null() {
+        let ps = &mut internal;
+    }
+    if s.is_null() {
+        let xs: [c_char; 1] = [0];
+        utf8_mbrtowc(pwc, &xs[0] as *const c_char, 1, ps);
+    }
+
+    return utf8_mbrtowc(pwc, s, n, ps);
+}
+
+#[no_mangle]
+unsafe extern "C" fn utf8_mbrtowc(
+    pwc: *mut wchar_t,
+    s: *const c_char,
+    n: usize,
+    ps: *mut mbstate_t,
+) -> usize {
+    let mut i: usize = 0;
+
+    while !(i > 0 && (*ps).mbs_count == 0) {
+        if (n <= i) {
+            return -2isize as usize;
+        }
+        let c = s.offset(i as isize);
+        let uc = c as u8;
+
+        if (*ps).mbs_count == 0 {
+            //1 byte sequence - 00–7F
+            if (uc & 0b10000000) == 0b00000000 {
+                (*ps).mbs_count = 0;
+                (*ps).mbs_length = 1;
+                (*ps).mbs_wch = (uc as wchar_t & 0b1111111) as wint_t;
+            }
+            //2 byte sequence - C2–DF
+            else if (uc & 0b11100000) == 0b11000000 {
+                (*ps).mbs_count = 1;
+                (*ps).mbs_length = 2;
+                (*ps).mbs_wch = (uc as wchar_t & 0b11111) as wint_t;
+            }
+            //3 byte sequence - E0–EF
+            else if (uc & 0b11110000) == 0b11100000 {
+                (*ps).mbs_count = 2;
+                (*ps).mbs_length = 3;
+                (*ps).mbs_wch = (uc as wchar_t & 0b1111) as wint_t;
+            }
+            //4 byte sequence - F0–F4
+            else if (uc & 0b11111000) == 0b11110000 {
+                (*ps).mbs_count = 3;
+                (*ps).mbs_length = 4;
+                (*ps).mbs_wch = (uc as wchar_t & 0b111) as wint_t;
+            } else {
+                platform::errno = errno::EILSEQ;
+                return -1isize as usize;
+            }
+        } else {
+            if (uc & 0b11000000) != 0b10000000 {
+                platform::errno = errno::EILSEQ;
+                return -1isize as usize;
+            }
+
+            (*ps).mbs_wch = (*ps).mbs_wch << 6 | (uc & 0b00111111) as wint_t;
+            (*ps).mbs_count -= 1;
+        }
+
+        i += 1;
+    }
+
+    // Reject the character if it was produced with an overly long sequence.
+    if (*ps).mbs_length == 1 && 1 << 7 <= (*ps).mbs_wch {
+        platform::errno = errno::EILSEQ;
+        return -1isize as usize;
+    }
+    if (*ps).mbs_length == 2 && 1 << (5 + 1 * 6) <= (*ps).mbs_wch {
+        platform::errno = errno::EILSEQ;
+        return -1isize as usize;
+    }
+    if (*ps).mbs_length == 3 && 1 << (5 + 2 * 6) <= (*ps).mbs_wch {
+        platform::errno = errno::EILSEQ;
+        return -1isize as usize;
+    }
+    if (*ps).mbs_length == 4 && 1 << (5 + 3 * 6) <= (*ps).mbs_wch {
+        platform::errno = errno::EILSEQ;
+        return -1isize as usize;
+    }
+
+    // The definition of UTF-8 prohibits encoding character numbers between
+    // U+D800 and U+DFFF, which are reserved for use with the UTF-16 encoding
+    // form (as surrogate pairs) and do not directly represent characters.
+    if 0xD800 <= (*ps).mbs_wch && (*ps).mbs_wch <= 0xDFFF {
+        platform::errno = errno::EILSEQ;
+        return -1isize as usize;
+    }
+    // RFC 3629 limits UTF-8 to 0x0 through 0x10FFFF.
+    if 0x10FFFF <= (*ps).mbs_wch {
+        platform::errno = errno::EILSEQ;
+        return -1isize as usize;
+    }
+
+    let result: wchar_t = (*ps).mbs_wch as wchar_t;
+
+    if !pwc.is_null() {
+        *pwc = result;
+    }
+
+    (*ps).mbs_length = 0;
+    (*ps).mbs_wch = 0;
+
+    return if result != 0 { i } else { 0 };
+}
+
+#[no_mangle]
+pub extern "C" fn mbsrtowcs(
+    dst: *mut wchar_t,
+    src: *mut *const c_char,
+    len: usize,
+    ps: *mut mbstate_t,
+) -> usize {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn putwchar(wc: wchar_t) -> wint_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn towlower(wc: wint_t) -> wint_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn towupper(wc: wint_t) -> wint_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcrtomb(s: *mut c_char, wc: wchar_t, ps: *mut mbstate_t) -> usize {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcscat(ws1: *mut wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcschr(ws1: *const wchar_t, ws2: wchar_t) -> *mut c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcscmp(ws1: *const wchar_t, ws2: *const wchar_t) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcscoll(ws1: *const wchar_t, ws2: *const wchar_t) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcscpy(ws1: *mut wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcscspn(ws1: *const wchar_t, ws2: *const wchar_t) -> usize {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcsftime(
+    wcs: *mut wchar_t,
+    maxsize: usize,
+    format: *const wchar_t,
+    timptr: *mut tm,
+) -> usize {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcslen(ws: *const wchar_t) -> c_ulong {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcsncat(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize) -> *mut wchar_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcsncmp(ws1: *const wchar_t, ws2: *const wchar_t, n: usize) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcsncpy(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize) -> *mut wchar_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcspbrk(ws1: *const wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcsrchr(ws1: *const wchar_t, ws2: wchar_t) -> *mut wchar_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcsrtombs(
+    dst: *mut c_char,
+    src: *mut *const wchar_t,
+    len: usize,
+    ps: *mut mbstate_t,
+) -> usize {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcsspn(ws1: *const wchar_t, ws2: *const wchar_t) -> usize {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcsstr(ws1: *const wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcstod(nptr: *const wchar_t, endptr: *mut *mut wchar_t) -> f64 {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcstok(
+    ws1: *mut wchar_t,
+    ws2: *const wchar_t,
+    ptr: *mut *mut wchar_t,
+) -> *mut wchar_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcstol(nptr: *const wchar_t, endptr: *mut *mut wchar_t, base: c_int) -> c_long {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcstoul(nptr: *const wchar_t, endptr: *mut *mut wchar_t, base: c_int) -> c_ulong {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcswcs(ws1: *const wchar_t, ws2: *const wchar_t) -> *mut wchar_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcswidth(pwcs: *const wchar_t, n: usize) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcsxfrm(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize) -> usize {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wctob(c: wint_t) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wcwidth(wc: wchar_t) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wmemchr(ws: *const wchar_t, wc: wchar_t, n: usize) -> *mut c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wmemcmp(ws1: *const wchar_t, ws2: *const wchar_t, n: usize) -> c_int {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wmemcpy(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize) -> *mut wchar_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wmemmove(ws1: *mut wchar_t, ws2: *const wchar_t, n: usize) -> *mut wchar_t {
+    unimplemented!();
+}
+
+#[no_mangle]
+pub extern "C" fn wmemset(ws1: *mut wchar_t, ws2: wchar_t, n: usize) -> *mut wchar_t {
+    unimplemented!();
+}

+ 6 - 2
tests/.gitignore

@@ -1,6 +1,7 @@
 /*.out
 /gen/
 /alloc
+/assert
 /args
 /atof
 /atoi
@@ -10,12 +11,14 @@
 /ctype
 /dup
 /error
+/exec
 /fchdir
 /fcntl
 /fsync
 /ftruncate
-/getid
 /getc_unget
+/gethostname
+/getid
 /link
 /locale
 /math
@@ -26,11 +29,12 @@
 /rename
 /scanf
 /setid
-/setid
+/setjmp
 /sleep
 /sprintf
 /stdlib/a64l
 /stdlib/bsearch
+/stdlib/mktemp
 /stdlib/rand
 /stdlib/strtol
 /stdlib/strtoul

+ 9 - 5
tests/Makefile

@@ -1,5 +1,6 @@
 # Binaries that should generate the same output every time
 EXPECT_BINS=\
+	assert \
 	atof \
 	atoi \
 	brk \
@@ -8,13 +9,12 @@ EXPECT_BINS=\
 	ctype \
 	dup \
 	error \
+	exec \
 	fchdir \
 	fcntl \
 	fsync \
 	ftruncate \
-	getid \
 	getc_unget \
-	link \
 	locale \
 	math \
 	mem \
@@ -23,12 +23,12 @@ EXPECT_BINS=\
 	rename \
 	rmdir \
 	scanf \
+	setjmp \
 	sleep \
 	sprintf \
 	stdio/fwrite \
 	stdio/all \
 	stdio/freopen \
-	stdlib/bsearch \
 	stdlib/strtol \
 	stdlib/strtoul \
 	stdlib/a64l \
@@ -43,7 +43,6 @@ EXPECT_BINS=\
 	string/strtok \
 	string/strtok_r \
 	unistd/getopt \
-	unlink \
 	waitpid \
 	write \
 	time \
@@ -55,8 +54,13 @@ BINS=\
 	$(EXPECT_BINS) \
 	alloc \
 	chdir \
+	gethostname \
 	getid \
-	setid
+	link \
+	setid \
+	stdlib/bsearch \
+	stdlib/mktemp \
+	unlink
 
 all: $(BINS)
 

+ 14 - 0
tests/assert.c

@@ -0,0 +1,14 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+    assert(1 == 1);
+    assert(1 + 1 == 2);
+
+    puts("yay!");
+
+    //This fails, but I can't test it because that'd
+    //make the test fail lol
+    //assert(42 == 1337);
+}

+ 8 - 0
tests/exec.c

@@ -0,0 +1,8 @@
+#include <unistd.h>
+
+int main(int argc, char** argv) {
+    char *const args[1] = {"arg"};
+    execv("write", args);
+    perror("execv");
+    return 0;
+}

+ 0 - 0
tests/expected/link.stdout → tests/expected/asctime.stderr


+ 0 - 0
tests/expected/unlink.stdout → tests/expected/asctime.stdout


+ 0 - 0
tests/expected/assert.stderr


+ 1 - 0
tests/expected/assert.stdout

@@ -0,0 +1 @@
+yay!

+ 0 - 0
tests/expected/getc_unget.stderr


+ 1 - 0
tests/expected/getc_unget.stdout

@@ -0,0 +1 @@
+Worked!

+ 0 - 0
tests/expected/gmtime.stderr


+ 0 - 0
tests/expected/gmtime.stdout


+ 0 - 1
tests/expected/link.stderr

@@ -1 +0,0 @@
-link: File exists

+ 1 - 0
tests/expected/printf.stdout

@@ -1,6 +1,7 @@
 percent: %
 string: String
 char: c
+char: þ
 int: -16
 uint: 32
 hex: beef

+ 0 - 0
tests/expected/rename.stderr


+ 0 - 0
tests/expected/rename.stdout


+ 0 - 0
tests/expected/setjmp.stderr


+ 2 - 0
tests/expected/setjmp.stdout

@@ -0,0 +1,2 @@
+jumping...
+hi from jump

+ 0 - 0
tests/expected/stdio/all.stderr


+ 3 - 0
tests/expected/stdio/all.stdout

@@ -0,0 +1,3 @@
+H
+Hello World!
+

+ 0 - 0
tests/expected/stdio/freopen.stderr


+ 1 - 0
tests/expected/stdio/freopen.stdout

@@ -0,0 +1 @@
+Hello 

+ 0 - 0
tests/expected/stdio/fwrite.stderr


Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů