Kaynağa Gözat

Merge pull request #22 from DragonOS-Community/update-dsc

Update dsc
GnoCiYeH 1 yıl önce
ebeveyn
işleme
565bc93b46
68 değiştirilmiş dosya ile 2768 ekleme ve 937 silme
  1. 2 0
      .cargo/config.toml
  2. 1 0
      .gitignore
  3. 6 6
      .gitmodules
  4. 18 0
      .vscode/c_cpp_properties.json
  5. 5 0
      .vscode/settings.json
  6. 0 761
      Cargo.lock
  7. 4 0
      Cargo.toml
  8. 27 7
      Makefile
  9. 11 1
      README.md
  10. 11 4
      build.rs
  11. 68 0
      init_dragonos_toolchain.sh
  12. 3 0
      src/c/dlmalloc.c
  13. 430 0
      src/c/dragonos_malloc.c
  14. 5 0
      src/c/unistd.c
  15. 1 7
      src/header/assert/mod.rs
  16. 9 0
      src/header/errno/mod.rs
  17. 1 0
      src/header/fcntl/cbindgen.toml
  18. 17 0
      src/header/fcntl/dragonos.rs
  19. 4 0
      src/header/fcntl/mod.rs
  20. 29 0
      src/header/netdb/dragonos.rs
  21. 4 0
      src/header/netdb/mod.rs
  22. 2 1
      src/header/poll/mod.rs
  23. 15 0
      src/header/pwd/dragonos.rs
  24. 5 0
      src/header/pwd/mod.rs
  25. 1 0
      src/header/signal/cbindgen.toml
  26. 76 0
      src/header/signal/dragonos.rs
  27. 4 0
      src/header/signal/mod.rs
  28. 1 1
      src/header/stdio/mod.rs
  29. 1 4
      src/header/stdlib/mod.rs
  30. 1 2
      src/header/strings/mod.rs
  31. 1 0
      src/header/sys_epoll/cbindgen.toml
  32. 20 0
      src/header/sys_epoll/dragonos.rs
  33. 4 0
      src/header/sys_epoll/mod.rs
  34. 1 0
      src/header/sys_ioctl/cbindgen.toml
  35. 195 0
      src/header/sys_ioctl/dragonos.rs
  36. 4 0
      src/header/sys_ioctl/mod.rs
  37. 1 0
      src/header/sys_mman/cbindgen.toml
  38. 9 0
      src/header/sys_mman/dragonos.rs
  39. 7 0
      src/header/sys_mman/mod.rs
  40. 1 0
      src/header/sys_resource/cbindgen.toml
  41. 1 0
      src/header/sys_socket/cbindgen.toml
  42. 1 0
      src/header/termios/cbindgen.toml
  43. 113 0
      src/header/termios/dragonos.rs
  44. 18 0
      src/header/termios/mod.rs
  45. 1 0
      src/header/time/cbindgen.toml
  46. 4 0
      src/header/time/constants.rs
  47. 13 0
      src/header/time/dragonos.rs
  48. 1 0
      src/header/unistd/cbindgen.toml
  49. 8 0
      src/header/unistd/mod.rs
  50. 7 0
      src/ld_so/access.rs
  51. 248 0
      src/ld_so/ld_script/x86_64-unknown-dragonos.ld
  52. 11 1
      src/ld_so/mod.rs
  53. 46 7
      src/ld_so/src/lib.rs
  54. 17 1
      src/ld_so/tcb.rs
  55. 6 0
      src/lib.rs
  56. 25 0
      src/platform/allocator/dlmalloc.rs
  57. 98 0
      src/platform/allocator/dragonos_malloc.rs
  58. 37 0
      src/platform/dragonos/epoll.rs
  59. 555 0
      src/platform/dragonos/mod.rs
  60. 11 0
      src/platform/dragonos/ptrace.rs
  61. 63 0
      src/platform/dragonos/signal.rs
  62. 128 0
      src/platform/dragonos/socket.rs
  63. 20 1
      src/platform/mod.rs
  64. 3 2
      src/platform/redox/redox-exec/src/arch/aarch64.rs
  65. 3 2
      src/platform/redox/redox-exec/src/arch/x86.rs
  66. 3 2
      src/platform/redox/redox-exec/src/arch/x86_64.rs
  67. 284 123
      src/platform/redox/redox-exec/src/lib.rs
  68. 38 4
      src/start.rs

+ 2 - 0
.cargo/config.toml

@@ -0,0 +1,2 @@
+[build]
+target = "x86_64-unknown-dragonos"

+ 1 - 0
.gitignore

@@ -6,3 +6,4 @@ sysroot/
 *.patch
 *.swp
 *.swo
+Cargo.lock

+ 6 - 6
.gitmodules

@@ -1,19 +1,19 @@
 [submodule "openlibm"]
 	path = openlibm
-	url = https://gitlab.redox-os.org/redox-os/openlibm.git
+	url = https://git.mirrors.dragonos.org/DragonOS-Community/relibc_openlibm.git
 [submodule "ralloc"]
 	path = ralloc
-	url = https://gitlab.redox-os.org/redox-os/ralloc.git
+	url = https://git.mirrors.dragonos.org/DragonOS-Community/relibc_ralloc.git
 [submodule "core_io"]
 	path = core_io
-	url = https://gitlab.redox-os.org/redox-os/core_io.git
+	url = https://git.mirrors.dragonos.org/DragonOS-Community/relibc_core_io.git
 [submodule "posix-regex"]
 	path = posix-regex
-	url = https://gitlab.redox-os.org/redox-os/posix-regex.git
+	url = https://git.mirrors.dragonos.org/DragonOS-Community/relibc_posix-regex.git
 [submodule "pthreads-emb"]
 	path = pthreads-emb
-	url = https://gitlab.redox-os.org/redox-os/pthreads-emb.git
+	url = https://git.mirrors.dragonos.org/DragonOS-Community/relibc_pthreads-emb.git
 [submodule "compiler-builtins"]
 	path = compiler-builtins
-	url = https://gitlab.redox-os.org/redox-os/compiler-builtins.git
+	url = https://git.mirrors.dragonos.org/DragonOS-Community/relibc_compiler-builtins.git
 	branch = relibc_fix_dup_symbols

+ 18 - 0
.vscode/c_cpp_properties.json

@@ -0,0 +1,18 @@
+{
+    "configurations": [
+        {
+            "name": "Linux",
+            "includePath": [
+                "${workspaceFolder}/**",
+                "${workspaceFolder}/include"
+            ],
+            "defines": [],
+            "compilerPath": "/usr/bin/clang",
+            "cStandard": "c17",
+            "cppStandard": "c++14",
+            "intelliSenseMode": "linux-clang-x64",
+            "configurationProvider": "ms-vscode.makefile-tools"
+        }
+    ],
+    "version": 4
+}

+ 5 - 0
.vscode/settings.json

@@ -0,0 +1,5 @@
+{
+    "rust-analyzer.linkedProjects": [
+        "./Cargo.toml"
+    ]
+}

+ 0 - 761
Cargo.lock

@@ -1,761 +0,0 @@
-# This file is automatically @generated by Cargo.
-# It is not intended for manual editing.
-version = 3
-
-[[package]]
-name = "atty"
-version = "0.2.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
-dependencies = [
- "hermit-abi",
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "autocfg"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
-
-[[package]]
-name = "bitflags"
-version = "1.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
-
-[[package]]
-name = "cbindgen"
-version = "0.24.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb"
-dependencies = [
- "clap",
- "heck",
- "indexmap",
- "log",
- "proc-macro2 1.0.51",
- "quote 1.0.23",
- "serde",
- "serde_json",
- "syn 1.0.109",
- "tempfile",
- "toml",
-]
-
-[[package]]
-name = "cbitset"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e3a9afa72f63942dd7e7f01c67b863ce9df35c523ae10e3dddd3eec8f1e07eac"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
-name = "cc"
-version = "1.0.79"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
-
-[[package]]
-name = "cfg-if"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
-
-[[package]]
-name = "clap"
-version = "3.2.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
-dependencies = [
- "atty",
- "bitflags",
- "clap_lex",
- "indexmap",
- "strsim",
- "termcolor",
- "textwrap",
-]
-
-[[package]]
-name = "clap_lex"
-version = "0.2.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
-dependencies = [
- "os_str_bytes",
-]
-
-[[package]]
-name = "core_io"
-version = "0.1.20181107"
-dependencies = [
- "rustc_version 0.1.7",
-]
-
-[[package]]
-name = "crt0"
-version = "0.1.0"
-
-[[package]]
-name = "crti"
-version = "0.1.0"
-
-[[package]]
-name = "crtn"
-version = "0.1.0"
-
-[[package]]
-name = "errno"
-version = "0.2.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
-dependencies = [
- "errno-dragonfly",
- "libc",
- "winapi",
-]
-
-[[package]]
-name = "errno-dragonfly"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
-dependencies = [
- "cc",
- "libc",
-]
-
-[[package]]
-name = "fastrand"
-version = "1.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
-dependencies = [
- "instant",
-]
-
-[[package]]
-name = "goblin"
-version = "0.0.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a4013e9182f2345c6b7829b9ef6e670bce0dfca12c6f974457ed2160c2c7fe9"
-dependencies = [
- "log",
- "plain",
- "scroll",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
-name = "heck"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "indexmap"
-version = "1.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
-dependencies = [
- "autocfg",
- "hashbrown",
-]
-
-[[package]]
-name = "instant"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "io-lifetimes"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfa919a82ea574332e2de6e74b4c36e74d41982b335080fa59d4ef31be20fdf3"
-dependencies = [
- "libc",
- "windows-sys 0.45.0",
-]
-
-[[package]]
-name = "itoa"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
-
-[[package]]
-name = "lazy_static"
-version = "1.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
-dependencies = [
- "spin 0.5.2",
-]
-
-[[package]]
-name = "ld_so"
-version = "0.1.0"
-
-[[package]]
-name = "libc"
-version = "0.2.140"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
-
-[[package]]
-name = "linux-raw-sys"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
-
-[[package]]
-name = "lock_api"
-version = "0.4.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
-dependencies = [
- "autocfg",
- "scopeguard",
-]
-
-[[package]]
-name = "log"
-version = "0.4.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
-name = "memchr"
-version = "2.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
-
-[[package]]
-name = "memoffset"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "num-traits"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
-dependencies = [
- "autocfg",
-]
-
-[[package]]
-name = "os_str_bytes"
-version = "6.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
-
-[[package]]
-name = "plain"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6"
-
-[[package]]
-name = "posix-regex"
-version = "0.1.0"
-
-[[package]]
-name = "proc-macro2"
-version = "0.4.30"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
-dependencies = [
- "unicode-xid",
-]
-
-[[package]]
-name = "proc-macro2"
-version = "1.0.51"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
-dependencies = [
- "unicode-ident",
-]
-
-[[package]]
-name = "quote"
-version = "0.6.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
-dependencies = [
- "proc-macro2 0.4.30",
-]
-
-[[package]]
-name = "quote"
-version = "1.0.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
-dependencies = [
- "proc-macro2 1.0.51",
-]
-
-[[package]]
-name = "ralloc"
-version = "1.0.0"
-dependencies = [
- "ralloc_shim",
- "unborrow",
-]
-
-[[package]]
-name = "ralloc_shim"
-version = "0.1.1"
-dependencies = [
- "redox_syscall 0.1.57",
- "sc",
-]
-
-[[package]]
-name = "rand"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9"
-dependencies = [
- "rand_core 0.3.1",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
-dependencies = [
- "rand_core 0.4.2",
-]
-
-[[package]]
-name = "rand_core"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
-
-[[package]]
-name = "redox-exec"
-version = "0.1.0"
-dependencies = [
- "goblin",
- "plain",
- "redox_syscall 0.3.4",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.1.57"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
-
-[[package]]
-name = "redox_syscall"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
-name = "redox_syscall"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fb02a9aee8e8c7ad8d86890f1e16b49e0bbbffc9961ff3788c31d57c98bcbf03"
-dependencies = [
- "bitflags",
-]
-
-[[package]]
-name = "relibc"
-version = "0.2.5"
-dependencies = [
- "cbindgen",
- "cbitset",
- "cc",
- "core_io",
- "goblin",
- "lazy_static",
- "memchr",
- "memoffset",
- "plain",
- "posix-regex",
- "ralloc",
- "rand",
- "redox-exec",
- "redox_syscall 0.3.4",
- "sc",
- "spin 0.9.5",
- "unicode-width",
-]
-
-[[package]]
-name = "rustc_version"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
-dependencies = [
- "semver 0.1.20",
-]
-
-[[package]]
-name = "rustc_version"
-version = "0.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
-dependencies = [
- "semver 0.9.0",
-]
-
-[[package]]
-name = "rustix"
-version = "0.36.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc"
-dependencies = [
- "bitflags",
- "errno",
- "io-lifetimes",
- "libc",
- "linux-raw-sys",
- "windows-sys 0.45.0",
-]
-
-[[package]]
-name = "ryu"
-version = "1.0.13"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
-
-[[package]]
-name = "sc"
-version = "0.2.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "010e18bd3bfd1d45a7e666b236c78720df0d9a7698ebaa9c1c559961eb60a38b"
-
-[[package]]
-name = "scopeguard"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
-
-[[package]]
-name = "scroll"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f84d114ef17fd144153d608fba7c446b0145d038985e7a8cc5d08bb0ce20383"
-dependencies = [
- "rustc_version 0.2.3",
- "scroll_derive",
-]
-
-[[package]]
-name = "scroll_derive"
-version = "0.9.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8f1aa96c45e7f5a91cb7fabe7b279f02fea7126239fc40b732316e8b6a2d0fcb"
-dependencies = [
- "proc-macro2 0.4.30",
- "quote 0.6.13",
- "syn 0.15.44",
-]
-
-[[package]]
-name = "semver"
-version = "0.1.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac"
-
-[[package]]
-name = "semver"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
-dependencies = [
- "semver-parser",
-]
-
-[[package]]
-name = "semver-parser"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-
-[[package]]
-name = "serde"
-version = "1.0.154"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cdd151213925e7f1ab45a9bbfb129316bd00799784b174b7cc7bcd16961c49e"
-dependencies = [
- "serde_derive",
-]
-
-[[package]]
-name = "serde_derive"
-version = "1.0.154"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fc80d722935453bcafdc2c9a73cd6fac4dc1938f0346035d84bf99fa9e33217"
-dependencies = [
- "proc-macro2 1.0.51",
- "quote 1.0.23",
- "syn 1.0.109",
-]
-
-[[package]]
-name = "serde_json"
-version = "1.0.94"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
-dependencies = [
- "itoa",
- "ryu",
- "serde",
-]
-
-[[package]]
-name = "spin"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
-
-[[package]]
-name = "spin"
-version = "0.9.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7dccf47db1b41fa1573ed27ccf5e08e3ca771cb994f776668c5ebda893b248fc"
-dependencies = [
- "lock_api",
-]
-
-[[package]]
-name = "strsim"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
-
-[[package]]
-name = "syn"
-version = "0.15.44"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
-dependencies = [
- "proc-macro2 0.4.30",
- "quote 0.6.13",
- "unicode-xid",
-]
-
-[[package]]
-name = "syn"
-version = "1.0.109"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
-dependencies = [
- "proc-macro2 1.0.51",
- "quote 1.0.23",
- "unicode-ident",
-]
-
-[[package]]
-name = "tempfile"
-version = "3.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95"
-dependencies = [
- "cfg-if",
- "fastrand",
- "redox_syscall 0.2.16",
- "rustix",
- "windows-sys 0.42.0",
-]
-
-[[package]]
-name = "termcolor"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
-name = "textwrap"
-version = "0.16.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
-
-[[package]]
-name = "toml"
-version = "0.5.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
-dependencies = [
- "serde",
-]
-
-[[package]]
-name = "unborrow"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e92e959f029e4f8ee25d70d15ab58d2b46f98a17bc238b9265ff0c26f6f3d67f"
-
-[[package]]
-name = "unicode-ident"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
-
-[[package]]
-name = "unicode-width"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
-
-[[package]]
-name = "unicode-xid"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
-
-[[package]]
-name = "winapi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
-dependencies = [
- "winapi-i686-pc-windows-gnu",
- "winapi-x86_64-pc-windows-gnu",
-]
-
-[[package]]
-name = "winapi-i686-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
-
-[[package]]
-name = "winapi-util"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
-dependencies = [
- "winapi",
-]
-
-[[package]]
-name = "winapi-x86_64-pc-windows-gnu"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-
-[[package]]
-name = "windows-sys"
-version = "0.42.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
-dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
-]
-
-[[package]]
-name = "windows-sys"
-version = "0.45.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
-dependencies = [
- "windows-targets",
-]
-
-[[package]]
-name = "windows-targets"
-version = "0.42.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
-dependencies = [
- "windows_aarch64_gnullvm",
- "windows_aarch64_msvc",
- "windows_i686_gnu",
- "windows_i686_msvc",
- "windows_x86_64_gnu",
- "windows_x86_64_gnullvm",
- "windows_x86_64_msvc",
-]
-
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.42.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
-
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.42.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
-
-[[package]]
-name = "windows_i686_gnu"
-version = "0.42.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
-
-[[package]]
-name = "windows_i686_msvc"
-version = "0.42.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
-
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.42.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
-
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.42.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
-
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.42.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"

+ 4 - 0
Cargo.toml

@@ -40,6 +40,10 @@ optional = true
 [target.'cfg(target_os = "linux")'.dependencies]
 sc = "0.2.3"
 
+[target.'cfg(target_os = "dragonos")'.dependencies]
+# Development
+dragonos-dsc = { git = "https://git.mirrors.dragonos.org/DragonOS-Community/dragonos-dsc.git", rev = "aa61cb0109" }
+
 [target.'cfg(target_os = "redox")'.dependencies]
 redox_syscall = "0.3"
 spin = "0.9.0"

+ 27 - 7
Makefile

@@ -1,4 +1,5 @@
-TARGET?=$(shell rustc -Z unstable-options --print target-spec-json | grep llvm-target | cut -d '"' -f4)
+# TARGET?=$(shell rustc -Z unstable-options --print target-spec-json | grep llvm-target | cut -d '"' -f4)
+TARGET=x86_64-unknown-dragonos
 
 CARGO?=cargo
 CARGO_TEST?=$(CARGO)
@@ -45,6 +46,25 @@ ifeq ($(TARGET),x86_64-unknown-redox)
 	export OBJCOPY=x86_64-unknown-redox-objcopy
 endif
 
+ifeq ($(TARGET),x86_64-unknown-dragonos)
+# 如果存在x86_64-dragonos-gcc,就用它,否则用gcc
+
+ifeq ($(shell which x86_64-dragonos-gcc),)
+	export CC=gcc
+# export LD=ld
+	export LD=ld
+	export AR=ar
+# export AR=x86_64-dragonos-ar
+	export OBJCOPY=objcopy
+# export OBJCOPY=x86_64-dragonos-objcopy
+else
+	export CC=x86_64-dragonos-gcc
+	export LD=x86_64-dragonos-ld
+	export AR=x86_64-dragonos-ar
+	export OBJCOPY=x86_64-dragonos-objcopy
+endif
+endif
+
 SRC=\
 	Cargo.* \
 	$(shell find src -type f)
@@ -74,24 +94,24 @@ install-headers: libs
 	cp -v "openlibm/src"/*.h "$(DESTDIR)/include"
 	cp -v "pthreads-emb/"*.h "$(DESTDIR)/include"
 
+# $(BUILD)/release/libc.so
 libs: \
 	$(BUILD)/release/libc.a \
-	$(BUILD)/release/libc.so \
 	$(BUILD)/release/crt0.o \
 	$(BUILD)/release/crti.o \
-	$(BUILD)/release/crtn.o \
-	$(BUILD)/release/ld_so
+	$(BUILD)/release/crtn.o
+#$(BUILD)/release/ld_so
 
 install-libs: libs
 	mkdir -pv "$(DESTDIR)/lib"
 	cp -v "$(BUILD)/release/libc.a" "$(DESTDIR)/lib"
-	cp -v "$(BUILD)/release/libc.so" "$(DESTDIR)/lib"
-	ln -frsv "$(DESTDIR)/lib/libc.so" "$(DESTDIR)/lib/libc.so.6"
+# cp -v "$(BUILD)/release/libc.so" "$(DESTDIR)/lib"
+# ln -frsv "$(DESTDIR)/lib/libc.so" "$(DESTDIR)/lib/libc.so.6"
 	cp -v "$(BUILD)/release/crt0.o" "$(DESTDIR)/lib"
 	ln -frsv "$(DESTDIR)/lib/crt0.o" "$(DESTDIR)/lib/crt1.o"
 	cp -v "$(BUILD)/release/crti.o" "$(DESTDIR)/lib"
 	cp -v "$(BUILD)/release/crtn.o" "$(DESTDIR)/lib"
-	cp -v "$(BUILD)/release/ld_so" "$(DESTDIR)/lib/ld64.so.1"
+# cp -v "$(BUILD)/release/ld_so" "$(DESTDIR)/lib/ld64.so.1"
 	cp -v "$(BUILD)/openlibm/libopenlibm.a" "$(DESTDIR)/lib/libm.a"
 	cp -v "$(BUILD)/pthreads-emb/libpthread.a" "$(DESTDIR)/lib/libpthread.a"
 	# Empty libraries for dl and rt

+ 11 - 1
README.md

@@ -1,11 +1,20 @@
 # relibc ![build](https://travis-ci.org/redox-os/relibc.svg?branch=master)
-relibc is a portable POSIX C standard library written in Rust. It is under heavy development, and currently supports Redox and Linux.
+relibc is a portable POSIX C standard library written in Rust. It is under heavy development, and currently supports Redox, Linux and DragonOS.
 
 The motivation for this project is twofold: Reduce issues the redox crew was having with newlib, and create a safer alternative to a C standard library written in C. It is mainly designed to be used under redox, as an alternative to newlib, but it also supports linux syscalls via the [sc](https://crates.io/crates/sc) crate.
 
 ## Building
 Just run `make all`.
 
+### Build for DragonOS
+
+You can follow the instructions to build relibc for DragonOS:
+
+```bash
+mkdir -p sysroot/usr
+make -j $(nproc) && DESTDIR=sysroot/usr make install -j $(nproc)
+```
+
 ### Issues
 #### I'm building for my own platform which I run, and am getting `x86_64-linux-gnu-ar: command not found` (or similar)
 The Makefile expects the gnu compiler tools prefixed with the platform specifier, as would be present when you'd install a cross compiler. Since you are building for your own platform, some distros (like Manjaro) don't install/symlink the prefixed executables.
@@ -27,6 +36,7 @@ An easy fix would be to replace the corresponding lines in the Makefile, e.g.
 
  - Redox OS
  - Linux
+ - DragonOS
 
 ## Supported architectures
 

+ 11 - 4
build.rs

@@ -53,8 +53,8 @@ fn main() {
             generate_bindings(&p);
         });
 
-    cc::Build::new()
-        .flag("-nostdinc")
+    let mut c = cc::Build::new();
+    c.flag("-nostdinc")
         .flag("-nostdlib")
         .include(&format!("{}/include", crate_dir))
         .include(&format!("{}/target/include", crate_dir))
@@ -65,8 +65,15 @@ fn main() {
             fs::read_dir("src/c")
                 .expect("src/c directory missing")
                 .map(|res| res.expect("read_dir error").path()),
-        )
-        .compile("relibc_c");
+        );
+
+    #[cfg(target_os = "dragonos")]
+    {
+        // for dragonos only
+        c.define("HAVE_MMAP", "0");
+    }
+
+    c.compile("relibc_c");
 
     println!("cargo:rustc-link-lib=static=relibc_c");
 }

+ 68 - 0
init_dragonos_toolchain.sh

@@ -0,0 +1,68 @@
+# 当前脚本用于初始化自定义的Rust工具链
+if [ -z "$(which cargo)" ]; then
+    echo "尚未安装Rust,请先安装Rust"
+    exit 1
+fi
+
+# 是否强制覆盖已有的工具链配置文件
+FORCE=0
+
+while getopts "f" arg
+do
+    case $arg in
+        f)
+            FORCE=1
+            ;;
+        ?)
+            echo "unkonw argument"
+            exit 1
+        ;;
+    esac
+done
+
+DRAGONOS_UNKNOWN_ELF_PATH=$(rustc --print sysroot)/lib/rustlib/x86_64-unknown-dragonos
+mkdir -p ${DRAGONOS_UNKNOWN_ELF_PATH}/lib
+echo $DRAGONOS_UNKNOWN_ELF_PATH
+
+# 判断是否已经存在工具链配置文件
+if [ -f "${DRAGONOS_UNKNOWN_ELF_PATH}/target.json" ]; then
+    if [ $FORCE -eq 0 ]; then
+        echo "已存在工具链配置文件,如需重新初始化,请使用-f参数"
+        exit 0
+    fi
+fi
+
+# 设置工具链配置文件
+echo   \
+"{\
+    \"arch\": \"x86_64\",
+    \"code-model\": \"kernel\",
+    \"cpu\": \"x86-64\",
+    \"os\": \"dragonos\",
+    \"target-endian\": \"little\",
+    \"target-pointer-width\": \"64\",
+    \"target-c-int-width\": \"32\",
+    \"data-layout\": \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128\",
+    \"disable-redzone\": true,
+    \"features\": \"-3dnow,-3dnowa,-avx,-avx2\",
+    \"linker\": \"rust-lld\",
+    \"linker-flavor\": \"ld.lld\",
+    \"llvm-target\": \"x86_64-unknown-none\",
+    \"max-atomic-width\": 64,
+    \"panic-strategy\": \"abort\",
+    \"position-independent-executables\": true,
+    \"relro-level\": \"full\",
+    \"stack-probes\": {
+      \"kind\": \"inline-or-call\",
+      \"min-llvm-version-for-inline\": [
+        16,
+        0,
+        0
+      ]
+    },
+    \"static-position-independent-executables\": true,
+    \"supported-sanitizers\": [
+      \"kcfi\"
+    ],
+    \"target-pointer-width\": \"64\"
+}" > ${DRAGONOS_UNKNOWN_ELF_PATH}/target.json || exit 1

+ 3 - 0
src/c/dlmalloc.c

@@ -665,6 +665,7 @@ MAX_RELEASE_CHECK_RATE   default: 4095 unless not HAVE_MMAP
 #ifndef MALLOC_FAILURE_ACTION
 #define MALLOC_FAILURE_ACTION  errno = ENOMEM;
 #endif  /* MALLOC_FAILURE_ACTION */
+
 #ifndef HAVE_MORECORE
 #if ONLY_MSPACES
 #define HAVE_MORECORE 0
@@ -5445,6 +5446,7 @@ mspace create_mspace(size_t capacity, int locked) {
   return (mspace)m;
 }
 
+
 mspace create_mspace_with_base(void* base, size_t capacity, int locked) {
   mstate m = 0;
   size_t msize;
@@ -5456,6 +5458,7 @@ mspace create_mspace_with_base(void* base, size_t capacity, int locked) {
     m->seg.sflags = EXTERN_BIT;
     set_lock(m, locked);
   }
+
   return (mspace)m;
 }
 

+ 430 - 0
src/c/dragonos_malloc.c

@@ -0,0 +1,430 @@
+// Copyright (C) DragonOS Community  longjin
+
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+// Or you can visit https://www.gnu.org/licenses/gpl-2.0.html
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#define PAGE_4K_SHIFT 12
+#define PAGE_2M_SHIFT 21
+#define PAGE_1G_SHIFT 30
+#define PAGE_GDT_SHIFT 39
+
+/***************************/
+
+// 不同大小的页的容量
+#define PAGE_4K_SIZE (1UL << PAGE_4K_SHIFT)
+#define PAGE_2M_SIZE (1UL << PAGE_2M_SHIFT)
+#define PAGE_1G_SIZE (1UL << PAGE_1G_SHIFT)
+
+// 屏蔽低于x的数值
+#define PAGE_4K_MASK (~(PAGE_4K_SIZE - 1))
+#define PAGE_2M_MASK (~(PAGE_2M_SIZE - 1))
+
+#define ALIGN_UP16(x) (((x) + 15) & ~15)
+#define PAGE_ALIGN_UP(x) (((x) + PAGE_4K_SIZE - 1) & PAGE_4K_MASK)
+
+// 将addr按照x的上边界对齐
+// #define PAGE_4K_ALIGN(addr) (((unsigned long)(addr) + PAGE_4K_SIZE - 1) & PAGE_4K_MASK)
+// #define PAGE_2M_ALIGN(addr) (((unsigned long)(addr) + PAGE_2M_SIZE - 1) & PAGE_2M_MASK)
+
+/**
+ * @brief 显式链表的结点
+ *
+ */
+typedef struct malloc_mem_chunk_t
+{
+    uint64_t length; // 整个块所占用的内存区域的大小
+    uint64_t padding;
+    struct malloc_mem_chunk_t *prev; // 上一个结点的指针
+    struct malloc_mem_chunk_t *next; // 下一个结点的指针
+} malloc_mem_chunk_t;
+
+static uint64_t brk_base_addr = 0;    // 堆区域的内存基地址
+static uint64_t brk_max_addr = 0;     // 堆区域的内存最大地址
+static uint64_t brk_managed_addr = 0; // 堆区域已经被管理的地址
+
+// 空闲链表
+//  按start_addr升序排序
+static malloc_mem_chunk_t *malloc_free_list = NULL;
+static malloc_mem_chunk_t *malloc_free_list_end = NULL; // 空闲链表的末尾结点
+
+static uint64_t count_last_free_size = 0; // 统计距离上一次回收内存,已经free了多少内存
+
+/**
+ * @brief 将块插入空闲链表
+ *
+ * @param ck 待插入的块
+ */
+static void malloc_insert_free_list(malloc_mem_chunk_t *ck);
+
+/**
+ * @brief 当堆顶空闲空间大于2个页的空间的时候,释放1个页
+ *
+ */
+static void release_brk();
+
+/**
+ * @brief 在链表中检索符合要求的空闲块(best fit)
+ *
+ * @param size 块的大小
+ * @return malloc_mem_chunk_t*
+ */
+static malloc_mem_chunk_t *malloc_query_free_chunk_bf(uint64_t size)
+{
+    // 在满足best fit的前提下,尽可能的使分配的内存在低地址
+    //  使得总的堆内存可以更快被释放
+
+    if (malloc_free_list == NULL)
+    {
+        return NULL;
+    }
+    malloc_mem_chunk_t *ptr = malloc_free_list;
+    malloc_mem_chunk_t *best = NULL;
+    // printf("query size=%d", size);
+    while (ptr != NULL)
+    {
+        // printf("ptr->length=%#010lx\n", ptr->length);
+        if (ptr->length == size)
+        {
+            best = ptr;
+            break;
+        }
+
+        if (ptr->length > size)
+        {
+            if (best == NULL)
+                best = ptr;
+            else if (best->length > ptr->length)
+                best = ptr;
+        }
+        ptr = ptr->next;
+    }
+
+    return best;
+}
+
+/**
+ * @brief 在链表中检索符合要求的空闲块(first fit)
+ *
+ * @param size
+ * @return malloc_mem_chunk_t*
+ */
+static malloc_mem_chunk_t *malloc_query_free_chunk_ff(uint64_t size)
+{
+    if (malloc_free_list == NULL)
+        return NULL;
+    malloc_mem_chunk_t *ptr = malloc_free_list;
+
+    while (ptr)
+    {
+        if (ptr->length >= size)
+        {
+            return ptr;
+        }
+        ptr = ptr->next;
+    }
+
+    return NULL;
+}
+
+/**
+ * @brief 扩容malloc管理的内存区域
+ *
+ * @param size 扩大的内存大小
+ */
+static int malloc_enlarge(int64_t size)
+{
+    if (brk_base_addr == 0) // 第一次调用,需要初始化
+    {
+        brk_base_addr = sbrk(0);
+        // printf("brk_base_addr=%#018lx\n", brk_base_addr);
+        brk_managed_addr = brk_base_addr;
+        brk_max_addr = sbrk(0);
+    }
+
+    int64_t free_space = brk_max_addr - brk_managed_addr;
+    // printf("size=%ld\tfree_space=%ld\n", size, free_space);
+    if (free_space < size) // 现有堆空间不足
+    {
+        if (sbrk(PAGE_ALIGN_UP(size - free_space)) != (void *)(-1))
+            brk_max_addr = sbrk((0));
+        else
+        {
+            // put_string("malloc_enlarge(): no_mem\n", COLOR_YELLOW, COLOR_BLACK);
+            return -ENOMEM;
+        }
+
+        // printf("brk max addr = %#018lx\n", brk_max_addr);
+    }
+
+    // 扩展管理的堆空间
+    // 在新分配的内存的底部放置header
+    // printf("managed addr = %#018lx\n", brk_managed_addr);
+    malloc_mem_chunk_t *new_ck = (malloc_mem_chunk_t *)brk_managed_addr;
+    new_ck->length = brk_max_addr - brk_managed_addr;
+    // printf("new_ck->start_addr=%#018lx\tbrk_max_addr=%#018lx\tbrk_managed_addr=%#018lx\n", (uint64_t)new_ck,
+    // brk_max_addr, brk_managed_addr);
+    new_ck->prev = NULL;
+    new_ck->next = NULL;
+    brk_managed_addr = brk_max_addr;
+
+    malloc_insert_free_list(new_ck);
+
+    return 0;
+}
+
+/**
+ * @brief 合并空闲块
+ *
+ */
+static void malloc_merge_free_chunk()
+{
+    if (malloc_free_list == NULL)
+        return;
+    malloc_mem_chunk_t *ptr = malloc_free_list->next;
+    while (ptr != NULL)
+    {
+        // 内存块连续
+        if (((uint64_t)(ptr->prev) + ptr->prev->length == (uint64_t)ptr))
+        {
+            // printf("merged %#018lx  and %#018lx\n", (uint64_t)ptr, (uint64_t)(ptr->prev));
+            // 将ptr与前面的空闲块合并
+            ptr->prev->length += ptr->length;
+            ptr->prev->next = ptr->next;
+            if (ptr->next == NULL)
+                malloc_free_list_end = ptr->prev;
+            else
+                ptr->next->prev = ptr->prev;
+            // 由于内存组成结构的原因,不需要free掉header
+            ptr = ptr->prev;
+        }
+        ptr = ptr->next;
+    }
+}
+
+/**
+ * @brief 将块插入空闲链表
+ *
+ * @param ck 待插入的块
+ */
+static void malloc_insert_free_list(malloc_mem_chunk_t *ck)
+{
+    if (malloc_free_list == NULL) // 空闲链表为空
+    {
+        malloc_free_list = ck;
+        malloc_free_list_end = ck;
+        ck->prev = ck->next = NULL;
+        return;
+    }
+    else
+    {
+
+        malloc_mem_chunk_t *ptr = malloc_free_list;
+        while (ptr != NULL)
+        {
+            if ((uint64_t)ptr < (uint64_t)ck)
+            {
+                if (ptr->next == NULL) // 当前是最后一个项
+                {
+                    ptr->next = ck;
+                    ck->next = NULL;
+                    ck->prev = ptr;
+                    malloc_free_list_end = ck;
+                    break;
+                }
+                else if ((uint64_t)(ptr->next) > (uint64_t)ck)
+                {
+                    ck->prev = ptr;
+                    ck->next = ptr->next;
+                    ptr->next = ck;
+                    ck->next->prev = ck;
+                    break;
+                }
+            }
+            else // 在ptr之前插入
+            {
+
+                if (ptr->prev == NULL) // 是第一个项
+                {
+                    malloc_free_list = ck;
+                    ck->prev = NULL;
+                    ck->next = ptr;
+                    ptr->prev = ck;
+                    break;
+                }
+                else
+                {
+                    ck->prev = ptr->prev;
+                    ck->next = ptr;
+                    ck->prev->next = ck;
+                    ptr->prev = ck;
+                    break;
+                }
+            }
+            ptr = ptr->next;
+        }
+    }
+}
+
+/**
+ * @brief 获取一块堆内存
+ *
+ * @param size 内存大小
+ * @return void* 内存空间的指针
+ *
+ * 分配内存的时候,结点的prev next指针所占用的空间被当做空闲空间分配出去
+ */
+void *_dragonos_malloc(ssize_t size)
+{
+    // 计算需要分配的块的大小
+    if (size < sizeof(malloc_mem_chunk_t) - 16)
+        size = sizeof(malloc_mem_chunk_t);
+    else
+    {
+        size += 16;
+    }
+    // 16字节对齐
+    size = ALIGN_UP16(size);
+
+    // 采用best fit
+    malloc_mem_chunk_t *ck = malloc_query_free_chunk_bf(size);
+
+    if (ck == NULL) // 没有空闲块
+    {
+
+        // printf("no free blocks\n");
+        // 尝试合并空闲块
+        malloc_merge_free_chunk();
+        ck = malloc_query_free_chunk_bf(size);
+
+        // 找到了合适的块
+        if (ck)
+            goto found;
+
+        // printf("before enlarge\n");
+        // 找不到合适的块,扩容堆区域
+        if (malloc_enlarge(size) == -ENOMEM)
+            return (void *)-ENOMEM; // 内存不足
+
+        malloc_merge_free_chunk(); // 扩容后运行合并,否则会导致碎片
+
+        // 扩容后再次尝试获取
+
+        ck = malloc_query_free_chunk_bf(size);
+    }
+found:;
+
+    // printf("ck = %#018lx\n", (uint64_t)ck);
+    if (ck == NULL)
+        return (void *)-ENOMEM;
+    // printf("ck->prev=%#018lx ck->next=%#018lx\n", ck->prev, ck->next);
+    // 分配空闲块
+    // 从空闲链表取出
+    if (ck->prev == NULL) // 当前是链表的第一个块
+    {
+        malloc_free_list = ck->next;
+    }
+    else
+        ck->prev->next = ck->next;
+
+    if (ck->next != NULL) // 当前不是最后一个块
+        ck->next->prev = ck->prev;
+    else
+        malloc_free_list_end = ck->prev;
+
+    // 当前块剩余的空间还能容纳多一个结点的空间,则分裂当前块
+    if ((int64_t)(ck->length) - size > sizeof(malloc_mem_chunk_t))
+    {
+        // printf("seperate\n");
+        malloc_mem_chunk_t *new_ck = (malloc_mem_chunk_t *)(((uint64_t)ck) + size);
+        new_ck->length = ck->length - size;
+        new_ck->prev = new_ck->next = NULL;
+        // printf("new_ck=%#018lx, new_ck->length=%#010lx\n", (uint64_t)new_ck, new_ck->length);
+        ck->length = size;
+        malloc_insert_free_list(new_ck);
+    }
+    // printf("malloc done: %#018lx, length=%#018lx\n", ((uint64_t)ck + sizeof(uint64_t)), ck->length);
+    // 此时链表结点的指针的空间被分配出去
+    return (void *)((uint64_t)ck + 2 * sizeof(uint64_t));
+}
+
+/**
+ * @brief 当堆顶空闲空间大于2个页的空间的时候,释放1个页
+ *
+ */
+static void release_brk()
+{
+    // 先检测最顶上的块
+    // 由于块按照开始地址排列,因此找最后一个块
+    if (malloc_free_list_end == NULL)
+    {
+        printf("release(): free list end is null. \n");
+        return;
+    }
+    if ((uint64_t)malloc_free_list_end + malloc_free_list_end->length == brk_max_addr &&
+        (uint64_t)malloc_free_list_end <= brk_max_addr - (PAGE_2M_SIZE << 1))
+    {
+        int64_t delta = ((brk_max_addr - (uint64_t)malloc_free_list_end) & PAGE_2M_MASK) - PAGE_2M_SIZE;
+        // printf("(brk_max_addr - (uint64_t)malloc_free_list_end) & PAGE_2M_MASK=%#018lx\n ", (brk_max_addr -
+        // (uint64_t)malloc_free_list_end) & PAGE_2M_MASK); printf("PAGE_2M_SIZE=%#018lx\n", PAGE_2M_SIZE);
+        // printf("tdfghgbdfggkmfn=%#018lx\n ", (brk_max_addr - (uint64_t)malloc_free_list_end) & PAGE_2M_MASK -
+        // PAGE_2M_SIZE); printf("delta=%#018lx\n ", delta);
+        if (delta <= 0) // 不用释放内存
+            return;
+        sbrk(-delta);
+        brk_max_addr = sbrk(0);
+        brk_managed_addr = brk_max_addr;
+
+        malloc_free_list_end->length = brk_max_addr - (uint64_t)malloc_free_list_end;
+    }
+}
+/**
+ * @brief 释放一块堆内存
+ *
+ * @param ptr 堆内存的指针
+ */
+void _dragonos_free(void *ptr)
+{
+    // 找到结点(此时prev和next都处于未初始化的状态)
+    malloc_mem_chunk_t *ck = (malloc_mem_chunk_t *)((uint64_t)ptr - 2 * sizeof(uint64_t));
+    // printf("free(): addr = %#018lx\t len=%#018lx\n", (uint64_t)ck, ck->length);
+    count_last_free_size += ck->length;
+
+    malloc_insert_free_list(ck);
+
+    if (count_last_free_size > PAGE_2M_SIZE)
+    {
+        count_last_free_size = 0;
+        malloc_merge_free_chunk();
+        release_brk();
+    }
+}
+
+/**
+ * @brief 根据分配出去的指针获取堆内存块的长度
+ * 
+ * @param ptr 分配出去的指针
+ * 
+ * @return 堆内存块的长度
+*/
+uint64_t _dragonos_chunk_length(void *ptr)
+{
+    malloc_mem_chunk_t *ck = (malloc_mem_chunk_t *)((uint64_t)ptr - 2 * sizeof(uint64_t));
+    return ck->length;
+}

+ 5 - 0
src/c/unistd.c

@@ -11,19 +11,24 @@ int execl(const char *path, const char* argv0, ...)
 	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 execve(const char *path, char *const *argv, char *const *envp);

+ 1 - 7
src/header/assert/mod.rs

@@ -17,13 +17,7 @@ pub unsafe extern "C" fn __assert_fail(
     let file = CStr::from_ptr(file).to_str().unwrap();
     let cond = CStr::from_ptr(cond).to_str().unwrap();
 
-    eprintln!(
-        "{}: {}:{}: Assertion `{}` failed.",
-        func,
-        file,
-        line,
-        cond
-    );
+    eprintln!("{}: {}:{}: Assertion `{}` failed.", func, file, line, cond);
 
     core::intrinsics::abort();
 }

+ 9 - 0
src/header/errno/mod.rs

@@ -63,7 +63,10 @@ pub const ENOLCK: c_int = 37; /* No record locks available */
 pub const ENOSYS: c_int = 38; /* Function not implemented */
 pub const ENOTEMPTY: c_int = 39; /* Directory not empty */
 pub const ELOOP: c_int = 40; /* Too many symbolic links encountered */
+#[cfg(not(target_os = "dragonos"))]
 pub const EWOULDBLOCK: c_int = 41; /* Operation would block */
+#[cfg(target_os = "dragonos")]
+pub const EWOULDBLOCK: c_int = EAGAIN; /* Operation would block */
 pub const ENOMSG: c_int = 42; /* No message of desired type */
 pub const EIDRM: c_int = 43; /* Identifier removed */
 pub const ECHRNG: c_int = 44; /* Channel number out of range */
@@ -167,7 +170,10 @@ pub static STR_ERROR: [&'static str; 132] = [
     "Exec format error",
     "Bad file number",
     "No child processes",
+    #[cfg(not(target_os = "dragonos"))]
     "Try again",
+    #[cfg(target_os = "dragonos")]
+    "Try again or operation would block",
     "Out of memory",
     "Permission denied",
     "Bad address",
@@ -197,6 +203,7 @@ pub static STR_ERROR: [&'static str; 132] = [
     "Function not implemented",
     "Directory not empty",
     "Too many symbolic links encountered",
+    #[cfg(not(target_os = "dragonos"))]
     "Operation would block",
     "No message of desired type",
     "Identifier removed",
@@ -288,4 +295,6 @@ pub static STR_ERROR: [&'static str; 132] = [
     "Key was rejected by service",
     "Owner died",
     "State not recoverable",
+    #[cfg(target_os = "dragonos")]
+    "Unknown",
 ];

+ 1 - 0
src/header/fcntl/cbindgen.toml

@@ -9,6 +9,7 @@ cpp_compat = true
 [defines]
 "target_os=linux" = "__linux__"
 "target_os=redox" = "__redox__"
+"target_os=dragonos" = "__dragonos__"
 
 [enum]
 prefix_with_name = true

+ 17 - 0
src/header/fcntl/dragonos.rs

@@ -0,0 +1,17 @@
+use crate::platform::types::*;
+
+pub const O_RDONLY: c_int = 0x0000;
+pub const O_WRONLY: c_int = 0x0001;
+pub const O_RDWR: c_int = 0x0002;
+pub const O_ACCMODE: c_int = 0x0003;
+pub const O_CREAT: c_int = 0x0040;
+pub const O_EXCL: c_int = 0x0080;
+pub const O_TRUNC: c_int = 0x0200;
+pub const O_APPEND: c_int = 0x0400;
+pub const O_NONBLOCK: c_int = 0x0800;
+pub const O_DIRECTORY: c_int = 0x1_0000;
+pub const O_NOFOLLOW: c_int = 0x2_0000;
+pub const O_CLOEXEC: c_int = 0x8_0000;
+pub const O_PATH: c_int = 0x20_0000;
+
+pub const FD_CLOEXEC: c_int = 0x8_0000;

+ 4 - 0
src/header/fcntl/mod.rs

@@ -11,6 +11,10 @@ pub use self::sys::*;
 #[path = "linux.rs"]
 pub mod sys;
 
+#[cfg(target_os = "dragonos")]
+#[path = "dragonos.rs"]
+pub mod sys;
+
 #[cfg(target_os = "redox")]
 #[path = "redox.rs"]
 pub mod sys;

+ 29 - 0
src/header/netdb/dragonos.rs

@@ -0,0 +1,29 @@
+use crate::{
+    c_str::CString,
+    fs::File,
+    header::fcntl,
+    io::{BufRead, BufReader},
+};
+use alloc::string::String;
+
+pub fn get_dns_server() -> String {
+    let file = match File::open(&CString::new("/etc/resolv.conf").unwrap(), fcntl::O_RDONLY) {
+        Ok(file) => file,
+        Err(_) => return String::new(), // TODO: better error handling
+    };
+    let file = BufReader::new(file);
+
+    for line in file.split(b'\n') {
+        let mut line = match line {
+            Ok(line) => line,
+            Err(_) => return String::new(), // TODO: pls handle errors
+        };
+        if line.starts_with(b"nameserver ") {
+            line.drain(..11);
+            return String::from_utf8(line).unwrap_or_default();
+        }
+    }
+
+    // TODO: better error handling
+    String::new()
+}

+ 4 - 0
src/header/netdb/mod.rs

@@ -33,6 +33,10 @@ use crate::{
 #[path = "linux.rs"]
 pub mod sys;
 
+#[cfg(target_os = "dragonos")]
+#[path = "dragonos.rs"]
+pub mod sys;
+
 #[cfg(target_os = "redox")]
 #[path = "redox.rs"]
 pub mod sys;

+ 2 - 1
src/header/poll/mod.rs

@@ -6,7 +6,8 @@ use crate::{
     fs::File,
     header::sys_epoll::{
         epoll_create1, epoll_ctl, epoll_data, epoll_event, epoll_wait, EPOLLERR, EPOLLHUP, EPOLLIN,
-        EPOLLNVAL, EPOLLOUT, EPOLLPRI, EPOLLRDBAND, EPOLLRDNORM, EPOLLWRBAND, EPOLLWRNORM, EPOLL_CLOEXEC, EPOLL_CTL_ADD,
+        EPOLLNVAL, EPOLLOUT, EPOLLPRI, EPOLLRDBAND, EPOLLRDNORM, EPOLLWRBAND, EPOLLWRNORM,
+        EPOLL_CLOEXEC, EPOLL_CTL_ADD,
     },
     platform::types::*,
 };

+ 15 - 0
src/header/pwd/dragonos.rs

@@ -0,0 +1,15 @@
+use super::{parsed, passwd};
+use crate::platform::types::*;
+
+pub fn split(line: &mut [u8]) -> Option<passwd> {
+    let mut parts = line.split_mut(|&c| c == b'\0');
+    Some(passwd {
+        pw_name: parts.next()?.as_mut_ptr() as *mut c_char,
+        pw_passwd: parts.next()?.as_mut_ptr() as *mut c_char,
+        pw_uid: parsed(parts.next())?,
+        pw_gid: parsed(parts.next())?,
+        pw_gecos: parts.next()?.as_mut_ptr() as *mut c_char,
+        pw_dir: parts.next()?.as_mut_ptr() as *mut c_char,
+        pw_shell: parts.next()?.as_mut_ptr() as *mut c_char,
+    })
+}

+ 5 - 0
src/header/pwd/mod.rs

@@ -16,9 +16,14 @@ use crate::{
 
 #[cfg(target_os = "linux")]
 mod linux;
+
+#[cfg(target_os = "dragonos")]
+mod dragonos;
 #[cfg(target_os = "redox")]
 mod redox;
 
+#[cfg(target_os = "dragonos")]
+use self::dragonos as sys;
 #[cfg(target_os = "linux")]
 use self::linux as sys;
 #[cfg(target_os = "redox")]

+ 1 - 0
src/header/signal/cbindgen.toml

@@ -9,6 +9,7 @@ cpp_compat = true
 [defines]
 "target_os=linux" = "__linux__"
 "target_os=redox" = "__redox__"
+"target_os=dragonos" = "__dragonos__"
 
 [enum]
 prefix_with_name = true

+ 76 - 0
src/header/signal/dragonos.rs

@@ -0,0 +1,76 @@
+use core::arch::global_asm;
+
+// Needs to be defined in assembly because it can't have a function prologue
+// rax is register, 25 is RT_SIGRETURN
+#[cfg(target_arch = "x86_64")]
+global_asm!(
+    "
+    .global __restore_rt
+    __restore_rt:
+        mov rax, 25
+        int 0x80
+"
+);
+
+// x8 is register, 139 is RT_SIGRETURN
+#[cfg(target_arch = "aarch64")]
+global_asm!(
+    "
+    .global __restore_rt
+    __restore_rt:
+        mov x8, #139
+        svc 0
+"
+);
+
+pub const SIGHUP: usize = 1;
+pub const SIGINT: usize = 2;
+pub const SIGQUIT: usize = 3;
+pub const SIGILL: usize = 4;
+pub const SIGTRAP: usize = 5;
+pub const SIGABRT: usize = 6;
+pub const SIGIOT: usize = SIGABRT;
+pub const SIGBUS: usize = 7;
+pub const SIGFPE: usize = 8;
+pub const SIGKILL: usize = 9;
+pub const SIGUSR1: usize = 10;
+pub const SIGSEGV: usize = 11;
+pub const SIGUSR2: usize = 12;
+pub const SIGPIPE: usize = 13;
+pub const SIGALRM: usize = 14;
+pub const SIGTERM: usize = 15;
+pub const SIGSTKFLT: usize = 16;
+pub const SIGCHLD: usize = 17;
+pub const SIGCONT: usize = 18;
+pub const SIGSTOP: usize = 19;
+pub const SIGTSTP: usize = 20;
+pub const SIGTTIN: usize = 21;
+pub const SIGTTOU: usize = 22;
+pub const SIGURG: usize = 23;
+pub const SIGXCPU: usize = 24;
+pub const SIGXFSZ: usize = 25;
+pub const SIGVTALRM: usize = 26;
+pub const SIGPROF: usize = 27;
+pub const SIGWINCH: usize = 28;
+pub const SIGIO: usize = 29;
+pub const SIGPOLL: usize = SIGIO;
+pub const SIGPWR: usize = 30;
+pub const SIGSYS: usize = 31;
+pub const SIGUNUSED: usize = SIGSYS;
+pub const NSIG: usize = 32;
+
+pub const SA_NOCLDSTOP: usize = 1;
+pub const SA_NOCLDWAIT: usize = 2;
+pub const SA_SIGINFO: usize = 4;
+pub const SA_ONSTACK: usize = 0x0800_0000;
+pub const SA_RESTART: usize = 0x1000_0000;
+pub const SA_NODEFER: usize = 0x4000_0000;
+pub const SA_RESETHAND: usize = 0x8000_0000;
+pub const SA_RESTORER: usize = 0x0400_0000;
+
+pub const SS_ONSTACK: usize = 1;
+pub const SS_DISABLE: usize = 2;
+
+// Those two should be updated from kernel headers
+pub const MINSIGSTKSZ: usize = 2048;
+pub const SIGSTKSZ: usize = 8096;

+ 4 - 0
src/header/signal/mod.rs

@@ -15,6 +15,10 @@ pub use self::sys::*;
 #[path = "linux.rs"]
 pub mod sys;
 
+#[cfg(target_os = "dragonos")]
+#[path = "dragonos.rs"]
+pub mod sys;
+
 #[cfg(target_os = "redox")]
 #[path = "redox.rs"]
 pub mod sys;

+ 1 - 1
src/header/stdio/mod.rs

@@ -498,7 +498,7 @@ pub unsafe extern "C" fn fopen(filename: *const c_char, mode: *const c_char) ->
 /// itself.
 #[no_mangle]
 pub unsafe extern "C" fn __fpurge(stream: *mut FILE) {
-    if ! stream.is_null() {
+    if !stream.is_null() {
         let mut stream = (*stream).lock();
         stream.purge();
     }

+ 1 - 4
src/header/stdlib/mod.rs

@@ -816,14 +816,11 @@ pub unsafe extern "C" fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void
 pub unsafe extern "C" fn reallocarray(ptr: *mut c_void, m: size_t, n: size_t) -> *mut c_void {
     //Handle possible integer overflow in size calculation
     match m.checked_mul(n) {
-        Some(size) => {
-            realloc(ptr, size)
-        }
+        Some(size) => realloc(ptr, size),
         None => {
             // For overflowing multiplication, we have to set errno here
             platform::errno = ENOMEM;
             ptr::null_mut()
-
         }
     }
 }

+ 1 - 2
src/header/strings/mod.rs

@@ -1,7 +1,6 @@
 //! strings implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/strings.h.html
 
-use core::ptr;
-use core::arch;
+use core::{arch, ptr};
 
 use crate::{
     header::{ctype, string},

+ 1 - 0
src/header/sys_epoll/cbindgen.toml

@@ -7,6 +7,7 @@ cpp_compat = true
 
 [defines]
 "target_os=linux" = "__linux__"
+"target_os=dragonos" = "__dragonos__"
 "target_os=redox" = "__redox__"
 "target_pointer_width=64" = "__LP64__"
 

+ 20 - 0
src/header/sys_epoll/dragonos.rs

@@ -0,0 +1,20 @@
+use crate::platform::types::*;
+
+pub const EPOLL_CLOEXEC: c_int = 0x8_0000;
+
+pub const EPOLLIN: c_uint = 0x001;
+pub const EPOLLPRI: c_uint = 0x002;
+pub const EPOLLOUT: c_uint = 0x004;
+pub const EPOLLRDNORM: c_uint = 0x040;
+pub const EPOLLNVAL: c_uint = 0x020;
+pub const EPOLLRDBAND: c_uint = 0x080;
+pub const EPOLLWRNORM: c_uint = 0x100;
+pub const EPOLLWRBAND: c_uint = 0x200;
+pub const EPOLLMSG: c_uint = 0x400;
+pub const EPOLLERR: c_uint = 0x008;
+pub const EPOLLHUP: c_uint = 0x010;
+pub const EPOLLRDHUP: c_uint = 0x2000;
+pub const EPOLLEXCLUSIVE: c_uint = 1 << 28;
+pub const EPOLLWAKEUP: c_uint = 1 << 29;
+pub const EPOLLONESHOT: c_uint = 1 << 30;
+pub const EPOLLET: c_uint = 1 << 31;

+ 4 - 0
src/header/sys_epoll/mod.rs

@@ -13,6 +13,10 @@ pub use self::sys::*;
 #[path = "linux.rs"]
 pub mod sys;
 
+#[cfg(target_os = "dragonos")]
+#[path = "dragonos.rs"]
+pub mod sys;
+
 #[cfg(target_os = "redox")]
 #[path = "redox.rs"]
 pub mod sys;

+ 1 - 0
src/header/sys_ioctl/cbindgen.toml

@@ -7,6 +7,7 @@ cpp_compat = true
 [defines]
 "target_os=linux" = "__linux__"
 "target_os=redox" = "__redox__"
+"target_os=dragonos" = "__dragonos__"
 
 [enum]
 prefix_with_name = true

+ 195 - 0
src/header/sys_ioctl/dragonos.rs

@@ -0,0 +1,195 @@
+use crate::platform::{types::*, Sys};
+
+#[no_mangle]
+pub unsafe extern "C" fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int {
+    // TODO: Somehow support varargs to syscall??
+    Sys::ioctl(fd, request, out)
+}
+
+pub const TCGETS: c_ulong = 0x5401;
+pub const TCSETS: c_ulong = 0x5402;
+pub const TCSETSW: c_ulong = 0x5403;
+pub const TCSETSF: c_ulong = 0x5404;
+pub const TCGETA: c_ulong = 0x5405;
+pub const TCSETA: c_ulong = 0x5406;
+pub const TCSETAW: c_ulong = 0x5407;
+pub const TCSETAF: c_ulong = 0x5408;
+pub const TCSBRK: c_ulong = 0x5409;
+pub const TCXONC: c_ulong = 0x540A;
+pub const TCFLSH: c_ulong = 0x540B;
+pub const TIOCEXCL: c_ulong = 0x540C;
+pub const TIOCNXCL: c_ulong = 0x540D;
+pub const TIOCSCTTY: c_ulong = 0x540E;
+pub const TIOCGPGRP: c_ulong = 0x540F;
+pub const TIOCSPGRP: c_ulong = 0x5410;
+pub const TIOCOUTQ: c_ulong = 0x5411;
+pub const TIOCSTI: c_ulong = 0x5412;
+pub const TIOCGWINSZ: c_ulong = 0x5413;
+pub const TIOCSWINSZ: c_ulong = 0x5414;
+pub const TIOCMGET: c_ulong = 0x5415;
+pub const TIOCMBIS: c_ulong = 0x5416;
+pub const TIOCMBIC: c_ulong = 0x5417;
+pub const TIOCMSET: c_ulong = 0x5418;
+pub const TIOCGSOFTCAR: c_ulong = 0x5419;
+pub const TIOCSSOFTCAR: c_ulong = 0x541A;
+pub const FIONREAD: c_ulong = 0x541B;
+pub const TIOCINQ: c_ulong = FIONREAD;
+pub const TIOCLINUX: c_ulong = 0x541C;
+pub const TIOCCONS: c_ulong = 0x541D;
+pub const TIOCGSERIAL: c_ulong = 0x541E;
+pub const TIOCSSERIAL: c_ulong = 0x541F;
+pub const TIOCPKT: c_ulong = 0x5420;
+pub const FIONBIO: c_ulong = 0x5421;
+pub const TIOCNOTTY: c_ulong = 0x5422;
+pub const TIOCSETD: c_ulong = 0x5423;
+pub const TIOCGETD: c_ulong = 0x5424;
+pub const TCSBRKP: c_ulong = 0x5425;
+pub const TIOCSBRK: c_ulong = 0x5427;
+pub const TIOCCBRK: c_ulong = 0x5428;
+pub const TIOCGSID: c_ulong = 0x5429;
+pub const TIOCGRS485: c_ulong = 0x542E;
+pub const TIOCSRS485: c_ulong = 0x542F;
+pub const TIOCGPTN: c_ulong = 0x8004_5430;
+pub const TIOCSPTLCK: c_ulong = 0x4004_5431;
+pub const TIOCGDEV: c_ulong = 0x8004_5432;
+pub const TCGETX: c_ulong = 0x5432;
+pub const TCSETX: c_ulong = 0x5433;
+pub const TCSETXF: c_ulong = 0x5434;
+pub const TCSETXW: c_ulong = 0x5435;
+pub const TIOCSIG: c_ulong = 0x4004_5436;
+pub const TIOCVHANGUP: c_ulong = 0x5437;
+pub const TIOCGPKT: c_ulong = 0x8004_5438;
+pub const TIOCGPTLCK: c_ulong = 0x8004_5439;
+pub const TIOCGEXCL: c_ulong = 0x8004_5440;
+pub const TIOCGPTPEER: c_ulong = 0x5441;
+
+pub const FIONCLEX: c_ulong = 0x5450;
+pub const FIOCLEX: c_ulong = 0x5451;
+pub const FIOASYNC: c_ulong = 0x5452;
+pub const TIOCSERCONFIG: c_ulong = 0x5453;
+pub const TIOCSERGWILD: c_ulong = 0x5454;
+pub const TIOCSERSWILD: c_ulong = 0x5455;
+pub const TIOCGLCKTRMIOS: c_ulong = 0x5456;
+pub const TIOCSLCKTRMIOS: c_ulong = 0x5457;
+pub const TIOCSERGSTRUCT: c_ulong = 0x5458;
+pub const TIOCSERGETLSR: c_ulong = 0x5459;
+pub const TIOCSERGETMULTI: c_ulong = 0x545A;
+pub const TIOCSERSETMULTI: c_ulong = 0x545B;
+
+pub const TIOCMIWAIT: c_ulong = 0x545C;
+pub const TIOCGICOUNT: c_ulong = 0x545D;
+pub const FIOQSIZE: c_ulong = 0x5460;
+
+pub const TIOCPKT_DATA: c_ulong = 0;
+pub const TIOCPKT_FLUSHREAD: c_ulong = 1;
+pub const TIOCPKT_FLUSHWRITE: c_ulong = 2;
+pub const TIOCPKT_STOP: c_ulong = 4;
+pub const TIOCPKT_START: c_ulong = 8;
+pub const TIOCPKT_NOSTOP: c_ulong = 16;
+pub const TIOCPKT_DOSTOP: c_ulong = 32;
+pub const TIOCPKT_IOCTL: c_ulong = 64;
+
+pub const TIOCSER_TEMT: c_ulong = 0x01;
+
+pub const TIOCM_LE: c_ulong = 0x001;
+pub const TIOCM_DTR: c_ulong = 0x002;
+pub const TIOCM_RTS: c_ulong = 0x004;
+pub const TIOCM_ST: c_ulong = 0x008;
+pub const TIOCM_SR: c_ulong = 0x010;
+pub const TIOCM_CTS: c_ulong = 0x020;
+pub const TIOCM_CAR: c_ulong = 0x040;
+pub const TIOCM_RNG: c_ulong = 0x080;
+pub const TIOCM_DSR: c_ulong = 0x100;
+pub const TIOCM_CD: c_ulong = TIOCM_CAR;
+pub const TIOCM_RI: c_ulong = TIOCM_RNG;
+pub const TIOCM_OUT1: c_ulong = 0x2000;
+pub const TIOCM_OUT2: c_ulong = 0x4000;
+pub const TIOCM_LOOP: c_ulong = 0x8000;
+
+pub const N_TTY: c_ulong = 0;
+pub const N_SLIP: c_ulong = 1;
+pub const N_MOUSE: c_ulong = 2;
+pub const N_PPP: c_ulong = 3;
+pub const N_STRIP: c_ulong = 4;
+pub const N_AX25: c_ulong = 5;
+pub const N_X25: c_ulong = 6;
+pub const N_6PACK: c_ulong = 7;
+pub const N_MASC: c_ulong = 8;
+pub const N_R3964: c_ulong = 9;
+pub const N_PROFIBUS_FDL: c_ulong = 10;
+pub const N_IRDA: c_ulong = 11;
+pub const N_SMSBLOCK: c_ulong = 12;
+pub const N_HDLC: c_ulong = 13;
+pub const N_SYNC_PPP: c_ulong = 14;
+pub const N_HCI: c_ulong = 15;
+
+pub const FIOSETOWN: c_ulong = 0x8901;
+pub const SIOCSPGRP: c_ulong = 0x8902;
+pub const FIOGETOWN: c_ulong = 0x8903;
+pub const SIOCGPGRP: c_ulong = 0x8904;
+pub const SIOCATMARK: c_ulong = 0x8905;
+pub const SIOCGSTAMP: c_ulong = 0x8906;
+pub const SIOCGSTAMPNS: c_ulong = 0x8907;
+
+pub const SIOCADDRT: c_ulong = 0x890B;
+pub const SIOCDELRT: c_ulong = 0x890C;
+pub const SIOCRTMSG: c_ulong = 0x890D;
+
+pub const SIOCGIFNAME: c_ulong = 0x8910;
+pub const SIOCSIFLINK: c_ulong = 0x8911;
+pub const SIOCGIFCONF: c_ulong = 0x8912;
+pub const SIOCGIFFLAGS: c_ulong = 0x8913;
+pub const SIOCSIFFLAGS: c_ulong = 0x8914;
+pub const SIOCGIFADDR: c_ulong = 0x8915;
+pub const SIOCSIFADDR: c_ulong = 0x8916;
+pub const SIOCGIFDSTADDR: c_ulong = 0x8917;
+pub const SIOCSIFDSTADDR: c_ulong = 0x8918;
+pub const SIOCGIFBRDADDR: c_ulong = 0x8919;
+pub const SIOCSIFBRDADDR: c_ulong = 0x891a;
+pub const SIOCGIFNETMASK: c_ulong = 0x891b;
+pub const SIOCSIFNETMASK: c_ulong = 0x891c;
+pub const SIOCGIFMETRIC: c_ulong = 0x891d;
+pub const SIOCSIFMETRIC: c_ulong = 0x891e;
+pub const SIOCGIFMEM: c_ulong = 0x891f;
+pub const SIOCSIFMEM: c_ulong = 0x8920;
+pub const SIOCGIFMTU: c_ulong = 0x8921;
+pub const SIOCSIFMTU: c_ulong = 0x8922;
+pub const SIOCSIFNAME: c_ulong = 0x8923;
+pub const SIOCSIFHWADDR: c_ulong = 0x8924;
+pub const SIOCGIFENCAP: c_ulong = 0x8925;
+pub const SIOCSIFENCAP: c_ulong = 0x8926;
+pub const SIOCGIFHWADDR: c_ulong = 0x8927;
+pub const SIOCGIFSLAVE: c_ulong = 0x8929;
+pub const SIOCSIFSLAVE: c_ulong = 0x8930;
+pub const SIOCADDMULTI: c_ulong = 0x8931;
+pub const SIOCDELMULTI: c_ulong = 0x8932;
+pub const SIOCGIFINDEX: c_ulong = 0x8933;
+pub const SIOGIFINDEX: c_ulong = SIOCGIFINDEX;
+pub const SIOCSIFPFLAGS: c_ulong = 0x8934;
+pub const SIOCGIFPFLAGS: c_ulong = 0x8935;
+pub const SIOCDIFADDR: c_ulong = 0x8936;
+pub const SIOCSIFHWBROADCAST: c_ulong = 0x8937;
+pub const SIOCGIFCOUNT: c_ulong = 0x8938;
+
+pub const SIOCGIFBR: c_ulong = 0x8940;
+pub const SIOCSIFBR: c_ulong = 0x8941;
+
+pub const SIOCGIFTXQLEN: c_ulong = 0x8942;
+pub const SIOCSIFTXQLEN: c_ulong = 0x8943;
+
+pub const SIOCDARP: c_ulong = 0x8953;
+pub const SIOCGARP: c_ulong = 0x8954;
+pub const SIOCSARP: c_ulong = 0x8955;
+
+pub const SIOCDRARP: c_ulong = 0x8960;
+pub const SIOCGRARP: c_ulong = 0x8961;
+pub const SIOCSRARP: c_ulong = 0x8962;
+
+pub const SIOCGIFMAP: c_ulong = 0x8970;
+pub const SIOCSIFMAP: c_ulong = 0x8971;
+
+pub const SIOCADDDLCI: c_ulong = 0x8980;
+pub const SIOCDELDLCI: c_ulong = 0x8981;
+
+pub const SIOCDEVPRIVATE: c_ulong = 0x89F0;
+pub const SIOCPROTOPRIVATE: c_ulong = 0x89E0;

+ 4 - 0
src/header/sys_ioctl/mod.rs

@@ -27,6 +27,10 @@ pub use self::sys::*;
 #[path = "linux.rs"]
 pub mod sys;
 
+#[cfg(target_os = "dragonos")]
+#[path = "dragonos.rs"]
+pub mod sys;
+
 #[cfg(target_os = "redox")]
 #[path = "redox.rs"]
 pub mod sys;

+ 1 - 0
src/header/sys_mman/cbindgen.toml

@@ -9,6 +9,7 @@ cpp_compat = true
 [defines]
 "target_os=linux" = "__linux__"
 "target_os=redox" = "__redox__"
+"target_os=dragonos" = "__dragonos__"
 
 [enum]
 prefix_with_name = true

+ 9 - 0
src/header/sys_mman/dragonos.rs

@@ -0,0 +1,9 @@
+use crate::platform::types::*;
+
+pub const PROT_READ: c_int = 0x0001;
+pub const PROT_WRITE: c_int = 0x0002;
+pub const PROT_EXEC: c_int = 0x0004;
+pub const PROT_NONE: c_int = 0x0000;
+
+pub const MAP_FIXED: c_int = 0x0010;
+pub const MAP_FIXED_NOREPLACE: c_int = 0x100000;

+ 7 - 0
src/header/sys_mman/mod.rs

@@ -10,6 +10,10 @@ pub use self::sys::*;
 #[path = "linux.rs"]
 pub mod sys;
 
+#[cfg(target_os = "dragonos")]
+#[path = "dragonos.rs"]
+pub mod sys;
+
 #[cfg(target_os = "redox")]
 #[path = "redox.rs"]
 pub mod sys;
@@ -89,6 +93,9 @@ pub unsafe extern "C" fn munmap(addr: *mut c_void, len: size_t) -> c_int {
 #[cfg(target_os = "linux")]
 static SHM_PATH: &'static [u8] = b"/dev/shm/";
 
+#[cfg(target_os = "dragonos")]
+static SHM_PATH: &'static [u8] = b"/dev/shm/";
+
 #[cfg(target_os = "redox")]
 static SHM_PATH: &'static [u8] = b"shm:";
 

+ 1 - 0
src/header/sys_resource/cbindgen.toml

@@ -9,6 +9,7 @@ cpp_compat = true
 [defines]
 "target_os=linux" = "__linux__"
 "target_os=redox" = "__redox__"
+"target_os=dragonos" = "__dragonos__"
 
 [enum]
 prefix_with_name = true

+ 1 - 0
src/header/sys_socket/cbindgen.toml

@@ -9,6 +9,7 @@ cpp_compat = true
 [defines]
 "target_os=linux" = "__linux__"
 "target_os=redox" = "__redox__"
+"target_os=dragonos" = "__dragonos__"
 
 [enum]
 prefix_with_name = true

+ 1 - 0
src/header/termios/cbindgen.toml

@@ -8,6 +8,7 @@ cpp_compat = true
 [defines]
 "target_os=linux" = "__linux__"
 "target_os=redox" = "__redox__"
+"target_os=dragonos" = "__dragonos__"
 
 [enum]
 prefix_with_name = true

+ 113 - 0
src/header/termios/dragonos.rs

@@ -0,0 +1,113 @@
+/* c_cc { */
+pub const VINTR: usize = 0;
+pub const VQUIT: usize = 1;
+pub const VERASE: usize = 2;
+pub const VKILL: usize = 3;
+pub const VEOF: usize = 4;
+pub const VTIME: usize = 5;
+pub const VMIN: usize = 6;
+pub const VSWTC: usize = 7;
+pub const VSTART: usize = 8;
+pub const VSTOP: usize = 9;
+pub const VSUSP: usize = 10;
+pub const VEOL: usize = 11;
+pub const VREPRINT: usize = 12;
+pub const VDISCARD: usize = 13;
+pub const VWERASE: usize = 14;
+pub const VLNEXT: usize = 15;
+pub const VEOL2: usize = 16;
+pub const NCCS: usize = 32;
+/* } c_cc */
+
+/* c_iflag { */
+pub const IGNBRK: usize = 0o000_001;
+pub const BRKINT: usize = 0o000_002;
+pub const IGNPAR: usize = 0o000_004;
+pub const PARMRK: usize = 0o000_010;
+pub const INPCK: usize = 0o000_020;
+pub const ISTRIP: usize = 0o000_040;
+pub const INLCR: usize = 0o000_100;
+pub const IGNCR: usize = 0o000_200;
+pub const ICRNL: usize = 0o000_400;
+pub const IUCLC: usize = 0o001_000;
+pub const IXON: usize = 0o002_000;
+pub const IXANY: usize = 0o004_000;
+pub const IXOFF: usize = 0o010_000;
+pub const IMAXBEL: usize = 0o020_000;
+pub const IUTF8: usize = 0o040_000;
+/* } c_iflag */
+
+/* c_oflag { */
+pub const OPOST: usize = 0o000_001;
+pub const OLCUC: usize = 0o000_002;
+pub const ONLCR: usize = 0o000_004;
+pub const OCRNL: usize = 0o000_010;
+pub const ONOCR: usize = 0o000_020;
+pub const ONLRET: usize = 0o000_040;
+pub const OFILL: usize = 0o000_100;
+pub const OFDEL: usize = 0o000_200;
+
+pub const VTDLY: usize = 0o040_000;
+pub const VT0: usize = 0o000_000;
+pub const VT1: usize = 0o040_000;
+/* } c_oflag */
+
+/* c_cflag { */
+pub const B0: usize = 0o000_000;
+pub const B50: usize = 0o000_001;
+pub const B75: usize = 0o000_002;
+pub const B110: usize = 0o000_003;
+pub const B134: usize = 0o000_004;
+pub const B150: usize = 0o000_005;
+pub const B200: usize = 0o000_006;
+pub const B300: usize = 0o000_007;
+pub const B600: usize = 0o000_010;
+pub const B1200: usize = 0o000_011;
+pub const B1800: usize = 0o000_012;
+pub const B2400: usize = 0o000_013;
+pub const B4800: usize = 0o000_014;
+pub const B9600: usize = 0o000_015;
+pub const B19200: usize = 0o000_016;
+pub const B38400: usize = 0o000_017;
+
+pub const B57600: usize = 0o010_001;
+pub const B115200: usize = 0o010_002;
+pub const B230400: usize = 0o010_003;
+pub const B460800: usize = 0o010_004;
+pub const B500000: usize = 0o010_005;
+pub const B576000: usize = 0o010_006;
+pub const B921600: usize = 0o010_007;
+pub const B1000000: usize = 0o010_010;
+pub const B1152000: usize = 0o010_011;
+pub const B1500000: usize = 0o010_012;
+pub const B2000000: usize = 0o010_013;
+pub const B2500000: usize = 0o010_014;
+pub const B3000000: usize = 0o010_015;
+pub const B3500000: usize = 0o010_016;
+pub const B4000000: usize = 0o010_017;
+
+pub const CSIZE: usize = 0o000_060;
+pub const CS5: usize = 0o000_000;
+pub const CS6: usize = 0o000_020;
+pub const CS7: usize = 0o000_040;
+pub const CS8: usize = 0o000_060;
+
+pub const CSTOPB: usize = 0o000_100;
+pub const CREAD: usize = 0o000_200;
+pub const PARENB: usize = 0o000_400;
+pub const PARODD: usize = 0o001_000;
+pub const HUPCL: usize = 0o002_000;
+pub const CLOCAL: usize = 0o004_000;
+/* } c_clfag */
+
+/* c_lflag { */
+pub const ISIG: usize = 0o000_001;
+pub const ICANON: usize = 0o000_002;
+pub const ECHO: usize = 0o000_010;
+pub const ECHOE: usize = 0o000_020;
+pub const ECHOK: usize = 0o000_040;
+pub const ECHONL: usize = 0o000_100;
+pub const NOFLSH: usize = 0o000_200;
+pub const TOSTOP: usize = 0o000_400;
+pub const IEXTEN: usize = 0o100_000;
+/* } c_lflag */

+ 18 - 0
src/header/termios/mod.rs

@@ -11,6 +11,10 @@ pub use self::sys::*;
 #[path = "linux.rs"]
 pub mod sys;
 
+#[cfg(target_os = "dragonos")]
+#[path = "dragonos.rs"]
+pub mod sys;
+
 #[cfg(target_os = "redox")]
 #[path = "redox.rs"]
 pub mod sys;
@@ -46,6 +50,20 @@ pub struct termios {
     __c_ospeed: speed_t,
 }
 
+#[cfg(target_os = "dragonos")]
+#[repr(C)]
+#[derive(Default)]
+pub struct termios {
+    c_iflag: tcflag_t,
+    c_oflag: tcflag_t,
+    c_cflag: tcflag_t,
+    c_lflag: tcflag_t,
+    c_line: cc_t,
+    c_cc: [cc_t; NCCS],
+    __c_ispeed: speed_t,
+    __c_ospeed: speed_t,
+}
+
 // Must match structure in redox_termios
 #[cfg(target_os = "redox")]
 #[repr(C)]

+ 1 - 0
src/header/time/cbindgen.toml

@@ -11,3 +11,4 @@ prefix_with_name = true
 [defines]
 "target_os = linux" = "__linux__"
 "target_os = redox" = "__redox__"
+"target_os = dragonos" = "__dragonos__"

+ 4 - 0
src/header/time/constants.rs

@@ -6,6 +6,10 @@ pub use self::sys::*;
 #[path = "linux.rs"]
 pub mod sys;
 
+#[cfg(target_os = "dragonos")]
+#[path = "dragonos.rs"]
+pub mod sys;
+
 #[cfg(target_os = "redox")]
 #[path = "redox.rs"]
 pub mod sys;

+ 13 - 0
src/header/time/dragonos.rs

@@ -0,0 +1,13 @@
+use crate::platform::types::*;
+
+pub const CLOCK_REALTIME: c_int = 0;
+pub const CLOCK_MONOTONIC: c_int = 1;
+pub const CLOCK_PROCESS_CPUTIME_ID: c_int = 2;
+pub const CLOCK_THREAD_CPUTIME_ID: c_int = 3;
+pub const CLOCK_MONOTONIC_RAW: c_int = 4;
+pub const CLOCK_REALTIME_COARSE: c_int = 5;
+pub const CLOCK_MONOTONIC_COARSE: c_int = 6;
+pub const CLOCK_BOOTTIME: c_int = 7;
+pub const CLOCK_REALTIME_ALARM: c_int = 8;
+pub const CLOCK_BOOTTIME_ALARM: c_int = 9;
+pub const CLOCK_TAI: c_int = 11;

+ 1 - 0
src/header/unistd/cbindgen.toml

@@ -12,3 +12,4 @@ prefix_with_name = true
 [defines]
 "target_os = linux" = "__linux__"
 "target_os = redox" = "__redox__"
+"target_os = dragonos" = "__dragonos__"

+ 8 - 0
src/header/unistd/mod.rs

@@ -37,9 +37,14 @@ pub const STDIN_FILENO: c_int = 0;
 pub const STDOUT_FILENO: c_int = 1;
 pub const STDERR_FILENO: c_int = 2;
 
+#[cfg(not(target_os = "dragonos"))]
 #[thread_local]
 pub static mut fork_hooks_static: Option<[LinkedList<extern "C" fn()>; 3]> = None;
 
+/// due to dragonos not supporting thread_local, we need to use a static directly
+#[cfg(target_os = "dragonos")]
+pub static mut fork_hooks_static: Option<[LinkedList<extern "C" fn()>; 3]> = None;
+
 unsafe fn init_fork_hooks<'a>() -> &'a mut [LinkedList<extern "C" fn()>; 3] {
     // Transmute the lifetime so we can return here. Should be safe as
     // long as one does not access the original fork_hooks.
@@ -171,6 +176,9 @@ pub unsafe extern "C" fn execve(
 #[cfg(target_os = "linux")]
 const PATH_SEPARATOR: u8 = b':';
 
+#[cfg(target_os = "dragonos")]
+const PATH_SEPARATOR: u8 = b':';
+
 #[cfg(target_os = "redox")]
 const PATH_SEPARATOR: u8 = b';';
 

+ 7 - 0
src/ld_so/access.rs

@@ -21,6 +21,13 @@ unsafe fn access(path: *const c_char, mode: c_int) -> c_int {
     syscall!(ACCESS, (path).as_ptr(), mode) as c_int
 }
 
+#[cfg(target_os = "dragonos")]
+unsafe fn access(path: *const c_char, mode: c_int) -> c_int {
+    // let path = CStr::from_ptr(path);
+    // syscall!(ACCESS, (path).as_ptr(), mode) as c_int
+    return -1;
+}
+
 // Wrapper over the systemcall, Do not use outside of ld_so
 #[cfg(target_os = "redox")]
 unsafe fn access(path: *const c_char, mode: c_int) -> c_int {

+ 248 - 0
src/ld_so/ld_script/x86_64-unknown-dragonos.ld

@@ -0,0 +1,248 @@
+/* Script for -z combreloc */
+/* Copyright (C) 2014-2020 Free Software Foundation, Inc.
+   Copying and distribution of this script, with or without modification,
+   are permitted in any medium without royalty provided the copyright
+   notice and this notice are preserved.  */
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
+              "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64");
+SEARCH_DIR("/usr/lib64/binutils/x86_64-pc-linux-gnu/2.33.164");
+SEARCH_DIR("/usr/local/lib64");
+SEARCH_DIR("/lib64");
+SEARCH_DIR("/usr/lib64");
+SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib");
+SEARCH_DIR("/usr/lib64/binutils/x86_64-pc-linux-gnu/2.33.1");
+SEARCH_DIR("/usr/local/lib");
+SEARCH_DIR("/lib");
+SEARCH_DIR("/usr/lib");
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x20000000) + SIZEOF_HEADERS;
+  .interp         : { *(.interp) }
+  .note.gnu.build-id  : { *(.note.gnu.build-id) }
+  .hash           : { *(.hash) }
+  .gnu.hash       : { *(.gnu.hash) }
+  .dynsym         : { *(.dynsym) }
+  .dynstr         : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rela.dyn       :
+    {
+      *(.rela.init)
+      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+      *(.rela.fini)
+      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+      *(.rela.ctors)
+      *(.rela.dtors)
+      *(.rela.got)
+      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+      *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
+      *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
+      *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
+      *(.rela.ifunc)
+    }
+  .rela.plt       :
+    {
+      *(.rela.plt)
+      PROVIDE_HIDDEN (__rela_iplt_start = .);
+      *(.rela.iplt)
+      PROVIDE_HIDDEN (__rela_iplt_end = .);
+    }
+  . = ALIGN(CONSTANT (MAXPAGESIZE));
+  .init           :
+  {
+    KEEP (*(SORT_NONE(.init)))
+  }
+  .plt            : { *(.plt) *(.iplt) }
+.plt.got        : { *(.plt.got) }
+.plt.sec        : { *(.plt.sec) }
+  .text           :
+  {
+    *(.text.unlikely .text.*_unlikely .text.unlikely.*)
+    *(.text.exit .text.exit.*)
+    *(.text.startup .text.startup.*)
+    *(.text.hot .text.hot.*)
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    /* .gnu.warning sections are handled specially by elf.em.  */
+    *(.gnu.warning)
+  }
+  .fini           :
+  {
+    KEEP (*(SORT_NONE(.fini)))
+  }
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  . = ALIGN(CONSTANT (MAXPAGESIZE));
+  /* Adjust the address for the rodata segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = SEGMENT_START("rodata-segment", ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)));
+  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1        : { *(.rodata1) }
+  .eh_frame_hdr   : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
+  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
+  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
+  .gnu_extab   : ONLY_IF_RO { *(.gnu_extab*) }
+  /* These sections are generated by the Sun/Oracle C++ compiler.  */
+  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges*) }
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
+  /* Exception handling  */
+  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
+  .gnu_extab      : ONLY_IF_RW { *(.gnu_extab) }
+  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges*) }
+  /* Thread Local Storage sections  */
+  .tdata          :
+   {
+     PROVIDE_HIDDEN (__tdata_start = .);
+     *(.tdata .tdata.* .gnu.linkonce.td.*)
+   }
+  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+  .preinit_array    :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+  }
+  .init_array    :
+  {
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
+    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
+    PROVIDE_HIDDEN (__init_array_end = .);
+  }
+  .fini_array    :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
+    KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  }
+  .ctors          :
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*crtbegin?.o(.ctors))
+    /* We don't want to include the .ctor section from
+       the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+  .dtors          :
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*crtbegin?.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+  .jcr            : { KEEP (*(.jcr)) }
+  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
+  .dynamic        : { *(.dynamic) }
+  .got            : { *(.got) *(.igot) }
+  . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
+  .got.plt        : { *(.got.plt) *(.igot.plt) }
+  .data           :
+  {
+    *(.data .data.* .gnu.linkonce.d.*)
+    SORT(CONSTRUCTORS)
+  }
+  .data1          : { *(.data1) }
+  _edata = .; PROVIDE (edata = .);
+  . = .;
+  __bss_start = .;
+  .bss            :
+  {
+   *(.dynbss)
+   *(.bss .bss.* .gnu.linkonce.b.*)
+   *(COMMON)
+   /* Align here to ensure that the .bss section occupies space up to
+      _end.  Align after .bss to ensure correct alignment even if the
+      .bss section disappears because there are no input sections.
+      FIXME: Why do we need it? When there is no .bss section, we do not
+      pad the .data section.  */
+   . = ALIGN(. != 0 ? 64 / 8 : 1);
+  }
+  .lbss   :
+  {
+    *(.dynlbss)
+    *(.lbss .lbss.* .gnu.linkonce.lb.*)
+    *(LARGE_COMMON)
+  }
+  . = ALIGN(64 / 8);
+  . = SEGMENT_START("ldata-segment", .);
+  .lrodata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
+  {
+    *(.lrodata .lrodata.* .gnu.linkonce.lr.*)
+  }
+  .ldata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
+  {
+    *(.ldata .ldata.* .gnu.linkonce.l.*)
+    . = ALIGN(. != 0 ? 64 / 8 : 1);
+  }
+  . = ALIGN(64 / 8);
+  _end = .; PROVIDE (end = .);
+  . = DATA_SEGMENT_END (.);
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line .debug_line.* .debug_line_end) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* DWARF 3 */
+  .debug_pubtypes 0 : { *(.debug_pubtypes) }
+  .debug_ranges   0 : { *(.debug_ranges) }
+  /* DWARF Extension.  */
+  .debug_macro    0 : { *(.debug_macro) }
+  .debug_addr     0 : { *(.debug_addr) }
+  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}

+ 11 - 1
src/ld_so/mod.rs

@@ -14,6 +14,9 @@ pub const PATH_SEP: char = ';';
 #[cfg(target_os = "linux")]
 pub const PATH_SEP: char = ':';
 
+#[cfg(target_os = "dragonos")]
+pub const PATH_SEP: char = ':';
+
 mod access;
 pub mod callbacks;
 pub mod debug;
@@ -138,7 +141,7 @@ pub fn static_init(sp: &'static Stack) {
     }
 }
 
-#[cfg(any(target_os = "linux", target_os = "redox"))]
+#[cfg(any(target_os = "linux", target_os = "redox", target_os = "dragonos"))]
 pub unsafe fn init(sp: &'static Stack) {
     let mut tp = 0usize;
 
@@ -147,6 +150,12 @@ pub unsafe fn init(sp: &'static Stack) {
         const ARCH_GET_FS: usize = 0x1003;
         syscall!(ARCH_PRCTL, ARCH_GET_FS, &mut tp as *mut usize);
     }
+    #[cfg(target_os = "dragonos")]
+    {
+        const ARCH_GET_FS: usize = 0x1003;
+        // syscall!(ARCH_PRCTL, ARCH_GET_FS, &mut tp as *mut usize);
+        // unimplemented!()
+    }
     #[cfg(all(target_os = "redox", target_arch = "aarch64"))]
     {
         core::arch::asm!(
@@ -187,6 +196,7 @@ pub unsafe fn init(sp: &'static Stack) {
         tp = env.fsbase as usize;
     }
 
+    #[cfg(not(target_os = "dragonos"))]
     if tp == 0 {
         static_init(sp);
     }

+ 46 - 7
src/ld_so/src/lib.rs

@@ -4,17 +4,20 @@
 use core::arch::global_asm;
 
 #[cfg(target_arch = "aarch64")]
-global_asm!("
+global_asm!(
+    "
 .globl _start
 _start:
     mov x0, sp
     bl relibc_ld_so_start
     # TODO: aarch64
     udf #0
-");
+"
+);
 
 #[cfg(target_arch = "x86")]
-global_asm!("
+global_asm!(
+    "
 .globl _start
 _start:
     push esp
@@ -22,10 +25,12 @@ _start:
     pop esp
     # TODO: x86
     ud2
-");
+"
+);
 
-#[cfg(target_arch = "x86_64")]
-global_asm!("
+#[cfg(all(target_arch = "x86_64", not(target_os = "dragonos")))]
+global_asm!(
+    "
 .globl _start
 _start:
     # rsi = _start + 5
@@ -53,7 +58,41 @@ _start:
     xor r11, r11
     fninit
     jmp rax
-");
+"
+);
+
+#[cfg(all(target_arch = "x86_64", target_os = "dragonos"))]
+global_asm!(
+    "
+.globl _start
+_start:
+    # rsi = _start + 5
+    call 2f
+2:  pop rsi
+
+    # Save original stack and align stack to 16 bytes
+    mov rbp, rsp
+    and rsp, 0xFFFFFFFFFFFFFFF0
+
+    # Call ld_so_start(stack, entry)
+    mov rdi, rbp
+    sub rsi, 5
+    # call relibc_ld_so_start
+
+    # Restore original stack, clear registers, and jump to new start function
+    mov rsp, rbp
+    xor rcx, rcx
+    xor rdx, rdx
+    xor rdi, rdi
+    xor rsi, rsi
+    xor r8, r8
+    xor r9, r9
+    xor r10, r10
+    xor r11, r11
+    fninit
+    jmp rax
+"
+);
 
 #[no_mangle]
 pub unsafe extern "C" fn main(_argc: isize, _argv: *const *const i8) -> usize {

+ 17 - 1
src/ld_so/tcb.rs

@@ -1,3 +1,4 @@
+use crate::println;
 use alloc::vec::Vec;
 use core::{arch::asm, mem, ptr, slice};
 use goblin::error::{Error, Result};
@@ -78,6 +79,7 @@ impl Tcb {
     }
 
     /// Get the current TCB
+    #[cfg(not(target_os = "dragonos"))]
     pub unsafe fn current() -> Option<&'static mut Self> {
         let tcb_ptr = Self::arch_read(offset_of!(Self, tcb_ptr)) as *mut Self;
         let tcb_len = Self::arch_read(offset_of!(Self, tcb_len));
@@ -88,6 +90,12 @@ impl Tcb {
         }
     }
 
+    /// Not yet implemented for dragonos
+    #[cfg(target_os = "dragonos")]
+    pub unsafe fn current() -> Option<&'static mut Self> {
+        return None;
+    }
+
     /// A slice for all of the TLS data
     pub unsafe fn tls(&self) -> Option<&'static mut [u8]> {
         if self.tls_end.is_null() || self.tls_len == 0 {
@@ -194,7 +202,7 @@ impl Tcb {
     }
 
     /// OS specific code to create a new TLS and TCB - Linux and Redox
-    #[cfg(any(target_os = "linux", target_os = "redox"))]
+    #[cfg(any(target_os = "linux", target_os = "redox", target_os = "dragonos"))]
     unsafe fn os_new(
         size: usize,
     ) -> Result<(&'static mut [u8], &'static mut [u8], &'static mut [u8])> {
@@ -256,6 +264,14 @@ impl Tcb {
         syscall!(ARCH_PRCTL, ARCH_SET_FS, tls_end);
     }
 
+    /// OS and architecture specific code to activate TLS - DragonOS x86_64
+    #[cfg(all(target_os = "dragonos", target_arch = "x86_64"))]
+    unsafe fn os_arch_activate(tls_end: usize, _tls_len: usize) {
+        const ARCH_SET_FS: usize = 0x1002;
+        // syscall!(ARCH_PRCTL, ARCH_SET_FS, tls_end);
+        unimplemented!()
+    }
+
     /// OS and architecture specific code to activate TLS - Redox aarch64
     #[cfg(all(target_os = "redox", target_arch = "aarch64"))]
     unsafe fn os_arch_activate(tls_end: usize, tls_len: usize) {

+ 6 - 0
src/lib.rs

@@ -15,6 +15,7 @@
 #![feature(stmt_expr_attributes)]
 #![feature(str_internals)]
 #![feature(thread_local)]
+#![feature(vec_into_raw_parts)]
 #![allow(clippy::cast_lossless)]
 #![allow(clippy::cast_ptr_alignment)]
 #![allow(clippy::derive_hash_xor_eq)]
@@ -40,6 +41,11 @@ extern crate rand;
 #[macro_use]
 extern crate sc;
 
+// TODO: fix this: adjust to dragonos sc
+#[cfg(target_os = "dragonos")]
+#[macro_use]
+extern crate dsc;
+
 #[cfg(target_os = "redox")]
 extern crate syscall;
 

+ 25 - 0
src/platform/allocator/dlmalloc.rs

@@ -8,6 +8,7 @@ use super::types::*;
 
 extern "C" {
     fn create_mspace(capacity: size_t, locked: c_int) -> usize;
+    fn create_mspace_with_base(base: *mut c_void, capacity: size_t, locked: c_int) -> usize;
     fn mspace_malloc(msp: usize, bytes: size_t) -> *mut c_void;
     fn mspace_memalign(msp: usize, alignment: size_t, bytes: size_t) -> *mut c_void;
     fn mspace_realloc(msp: usize, oldmem: *mut c_void, bytes: size_t) -> *mut c_void;
@@ -30,10 +31,12 @@ impl Allocator {
     pub fn set_book_keeper(&self, mstate: usize) {
         self.mstate.store(mstate, Ordering::Relaxed);
     }
+
     pub fn get_book_keeper(&self) -> usize {
         self.mstate.load(Ordering::Relaxed)
     }
 }
+
 unsafe impl<'a> GlobalAlloc for Allocator {
     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
         alloc_align(layout.size(), layout.align()) as *mut u8
@@ -60,6 +63,28 @@ pub unsafe fn free(ptr: *mut c_void) {
     mspace_free(ALLOCATOR.get_book_keeper(), ptr)
 }
 
+#[cfg(not(target_os = "dragonos"))]
 pub fn new_mspace() -> usize {
     unsafe { create_mspace(0, 0) }
 }
+
+#[cfg(target_os = "dragonos")]
+pub fn new_mspace() -> usize {
+    use core::sync::atomic::AtomicU8;
+
+    use crate::header::stdlib::malloc;
+
+    static mut space: [[u8; 128 * 16]; 2] = [[0; 128 * 16]; 2];
+    static cnt: AtomicU8 = AtomicU8::new(0);
+    let x = cnt.fetch_add(1, Ordering::Relaxed);
+    if x > 2 {
+        panic!("new_mspace: too many mspace");
+    }
+    //println!("I am here");
+    //println!("{:#?}",unsafe{space[x as usize].as_mut_ptr()});
+    let r = unsafe {
+        create_mspace_with_base(space[x as usize].as_mut_ptr() as *mut c_void, 128 * 16, 0)
+    };
+    println!("new_mspace: {:#018x}", r);
+    return r;
+}

+ 98 - 0
src/platform/allocator/dragonos_malloc.rs

@@ -0,0 +1,98 @@
+use crate::ALLOCATOR;
+use core::{
+    alloc::{GlobalAlloc, Layout},
+    ptr::null_mut,
+    sync::atomic::{AtomicUsize, Ordering},
+};
+
+use super::types::*;
+
+extern "C" {
+    fn _dragonos_free(ptr: *mut c_void) -> *mut c_void;
+    fn _dragonos_malloc(size: usize) -> *mut c_void;
+    fn _dragonos_chunk_length(ptr: *mut c_void) -> usize;
+}
+
+pub struct Allocator {
+    mstate: AtomicUsize,
+}
+
+pub const NEWALLOCATOR: Allocator = Allocator {
+    mstate: AtomicUsize::new(0),
+};
+
+impl Allocator {
+    pub fn set_book_keeper(&self, mstate: usize) {
+        self.mstate.store(mstate, Ordering::Relaxed);
+    }
+    pub fn get_book_keeper(&self) -> usize {
+        self.mstate.load(Ordering::Relaxed)
+    }
+}
+
+unsafe impl<'a> GlobalAlloc for Allocator {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        alloc(layout.size()) as *mut u8
+        //alloc_align(layout.size(), layout.align()) as *mut u8
+    }
+
+    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
+        free(ptr as *mut c_void);
+    }
+}
+
+pub unsafe fn alloc(size: usize) -> *mut c_void {
+    // println!("alloc size: {}", size);
+    _dragonos_malloc(size)
+    //mspace_malloc(ALLOCATOR.get_book_keeper(), size)
+}
+
+fn align_up(addr: usize, align: usize) -> usize {
+    (addr + align - 1) & !(align - 1)
+}
+pub unsafe fn alloc_align(mut size: usize, alignment: usize) -> *mut c_void {
+    // println!("alloc align size: {}, alignment: {}", size, alignment);
+    size = align_up(size, alignment);
+
+    // TODO: 实现对齐分配
+    _dragonos_malloc(size)
+    //mspace_memalign(ALLOCATOR.get_book_keeper(), alignment, size)
+}
+
+pub unsafe fn realloc(ptr: *mut c_void, size: size_t) -> *mut c_void {
+    if ptr.is_null() {
+        return alloc(size);
+    }
+    if size == 0 {
+        free(ptr);
+        return null_mut();
+    }
+
+    let old_len = _dragonos_chunk_length(ptr) - 16;
+
+    // 暴力实现
+
+    let new_ptr = alloc(size);
+    if new_ptr.is_null() {
+        return null_mut();
+    }
+
+    let copy_len = if old_len < size { old_len } else { size };
+    core::ptr::copy_nonoverlapping(ptr, new_ptr, copy_len);
+
+    free(ptr);
+
+    return new_ptr;
+}
+
+pub unsafe fn free(ptr: *mut c_void) {
+    // println!("free ptr: {:#018x}", ptr as usize);
+    _dragonos_free(ptr);
+    //mspace_free(ALLOCATOR.get_book_keeper(), ptr)
+}
+
+#[cfg(target_os = "dragonos")]
+pub fn new_mspace() -> usize {
+    // dbg!("new_mspace");
+    1
+}

+ 37 - 0
src/platform/dragonos/epoll.rs

@@ -0,0 +1,37 @@
+use super::{
+    super::{types::*, PalEpoll},
+    e, Sys,
+};
+use crate::header::{signal::sigset_t, sys_epoll::epoll_event};
+
+impl PalEpoll for Sys {
+    fn epoll_create1(flags: c_int) -> c_int {
+        // unsafe { e(syscall!(EPOLL_CREATE1, flags)) as c_int }
+        unimplemented!()
+    }
+
+    fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> c_int {
+        // unsafe { e(syscall!(EPOLL_CTL, epfd, op, fd, event)) as c_int }
+        unimplemented!()
+    }
+
+    fn epoll_pwait(
+        epfd: c_int,
+        events: *mut epoll_event,
+        maxevents: c_int,
+        timeout: c_int,
+        sigmask: *const sigset_t,
+    ) -> c_int {
+        // unsafe {
+        //     e(syscall!(
+        //         EPOLL_PWAIT,
+        //         epfd,
+        //         events,
+        //         maxevents,
+        //         timeout,
+        //         sigmask
+        //     )) as c_int
+        // }
+        unimplemented!()
+    }
+}

+ 555 - 0
src/platform/dragonos/mod.rs

@@ -0,0 +1,555 @@
+use core::{arch::asm, ptr};
+use core_io::Write;
+
+use super::{errno, types::*, Pal};
+use crate::{
+    c_str::CStr,
+    header::{dirent::dirent, errno::ENOSYS, signal::SIGCHLD, sys_stat::S_IFIFO},
+};
+// use header::sys_resource::rusage;
+use crate::header::{
+    sys_resource::rlimit,
+    sys_stat::stat,
+    sys_statvfs::statvfs,
+    sys_time::{timeval, timezone},
+};
+// use header::sys_times::tms;
+use crate::header::{sys_utsname::utsname, time::timespec};
+
+mod epoll;
+mod ptrace;
+mod signal;
+mod socket;
+
+const AT_FDCWD: c_int = -100;
+const AT_EMPTY_PATH: c_int = 0x1000;
+const AT_REMOVEDIR: c_int = 0x200;
+
+const SYS_CLONE: usize = 56;
+const CLONE_VM: usize = 0x0100;
+const CLONE_FS: usize = 0x0200;
+const CLONE_FILES: usize = 0x0400;
+const CLONE_SIGHAND: usize = 0x0800;
+const CLONE_THREAD: usize = 0x00010000;
+
+#[repr(C)]
+#[derive(Default)]
+struct linux_statfs {
+    f_type: c_long,       /* type of file system (see below) */
+    f_bsize: c_long,      /* optimal transfer block size */
+    f_blocks: fsblkcnt_t, /* total data blocks in file system */
+    f_bfree: fsblkcnt_t,  /* free blocks in fs */
+    f_bavail: fsblkcnt_t, /* free blocks available to unprivileged user */
+    f_files: fsfilcnt_t,  /* total file nodes in file system */
+    f_ffree: fsfilcnt_t,  /* free file nodes in fs */
+    f_fsid: c_long,       /* file system id */
+    f_namelen: c_long,    /* maximum length of filenames */
+    f_frsize: c_long,     /* fragment size (since Linux 2.6) */
+    f_flags: c_long,
+    f_spare: [c_long; 4],
+}
+
+pub fn e(sys: usize) -> usize {
+    if (sys as isize) < 0 && (sys as isize) >= -256 {
+        unsafe {
+            errno = -(sys as isize) as c_int;
+        }
+        !0
+    } else {
+        sys
+    }
+}
+
+pub struct Sys;
+
+impl Sys {
+    // fn getrusage(who: c_int, r_usage: *mut rusage) -> c_int {
+    //     e(unsafe { syscall!(GETRUSAGE, who, r_usage) }) as c_int
+    // }
+
+    pub unsafe fn ioctl(fd: c_int, request: c_ulong, out: *mut c_void) -> c_int {
+        // TODO: Somehow support varargs to syscall??
+        // e(syscall!(IOCTL, fd, request, out)) as c_int
+        unimplemented!()
+    }
+
+    // fn times(out: *mut tms) -> clock_t {
+    //     unsafe { syscall!(TIMES, out) as clock_t }
+    // }
+}
+
+impl Pal for Sys {
+    fn access(path: &CStr, mode: c_int) -> c_int {
+        // e(unsafe { syscall!(ACCESS, path.as_ptr(), mode) }) as c_int
+        unimplemented!()
+    }
+
+    fn brk(addr: *mut c_void) -> *mut c_void {
+        unsafe { syscall!(SYS_BRK, addr) as *mut c_void }
+    }
+
+    fn chdir(path: &CStr) -> c_int {
+        e(unsafe { syscall!(SYS_CHDIR, path.as_ptr()) }) as c_int
+    }
+
+    fn chmod(path: &CStr, mode: mode_t) -> c_int {
+        // e(unsafe { syscall!(FCHMODAT, AT_FDCWD, path.as_ptr(), mode, 0) }) as c_int
+        return 0;
+    }
+
+    fn chown(path: &CStr, owner: uid_t, group: gid_t) -> c_int {
+        // e(unsafe {
+        //     syscall!(
+        //         FCHOWNAT,
+        //         AT_FDCWD,
+        //         path.as_ptr(),
+        //         owner as u32,
+        //         group as u32
+        //     )
+        // }) as c_int
+        return 0;
+    }
+
+    fn clock_gettime(clk_id: clockid_t, tp: *mut timespec) -> c_int {
+        // e(unsafe { syscall!(CLOCK_GETTIME, clk_id, tp) }) as c_int
+        // unimplemented!()
+        return -ENOSYS;
+    }
+
+    fn close(fildes: c_int) -> c_int {
+        e(unsafe { syscall!(SYS_CLOSE, fildes) }) as c_int
+    }
+
+    fn dup(fildes: c_int) -> c_int {
+        e(unsafe { syscall!(SYS_DUP, fildes) }) as c_int
+    }
+
+    fn dup2(fildes: c_int, fildes2: c_int) -> c_int {
+        e(unsafe { syscall!(SYS_DUP2, fildes, fildes2) }) as c_int
+    }
+
+    unsafe fn execve(path: &CStr, argv: *const *mut c_char, envp: *const *mut c_char) -> c_int {
+        e(syscall!(SYS_EXECVE, path.as_ptr(), argv, envp)) as c_int
+    }
+
+    fn exit(status: c_int) -> ! {
+        unsafe {
+            syscall!(SYS_EXIT, status);
+        }
+        loop {}
+    }
+
+    fn fchdir(fildes: c_int) -> c_int {
+        // e(unsafe { syscall!(FCHDIR, fildes) }) as c_int
+        unimplemented!()
+    }
+
+    fn fchmod(fildes: c_int, mode: mode_t) -> c_int {
+        // e(unsafe { syscall!(FCHMOD, fildes, mode) }) as c_int
+        return 0;
+    }
+
+    fn fchown(fildes: c_int, owner: uid_t, group: gid_t) -> c_int {
+        // e(unsafe { syscall!(FCHOWN, fildes, owner, group) }) as c_int
+        return 0;
+    }
+
+    fn flock(fd: c_int, operation: c_int) -> c_int {
+        // e(unsafe { syscall!(FLOCK, fd, operation) }) as c_int
+        return 0;
+    }
+
+    fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
+        // let empty = b"\0";
+        // let empty_ptr = empty.as_ptr() as *const c_char;
+        // e(unsafe { syscall!(NEWFSTATAT, fildes, empty_ptr, buf, AT_EMPTY_PATH) }) as c_int
+        // unimplemented!()
+        e(unsafe { syscall!(SYS_FSTAT, fildes, buf) }) as c_int
+    }
+
+    fn fstatvfs(fildes: c_int, buf: *mut statvfs) -> c_int {
+        // let mut kbuf = linux_statfs::default();
+        // let kbuf_ptr = &mut kbuf as *mut linux_statfs;
+        // let res = e(unsafe { syscall!(FSTATFS, fildes, kbuf_ptr) }) as c_int;
+        // if res == 0 {
+        //     unsafe {
+        //         if !buf.is_null() {
+        //             (*buf).f_bsize = kbuf.f_bsize as c_ulong;
+        //             (*buf).f_frsize = if kbuf.f_frsize != 0 {
+        //                 kbuf.f_frsize
+        //             } else {
+        //                 kbuf.f_bsize
+        //             } as c_ulong;
+        //             (*buf).f_blocks = kbuf.f_blocks;
+        //             (*buf).f_bfree = kbuf.f_bfree;
+        //             (*buf).f_bavail = kbuf.f_bavail;
+        //             (*buf).f_files = kbuf.f_files;
+        //             (*buf).f_ffree = kbuf.f_ffree;
+        //             (*buf).f_favail = kbuf.f_ffree;
+        //             (*buf).f_fsid = kbuf.f_fsid as c_ulong;
+        //             (*buf).f_flag = kbuf.f_flags as c_ulong;
+        //             (*buf).f_namemax = kbuf.f_namelen as c_ulong;
+        //         }
+        //     }
+        // }
+        // res
+
+        unimplemented!()
+    }
+
+    fn fcntl(fildes: c_int, cmd: c_int, arg: c_int) -> c_int {
+        let rc = e(unsafe { syscall!(SYS_FCNTL, fildes, cmd, arg) }) as c_int;
+        // println!("fcntl: fildes: {}, cmd: {}, arg: {}, rc: {}", fildes, cmd, arg, rc);
+        return rc;
+    }
+
+    fn fork() -> pid_t {
+        // e(unsafe { syscall!(CLONE, SIGCHLD, 0, 0, 0, 0) }) as pid_t
+        e(unsafe { syscall!(SYS_FORK) }) as pid_t
+    }
+
+    fn fpath(fildes: c_int, out: &mut [u8]) -> ssize_t {
+        // let mut proc_path = b"/proc/self/fd/".to_vec();
+        // write!(proc_path, "{}", fildes).unwrap();
+        // proc_path.push(0);
+
+        // Self::readlink(CStr::from_bytes_with_nul(&proc_path).unwrap(), out)
+        unimplemented!()
+    }
+
+    fn fsync(fildes: c_int) -> c_int {
+        // e(unsafe { syscall!(FSYNC, fildes) }) as c_int
+        return 0;
+    }
+
+    fn ftruncate(fildes: c_int, length: off_t) -> c_int {
+        e(unsafe { syscall!(SYS_FTRUNCATE, fildes, length) }) as c_int
+    }
+
+    fn futex(addr: *mut c_int, op: c_int, val: c_int, val2: usize) -> c_int {
+        // unsafe { syscall!(FUTEX, addr, op, val, val2, 0, 0) as c_int }
+        unimplemented!()
+    }
+
+    fn futimens(fd: c_int, times: *const timespec) -> c_int {
+        // e(unsafe { syscall!(UTIMENSAT, fd, ptr::null::<c_char>(), times, 0) }) as c_int
+        unimplemented!()
+    }
+
+    fn utimens(path: &CStr, times: *const timespec) -> c_int {
+        // e(unsafe { syscall!(UTIMENSAT, AT_FDCWD, path.as_ptr(), times, 0) }) as c_int
+        unimplemented!()
+    }
+
+    fn getcwd(buf: *mut c_char, size: size_t) -> *mut c_char {
+        // if e(unsafe { syscall!(GETCWD, buf, size) }) == !0 {
+        //     ptr::null_mut()
+        // } else {
+        //     buf
+        // }
+        // 临时实现,设置所有的cwd为根目录
+        if size > 2 {
+            unsafe {
+                *buf = b'/' as c_char;
+                *buf.add(1) = b'\0' as c_char;
+            }
+        }
+
+        return buf;
+    }
+
+    fn getdents(fd: c_int, dirents: *mut dirent, bytes: usize) -> c_int {
+        unsafe { syscall!(SYS_GET_DENTS, fd, dirents, bytes) as c_int }
+    }
+
+    fn getegid() -> gid_t {
+        // e(unsafe { syscall!(GETEGID) }) as gid_t
+        return 0;
+    }
+
+    fn geteuid() -> uid_t {
+        // e(unsafe { syscall!(GETEUID) }) as uid_t
+        return 0;
+    }
+
+    fn getgid() -> gid_t {
+        // e(unsafe { syscall!(GETGID) }) as gid_t
+        return 0;
+    }
+
+    fn getpagesize() -> usize {
+        return 4096;
+    }
+
+    fn getpgid(pid: pid_t) -> pid_t {
+        // e(unsafe { syscall!(GETPGID, pid) }) as pid_t
+        return 0;
+    }
+
+    fn getpid() -> pid_t {
+        e(unsafe { syscall!(SYS_GETPID) }) as pid_t
+    }
+
+    fn getppid() -> pid_t {
+        // e(unsafe { syscall!(GETPPID) }) as pid_t
+        return 0;
+    }
+
+    fn getrandom(buf: &mut [u8], flags: c_uint) -> ssize_t {
+        // e(unsafe { syscall!(GETRANDOM, buf.as_mut_ptr(), buf.len(), flags) }) as ssize_t
+        unimplemented!()
+    }
+
+    unsafe fn getrlimit(resource: c_int, rlim: *mut rlimit) -> c_int {
+        // e(syscall!(GETRLIMIT, resource, rlim)) as c_int
+        unimplemented!()
+    }
+
+    fn getsid(pid: pid_t) -> pid_t {
+        // e(unsafe { syscall!(GETSID, pid) }) as pid_t
+        return 0;
+    }
+
+    fn gettid() -> pid_t {
+        // e(unsafe { syscall!(GETTID) }) as pid_t
+        return Self::getpid();
+    }
+
+    fn gettimeofday(tp: *mut timeval, tzp: *mut timezone) -> c_int {
+        e(unsafe { syscall!(SYS_GETTIMEOFDAY, tp, tzp) }) as c_int
+    }
+
+    fn getuid() -> uid_t {
+        // e(unsafe { syscall!(GETUID) }) as uid_t
+        return 0;
+    }
+
+    fn lchown(path: &CStr, owner: uid_t, group: gid_t) -> c_int {
+        // e(unsafe { syscall!(LCHOWN, path.as_ptr(), owner, group) }) as c_int
+        return 0;
+    }
+
+    fn link(path1: &CStr, path2: &CStr) -> c_int {
+        // e(unsafe {
+        //     syscall!(
+        //         LINKAT,
+        //         AT_FDCWD,
+        //         path1.as_ptr(),
+        //         AT_FDCWD,
+        //         path2.as_ptr(),
+        //         0
+        //     )
+        // }) as c_int
+        unimplemented!()
+    }
+
+    fn lseek(fildes: c_int, offset: off_t, whence: c_int) -> off_t {
+        e(unsafe { syscall!(SYS_LSEEK, fildes, offset, whence) }) as off_t
+    }
+
+    fn mkdir(path: &CStr, mode: mode_t) -> c_int {
+        // e(unsafe { syscall!(MKDIRAT, AT_FDCWD, path.as_ptr(), mode) }) as c_int
+        e(unsafe { syscall!(SYS_MKDIR, path.as_ptr(), mode) }) as c_int
+    }
+
+    fn mkfifo(path: &CStr, mode: mode_t) -> c_int {
+        e(unsafe { syscall!(SYS_MKNOD, path.as_ptr(), mode | S_IFIFO, 0) }) as c_int
+    }
+
+    unsafe fn mlock(addr: *const c_void, len: usize) -> c_int {
+        // e(syscall!(MLOCK, addr, len)) as c_int
+        unimplemented!()
+    }
+
+    fn mlockall(flags: c_int) -> c_int {
+        // e(unsafe { syscall!(MLOCKALL, flags) }) as c_int
+        unimplemented!()
+    }
+
+    unsafe fn mmap(
+        addr: *mut c_void,
+        len: usize,
+        prot: c_int,
+        flags: c_int,
+        fildes: c_int,
+        off: off_t,
+    ) -> *mut c_void {
+        e(syscall!(SYS_MMAP, addr, len, prot, flags, fildes, off)) as *mut c_void
+    }
+
+    unsafe fn mprotect(addr: *mut c_void, len: usize, prot: c_int) -> c_int {
+        e(syscall!(SYS_MPROTECT, addr, len, prot)) as c_int
+    }
+
+    unsafe fn msync(addr: *mut c_void, len: usize, flags: c_int) -> c_int {
+        // e(syscall!(MSYNC, addr, len, flags)) as c_int
+        unimplemented!()
+    }
+
+    unsafe fn munlock(addr: *const c_void, len: usize) -> c_int {
+        // e(syscall!(MUNLOCK, addr, len)) as c_int
+        unimplemented!()
+    }
+
+    fn munlockall() -> c_int {
+        // e(unsafe { syscall!(MUNLOCKALL) }) as c_int
+        unimplemented!()
+    }
+
+    unsafe fn munmap(addr: *mut c_void, len: usize) -> c_int {
+        e(syscall!(SYS_MUNMAP, addr, len)) as c_int
+    }
+
+    fn nanosleep(rqtp: *const timespec, rmtp: *mut timespec) -> c_int {
+        e(unsafe { syscall!(SYS_NANOSLEEP, rqtp, rmtp) }) as c_int
+    }
+
+    fn open(path: &CStr, oflag: c_int, mode: mode_t) -> c_int {
+        e(unsafe { syscall!(SYS_OPEN, path.as_ptr(), oflag, mode) }) as c_int
+    }
+
+    fn pipe2(fildes: &mut [c_int], flags: c_int) -> c_int {
+        // e(unsafe { syscall!(PIPE2, fildes.as_mut_ptr(), flags) }) as c_int
+
+        //since dragonos hasn't implemented pipe2 system call yet. We use a seperate pipe function instead of a special type of pipe2 function
+        if flags == 0 {
+            e(unsafe { syscall!(SYS_PIPE, fildes.as_mut_ptr()) }) as c_int
+        } else {
+            unimplemented!()
+        }
+    }
+
+    #[cfg(target_arch = "x86_64")]
+    unsafe fn pte_clone(stack: *mut usize) -> pid_t {
+        unimplemented!()
+        // let flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD;
+        // let pid;
+        // asm!("
+        //     # Call clone syscall
+        //     syscall
+
+        //     # Check if child or parent
+        //     test rax, rax
+        //     jnz 1f
+
+        //     # Load registers
+        //     pop rax
+        //     pop rdi
+        //     pop rsi
+        //     pop rdx
+        //     pop rcx
+        //     pop r8
+        //     pop r9
+
+        //     # Call entry point
+        //     call rax
+
+        //     # Exit
+        //     mov rax, 60
+        //     xor rdi, rdi
+        //     syscall
+
+        //     # Invalid instruction on failure to exit
+        //     ud2
+
+        //     # Return PID if parent
+        //     1:
+        //     ",
+        //     inout("rax") SYS_CLONE => pid,
+        //     inout("rdi") flags => _,
+        //     inout("rsi") stack => _,
+        //     inout("rdx") 0 => _,
+        //     inout("r10") 0 => _,
+        //     inout("r8") 0 => _,
+        //     //TODO: out("rbx") _,
+        //     out("rcx") _,
+        //     out("r9") _,
+        //     out("r11") _,
+        //     out("r12") _,
+        //     out("r13") _,
+        //     out("r14") _,
+        //     out("r15") _,
+        // );
+        // e(pid) as pid_t
+    }
+
+    fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t {
+        e(unsafe { syscall!(SYS_READ, fildes, buf.as_mut_ptr(), buf.len()) }) as ssize_t
+    }
+
+    fn readlink(pathname: &CStr, out: &mut [u8]) -> ssize_t {
+        unimplemented!()
+        // e(unsafe {
+        //     syscall!(
+        //         READLINKAT,
+        //         AT_FDCWD,
+        //         pathname.as_ptr(),
+        //         out.as_mut_ptr(),
+        //         out.len()
+        //     )
+        // }) as ssize_t
+    }
+
+    fn rename(old: &CStr, new: &CStr) -> c_int {
+        // e(unsafe { syscall!(RENAMEAT, AT_FDCWD, old.as_ptr(), AT_FDCWD, new.as_ptr()) }) as c_int
+        unimplemented!()
+    }
+
+    fn rmdir(path: &CStr) -> c_int {
+        e(unsafe { syscall!(SYS_UNLINK_AT, 0, path.as_ptr(), AT_REMOVEDIR) }) as c_int
+    }
+
+    fn sched_yield() -> c_int {
+        // e(unsafe { syscall!(SCHED_YIELD) }) as c_int
+        unimplemented!()
+    }
+
+    fn setpgid(pid: pid_t, pgid: pid_t) -> c_int {
+        // e(unsafe { syscall!(SETPGID, pid, pgid) }) as c_int
+        unimplemented!()
+    }
+
+    fn setregid(rgid: gid_t, egid: gid_t) -> c_int {
+        // e(unsafe { syscall!(SETREGID, rgid, egid) }) as c_int
+        unimplemented!()
+    }
+
+    fn setreuid(ruid: uid_t, euid: uid_t) -> c_int {
+        // e(unsafe { syscall!(SETREUID, ruid, euid) }) as c_int
+        unimplemented!()
+    }
+
+    fn symlink(path1: &CStr, path2: &CStr) -> c_int {
+        // e(unsafe { syscall!(SYMLINKAT, path1.as_ptr(), AT_FDCWD, path2.as_ptr()) }) as c_int
+        unimplemented!()
+    }
+
+    fn umask(mask: mode_t) -> mode_t {
+        // unsafe { syscall!(UMASK, mask) as mode_t }
+        unimplemented!()
+    }
+
+    fn uname(utsname: *mut utsname) -> c_int {
+        // e(unsafe { syscall!(UNAME, utsname, 0) }) as c_int
+        unimplemented!()
+    }
+
+    fn unlink(path: &CStr) -> c_int {
+        e(unsafe { syscall!(SYS_UNLINK_AT, AT_FDCWD, path.as_ptr(), 0) }) as c_int
+    }
+
+    fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t {
+        e(unsafe { syscall!(SYS_WAIT4, pid, stat_loc, options, 0) }) as pid_t
+    }
+
+    fn write(fildes: c_int, buf: &[u8]) -> ssize_t {
+        e(unsafe { syscall!(SYS_WRITE, fildes, buf.as_ptr(), buf.len()) }) as ssize_t
+    }
+
+    fn verify() -> bool {
+        // GETPID on Linux is 39, which does not exist on Redox
+        // e(unsafe { dsc::syscall5(dsc::nr::GETPID, !0, !0, !0, !0, !0) }) != !0
+        // unimplemented!()
+        return true;
+    }
+}

+ 11 - 0
src/platform/dragonos/ptrace.rs

@@ -0,0 +1,11 @@
+use super::{
+    super::{types::*, PalPtrace},
+    e, Sys,
+};
+
+impl PalPtrace for Sys {
+    fn ptrace(request: c_int, pid: pid_t, addr: *mut c_void, data: *mut c_void) -> c_int {
+        // unsafe { e(syscall!(PTRACE, request, pid, addr, data)) as c_int }
+        unimplemented!()
+    }
+}

+ 63 - 0
src/platform/dragonos/signal.rs

@@ -0,0 +1,63 @@
+use core::mem;
+
+use super::{
+    super::{types::*, PalSignal},
+    e, Sys,
+};
+
+use crate::header::{
+    signal::{sigaction, sigset_t, stack_t},
+    sys_time::itimerval,
+};
+
+impl PalSignal for Sys {
+    fn getitimer(which: c_int, out: *mut itimerval) -> c_int {
+        // e(unsafe { syscall!(GETITIMER, which, out) }) as c_int
+        unimplemented!()
+    }
+
+    fn kill(pid: pid_t, sig: c_int) -> c_int {
+        e(unsafe { syscall!(SYS_KILL, pid, sig) }) as c_int
+    }
+
+    fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
+        e(unsafe { syscall!(SYS_KILL, -(pgrp as isize) as pid_t, sig) }) as c_int
+    }
+
+    fn raise(sig: c_int) -> c_int {
+        let tid = e(unsafe { syscall!(SYS_GETPID) }) as pid_t;
+        if tid == !0 {
+            -1
+        } else {
+            // e(unsafe { syscall!(TKILL, tid, sig) }) as c_int
+            Self::kill(tid, sig)
+        }
+    }
+
+    fn setitimer(which: c_int, new: *const itimerval, old: *mut itimerval) -> c_int {
+        // e(unsafe { syscall!(SETITIMER, which, new, old) }) as c_int
+        unimplemented!()
+    }
+
+    fn sigaction(sig: c_int, act: Option<&sigaction>, oact: Option<&mut sigaction>) -> c_int {
+        e(unsafe {
+            syscall!(
+                SYS_SIGACTION,
+                sig,
+                act.map_or_else(core::ptr::null, |x| x as *const _),
+                oact.map_or_else(core::ptr::null_mut, |x| x as *mut _),
+                mem::size_of::<sigset_t>()
+            )
+        }) as c_int
+    }
+
+    fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int {
+        // e(unsafe { syscall!(SIGALTSTACK, ss, old_ss) }) as c_int
+        unimplemented!()
+    }
+
+    fn sigprocmask(how: c_int, set: *const sigset_t, oset: *mut sigset_t) -> c_int {
+        // e(unsafe { syscall!(RT_SIGPROCMASK, how, set, oset, mem::size_of::<sigset_t>()) }) as c_int
+        unimplemented!()
+    }
+}

+ 128 - 0
src/platform/dragonos/socket.rs

@@ -0,0 +1,128 @@
+use super::{
+    super::{types::*, PalSocket},
+    e, Sys,
+};
+
+use crate::header::sys_socket::{sockaddr, socklen_t};
+
+impl PalSocket for Sys {
+    unsafe fn accept(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int {
+        e(syscall!(
+            SYS_ACCEPT,
+            socket as usize,
+            address as usize,
+            address_len as usize
+        )) as c_int
+    }
+
+    unsafe fn bind(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
+        e(syscall!(SYS_BIND, socket, address, address_len)) as c_int
+    }
+
+    unsafe fn connect(socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int {
+        e(syscall!(SYS_CONNECT, socket, address, address_len)) as c_int
+    }
+
+    unsafe fn getpeername(
+        socket: c_int,
+        address: *mut sockaddr,
+        address_len: *mut socklen_t,
+    ) -> c_int {
+        e(syscall!(SYS_GETPEERNAME, socket, address, address_len)) as c_int
+    }
+
+    unsafe fn getsockname(
+        socket: c_int,
+        address: *mut sockaddr,
+        address_len: *mut socklen_t,
+    ) -> c_int {
+        e(syscall!(SYS_GETSOCKNAME, socket, address, address_len)) as c_int
+    }
+
+    fn getsockopt(
+        socket: c_int,
+        level: c_int,
+        option_name: c_int,
+        option_value: *mut c_void,
+        option_len: *mut socklen_t,
+    ) -> c_int {
+        e(unsafe {
+            syscall!(
+                SYS_GETSOCKOPT,
+                socket,
+                level,
+                option_name,
+                option_value,
+                option_len
+            )
+        }) as c_int
+    }
+
+    fn listen(socket: c_int, backlog: c_int) -> c_int {
+        e(unsafe { syscall!(SYS_LISTEN, socket, backlog) }) as c_int
+    }
+
+    unsafe fn recvfrom(
+        socket: c_int,
+        buf: *mut c_void,
+        len: size_t,
+        flags: c_int,
+        address: *mut sockaddr,
+        address_len: *mut socklen_t,
+    ) -> ssize_t {
+        e(syscall!(
+            SYS_RECVFROM,
+            socket,
+            buf,
+            len,
+            flags,
+            address,
+            address_len
+        )) as ssize_t
+    }
+
+    unsafe fn sendto(
+        socket: c_int,
+        buf: *const c_void,
+        len: size_t,
+        flags: c_int,
+        dest_addr: *const sockaddr,
+        dest_len: socklen_t,
+    ) -> ssize_t {
+        e(syscall!(
+            SYS_SENDTO, socket, buf, len, flags, dest_addr, dest_len
+        )) as ssize_t
+    }
+
+    fn setsockopt(
+        socket: c_int,
+        level: c_int,
+        option_name: c_int,
+        option_value: *const c_void,
+        option_len: socklen_t,
+    ) -> c_int {
+        e(unsafe {
+            syscall!(
+                SYS_SETSOCKOPT,
+                socket,
+                level,
+                option_name,
+                option_value,
+                option_len
+            )
+        }) as c_int
+    }
+
+    fn shutdown(socket: c_int, how: c_int) -> c_int {
+        e(unsafe { syscall!(SYS_SHUTDOWN, socket, how) }) as c_int
+    }
+
+    unsafe fn socket(domain: c_int, kind: c_int, protocol: c_int) -> c_int {
+        e(syscall!(SYS_SOCKET, domain, kind, protocol)) as c_int
+    }
+
+    fn socketpair(domain: c_int, kind: c_int, protocol: c_int, sv: &mut [c_int; 2]) -> c_int {
+        // e(unsafe { syscall!(SOCKETPAIR, domain, kind, protocol, sv.as_mut_ptr()) }) as c_int
+        unimplemented!()
+    }
+}

+ 20 - 1
src/platform/mod.rs

@@ -4,10 +4,14 @@ use core::{fmt, ptr};
 
 pub use self::allocator::*;
 
-#[cfg(not(feature = "ralloc"))]
+#[cfg(all(not(feature = "ralloc"), not(target_os = "dragonos")))]
 #[path = "allocator/dlmalloc.rs"]
 mod allocator;
 
+#[cfg(all(not(feature = "ralloc"), target_os = "dragonos"))]
+#[path = "allocator/dragonos_malloc.rs"]
+mod allocator;
+
 #[cfg(feature = "ralloc")]
 #[path = "allocator/ralloc.rs"]
 mod allocator;
@@ -22,6 +26,10 @@ pub use self::sys::{e, Sys};
 #[path = "linux/mod.rs"]
 pub(crate) mod sys;
 
+#[cfg(all(not(feature = "no_std"), target_os = "dragonos"))]
+#[path = "dragonos/mod.rs"]
+pub(crate) mod sys;
+
 #[cfg(all(not(feature = "no_std"), target_os = "redox"))]
 #[path = "redox/mod.rs"]
 pub(crate) mod sys;
@@ -37,17 +45,28 @@ pub mod rlb;
 #[cfg(target_os = "linux")]
 pub mod auxv_defs;
 
+#[cfg(target_os = "dragonos")]
+pub mod auxv_defs;
+
 #[cfg(target_os = "redox")]
 pub use redox_exec::auxv_defs;
 
 use self::types::*;
 pub mod types;
 
+#[cfg(not(target_os = "dragonos"))]
 #[thread_local]
 #[allow(non_upper_case_globals)]
 #[no_mangle]
 pub static mut errno: c_int = 0;
 
+/// DragonOS doesn't have thread_local, so we use a global variable instead.
+/// TODO: This is a hack, and should be fixed.
+#[cfg(target_os = "dragonos")]
+#[allow(non_upper_case_globals)]
+#[no_mangle]
+pub static mut errno: c_int = 0;
+
 #[allow(non_upper_case_globals)]
 pub static mut argv: *mut *mut c_char = ptr::null_mut();
 #[allow(non_upper_case_globals)]

+ 3 - 2
src/platform/redox/redox-exec/src/arch/aarch64.rs

@@ -1,6 +1,6 @@
 use syscall::error::*;
 
-use crate::{FdGuard, fork_inner};
+use crate::{fork_inner, FdGuard};
 
 // Setup a stack starting from the very end of the address space, and then growing downwards.
 pub(crate) const STACK_TOP: usize = 1 << 47;
@@ -44,7 +44,8 @@ unsafe extern "C" fn __relibc_internal_fork_hook(cur_filetable_fd: usize, new_pi
     let _ = syscall::close(new_pid_fd);
 }
 
-core::arch::global_asm!("
+core::arch::global_asm!(
+    "
     .p2align 6
     .globl __relibc_internal_fork_wrapper
     .type __relibc_internal_fork_wrapper, @function

+ 3 - 2
src/platform/redox/redox-exec/src/arch/x86.rs

@@ -1,6 +1,6 @@
 use syscall::error::*;
 
-use crate::{FdGuard, fork_inner};
+use crate::{fork_inner, FdGuard};
 
 // Setup a stack starting from the very end of the address space, and then growing downwards.
 pub(crate) const STACK_TOP: usize = 1 << 31;
@@ -46,7 +46,8 @@ unsafe extern "cdecl" fn __relibc_internal_fork_hook(cur_filetable_fd: usize, ne
 }
 
 //TODO: x86
-core::arch::global_asm!("
+core::arch::global_asm!(
+    "
     .p2align 6
     .globl __relibc_internal_fork_wrapper
     .type __relibc_internal_fork_wrapper, @function

+ 3 - 2
src/platform/redox/redox-exec/src/arch/x86_64.rs

@@ -1,6 +1,6 @@
 use syscall::error::*;
 
-use crate::{FdGuard, fork_inner};
+use crate::{fork_inner, FdGuard};
 
 // Setup a stack starting from the very end of the address space, and then growing downwards.
 pub(crate) const STACK_TOP: usize = 1 << 47;
@@ -45,7 +45,8 @@ unsafe extern "sysv64" fn __relibc_internal_fork_hook(cur_filetable_fd: usize, n
     let _ = syscall::close(new_pid_fd);
 }
 
-core::arch::global_asm!("
+core::arch::global_asm!(
+    "
     .p2align 6
     .globl __relibc_internal_fork_wrapper
     .type __relibc_internal_fork_wrapper, @function

+ 284 - 123
src/platform/redox/redox-exec/src/lib.rs

@@ -1,36 +1,43 @@
 #![no_std]
-
 #![feature(array_chunks, map_first_last)]
 
 extern crate alloc;
 
 use core::mem::size_of;
 
-use alloc::{
-    boxed::Box,
-    collections::BTreeMap,
-    vec,
-};
+use alloc::{boxed::Box, collections::BTreeMap, vec};
 
 //TODO: allow use of either 32-bit or 64-bit programs
 #[cfg(target_pointer_width = "32")]
-use goblin::elf32::{header::Header, program_header::program_header32::{ProgramHeader, PT_LOAD, PT_INTERP, PF_W, PF_X}};
+use goblin::elf32::{
+    header::Header,
+    program_header::program_header32::{ProgramHeader, PF_W, PF_X, PT_INTERP, PT_LOAD},
+};
 #[cfg(target_pointer_width = "64")]
-use goblin::elf64::{header::Header, program_header::program_header64::{ProgramHeader, PT_LOAD, PT_INTERP, PF_W, PF_X}};
-
+use goblin::elf64::{
+    header::Header,
+    program_header::program_header64::{ProgramHeader, PF_W, PF_X, PT_INTERP, PT_LOAD},
+};
 
 use syscall::{
-    PAGE_SIZE,
     error::*,
     flag::{MapFlags, SEEK_SET},
+    PAGE_SIZE,
 };
 
 pub use self::arch::*;
 mod arch;
 
 pub enum FexecResult {
-    Normal { addrspace_handle: FdGuard },
-    Interp { path: Box<[u8]>, image_file: FdGuard, open_via_dup: FdGuard, interp_override: InterpOverride },
+    Normal {
+        addrspace_handle: FdGuard,
+    },
+    Interp {
+        path: Box<[u8]>,
+        image_file: FdGuard,
+        open_via_dup: FdGuard,
+        interp_override: InterpOverride,
+    },
 }
 pub struct InterpOverride {
     phs: Box<[u8]>,
@@ -45,7 +52,17 @@ pub struct ExtraInfo<'a> {
     pub cwd: Option<&'a [u8]>,
 }
 
-pub fn fexec_impl<A, E>(image_file: FdGuard, open_via_dup: FdGuard, memory_scheme_fd: &FdGuard, path: &[u8], args: A, envs: E, total_args_envs_size: usize, extrainfo: &ExtraInfo, mut interp_override: Option<InterpOverride>) -> Result<FexecResult>
+pub fn fexec_impl<A, E>(
+    image_file: FdGuard,
+    open_via_dup: FdGuard,
+    memory_scheme_fd: &FdGuard,
+    path: &[u8],
+    args: A,
+    envs: E,
+    total_args_envs_size: usize,
+    extrainfo: &ExtraInfo,
+    mut interp_override: Option<InterpOverride>,
+) -> Result<FexecResult>
 where
     A: IntoIterator,
     E: IntoIterator,
@@ -71,28 +88,33 @@ where
     const MAX_PH_SIZE: usize = 1024 * 1024;
     let phentsize = u64::from(header.e_phentsize) as usize;
     let phnum = u64::from(header.e_phnum) as usize;
-    let pheaders_size = phentsize.saturating_mul(phnum).saturating_add(size_of::<Header>());
+    let pheaders_size = phentsize
+        .saturating_mul(phnum)
+        .saturating_add(size_of::<Header>());
 
     if pheaders_size > MAX_PH_SIZE {
         return Err(Error::new(E2BIG));
     }
-    let mut phs_raw = vec! [0_u8; pheaders_size];
+    let mut phs_raw = vec![0_u8; pheaders_size];
     phs_raw[..size_of::<Header>()].copy_from_slice(&header_bytes);
     let phs = &mut phs_raw[size_of::<Header>()..];
 
     // TODO: Remove clone, but this would require more as_refs and as_muts
-    let mut tree = interp_override.as_mut().map_or_else(|| {
-        core::iter::once((0, PAGE_SIZE)).collect::<BTreeMap<_, _>>()
-    }, |o| core::mem::take(&mut o.tree));
+    let mut tree = interp_override.as_mut().map_or_else(
+        || core::iter::once((0, PAGE_SIZE)).collect::<BTreeMap<_, _>>(),
+        |o| core::mem::take(&mut o.tree),
+    );
 
     const BUFSZ: usize = 1024 * 256;
-    let mut buf = vec! [0_u8; BUFSZ];
+    let mut buf = vec![0_u8; BUFSZ];
 
-    read_all(*image_file as usize, Some(header.e_phoff as u64), phs).map_err(|_| Error::new(EIO))?;
+    read_all(*image_file as usize, Some(header.e_phoff as u64), phs)
+        .map_err(|_| Error::new(EIO))?;
 
     for ph_idx in 0..phnum {
         let ph_bytes = &phs[ph_idx * phentsize..(ph_idx + 1) * phentsize];
-        let segment: &ProgramHeader = plain::from_bytes(ph_bytes).map_err(|_| Error::new(EINVAL))?;
+        let segment: &ProgramHeader =
+            plain::from_bytes(ph_bytes).map_err(|_| Error::new(EINVAL))?;
         let mut flags = syscall::PROT_READ;
 
         // W ^ X. If it is executable, do not allow it to be writable, even if requested
@@ -104,8 +126,7 @@ where
 
         let voff = segment.p_vaddr as usize % PAGE_SIZE;
         let vaddr = segment.p_vaddr as usize - voff;
-        let size =
-            (segment.p_memsz as usize + voff + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
+        let size = (segment.p_memsz as usize + voff + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
 
         if segment.p_filesz > segment.p_memsz {
             return Err(Error::new(ENOEXEC));
@@ -114,8 +135,12 @@ where
         match segment.p_type {
             // PT_INTERP must come before any PT_LOAD, so we don't have to iterate twice.
             PT_INTERP => {
-                let mut interp = vec! [0_u8; segment.p_filesz as usize];
-                read_all(*image_file as usize, Some(segment.p_offset as u64), &mut interp)?;
+                let mut interp = vec![0_u8; segment.p_filesz as usize];
+                read_all(
+                    *image_file as usize,
+                    Some(segment.p_offset as u64),
+                    &mut interp,
+                )?;
 
                 return Ok(FexecResult::Interp {
                     path: interp.into_boxed_slice(),
@@ -128,21 +153,39 @@ where
                         phs: phs_raw.into_boxed_slice(),
                         name: path.into(),
                         tree,
-                    }
+                    },
                 });
             }
             PT_LOAD => {
-                allocate_remote(&grants_fd, memory_scheme_fd, vaddr, size, syscall::PROT_READ | syscall::PROT_WRITE)?;
-                syscall::lseek(*image_file as usize, segment.p_offset as isize, SEEK_SET).map_err(|_| Error::new(EIO))?;
-                syscall::lseek(*memory_fd, segment.p_vaddr as isize, SEEK_SET).map_err(|_| Error::new(EIO))?;
-
-                for size in core::iter::repeat(buf.len()).take((segment.p_filesz as usize) / buf.len()).chain(Some((segment.p_filesz as usize) % buf.len())) {
-                    read_all(*image_file as usize, None, &mut buf[..size]).map_err(|_| Error::new(EIO))?;
-                    let _ = syscall::write(*memory_fd, &buf[..size]).map_err(|_| Error::new(EIO))?;
+                allocate_remote(
+                    &grants_fd,
+                    memory_scheme_fd,
+                    vaddr,
+                    size,
+                    syscall::PROT_READ | syscall::PROT_WRITE,
+                )?;
+                syscall::lseek(*image_file as usize, segment.p_offset as isize, SEEK_SET)
+                    .map_err(|_| Error::new(EIO))?;
+                syscall::lseek(*memory_fd, segment.p_vaddr as isize, SEEK_SET)
+                    .map_err(|_| Error::new(EIO))?;
+
+                for size in core::iter::repeat(buf.len())
+                    .take((segment.p_filesz as usize) / buf.len())
+                    .chain(Some((segment.p_filesz as usize) % buf.len()))
+                {
+                    read_all(*image_file as usize, None, &mut buf[..size])
+                        .map_err(|_| Error::new(EIO))?;
+                    let _ =
+                        syscall::write(*memory_fd, &buf[..size]).map_err(|_| Error::new(EIO))?;
                 }
                 mprotect_remote(&grants_fd, vaddr, size, flags)?;
 
-                if !tree.range(..=vaddr).next_back().filter(|(start, size)| **start + **size > vaddr).is_some() {
+                if !tree
+                    .range(..=vaddr)
+                    .next_back()
+                    .filter(|(start, size)| **start + **size > vaddr)
+                    .is_some()
+                {
                     tree.insert(vaddr, size);
                 }
             }
@@ -150,7 +193,13 @@ where
         }
     }
 
-    allocate_remote(&grants_fd, memory_scheme_fd, STACK_TOP - STACK_SIZE, STACK_SIZE, MapFlags::PROT_READ | MapFlags::PROT_WRITE)?;
+    allocate_remote(
+        &grants_fd,
+        memory_scheme_fd,
+        STACK_TOP - STACK_SIZE,
+        STACK_SIZE,
+        MapFlags::PROT_READ | MapFlags::PROT_WRITE,
+    )?;
     tree.insert(STACK_TOP - STACK_SIZE, STACK_SIZE);
 
     let mut sp = STACK_TOP - 256;
@@ -165,12 +214,23 @@ where
     } else {
         &*phs_raw
     };
-    let pheaders_size_aligned = (pheaders_to_convey.len()+PAGE_SIZE-1)/PAGE_SIZE*PAGE_SIZE;
+    let pheaders_size_aligned = (pheaders_to_convey.len() + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
     let pheaders = find_free_target_addr(&tree, pheaders_size_aligned).ok_or(Error::new(ENOMEM))?;
     tree.insert(pheaders, pheaders_size_aligned);
-    allocate_remote(&grants_fd, memory_scheme_fd, pheaders, pheaders_size_aligned, MapFlags::PROT_READ | MapFlags::PROT_WRITE)?;
+    allocate_remote(
+        &grants_fd,
+        memory_scheme_fd,
+        pheaders,
+        pheaders_size_aligned,
+        MapFlags::PROT_READ | MapFlags::PROT_WRITE,
+    )?;
     write_all(*memory_fd, Some(pheaders as u64), &pheaders_to_convey)?;
-    mprotect_remote(&grants_fd, pheaders, pheaders_size_aligned, MapFlags::PROT_READ)?;
+    mprotect_remote(
+        &grants_fd,
+        pheaders,
+        pheaders_size_aligned,
+        MapFlags::PROT_READ,
+    )?;
 
     push(0)?;
     push(AT_NULL)?;
@@ -182,15 +242,32 @@ where
     push(AT_ENTRY)?;
     push(pheaders + size_of::<Header>())?;
     push(AT_PHDR)?;
-    push(interp_override.as_ref().map_or(header.e_phnum as usize, |o| o.at_phnum))?;
+    push(
+        interp_override
+            .as_ref()
+            .map_or(header.e_phnum as usize, |o| o.at_phnum),
+    )?;
     push(AT_PHNUM)?;
-    push(interp_override.as_ref().map_or(header.e_phentsize as usize, |o| o.at_phent))?;
+    push(
+        interp_override
+            .as_ref()
+            .map_or(header.e_phentsize as usize, |o| o.at_phent),
+    )?;
     push(AT_PHENT)?;
 
-    let total_args_envs_auxvpointee_size = total_args_envs_size + extrainfo.cwd.map_or(0, |s| s.len() + 1);
-    let args_envs_size_aligned = (total_args_envs_auxvpointee_size+PAGE_SIZE-1)/PAGE_SIZE*PAGE_SIZE;
-    let target_args_env_address = find_free_target_addr(&tree, args_envs_size_aligned).ok_or(Error::new(ENOMEM))?;
-    allocate_remote(&grants_fd, memory_scheme_fd, target_args_env_address, args_envs_size_aligned, MapFlags::PROT_READ | MapFlags::PROT_WRITE)?;
+    let total_args_envs_auxvpointee_size =
+        total_args_envs_size + extrainfo.cwd.map_or(0, |s| s.len() + 1);
+    let args_envs_size_aligned =
+        (total_args_envs_auxvpointee_size + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE;
+    let target_args_env_address =
+        find_free_target_addr(&tree, args_envs_size_aligned).ok_or(Error::new(ENOMEM))?;
+    allocate_remote(
+        &grants_fd,
+        memory_scheme_fd,
+        target_args_env_address,
+        args_envs_size_aligned,
+        MapFlags::PROT_READ | MapFlags::PROT_WRITE,
+    )?;
     tree.insert(target_args_env_address, args_envs_size_aligned);
 
     let mut offset = 0;
@@ -228,14 +305,20 @@ where
 
     push(argc)?;
 
-    unsafe { deactivate_tcb(*open_via_dup)?; }
+    unsafe {
+        deactivate_tcb(*open_via_dup)?;
+    }
 
     {
         let current_sigaction_fd = FdGuard::new(syscall::dup(*open_via_dup, b"sigactions")?);
         let empty_sigaction_fd = FdGuard::new(syscall::dup(*current_sigaction_fd, b"empty")?);
-        let sigaction_selection_fd = FdGuard::new(syscall::dup(*open_via_dup, b"current-sigactions")?);
+        let sigaction_selection_fd =
+            FdGuard::new(syscall::dup(*open_via_dup, b"current-sigactions")?);
 
-        let _ = syscall::write(*sigaction_selection_fd, &usize::to_ne_bytes(*empty_sigaction_fd))?;
+        let _ = syscall::write(
+            *sigaction_selection_fd,
+            &usize::to_ne_bytes(*empty_sigaction_fd),
+        )?;
     }
 
     // TODO: Restore old name if exec failed?
@@ -251,70 +334,112 @@ where
 
     let addrspace_selection_fd = FdGuard::new(syscall::dup(*open_via_dup, b"current-addrspace")?);
 
-    let _ = syscall::write(*addrspace_selection_fd, &create_set_addr_space_buf(*grants_fd, header.e_entry as usize, sp));
+    let _ = syscall::write(
+        *addrspace_selection_fd,
+        &create_set_addr_space_buf(*grants_fd, header.e_entry as usize, sp),
+    );
 
-    Ok(FexecResult::Normal { addrspace_handle: addrspace_selection_fd })
+    Ok(FexecResult::Normal {
+        addrspace_handle: addrspace_selection_fd,
+    })
 }
 fn write_usizes<const N: usize>(fd: &FdGuard, usizes: [usize; N]) -> Result<()> {
     let _ = syscall::write(**fd, unsafe { plain::as_bytes(&usizes) });
     Ok(())
 }
-fn allocate_remote(addrspace_fd: &FdGuard, memory_scheme_fd: &FdGuard, dst_addr: usize, len: usize, flags: MapFlags) -> Result<()> {
+fn allocate_remote(
+    addrspace_fd: &FdGuard,
+    memory_scheme_fd: &FdGuard,
+    dst_addr: usize,
+    len: usize,
+    flags: MapFlags,
+) -> Result<()> {
     mmap_remote(addrspace_fd, memory_scheme_fd, 0, dst_addr, len, flags)
 }
-pub fn mmap_remote(addrspace_fd: &FdGuard, fd: &FdGuard, offset: usize, dst_addr: usize, len: usize, flags: MapFlags) -> Result<()> {
-    write_usizes(addrspace_fd, [
-        // op
-        syscall::flag::ADDRSPACE_OP_MMAP,
-        // fd
-        **fd,
-        // "offset"
-        offset,
-        // address
-        dst_addr,
-        // size
-        len,
-        // flags
-        (flags | MapFlags::MAP_FIXED_NOREPLACE).bits(),
-    ])
+pub fn mmap_remote(
+    addrspace_fd: &FdGuard,
+    fd: &FdGuard,
+    offset: usize,
+    dst_addr: usize,
+    len: usize,
+    flags: MapFlags,
+) -> Result<()> {
+    write_usizes(
+        addrspace_fd,
+        [
+            // op
+            syscall::flag::ADDRSPACE_OP_MMAP,
+            // fd
+            **fd,
+            // "offset"
+            offset,
+            // address
+            dst_addr,
+            // size
+            len,
+            // flags
+            (flags | MapFlags::MAP_FIXED_NOREPLACE).bits(),
+        ],
+    )
 }
-pub fn mprotect_remote(addrspace_fd: &FdGuard, addr: usize, len: usize, flags: MapFlags) -> Result<()> {
-    write_usizes(addrspace_fd, [
-        // op
-        syscall::flag::ADDRSPACE_OP_MPROTECT,
-        // address
-        addr,
-        // size
-        len,
-        // flags
-        flags.bits(),
-    ])
+pub fn mprotect_remote(
+    addrspace_fd: &FdGuard,
+    addr: usize,
+    len: usize,
+    flags: MapFlags,
+) -> Result<()> {
+    write_usizes(
+        addrspace_fd,
+        [
+            // op
+            syscall::flag::ADDRSPACE_OP_MPROTECT,
+            // address
+            addr,
+            // size
+            len,
+            // flags
+            flags.bits(),
+        ],
+    )
 }
 pub fn munmap_remote(addrspace_fd: &FdGuard, addr: usize, len: usize) -> Result<()> {
-    write_usizes(addrspace_fd, [
-        // op
-        syscall::flag::ADDRSPACE_OP_MUNMAP,
-        // address
-        addr,
-        // size
-        len,
-    ])
+    write_usizes(
+        addrspace_fd,
+        [
+            // op
+            syscall::flag::ADDRSPACE_OP_MUNMAP,
+            // address
+            addr,
+            // size
+            len,
+        ],
+    )
 }
-pub fn munmap_transfer(src: &FdGuard, dst: &FdGuard, src_addr: usize, dst_addr: usize, len: usize, flags: MapFlags) -> Result<()> {
-    write_usizes(dst, [
-        // op
-        syscall::flag::ADDRSPACE_OP_TRANSFER,
-        // fd
-        **src,
-        // "offset" (source address)
-        src_addr,
-        // address
-        dst_addr,
-        // size
-        len,
-        // flags
-        (flags | MapFlags::MAP_FIXED_NOREPLACE).bits(),
-    ])
+pub fn munmap_transfer(
+    src: &FdGuard,
+    dst: &FdGuard,
+    src_addr: usize,
+    dst_addr: usize,
+    len: usize,
+    flags: MapFlags,
+) -> Result<()> {
+    write_usizes(
+        dst,
+        [
+            // op
+            syscall::flag::ADDRSPACE_OP_TRANSFER,
+            // fd
+            **src,
+            // "offset" (source address)
+            src_addr,
+            // address
+            dst_addr,
+            // size
+            len,
+            // flags
+            (flags | MapFlags::MAP_FIXED_NOREPLACE).bits(),
+        ],
+    )
 }
 fn read_all(fd: usize, offset: Option<u64>, buf: &mut [u8]) -> Result<()> {
     if let Some(offset) = offset {
@@ -374,9 +499,7 @@ pub struct FdGuard {
 }
 impl FdGuard {
     pub fn new(fd: usize) -> Self {
-        Self {
-            fd, taken: false,
-        }
+        Self { fd, taken: false }
     }
     pub fn take(&mut self) -> usize {
         self.taken = true;
@@ -398,9 +521,13 @@ impl Drop for FdGuard {
         }
     }
 }
-pub fn create_set_addr_space_buf(space: usize, ip: usize, sp: usize) -> [u8; size_of::<usize>() * 3] {
+pub fn create_set_addr_space_buf(
+    space: usize,
+    ip: usize,
+    sp: usize,
+) -> [u8; size_of::<usize>() * 3] {
     let mut buf = [0_u8; 3 * size_of::<usize>()];
-    let mut chunks = buf.array_chunks_mut::<{size_of::<usize>()}>();
+    let mut chunks = buf.array_chunks_mut::<{ size_of::<usize>() }>();
     *chunks.next().unwrap() = usize::to_ne_bytes(space);
     *chunks.next().unwrap() = usize::to_ne_bytes(sp);
     *chunks.next().unwrap() = usize::to_ne_bytes(ip);
@@ -416,16 +543,17 @@ use auxv_defs::*;
 /// descriptors from other schemes are reobtained with `dup`, and grants referencing such file
 /// descriptors are reobtained through `fmap`. Other mappings are kept but duplicated using CoW.
 pub fn fork_impl() -> Result<usize> {
-    unsafe {
-        Error::demux(__relibc_internal_fork_wrapper())
-    }
+    unsafe { Error::demux(__relibc_internal_fork_wrapper()) }
 }
 
 fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
     let (cur_filetable_fd, new_pid_fd, new_pid);
 
     {
-        let cur_pid_fd = FdGuard::new(syscall::open("thisproc:current/open_via_dup", syscall::O_CLOEXEC)?);
+        let cur_pid_fd = FdGuard::new(syscall::open(
+            "thisproc:current/open_via_dup",
+            syscall::O_CLOEXEC,
+        )?);
         (new_pid_fd, new_pid) = new_context()?;
 
         // Do not allocate new signal stack, but copy existing address (all memory will be re-mapped
@@ -445,9 +573,13 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
         {
             let cur_sigaction_fd = FdGuard::new(syscall::dup(*cur_pid_fd, b"sigactions")?);
             let new_sigaction_fd = FdGuard::new(syscall::dup(*cur_sigaction_fd, b"copy")?);
-            let new_sigaction_sel_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"current-sigactions")?);
+            let new_sigaction_sel_fd =
+                FdGuard::new(syscall::dup(*new_pid_fd, b"current-sigactions")?);
 
-            let _ = syscall::write(*new_sigaction_sel_fd, &usize::to_ne_bytes(*new_sigaction_fd))?;
+            let _ = syscall::write(
+                *new_sigaction_sel_fd,
+                &usize::to_ne_bytes(*new_sigaction_fd),
+            )?;
         }
 
         // Copy existing files into new file table, but do not reuse the same file table (i.e. new
@@ -470,20 +602,25 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
 
             let new_addr_space_fd = FdGuard::new(syscall::dup(*cur_addr_space_fd, b"exclusive")?);
 
-            let mut buf = vec! [0_u8; 4096];
+            let mut buf = vec![0_u8; 4096];
             let mut bytes_read = 0;
 
             loop {
                 let new_bytes_read = syscall::read(*cur_addr_space_fd, &mut buf[bytes_read..])?;
 
-                if new_bytes_read == 0 { break }
+                if new_bytes_read == 0 {
+                    break;
+                }
 
                 bytes_read += new_bytes_read;
             }
             let bytes = &buf[..bytes_read];
 
-            for struct_bytes in bytes.array_chunks::<{size_of::<usize>() * 4}>() {
-                let mut words = struct_bytes.array_chunks::<{size_of::<usize>()}>().copied().map(usize::from_ne_bytes);
+            for struct_bytes in bytes.array_chunks::<{ size_of::<usize>() * 4 }>() {
+                let mut words = struct_bytes
+                    .array_chunks::<{ size_of::<usize>() }>()
+                    .copied()
+                    .map(usize::from_ne_bytes);
 
                 let addr = words.next().unwrap();
                 let size = words.next().unwrap();
@@ -495,12 +632,20 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
                 }
                 let map_flags = MapFlags::from_bits_truncate(flags);
 
-                let grant_fd = FdGuard::new(syscall::dup(*cur_addr_space_fd, alloc::format!("grant-{:x}", addr).as_bytes())?);
+                let grant_fd = FdGuard::new(syscall::dup(
+                    *cur_addr_space_fd,
+                    alloc::format!("grant-{:x}", addr).as_bytes(),
+                )?);
                 mmap_remote(&new_addr_space_fd, &grant_fd, offset, addr, size, map_flags)?;
             }
-            let new_addr_space_sel_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"current-addrspace")?);
-
-            let buf = create_set_addr_space_buf(*new_addr_space_fd, __relibc_internal_fork_ret as usize, initial_rsp as usize);
+            let new_addr_space_sel_fd =
+                FdGuard::new(syscall::dup(*new_pid_fd, b"current-addrspace")?);
+
+            let buf = create_set_addr_space_buf(
+                *new_addr_space_fd,
+                __relibc_internal_fork_ret as usize,
+                initial_rsp as usize,
+            );
             let _ = syscall::write(*new_addr_space_sel_fd, &buf)?;
         }
         copy_env_regs(*cur_pid_fd, *new_pid_fd)?;
@@ -513,7 +658,10 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
         // kernel.
         let new_filetable_fd = FdGuard::new(syscall::dup(*cur_filetable_fd, b"copy")?);
         let new_filetable_sel_fd = FdGuard::new(syscall::dup(*new_pid_fd, b"current-filetable")?);
-        let _ = syscall::write(*new_filetable_sel_fd, &usize::to_ne_bytes(*new_filetable_fd));
+        let _ = syscall::write(
+            *new_filetable_sel_fd,
+            &usize::to_ne_bytes(*new_filetable_fd),
+        );
     }
 
     // Unblock context.
@@ -530,16 +678,29 @@ fn fork_inner(initial_rsp: *mut usize) -> Result<usize> {
 
 pub fn new_context() -> Result<(FdGuard, usize)> {
     // Create a new context (fields such as uid/gid will be inherited from the current context).
-    let fd = FdGuard::new(syscall::open("thisproc:new/open_via_dup", syscall::O_CLOEXEC)?);
+    let fd = FdGuard::new(syscall::open(
+        "thisproc:new/open_via_dup",
+        syscall::O_CLOEXEC,
+    )?);
 
     // Extract pid.
     let mut buffer = [0_u8; 64];
     let len = syscall::fpath(*fd, &mut buffer)?;
     let buffer = buffer.get(..len).ok_or(Error::new(ENAMETOOLONG))?;
 
-    let colon_idx = buffer.iter().position(|c| *c == b':').ok_or(Error::new(EINVAL))?;
-    let slash_idx = buffer.iter().skip(colon_idx).position(|c| *c == b'/').ok_or(Error::new(EINVAL))? + colon_idx;
-    let pid_bytes = buffer.get(colon_idx + 1..slash_idx).ok_or(Error::new(EINVAL))?;
+    let colon_idx = buffer
+        .iter()
+        .position(|c| *c == b':')
+        .ok_or(Error::new(EINVAL))?;
+    let slash_idx = buffer
+        .iter()
+        .skip(colon_idx)
+        .position(|c| *c == b'/')
+        .ok_or(Error::new(EINVAL))?
+        + colon_idx;
+    let pid_bytes = buffer
+        .get(colon_idx + 1..slash_idx)
+        .ok_or(Error::new(EINVAL))?;
     let pid_str = core::str::from_utf8(pid_bytes).map_err(|_| Error::new(EINVAL))?;
     let pid = pid_str.parse::<usize>().map_err(|_| Error::new(EINVAL))?;
 

+ 38 - 4
src/start.rs

@@ -1,5 +1,5 @@
 use alloc::{boxed::Box, vec::Vec};
-use core::{intrinsics, ptr};
+use core::{fmt::Debug, intrinsics, ptr};
 
 use crate::{
     header::{libgen, stdio, stdlib},
@@ -35,8 +35,20 @@ impl Stack {
     }
 }
 
+impl Debug for Stack {
+    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+        f.debug_struct("Stack")
+            .field("argc", &self.argc)
+            .field("argv0", &self.argv0)
+            .finish()
+    }
+}
+
 unsafe fn copy_string_array(array: *const *const c_char, len: usize) -> Vec<*mut c_char> {
+    // println!("copy_string_array: array: {:p}, len: {}", array, len);
+
     let mut vec = Vec::with_capacity(len + 1);
+
     for i in 0..len {
         let item = *array.add(i);
         let mut len = 0;
@@ -79,14 +91,18 @@ fn alloc_init() {
         }
     }
     unsafe {
+        // dbg!("in alloc init");
         if let Some(tcb) = ld_so::tcb::Tcb::current() {
+            // println!("tcb.mspace {}",tcb.mspace);
             if tcb.mspace != 0 {
                 ALLOCATOR.set_book_keeper(tcb.mspace);
             } else if ALLOCATOR.get_book_keeper() == 0 {
                 ALLOCATOR.set_book_keeper(new_mspace());
             }
         } else if ALLOCATOR.get_book_keeper() == 0 {
+            // dbg!("TRY");
             ALLOCATOR.set_book_keeper(new_mspace());
+            // dbg!("ALLOCATOR OWARI DAWA");
         }
     }
 }
@@ -120,9 +136,11 @@ extern "C" fn init_array() {
         init_complete = true
     }
 }
+
 fn io_init() {
     unsafe {
-        // Initialize stdin/stdout/stderr, see https://github.com/rust-lang/rust/issues/51718
+        // Initialize stdin/stdout/stderr,
+        // see https://github.com/rust-lang/rust/issues/51718
         stdio::stdin = stdio::default_stdin.get();
         stdio::stdout = stdio::default_stdout.get();
         stdio::stderr = stdio::default_stderr.get();
@@ -172,14 +190,19 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
 
     // Ensure correct host system before executing more system calls
     relibc_verify_host();
+    use core::arch::asm;
 
     // Initialize TLS, if necessary
     ld_so::init(sp);
 
+    // println!("alloc init");
+
     // Set up the right allocator...
     // if any memory rust based memory allocation happen before this step .. we are doomed.
     alloc_init();
 
+    // println!("alloc init ok");
+
     if let Some(tcb) = ld_so::tcb::Tcb::current() {
         // Update TCB mspace
         tcb.mspace = ALLOCATOR.get_book_keeper();
@@ -193,16 +216,22 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
         }
     }
 
+    // println!("to copy args");
     // Set up argc and argv
     let argc = sp.argc;
     let argv = sp.argv();
+
     platform::inner_argv = copy_string_array(argv, argc as usize);
+
+    // println!("copy args ok");
     platform::argv = platform::inner_argv.as_mut_ptr();
     // Special code for program_invocation_name and program_invocation_short_name
     if let Some(arg) = platform::inner_argv.get(0) {
         platform::program_invocation_name = *arg;
         platform::program_invocation_short_name = libgen::basename(*arg);
     }
+    // println!("to check environ");
+
     // We check for NULL here since ld.so might already have initialized it for us, and we don't
     // want to overwrite it if constructors in .init_array of dependency libraries have called
     // setenv.
@@ -216,14 +245,17 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
         platform::OUR_ENVIRON = copy_string_array(envp, len);
         platform::environ = platform::OUR_ENVIRON.as_mut_ptr();
     }
+    // println!("to get auxvs");
     let auxvs = get_auxvs(sp.auxv().cast());
+    // println!("to init platform");
     crate::platform::init(auxvs);
 
     // Setup signal stack, otherwise we cannot handle any signals besides SIG_IGN/SIG_DFL behavior.
     #[cfg(target_os = "redox")]
     setup_sigstack();
-
+    // println!("before init_array()");
     init_array();
+    // println!("init_array() ok");
 
     // Run preinit array
     {
@@ -235,9 +267,10 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
         }
     }
 
+    // println!("before _init()");
     // Call init section
     _init();
-
+    // println!("after _init()");
     // Run init array
     {
         let mut f = &__init_array_start as *const _;
@@ -248,6 +281,7 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
         }
     }
 
+    // println!("to run main()");
     // not argv or envp, because programs like bash try to modify this *const* pointer :|
     stdlib::exit(main(argc, platform::argv, platform::environ));