diff --git a/.gitignore b/.gitignore index 87f3c62..f165ffe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build/ target/ .DS_Store +.vscode diff --git a/.travis.yml b/.travis.yml index dad0dc3..8e59c0f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,7 @@ env: - ARCH="aarch64" SRC="all" - ARCH="riscv32" SRC="all" - ARCH="riscv64" SRC="all" + - ARCH="mipsel" SRC="all" matrix: allow_failures: @@ -42,7 +43,7 @@ install: if [ $TRAVIS_OS_NAME = linux ]; then export FILE="gcc-arm-8.2-2018.11-x86_64-aarch64-elf"; wget https://developer.arm.com/-/media/Files/downloads/gnu-a/8.2-2018.11/$FILE.tar.xz; - tar -xvf $FILE.tar.xz; + tar -xf $FILE.tar.xz; export PATH=$PATH:$PWD/$FILE/bin; sudo apt update; sudo apt install linux-headers-$(uname -r); @@ -73,7 +74,7 @@ install: sudo apt update; sudo apt install linux-headers-$(uname -r); wget https://musl.cc/riscv32-linux-musl-cross.tgz; - tar -xvf riscv32-linux-musl-cross.tgz; + tar -xf riscv32-linux-musl-cross.tgz; export PATH=$PATH:$PWD/riscv32-linux-musl-cross/bin; fi; fi @@ -82,10 +83,19 @@ install: sudo apt update; sudo apt install linux-headers-$(uname -r); wget https://musl.cc/riscv64-linux-musl-cross.tgz; - tar -xvf riscv64-linux-musl-cross.tgz; + tar -xf riscv64-linux-musl-cross.tgz; export PATH=$PATH:$PWD/riscv64-linux-musl-cross/bin; fi; fi + - if [ $ARCH = mipsel ]; then + if [ $TRAVIS_OS_NAME = linux ]; then + sudo apt update; + sudo apt install linux-headers-$(uname -r); + wget https://musl.cc/mipsel-linux-musln32-cross.tgz; + tar -xvf mipsel-linux-musln32-cross.tgz; + export PATH=$PATH:$PWD/mipsel-linux-musln32-cross/bin; + fi; + fi before_script: diff --git a/Makefile b/Makefile index 651c0e3..37acd8c 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# arch = {riscv32, riscv64, x86_64, aarch64} +# arch = {riscv32, riscv64, x86_64, aarch64, mipsel} # mode = {debug, release} arch ?= riscv32 mode ?= debug @@ -6,6 +6,8 @@ out_dir ?= build/$(arch) out_img ?= build/$(arch).img out_qcow2 ?= build/$(arch).qcow2 +rcore_fs_fuse_revision ?= 585eb61 + rust_src_dir := rust/src/bin rust_bin_path := rust/target/$(arch)-rcore/$(mode) rust_bins := $(patsubst $(rust_src_dir)/%.rs, $(rust_bin_path)/%, $(wildcard $(rust_src_dir)/*.rs)) @@ -13,8 +15,8 @@ ucore_bin_path := ucore/build/$(arch) biscuit_bin_path := biscuit/build/$(arch) busybox := $(out_dir)/busybox alpine_version_major := 3.9 -alpine_version_full := 3.9.2 -alpine_file := alpine-minirootfs-3.9.2-$(arch).tar.gz +alpine_version_full := 3.9.3 +alpine_file := alpine-minirootfs-3.9.3-$(arch).tar.gz alpine := alpine/$(alpine_file) rust_build_args := --target targets/$(arch)-rcore.json @@ -37,24 +39,20 @@ rust: @cp $(rust_bins) $(out_dir)/rust ucore: -ifneq ($(arch), x86_64) @echo Building ucore programs @mkdir -p ucore/build @cd ucore/build && cmake $(cmake_build_args) .. && make @rm -rf $(out_dir)/ucore && mkdir -p $(out_dir)/ucore @cp $(ucore_bin_path)/* $(out_dir)/ucore -endif biscuit: -ifeq ($(arch), $(filter $(arch), x86_64 aarch64 riscv64)) -ifneq ($(shell uname)-$(arch), Darwin-riscv64) +ifneq ($(shell uname)-$(arch), Darwin-$(filter $(arch), riscv32 riscv64 aarch64)) @echo Building biscuit programs @mkdir -p biscuit/build @cd biscuit/build && cmake $(cmake_build_args) .. && make @rm -rf $(out_dir)/biscuit && mkdir -p $(out_dir)/biscuit @cp $(biscuit_bin_path)/* $(out_dir)/biscuit endif -endif $(busybox): ifeq ($(arch), x86_64) @@ -68,14 +66,13 @@ ifeq ($(arch), $(filter $(arch), x86_64 aarch64)) @mv tmp/bin/busybox $(busybox) @rm -rf tmp && rm busybox.tar.xz endif -ifeq ($(arch), riscv64) - @wget https://github.com/rcore-os/busybox-riscv-prebuilts/raw/master/busybox-1.30.1-riscv64/busybox -O $(busybox) +ifeq ($(arch), $(filter $(arch), riscv64 riscv32 mipsel)) + @wget https://github.com/rcore-os/busybox-prebuilts/raw/master/busybox-1.30.1-${arch}/busybox -O $(busybox) endif busybox: $(busybox) nginx: -ifneq ($(arch), riscv32) ifneq ($(shell uname), Darwin) @echo Building nginx mkdir -p $(out_dir)/usr/local/nginx/conf @@ -84,10 +81,8 @@ ifneq ($(shell uname), Darwin) @cp nginx/build/$(arch)/nginx $(out_dir) @cp nginx/nginx.conf $(out_dir)/usr/local/nginx/conf endif -endif redis: -ifneq ($(arch), riscv64) ifneq ($(shell uname), Darwin) @echo Building redis @mkdir -p $(out_dir) @@ -96,7 +91,6 @@ ifneq ($(shell uname), Darwin) @cp redis/build/$(arch)/redis-cli $(out_dir)/redis-cli @cp redis/redis.conf $(out_dir)/redis.conf endif -endif iperf3: ifeq ($(arch), x86_64) @@ -110,7 +104,7 @@ endif endif $(alpine): - wget "http://dl-cdn.alpinelinux.org/alpine/v3.9/releases/$(arch)/$(alpine_file)" -O $(alpine) + -wget "http://dl-cdn.alpinelinux.org/alpine/v3.9/releases/$(arch)/$(alpine_file)" -O $(alpine) alpine: $(alpine) ifeq ($(arch), $(filter $(arch), x86_64 aarch64)) @@ -119,7 +113,14 @@ ifeq ($(arch), $(filter $(arch), x86_64 aarch64)) @cd $(out_dir) && tar xvf ../../$(alpine) endif -build: rust ucore biscuit $(busybox) nginx redis iperf3 +test: +ifeq ($(arch), $(filter $(arch), x86_64 aarch64)) + @echo setup test DIR + @mkdir -p $(out_dir) + @cp -r testsuits_alpine $(out_dir)/test +endif + +build: rust ucore biscuit $(busybox) nginx redis iperf3 test sfsimg: $(out_qcow2) @@ -132,9 +133,9 @@ $(out_qcow2): $(out_img) @qemu-img resize $@ +1G rcore-fs-fuse: -ifeq ($(shell which rcore-fs-fuse),) +ifneq ($(shell rcore-fs-fuse dir image git-version), $(rcore_fs_fuse_revision)) @echo Installing rcore-fs-fuse - @cargo install rcore-fs-fuse --git https://github.com/rcore-os/rcore-fs --rev ff3dd7d + @cargo install rcore-fs-fuse --git https://github.com/rcore-os/rcore-fs --rev $(rcore_fs_fuse_revision) --force endif clean: diff --git a/README.md b/README.md index a1810da..4a10636 100644 --- a/README.md +++ b/README.md @@ -36,37 +36,41 @@ To build biscuit programs, install musl toolchain first: # 2.1 for macOS musl toolchain for x86_64(,aarch64) $ brew install FileSottile/musl-cross/musl-cross {--with-aarch64} # 2.2 for ubuntu 16.04, we should build gcc-musl for newest musl-1.1.21, please see build-gcc-musl.md for instructions -# 2.3 for riscv musl toolchain, please install [musl-riscv-toolchain](https://github.com/jiegec/musl-riscv-toolchain) +# 2.3 for riscv musl toolchain, please install [musl-riscv-toolchain](https://github.com/jiegec/musl-riscv-toolchain), however, this one might not be able to build redis on rv64 for lack of libatomic ``` Then, build userspace programs for rCore: ```bash -$ make {ucore,biscuit,rust,nginx,redis,all} arch={x86_64,aarch64,riscv32,riscv64} +$ make {ucore,biscuit,rust,nginx,redis,all} arch={x86_64,aarch64,riscv32,riscv64,mipsel} $ make alpine arch={x86_64,aarch64} # if you want to use alpine rootfs -$ make sfsimg arch={x86_64,aarch64,riscv32,riscv64} +$ make test arch={x86_64} # test alpine real apps, e.g. python, gcc, rust, go, lua, etc.(need rootfs with these real apps) +$ make sfsimg arch={x86_64,aarch64,riscv32,riscv64,mipsel} ``` A rootfs is created at `build/$(arch)` and converted to `qcow2`. ## Support matrix -| | x86_64 | aarch64 | riscv32 | riscv64 | -| ------------------ | ------ | ------- | ------- | ------- | -| ucore | ❌ | ✅ | ✅ | ✅ | -| rust | ✅ | ✅ | ✅ | ✅ | -| biscuit | ✅ | ✅ | ❌ | ✅ | -| nginx (linux only) | ✅ | ✅ | ❌ | ✅ | -| redis (linux only) | ✅ | ✅ | ✅ | ❌ | -| busybox | ✅ | ✅ | ❌ | ✅ | -| alpine rootfs | ✅ | ✅ | ❌ | ❌ | -| iperf3 | ✅ | ❌ | ❌ | ❌ | +| | x86_64 | aarch64 | riscv32 | riscv64 | mipsel | +| ------------------ | ------ | ------- | ------- | ------- | ------ | +| ucore | ✅ | ✅ | ✅ | ✅ | ❗ | +| rust | ✅ | ✅ | ✅ | ✅ | ✅ | +| biscuit | ✅ | ✅ | ✅ | ✅ | ✅ | +| nginx (linux only) | ✅ | ✅ | ❗ | ✅ | ❗ | +| redis (linux only) | ✅ | ✅ | ✅ | ✅ | ✅ | +| busybox | ✅ | ✅ | ✅ | ✅ | ✅ | +| alpine rootfs | ✅ | ✅ | ❌ | ❌ | ❌ | +| iperf3 | ✅ | ❌ | ❌ | ❌ | ❌ | +| test | ✅ | ❌ | ❌ | ❌ | ❌ | + +Note: ❗ means workarounds are used so that they may not work properly. ❌ means failure in compiling or not existed on such platform. ## How to run real world programs ### How to use Redis -If redis is dynamically linked to musl (default if you use commands above), you might need to copy `ld-musl-$(arch).so.1` to rootfs `/lib` . Alpine rootfs includes one as well. +If redis is dynamically linked to musl (default if you use commands above), you might need to copy `ld-musl-$(arch).so.1` to rootfs `/lib` by yourself .Alpine rootfs includes one as well. After building redis, you should be able to run redis-server in rCore. Then, start `redis-server` in rCore: @@ -155,4 +159,22 @@ $ printf Built within rCore ``` -Note: the long linker args can be replaced by invoking gcc instead later when we fix the problem. If you encountered `rcore-fs-fuse` panicking, consider upgrading it to latest version. \ No newline at end of file +Note: the long linker args can be replaced by invoking gcc instead later when we fix the problem. If you encountered `rcore-fs-fuse` panicking, consider upgrading it to latest version. + + +### How to test real alpine apps +#### simple test for alpine minifs with little apps +```bash +1. make alpine arch=x86_64 +2. make test arch=x86_64 +3. make sfsimg arch=x86_64 +4. cd $(RCORE_ROOT)/kernel; make run arch=x86_64 mode=release +``` + +#### test gcc/go/python2/python3/ruby/lua/java/rust +```bash +1. download x86_64.qcow2.realapps.xz from cloud tsinghua +2. xz -d x86_64.qcow2.realapps.xz; mv x86_64.qcow2.realapps x86_64.qcow2 +3. mv x86_64.qcow2 $(RCORE_ROOT)/user/build +4. cd $(RCORE_ROOT)/kernel; make run arch=x86_64 mode=release +``` diff --git a/biscuit/CMakeLists.txt b/biscuit/CMakeLists.txt index f05f3d2..a95a3b2 100644 --- a/biscuit/CMakeLists.txt +++ b/biscuit/CMakeLists.txt @@ -23,17 +23,18 @@ find_path(KERNEL_HEADERS_DIR ) # Toolchain + +set(PREFIX ${ARCH}-linux-musl-) + if (${ARCH} STREQUAL x86_64) - set(PREFIX x86_64-linux-musl-) set(CMAKE_C_FLAGS "-m64 -mno-red-zone") elseif (${ARCH} STREQUAL riscv32) - set(PREFIX riscv64-unknown-elf-) - set(CMAKE_C_FLAGS "-march=rv32imac -mabi=ilp32 -mcmodel=medany") + set(CMAKE_C_FLAGS "-march=rv32imafdc -mabi=ilp32d -mcmodel=medany") elseif (${ARCH} STREQUAL riscv64) - set(PREFIX riscv64-linux-musl-) set(CMAKE_C_FLAGS "-march=rv64imafdc -mabi=lp64d -mcmodel=medany") elseif (${ARCH} STREQUAL aarch64) - set(PREFIX aarch64-linux-musl-) +elseif (${ARCH} STREQUAL mipsel) + set(PREFIX ${ARCH}-linux-musln32-) else () message("Unsupported arch: ${ARCH}") endif () diff --git a/biscuit/c/ls.c b/biscuit/c/ls.c index 293b48d..2423fc2 100644 --- a/biscuit/c/ls.c +++ b/biscuit/c/ls.c @@ -34,7 +34,7 @@ void dprint(int fd, char *par, int left, int rec) spec = 's'; else spec = '-'; - printf("%crwxr-xr-x %ld %s\n", spec, st.st_size, de->d_name); + printf("%crwxr-xr-x %ld %s\n", spec, (long)st.st_size, de->d_name); } if (!rec) { if (closedir(dir) == -1) diff --git a/biscuit/c/usertests.c b/biscuit/c/usertests.c index 851fd20..42c7a47 100644 --- a/biscuit/c/usertests.c +++ b/biscuit/c/usertests.c @@ -2798,12 +2798,18 @@ static volatile int go; static void *_locker(void *v) { - while (go != 1) + while (go != 1) { #if defined(__x86_64__) asm volatile("pause\n":::"memory"); #elif defined(__aarch64__) asm volatile("yield\n":::"memory"); +#elif defined(__mips__) || defined(__riscv32__) || defined(__riscv64__) + asm volatile("nop\n":::"memory"); +#else +#warning Yield instruction is not implemented #endif + } + pthread_mutex_t *m = (pthread_mutex_t *)v; int i; for (i = 0; i < ltimes; i++) { @@ -2917,12 +2923,17 @@ static void _condtest(const int nt) go = 0; if (pthread_create(&t[i], NULL, _condsleep, &args[i])) errx(-1, "pthread_ create"); - while (go == 0) + while (go == 0) { #if defined(__x86_64__) asm volatile("pause\n":::"memory"); #elif defined(__aarch64__) asm volatile("yield\n":::"memory"); +#elif defined(__mips__) || defined(__riscv32__) || defined(__riscv64__) + asm volatile("nop\n":::"memory"); +#else +#warning Yield instruction is not implemented #endif + } } for (i = 0; i < nt; i++) diff --git a/iperf3/Makefile b/iperf3/Makefile index 15f34d3..1b6b0b2 100644 --- a/iperf3/Makefile +++ b/iperf3/Makefile @@ -3,11 +3,17 @@ iperf3_tarball := iperf3-$(iperf3_version).tar.gz iperf3_tarball_path := src/$(iperf3_tarball) build_dir := build/$(arch) iperf3_dir := $(build_dir)/iperf-$(iperf3_version) -cc := $(arch)-linux-musl-gcc -strip := $(arch)-linux-musl-strip +prefix := $(arch)-linux-musl- bin_unstripped := build/$(arch)/iperf3_unstripped bin := build/$(arch)/iperf3 +ifeq ($(arch), mipsel) + prefix := mipsel-linux-musln32- +endif + +cc := $(prefix)gcc +strip := $(prefix)strip + $(iperf3_tarball_path): wget https://github.com/esnet/iperf/archive/$(iperf3_version).tar.gz -O $(iperf3_tarball_path) diff --git a/nginx/Makefile b/nginx/Makefile index 014fa04..de22b74 100644 --- a/nginx/Makefile +++ b/nginx/Makefile @@ -3,11 +3,17 @@ nginx_tarball := nginx-$(nginx_version).tar.gz nginx_tarball_path := src/nginx-$(nginx_version).tar.gz build_dir := build/$(arch) nginx_dir := $(build_dir)/nginx-$(nginx_version) -cc := $(arch)-linux-musl-gcc -strip := $(arch)-linux-musl-strip +prefix := $(arch)-linux-musl- bin_unstripped := build/$(arch)/nginx_unstripped bin := build/$(arch)/nginx +ifeq ($(arch), mipsel) + prefix := mipsel-linux-musln32- +endif + +cc := $(prefix)gcc +strip := $(prefix)strip + $(nginx_tarball_path): wget https://nginx.org/download/$(nginx_tarball) -O $(nginx_tarball_path) @@ -21,9 +27,10 @@ $(nginx_dir)/objs/nginx: $(nginx_dir) sed -i 's/ngx_feature_run=yes/ngx_feature_run=no/' $(nginx_dir)/auto/cc/name sed -i 's/ngx_test="$$CC /ngx_test="gcc /' $(nginx_dir)/auto/types/sizeof cd $(nginx_dir) && ./configure --with-cc=$(cc) --with-cc-opt=-static --with-ld-opt=-static --without-pcre --without-http_rewrite_module --without-http_gzip_module --with-poll_module --without-http_upstream_zone_module - cd $(nginx_dir) && echo "#ifndef NGX_SYS_NERR\n#define NGX_SYS_NERR 132\n#endif\n" >> objs/ngx_auto_config.h - cd $(nginx_dir) && echo "#ifndef NGX_HAVE_SVSVSHM\n#define NGX_HAVE_SYSVSHM 1\n#endif\n" >> objs/ngx_auto_config.h - cd $(nginx_dir) && make + cd $(nginx_dir) && printf "#ifndef NGX_SYS_NERR\n#define NGX_SYS_NERR 132\n#endif\n" >> objs/ngx_auto_config.h + cd $(nginx_dir) && printf "#ifndef NGX_HAVE_SVSVSHM\n#define NGX_HAVE_SYSVSHM 1\n#endif\n" >> objs/ngx_auto_config.h + # FIXME: overflow will occur on 32-bit platforms, this is only a temporary workaround + cd $(nginx_dir) && make CFLAGS="${CFLGAS} -Wno-error=overflow" $(bin_unstripped): $(nginx_dir)/objs/nginx cp $(nginx_dir)/objs/nginx $(bin_unstripped) diff --git a/redis/Makefile b/redis/Makefile index 263edbd..2e42614 100644 --- a/redis/Makefile +++ b/redis/Makefile @@ -3,13 +3,19 @@ redis_tarball := redis-$(redis_version).tar.gz redis_tarball_path := src/redis-$(redis_version).tar.gz build_dir := build/$(arch) redis_dir := $(build_dir)/redis-$(redis_version) -cc := $(arch)-linux-musl-gcc -strip := $(arch)-linux-musl-strip +prefix := $(arch)-linux-musl- bin_server_unstripped := build/$(arch)/redis-server-unstripped bin_server := build/$(arch)/redis-server bin_cli_unstripped := build/$(arch)/redis-cli-unstripped bin_cli := build/$(arch)/redis-cli +ifeq ($(arch), mipsel) + prefix := mipsel-linux-musln32- +endif + +cc := $(prefix)gcc +strip := $(prefix)strip + # $ARCH is also used in redis internal Makefile, avoid clashing undefine ARCH @@ -25,7 +31,9 @@ $(redis_dir)/src/redis-server: $(redis_dir)/src/config.h sed -i 's/#define HAVE_EPOLL 1//' $(redis_dir)/src/config.h # our accept does not have backlog sed -i 's/#define MAX_ACCEPTS_PER_CALL 1000/#define MAX_ACCEPTS_PER_CALL 1/' $(redis_dir)/src/networking.c - cd $(redis_dir) && make CC=$(cc) MALLOC=libc + # note: on some platforms gcc seems to forget linking with libatomic, fix it anyway + sed -i 's/-ldl -pthread -lrt/-ldl -pthread -lrt -latomic/' $(redis_dir)/src/Makefile + cd $(redis_dir) && make CC=$(cc) LDFLAGS="${LDFLAGS} -static" MALLOC=libc $(bin_server_unstripped): $(redis_dir)/src/redis-server cp $(redis_dir)/src/redis-server $(bin_server_unstripped) diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 66f055c..1b3e65a 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -62,6 +62,7 @@ dependencies = [ "buddy_system_allocator 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "isomorphic_drivers 0.1.0 (git+https://github.com/rcore-os/isomorphic_drivers)", "smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "treebitmap 0.3.1 (git+https://github.com/jiegec/treebitmap)", ] [[package]] @@ -80,6 +81,11 @@ name = "spin" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "treebitmap" +version = "0.3.1" +source = "git+https://github.com/jiegec/treebitmap#a89d725c1308719e327993dc5c5c0357c43dccf1" + [[package]] name = "volatile" version = "0.2.6" @@ -96,4 +102,5 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum managed 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fdcec5e97041c7f0f1c5b7d93f12e57293c831c646f4cc7a5db59460c7ea8de6" "checksum smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fef582369edb298c6c41319a544ca9c4e83622f226055ccfcb35974fbb55ed34" "checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" +"checksum treebitmap 0.3.1 (git+https://github.com/jiegec/treebitmap)" = "" "checksum volatile 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6af0edf5b4faacc31fc51159244d78d65ec580f021afcef7bd53c04aeabc7f29" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 5c55341..aa3a560 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -7,4 +7,5 @@ edition = "2018" [dependencies] buddy_system_allocator = "0.1" isomorphic_drivers = { git = "https://github.com/rcore-os/isomorphic_drivers", default-features = false, features = ["log"]} -smoltcp = { version = "0.5.0", default-features = false, features = ["alloc", "log", "proto-ipv4", "socket-tcp", "socket-raw"] } \ No newline at end of file +smoltcp = { version = "0.5.0", default-features = false, features = ["alloc", "log", "proto-ipv4", "socket-tcp", "socket-raw"] } +treebitmap = { git = "https://github.com/jiegec/treebitmap" , features = ["alloc"] } \ No newline at end of file diff --git a/rust/src/bin/fantastic_text.rs b/rust/src/bin/fantastic_text.rs index b1403ed..d0770ad 100644 --- a/rust/src/bin/fantastic_text.rs +++ b/rust/src/bin/fantastic_text.rs @@ -32,7 +32,8 @@ pub fn main() { color_text!("!", 97), ); - let text = "reguler \x1b[4munderline\x1b[24m \x1b[7mreverse\x1b[27m \x1b[9mstrikethrough\x1b[29m"; + let text = + "reguler \x1b[4munderline\x1b[24m \x1b[7mreverse\x1b[27m \x1b[9mstrikethrough\x1b[29m"; println!("\x1b[47m{}\x1b[0m", color_text!(text, 30)); for i in 31..38 { println!("{}", color_text!(text, i)); diff --git a/rust/src/bin/float.rs b/rust/src/bin/float.rs index 578ba8e..a07c97d 100644 --- a/rust/src/bin/float.rs +++ b/rust/src/bin/float.rs @@ -7,7 +7,6 @@ extern crate rcore_user; use rcore_user::syscall::*; - // IMPORTANT: Must define main() like this #[no_mangle] pub fn main() { diff --git a/rust/src/bin/raw_socket.rs b/rust/src/bin/raw_socket.rs new file mode 100644 index 0000000..0c903c7 --- /dev/null +++ b/rust/src/bin/raw_socket.rs @@ -0,0 +1,203 @@ +#![feature(alloc)] +#![no_std] +#![no_main] + +#[macro_use] +extern crate rcore_user; +extern crate alloc; + +extern crate treebitmap; + +use alloc::format; +use core::default::Default; +use core::mem::size_of; +use rcore_user::syscall::{sys_ioctl, sys_read, sys_sendto, sys_setsockopt, sys_socket}; +use treebitmap::*; + +#[repr(C)] +#[derive(Default)] +pub struct SockAddrLl { + sll_family: u16, + sll_protocol: u16, + sll_ifindex: u32, + sll_hatype: u16, + sll_pkttype: u8, + sll_halen: u8, + sll_addr: [u8; 8], +} + +#[repr(C)] +#[derive(Default)] +pub struct SockAddrIn { + sin_family: u16, + sin_port: u16, + sin_addr: u32, + sin_zero: [u8; 8], +} + +#[repr(C)] +#[derive(Default)] +pub struct SockAddrHa { + sha_family: u16, + sha_data: [u8; 14], +} + +#[repr(C)] +#[derive(Default)] +struct ArpReq { + arp_pa: SockAddrIn, + arp_ha: SockAddrHa, + arp_flags: u32, + arp_netmask: SockAddrIn, + arp_dev: [u8; 16], +} + +pub fn get_routing_table() -> IpLookupTable { + let mut table = IpLookupTable::new(); + // iface 0 10.0.0.0/24 00:16:31:ff:a4:9f enp0s4f0 + table.insert( + Ipv4Addr::new(10, 0, 0, 0), + 24, + (0, [0x00, 0x16, 0x31, 0xff, 0xa4, 0x9f], "enp0s4f0\0"), + ); + // iface 1 10.0.1.0/24 54:51:9f:71:c0:01 enp0s5f0 + table.insert( + Ipv4Addr::new(10, 0, 1, 0), + 24, + (1, [0x54, 0x51, 0x9f, 0x71, 0xc0, 0x01], "enp0s5f0\0"), + ); + + table +} + +// IMPORTANT: Must define main() like this +#[no_mangle] +pub unsafe fn main() { + println!("Raw socket test"); + + // raw socket, icmp + let capture_fd = sys_socket(2, 3, 1); + // inet socket, udp + let arp_fd = sys_socket(2, 2, 0); + // packet socket, raw + let packet_fd = sys_socket(17, 3, 0); + // netlink socket, raw + let netlink_fd = sys_socket(16, 3, 0); + + let table = get_routing_table(); + + let mut buffer = [0u8; 2048]; + // set header included + let included = 1u32; + sys_setsockopt( + capture_fd as usize, + 0, + 3, + &included as *const u32 as usize, + 4, + ); + + let mut addr: SockAddrLl = Default::default(); + // packet + addr.sll_family = 17; + const ETHER_HEADER_LEN: usize = 6 + 6 + 2; + // ethertype 0x0800 ipv4 + buffer[12] = 0x08; + buffer[13] = 0x00; + + let mut arp: ArpReq = Default::default(); + // inet + arp.arp_pa.sin_family = 2; + loop { + let len = sys_read( + capture_fd as usize, + buffer.as_mut_ptr().add(ETHER_HEADER_LEN), + buffer.len(), + ) as usize; + println!("Got packet of len {}", len); + // check ethertype and ip version ihl + if ETHER_HEADER_LEN + len > 20 + && buffer[12] == 0x08 + && buffer[13] == 0x00 + && buffer[ETHER_HEADER_LEN + 0] == 0x45 + { + // ipv4 + let ttl = buffer[ETHER_HEADER_LEN + 8]; + if ttl > 1 { + if buffer[ETHER_HEADER_LEN + 19] == 2 { + // to myself + println!("packet to myself"); + continue; + } + let lookup_ip = Ipv4Addr::new( + buffer[ETHER_HEADER_LEN + 16], + buffer[ETHER_HEADER_LEN + 17], + buffer[ETHER_HEADER_LEN + 18], + buffer[ETHER_HEADER_LEN + 19], + ); + let route_match = table.longest_match(lookup_ip); + match route_match { + Some((_, _, (out_if, mac, name))) => { + let dst_ip = (buffer[ETHER_HEADER_LEN + 19] as u32) << 24 + | (buffer[ETHER_HEADER_LEN + 18] as u32) << 16 + | (buffer[ETHER_HEADER_LEN + 17] as u32) << 8 + | (buffer[ETHER_HEADER_LEN + 16] as u32); + arp.arp_pa.sin_addr = dst_ip; + arp.arp_dev[0..9].copy_from_slice(name.as_bytes()); + // SIOCGARP + if sys_ioctl(arp_fd as usize, 0x8954, &arp as *const ArpReq as usize) < 0 { + println!("dst ip not in arp table, skipping"); + continue; + } + + let message = format!("from {}.{}.{}.{} {:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X} to {}.{}.{}.{} {:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X} dev {}:{} with ttl {}", buffer[ETHER_HEADER_LEN + 12], + buffer[ETHER_HEADER_LEN+ 13], + buffer[ETHER_HEADER_LEN+ 14], + buffer[ETHER_HEADER_LEN+ 15], + mac[0], + mac[1], + mac[2], + mac[3], + mac[4], + mac[5], + buffer[ETHER_HEADER_LEN+ 16], + buffer[ETHER_HEADER_LEN+ 17], + buffer[ETHER_HEADER_LEN+ 18], + buffer[ETHER_HEADER_LEN+ 19], + arp.arp_ha.sha_data[0], + arp.arp_ha.sha_data[1], + arp.arp_ha.sha_data[2], + arp.arp_ha.sha_data[3], + arp.arp_ha.sha_data[4], + arp.arp_ha.sha_data[5], + out_if, + name, + ttl, + ); + println!("{}", message); + + // fill dst and src mac + // todo: get mac from if instead of hard coding + buffer[0..6].copy_from_slice(&arp.arp_ha.sha_data[0..6]); + buffer[6..12].copy_from_slice(mac); + buffer[ETHER_HEADER_LEN + 8] = ttl - 1; + let checksum = (buffer[ETHER_HEADER_LEN + 10] as u16) << 8 + | (buffer[ETHER_HEADER_LEN + 11] as u16); + buffer[ETHER_HEADER_LEN + 10] = ((checksum + 0x0100) >> 8) as u8; + buffer[ETHER_HEADER_LEN + 11] = (checksum + 0x0100) as u8; + addr.sll_ifindex = *out_if; + sys_sendto( + packet_fd as usize, + buffer.as_ptr(), + len as usize + ETHER_HEADER_LEN, + 0, + &addr as *const SockAddrLl as usize, + size_of::(), + ); + } + None => continue, + } + } + } + } +} diff --git a/rust/src/bin/sh.rs b/rust/src/bin/sh.rs index c7932d4..d271209 100644 --- a/rust/src/bin/sh.rs +++ b/rust/src/bin/sh.rs @@ -10,7 +10,7 @@ use alloc::vec::Vec; use core::ptr; use rcore_user::io::get_line; -use rcore_user::syscall::{sys_exec, sys_vfork, sys_wait, sys_getcwd, sys_chdir, sys_access}; +use rcore_user::syscall::{sys_access, sys_chdir, sys_exec, sys_getcwd, sys_vfork, sys_wait}; // IMPORTANT: Must define main() like this #[no_mangle] diff --git a/rust/src/bin/tls.rs b/rust/src/bin/tls.rs index a963704..d0135a0 100644 --- a/rust/src/bin/tls.rs +++ b/rust/src/bin/tls.rs @@ -5,7 +5,10 @@ #[macro_use] extern crate rcore_user; -use rcore_user::syscall::{sys_arch_prctl, sys_vfork, sys_getpid, sys_sleep}; +use rcore_user::syscall::{sys_arch_prctl, sys_getpid, sys_sleep, sys_vfork}; + +#[cfg(target_arch = "mips")] +use rcore_user::syscall::sys_set_theaad_area; fn set_tls(tls: usize, pid: usize) { #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] @@ -23,6 +26,8 @@ fn set_tls(tls: usize, pid: usize) { // set fs base sys_arch_prctl(0x1002, &DATA[pid] as *const usize as usize); } + #[cfg(target_arch = "mips")] + sys_set_theaad_area(tls); } fn get_tls() -> usize { @@ -39,6 +44,10 @@ fn get_tls() -> usize { unsafe { asm!("mov %fs:0, $0" : "=r"(tls) :); } + #[cfg(target_arch = "mips")] + unsafe { + asm!("rdhwr $0, $$29" : "=r"(tls) :); + } tls } diff --git a/rust/src/io.rs b/rust/src/io.rs index 370101b..21bd6f3 100644 --- a/rust/src/io.rs +++ b/rust/src/io.rs @@ -194,8 +194,8 @@ impl fmt::Write for StdOut { pub const O_RDONLY: usize = 0; // open for reading only pub const O_WRONLY: usize = 1; // open for writing only pub const O_RDWR: usize = 2; // open for reading and writing -// then or in any of these: + // then or in any of these: pub const O_CREAT: usize = 0x00000004; // create file if it does not exist pub const O_EXCL: usize = 0x00000008; // error if O_CREAT and the file exists pub const O_TRUNC: usize = 0x00000010; // truncate file upon open -pub const O_APPEND: usize = 0x00000020; // append on each write \ No newline at end of file +pub const O_APPEND: usize = 0x00000020; // append on each write diff --git a/rust/src/lang_items.rs b/rust/src/lang_items.rs index 67624ad..1900d18 100644 --- a/rust/src/lang_items.rs +++ b/rust/src/lang_items.rs @@ -1,9 +1,9 @@ use crate::syscall::sys_exit; use crate::ALLOCATOR; +use super::syscall::*; use core::alloc::Layout; use core::panic::PanicInfo; -use super::syscall::*; #[linkage = "weak"] #[no_mangle] @@ -14,7 +14,15 @@ fn main() { fn init_heap() { const HEAP_SIZE: usize = 0x1000; static mut HEAP: [u8; HEAP_SIZE] = [0; HEAP_SIZE]; - unsafe { ALLOCATOR.lock().init(HEAP.as_ptr() as usize, HEAP_SIZE); } + unsafe { + ALLOCATOR.lock().init(HEAP.as_ptr() as usize, HEAP_SIZE); + } +} + +/// MIPS use __start for entry point instead of _start +#[no_mangle] +pub extern "C" fn __start(argc: isize, argv: *const *const u8) -> ! { + _start(argc, argv) } #[no_mangle] diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 1b22e9a..e345aba 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -10,10 +10,10 @@ extern crate alloc; #[macro_use] pub mod io; -pub mod syscall; pub mod lang_items; +pub mod syscall; use buddy_system_allocator::LockedHeap; #[global_allocator] -static ALLOCATOR: LockedHeap = LockedHeap::empty(); \ No newline at end of file +static ALLOCATOR: LockedHeap = LockedHeap::empty(); diff --git a/rust/src/syscall.rs b/rust/src/syscall.rs index 5b36464..78ab96d 100644 --- a/rust/src/syscall.rs +++ b/rust/src/syscall.rs @@ -2,35 +2,57 @@ use crate::ALLOCATOR; use alloc::string::String; #[inline(always)] -fn sys_call(syscall_id: SyscallId, arg0: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> i32 { +fn sys_call( + syscall_id: SyscallId, + arg0: usize, + arg1: usize, + arg2: usize, + arg3: usize, + arg4: usize, + arg5: usize, +) -> i32 { let id = syscall_id as usize; - let ret: i32; + let mut ret: i32; + let failed: i32; unsafe { #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] - asm!("ecall" + asm!("ecall" : "={x10}" (ret) : "{x17}" (id), "{x10}" (arg0), "{x11}" (arg1), "{x12}" (arg2), "{x13}" (arg3), "{x14}" (arg4), "{x15}" (arg5) : "memory" : "volatile"); #[cfg(target_arch = "x86")] - asm!("int 0x80" + asm!("int 0x80" : "={eax}" (ret) : "{eax}" (id), "{edx}" (arg0), "{ecx}" (arg1), "{ebx}" (arg2), "{edi}" (arg3), "{esi}" (arg4) : "memory" : "intel" "volatile"); #[cfg(target_arch = "x86_64")] - asm!("syscall" + asm!("syscall" : "={rax}" (ret) : "{rax}" (id), "{rdi}" (arg0), "{rsi}" (arg1), "{rdx}" (arg2), "{r10}" (arg3), "{r8}" (arg4), "{r9}" (arg5) : "rcx" "r11" "memory" : "intel" "volatile"); #[cfg(target_arch = "aarch64")] - asm!("svc 0" + asm!("svc 0" : "={x0}" (ret) : "{x8}" (id), "{x0}" (arg0), "{x1}" (arg1), "{x2}" (arg2), "{x3}" (arg3), "{x4}" (arg4), "{x5}" (arg5) : "memory" : "volatile"); + #[cfg(target_arch = "mips")] + { + asm!("syscall" + // v0 for syscall id + : "={$2}" (ret), "={$7}" (failed) + // v0, a0, a1, a2, a3, a4, a5 + : "{$2}" (id), "{$4}" (arg0), "{$5}" (arg1), "{$6}" (arg2), "{$7}" (arg3), "{$8}" (arg4), "{$9}" (arg5) + : "memory" + : "volatile"); + if failed != 0 { + ret = - ret; + } + } } ret } @@ -38,7 +60,9 @@ fn sys_call(syscall_id: SyscallId, arg0: usize, arg1: usize, arg2: usize, arg3: pub fn enlarge_heap() { const HEAP_SIZE: usize = 16 * 1024 * 1024; let addr = sys_mmap(0, HEAP_SIZE, 0x3, 0x22, 0, 0) as usize; - unsafe { ALLOCATOR.lock().init(addr, HEAP_SIZE); } + unsafe { + ALLOCATOR.lock().init(addr, HEAP_SIZE); + } } pub fn sys_exit(code: usize) -> ! { @@ -46,9 +70,16 @@ pub fn sys_exit(code: usize) -> ! { unreachable!() } - pub fn sys_exec(name: *const u8, argv: *const *const u8, envp: *const *const u8) -> i32 { - sys_call(SyscallId::Exec, name as usize, argv as usize, envp as usize, 0, 0, 0) + sys_call( + SyscallId::Exec, + name as usize, + argv as usize, + envp as usize, + 0, + 0, + 0, + ) } pub fn sys_write(fd: usize, base: *const u8, len: usize) -> i32 { @@ -65,7 +96,15 @@ pub fn sys_open(path: &str, flags: usize) -> i32 { let end = unsafe { &mut *(path.as_ptr().offset(path.len() as isize) as *mut u8) }; let backup = replace(end, 0); const AT_FDCWD: isize = -100; - let ret = sys_call(SyscallId::Openat, AT_FDCWD as usize, path.as_ptr() as usize, flags, 0, 0, 0); + let ret = sys_call( + SyscallId::Openat, + AT_FDCWD as usize, + path.as_ptr() as usize, + flags, + 0, + 0, + 0, + ); *end = backup; ret } @@ -89,7 +128,15 @@ pub fn sys_vfork() -> i32 { const CLONE_VFORK: usize = 0x00004000; const CLONE_VM: usize = 0x00000100; const SIGCHILD: usize = 17; - sys_call(SyscallId::Clone, CLONE_VFORK | CLONE_VM | SIGCHILD, sp, 0, 0, 0, 0) + sys_call( + SyscallId::Clone, + CLONE_VFORK | CLONE_VM | SIGCHILD, + sp, + 0, + 0, + 0, + 0, + ) } /// Wait the process exit. @@ -122,13 +169,29 @@ pub fn sys_getcwd() -> String { /// Change the current working directory pub fn sys_chdir(path: &str) { let path = String::from(path) + "\0"; - sys_call(SyscallId::Chdir, path.as_bytes().as_ptr() as usize, 0, 0, 0, 0, 0); + sys_call( + SyscallId::Chdir, + path.as_bytes().as_ptr() as usize, + 0, + 0, + 0, + 0, + 0, + ); } /// Check file accessibility pub fn sys_access(path: &str) -> i32 { let path = String::from(path) + "\0"; - sys_call(SyscallId::FAccessAt, -100isize as usize, path.as_bytes().as_ptr() as usize, 0, 0, 0, 0) + sys_call( + SyscallId::FAccessAt, + -100isize as usize, + path.as_bytes().as_ptr() as usize, + 0, + 0, + 0, + 0, + ) } #[repr(C)] @@ -141,9 +204,17 @@ pub struct TimeSpec { pub fn sys_sleep(time: usize) -> i32 { let ts = TimeSpec { sec: time as u64, - nsec: 0 + nsec: 0, }; - sys_call(SyscallId::Sleep, &ts as *const TimeSpec as usize, 0, 0, 0, 0, 0) + sys_call( + SyscallId::Sleep, + &ts as *const TimeSpec as usize, + 0, + 0, + 0, + 0, + 0, + ) } pub fn sys_get_time() -> i32 { @@ -164,13 +235,59 @@ pub fn sys_map_pci_device(vendor: usize, product: usize) -> i32 { pub fn sys_get_paddr(vaddr: &[u64], paddr: &mut [u64]) -> i32 { assert_eq!(vaddr.len(), paddr.len()); - sys_call(SyscallId::GetPaddr, vaddr.as_ptr() as usize, paddr.as_ptr() as usize, vaddr.len(), 0, 0, 0) + sys_call( + SyscallId::GetPaddr, + vaddr.as_ptr() as usize, + paddr.as_ptr() as usize, + vaddr.len(), + 0, + 0, + 0, + ) } -pub fn sys_mmap(addr: usize, len: usize, prot: usize, flags: usize, fd: usize, offset: usize) -> i32 { +pub fn sys_mmap( + addr: usize, + len: usize, + prot: usize, + flags: usize, + fd: usize, + offset: usize, +) -> i32 { sys_call(SyscallId::Mmap, addr, len, prot, flags, fd, offset) } +pub fn sys_socket(domain: usize, socket_type: usize, protocol: usize) -> i32 { + sys_call(SyscallId::Socket, domain, socket_type, protocol, 0, 0, 0) +} + +pub fn sys_setsockopt(fd: usize, level: usize, opt: usize, optval: usize, optlen: usize) -> i32 { + sys_call(SyscallId::SetSockOpt, fd, level, opt, optval, optlen, 0) +} + +pub fn sys_sendto( + fd: usize, + base: *const u8, + len: usize, + flags: usize, + addr: usize, + addr_len: usize, +) -> i32 { + sys_call( + SyscallId::SendTo, + fd, + base as usize, + len, + flags, + addr, + addr_len, + ) +} + +pub fn sys_ioctl(fd: usize, request: usize, arg1: usize) -> i32 { + sys_call(SyscallId::Ioctl, fd, request, arg1, 0, 0, 0) +} + #[cfg(target_arch = "x86_64")] #[allow(dead_code)] enum SyscallId { @@ -181,9 +298,13 @@ enum SyscallId { Seek = 8, Mmap = 9, Munmap = 11, + Ioctl = 16, Yield = 24, Sleep = 35, GetPid = 39, + Socket = 41, + SendTo = 44, + SetSockOpt = 54, Clone = 56, Exec = 59, Exit = 60, @@ -204,7 +325,52 @@ enum SyscallId { GetPaddr = 998, } -#[cfg(not(target_arch = "x86_64"))] +#[cfg(target_arch = "mips")] +pub fn sys_set_theaad_area(tls: usize) { + sys_call(SyscallId::SetThreadArea, tls, 0, 0, 0, 0, 0); +} + +// only for mips N32 abi +// see https://git.linux-mips.org/cgit/ralf/linux.git/tree/arch/mips/include/uapi/asm/unistd.h +#[cfg(target_arch = "mips")] +#[allow(dead_code)] +enum SyscallId { + Read = 4003, + Write = 4004, + Close = 4006, + Fstat = 4198, + Seek = 4018, + Mmap = 4090, + Munmap = 4091, + Ioctl = 4054, + Yield = 4162, + Sleep = 4166, + GetPid = 4020, + Socket = 4183, + SendTo = 4180, + SetSockOpt = 4181, + Clone = 4120, + Exec = 4011, + Exit = 4001, + Wait = 4114, + Kill = 4037, + Fsync = 4118, + GetCwd = 4203, + Chdir = 4012, + GetTime = 4078, + SetPriority = 4097, + SetThreadArea = 4283, + ArchPrctl = -1, + GetDirEntry64 = 4219, + Openat = 4288, + FAccessAt = 4300, + Dup3 = 4327, + // custom + MapPciDevice = 999, + GetPaddr = 998, +} + +#[cfg(not(any(target_arch = "x86_64", target_arch = "mips")))] #[allow(dead_code)] enum SyscallId { Read = 63, @@ -214,7 +380,11 @@ enum SyscallId { Seek = 62, Mmap = 222, Munmap = 215, + Ioctl = 29, Yield = 124, + Socket = 198, + SendTo = 206, + SetSockOpt = 208, Sleep = 101, GetPid = 172, Clone = 220, diff --git a/rust/targets/mipsel-rcore.json b/rust/targets/mipsel-rcore.json new file mode 100644 index 0000000..582df4f --- /dev/null +++ b/rust/targets/mipsel-rcore.json @@ -0,0 +1,32 @@ +{ + "arch": "mips", + "cpu": "mips32r2", + "llvm-target": "mipsel-unknown-none", + "data-layout": "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64", + "target-endian": "little", + "target-pointer-width": "32", + "target-c-int-width": "32", + "os": "none", + "features": "+mips32r2,+soft-float", + "max-atomic-width": "32", + "linker": "rust-lld", + "linker-flavor": "ld.lld", + "executables": true, + "panic-strategy": "abort", + "relocation-model": "static", + "abi-blacklist": [ + "cdecl", + "stdcall", + "fastcall", + "vectorcall", + "thiscall", + "aapcs", + "win64", + "sysv64", + "ptx-kernel", + "msp430-interrupt", + "x86-interrupt" + ], + "eliminate-frame-pointer": false + } + \ No newline at end of file diff --git a/testsuits_alpine/HelloWorld.class b/testsuits_alpine/HelloWorld.class new file mode 100644 index 0000000..ec7eb39 Binary files /dev/null and b/testsuits_alpine/HelloWorld.class differ diff --git a/testsuits_alpine/HelloWorld.java b/testsuits_alpine/HelloWorld.java new file mode 100644 index 0000000..c58ed11 --- /dev/null +++ b/testsuits_alpine/HelloWorld.java @@ -0,0 +1,6 @@ + +public class HelloWorld { + public static void main(String[] args) { + System.out.println("Hello World"); + } +} diff --git a/testsuits_alpine/brk.c b/testsuits_alpine/brk.c new file mode 100644 index 0000000..909e2be --- /dev/null +++ b/testsuits_alpine/brk.c @@ -0,0 +1,27 @@ +/* sbrk and brk example */ +#include +#include +#include + +int main(int argc, char ** argv) +{ + int *curr_brk, *tmp_brk = NULL; + int num,i; + if(argc >1) { num=atoi(argv[1]);} + printf("Welcome to sbrk example:%d num %d\n", getpid(),num); + for(i=0;i +#include + +int main(void) { + void *b; + char *p, *end; + + b = sbrk(0); + p = (char *)b; + end = p + 0x1000000; + brk(end); + while (p < end) { + *(p++) = 1; + } + brk(b); + return 0; +} diff --git a/testsuits_alpine/build.sh b/testsuits_alpine/build.sh new file mode 100755 index 0000000..d56d777 --- /dev/null +++ b/testsuits_alpine/build.sh @@ -0,0 +1,10 @@ +gcc -c dlmain.c -o dlmain.o +gcc -c func.c -o func.o +cc -shared -fPIC func.c -o libfunc.so +gcc dlmain.c libfunc.so -o dlmain + +go build hello.go + +javac HelloWorld.java + +#java HelloWorld diff --git a/testsuits_alpine/dlmain b/testsuits_alpine/dlmain new file mode 100755 index 0000000..5065f0e Binary files /dev/null and b/testsuits_alpine/dlmain differ diff --git a/testsuits_alpine/dlmain.c b/testsuits_alpine/dlmain.c new file mode 100644 index 0000000..e93d9cb --- /dev/null +++ b/testsuits_alpine/dlmain.c @@ -0,0 +1,6 @@ +#include "func.h" +int main() +{ + func(); + return 0; +} diff --git a/testsuits_alpine/dlmain.o b/testsuits_alpine/dlmain.o new file mode 100644 index 0000000..69b6769 Binary files /dev/null and b/testsuits_alpine/dlmain.o differ diff --git a/testsuits_alpine/env.c b/testsuits_alpine/env.c new file mode 100644 index 0000000..f606a33 --- /dev/null +++ b/testsuits_alpine/env.c @@ -0,0 +1,26 @@ +#include +#include +#include + +extern char **environ; +char **env ; +int main() +{ +env= environ; +while(*environ){ + puts(*environ); + environ++; +} + +char * p; +puts("----------------------\n"); +if((p=getenv("USER"))) +printf("USER =%s\n",p); +setenv("USER","test",1); +printf("USER=%s\n",getenv("USER")); +//unsetenv("USER"); +//printf("USER=%s\n",getenv("USER")); +char * argv[]={"env2", NULL}; +execve("./env2",argv,env); +return 0; +} diff --git a/testsuits_alpine/env1 b/testsuits_alpine/env1 new file mode 100755 index 0000000..613fd92 Binary files /dev/null and b/testsuits_alpine/env1 differ diff --git a/testsuits_alpine/env1.c b/testsuits_alpine/env1.c new file mode 100644 index 0000000..f606a33 --- /dev/null +++ b/testsuits_alpine/env1.c @@ -0,0 +1,26 @@ +#include +#include +#include + +extern char **environ; +char **env ; +int main() +{ +env= environ; +while(*environ){ + puts(*environ); + environ++; +} + +char * p; +puts("----------------------\n"); +if((p=getenv("USER"))) +printf("USER =%s\n",p); +setenv("USER","test",1); +printf("USER=%s\n",getenv("USER")); +//unsetenv("USER"); +//printf("USER=%s\n",getenv("USER")); +char * argv[]={"env2", NULL}; +execve("./env2",argv,env); +return 0; +} diff --git a/testsuits_alpine/env1.i b/testsuits_alpine/env1.i new file mode 100644 index 0000000..37475d7 --- /dev/null +++ b/testsuits_alpine/env1.i @@ -0,0 +1,490 @@ +# 1 "env1.c" +# 1 "" +# 1 "" +# 31 "" +# 1 "/usr/include/stdc-predef.h" 1 3 4 +# 32 "" 2 +# 1 "env1.c" +# 1 "/usr/include/stdlib.h" 1 3 4 + + + + + + + +# 1 "/usr/include/features.h" 1 3 4 +# 9 "/usr/include/stdlib.h" 2 3 4 +# 19 "/usr/include/stdlib.h" 3 4 +# 1 "/usr/include/bits/alltypes.h" 1 3 4 +# 18 "/usr/include/bits/alltypes.h" 3 4 + +# 18 "/usr/include/bits/alltypes.h" 3 4 +typedef int wchar_t; +# 101 "/usr/include/bits/alltypes.h" 3 4 +typedef unsigned long size_t; +# 20 "/usr/include/stdlib.h" 2 3 4 + +int atoi (const char *); +long atol (const char *); +long long atoll (const char *); +double atof (const char *); + +float strtof (const char *restrict, char **restrict); +double strtod (const char *restrict, char **restrict); +long double strtold (const char *restrict, char **restrict); + +long strtol (const char *restrict, char **restrict, int); +unsigned long strtoul (const char *restrict, char **restrict, int); +long long strtoll (const char *restrict, char **restrict, int); +unsigned long long strtoull (const char *restrict, char **restrict, int); + +int rand (void); +void srand (unsigned); + +void *malloc (size_t); +void *calloc (size_t, size_t); +void *realloc (void *, size_t); +void free (void *); +void *aligned_alloc(size_t, size_t); + +_Noreturn void abort (void); +int atexit (void (*) (void)); +_Noreturn void exit (int); +_Noreturn void _Exit (int); +int at_quick_exit (void (*) (void)); +_Noreturn void quick_exit (int); + +char *getenv (const char *); + +int system (const char *); + +void *bsearch (const void *, const void *, size_t, size_t, int (*)(const void *, const void *)); +void qsort (void *, size_t, size_t, int (*)(const void *, const void *)); + +int abs (int); +long labs (long); +long long llabs (long long); + +typedef struct { int quot, rem; } div_t; +typedef struct { long quot, rem; } ldiv_t; +typedef struct { long long quot, rem; } lldiv_t; + +div_t div (int, int); +ldiv_t ldiv (long, long); +lldiv_t lldiv (long long, long long); + +int mblen (const char *, size_t); +int mbtowc (wchar_t *restrict, const char *restrict, size_t); +int wctomb (char *, wchar_t); +size_t mbstowcs (wchar_t *restrict, const char *restrict, size_t); +size_t wcstombs (char *restrict, const wchar_t *restrict, size_t); + + + + +size_t __ctype_get_mb_cur_max(void); +# 99 "/usr/include/stdlib.h" 3 4 +int posix_memalign (void **, size_t, size_t); +int setenv (const char *, const char *, int); +int unsetenv (const char *); +int mkstemp (char *); +int mkostemp (char *, int); +char *mkdtemp (char *); +int getsubopt (char **, char *const *, char **); +int rand_r (unsigned *); + + + + + + +char *realpath (const char *restrict, char *restrict); +long int random (void); +void srandom (unsigned int); +char *initstate (unsigned int, char *, size_t); +char *setstate (char *); +int putenv (char *); +int posix_openpt (int); +int grantpt (int); +int unlockpt (int); +char *ptsname (int); +char *l64a (long); +long a64l (const char *); +void setkey (const char *); +double drand48 (void); +double erand48 (unsigned short [3]); +long int lrand48 (void); +long int nrand48 (unsigned short [3]); +long mrand48 (void); +long jrand48 (unsigned short [3]); +void srand48 (long); +unsigned short *seed48 (unsigned short [3]); +void lcong48 (unsigned short [7]); + + + +# 1 "/usr/include/alloca.h" 1 3 4 +# 9 "/usr/include/alloca.h" 3 4 +# 1 "/usr/include/bits/alltypes.h" 1 3 4 +# 10 "/usr/include/alloca.h" 2 3 4 + +void *alloca(size_t); +# 139 "/usr/include/stdlib.h" 2 3 4 +char *mktemp (char *); +int mkstemps (char *, int); +int mkostemps (char *, int, int); +void *valloc (size_t); +void *memalign(size_t, size_t); +int getloadavg(double *, int); +int clearenv(void); +# 2 "env1.c" 2 +# 1 "/usr/include/stdio.h" 1 3 4 +# 22 "/usr/include/stdio.h" 3 4 +# 1 "/usr/include/bits/alltypes.h" 1 3 4 + + + + + +typedef __builtin_va_list va_list; + + + + +typedef __builtin_va_list __isoc_va_list; +# 116 "/usr/include/bits/alltypes.h" 3 4 +typedef long ssize_t; +# 203 "/usr/include/bits/alltypes.h" 3 4 +typedef long off_t; +# 356 "/usr/include/bits/alltypes.h" 3 4 +typedef struct _IO_FILE FILE; +# 23 "/usr/include/stdio.h" 2 3 4 +# 50 "/usr/include/stdio.h" 3 4 +typedef union _G_fpos64_t { + char __opaque[16]; + long long __lldata; + double __align; +} fpos_t; + +extern FILE *const stdin; +extern FILE *const stdout; +extern FILE *const stderr; + + + + + +FILE *fopen(const char *restrict, const char *restrict); +FILE *freopen(const char *restrict, const char *restrict, FILE *restrict); +int fclose(FILE *); + +int remove(const char *); +int rename(const char *, const char *); + +int feof(FILE *); +int ferror(FILE *); +int fflush(FILE *); +void clearerr(FILE *); + +int fseek(FILE *, long, int); +long ftell(FILE *); +void rewind(FILE *); + +int fgetpos(FILE *restrict, fpos_t *restrict); +int fsetpos(FILE *, const fpos_t *); + +size_t fread(void *restrict, size_t, size_t, FILE *restrict); +size_t fwrite(const void *restrict, size_t, size_t, FILE *restrict); + +int fgetc(FILE *); +int getc(FILE *); +int getchar(void); +int ungetc(int, FILE *); + +int fputc(int, FILE *); +int putc(int, FILE *); +int putchar(int); + +char *fgets(char *restrict, int, FILE *restrict); + + + + +int fputs(const char *restrict, FILE *restrict); +int puts(const char *); + +int printf(const char *restrict, ...); +int fprintf(FILE *restrict, const char *restrict, ...); +int sprintf(char *restrict, const char *restrict, ...); +int snprintf(char *restrict, size_t, const char *restrict, ...); + +int vprintf(const char *restrict, __isoc_va_list); +int vfprintf(FILE *restrict, const char *restrict, __isoc_va_list); +int vsprintf(char *restrict, const char *restrict, __isoc_va_list); +int vsnprintf(char *restrict, size_t, const char *restrict, __isoc_va_list); + +int scanf(const char *restrict, ...); +int fscanf(FILE *restrict, const char *restrict, ...); +int sscanf(const char *restrict, const char *restrict, ...); +int vscanf(const char *restrict, __isoc_va_list); +int vfscanf(FILE *restrict, const char *restrict, __isoc_va_list); +int vsscanf(const char *restrict, const char *restrict, __isoc_va_list); + +void perror(const char *); + +int setvbuf(FILE *restrict, char *restrict, int, size_t); +void setbuf(FILE *restrict, char *restrict); + +char *tmpnam(char *); +FILE *tmpfile(void); + + + + +FILE *fmemopen(void *restrict, size_t, const char *restrict); +FILE *open_memstream(char **, size_t *); +FILE *fdopen(int, const char *); +FILE *popen(const char *, const char *); +int pclose(FILE *); +int fileno(FILE *); +int fseeko(FILE *, off_t, int); +off_t ftello(FILE *); +int dprintf(int, const char *restrict, ...); +int vdprintf(int, const char *restrict, __isoc_va_list); +void flockfile(FILE *); +int ftrylockfile(FILE *); +void funlockfile(FILE *); +int getc_unlocked(FILE *); +int getchar_unlocked(void); +int putc_unlocked(int, FILE *); +int putchar_unlocked(int); +ssize_t getdelim(char **restrict, size_t *restrict, int, FILE *restrict); +ssize_t getline(char **restrict, size_t *restrict, FILE *restrict); +int renameat(int, const char *, int, const char *); +char *ctermid(char *); + + + + + + + +char *tempnam(const char *, const char *); + + + + +char *cuserid(char *); +void setlinebuf(FILE *); +void setbuffer(FILE *, char *, size_t); +int fgetc_unlocked(FILE *); +int fputc_unlocked(int, FILE *); +int fflush_unlocked(FILE *); +size_t fread_unlocked(void *, size_t, size_t, FILE *); +size_t fwrite_unlocked(const void *, size_t, size_t, FILE *); +void clearerr_unlocked(FILE *); +int feof_unlocked(FILE *); +int ferror_unlocked(FILE *); +int fileno_unlocked(FILE *); +int getw(FILE *); +int putw(int, FILE *); +char *fgetln(FILE *, size_t *); +int asprintf(char **, const char *, ...); +int vasprintf(char **, const char *, __isoc_va_list); +# 3 "env1.c" 2 +# 1 "/usr/include/unistd.h" 1 3 4 +# 33 "/usr/include/unistd.h" 3 4 +# 1 "/usr/include/bits/alltypes.h" 1 3 4 +# 121 "/usr/include/bits/alltypes.h" 3 4 +typedef long intptr_t; +# 276 "/usr/include/bits/alltypes.h" 3 4 +typedef int pid_t; +# 286 "/usr/include/bits/alltypes.h" 3 4 +typedef unsigned uid_t; + + + + +typedef unsigned gid_t; +# 301 "/usr/include/bits/alltypes.h" 3 4 +typedef unsigned useconds_t; +# 34 "/usr/include/unistd.h" 2 3 4 + +int pipe(int [2]); +int pipe2(int [2], int); +int close(int); +int posix_close(int, int); +int dup(int); +int dup2(int, int); +int dup3(int, int, int); +off_t lseek(int, off_t, int); +int fsync(int); +int fdatasync(int); + +ssize_t read(int, void *, size_t); +ssize_t write(int, const void *, size_t); +ssize_t pread(int, void *, size_t, off_t); +ssize_t pwrite(int, const void *, size_t, off_t); + +int chown(const char *, uid_t, gid_t); +int fchown(int, uid_t, gid_t); +int lchown(const char *, uid_t, gid_t); +int fchownat(int, const char *, uid_t, gid_t, int); + +int link(const char *, const char *); +int linkat(int, const char *, int, const char *, int); +int symlink(const char *, const char *); +int symlinkat(const char *, int, const char *); +ssize_t readlink(const char *restrict, char *restrict, size_t); +ssize_t readlinkat(int, const char *restrict, char *restrict, size_t); +int unlink(const char *); +int unlinkat(int, const char *, int); +int rmdir(const char *); +int truncate(const char *, off_t); +int ftruncate(int, off_t); + + + + + + +int access(const char *, int); +int faccessat(int, const char *, int, int); + +int chdir(const char *); +int fchdir(int); +char *getcwd(char *, size_t); + +unsigned alarm(unsigned); +unsigned sleep(unsigned); +int pause(void); + +pid_t fork(void); +int execve(const char *, char *const [], char *const []); +int execv(const char *, char *const []); +int execle(const char *, const char *, ...); +int execl(const char *, const char *, ...); +int execvp(const char *, char *const []); +int execlp(const char *, const char *, ...); +int fexecve(int, char *const [], char *const []); +_Noreturn void _exit(int); + +pid_t getpid(void); +pid_t getppid(void); +pid_t getpgrp(void); +pid_t getpgid(pid_t); +int setpgid(pid_t, pid_t); +pid_t setsid(void); +pid_t getsid(pid_t); +char *ttyname(int); +int ttyname_r(int, char *, size_t); +int isatty(int); +pid_t tcgetpgrp(int); +int tcsetpgrp(int, pid_t); + +uid_t getuid(void); +uid_t geteuid(void); +gid_t getgid(void); +gid_t getegid(void); +int getgroups(int, gid_t []); +int setuid(uid_t); +int seteuid(uid_t); +int setgid(gid_t); +int setegid(gid_t); + +char *getlogin(void); +int getlogin_r(char *, size_t); +int gethostname(char *, size_t); +char *ctermid(char *); + +int getopt(int, char * const [], const char *); +extern char *optarg; +extern int optind, opterr, optopt; + +long pathconf(const char *, int); +long fpathconf(int, int); +long sysconf(int); +size_t confstr(int, char *, size_t); + + + + + + +int setreuid(uid_t, uid_t); +int setregid(gid_t, gid_t); +int lockf(int, int, off_t); +long gethostid(void); +int nice(int); +void sync(void); +pid_t setpgrp(void); +char *crypt(const char *, const char *); +void encrypt(char *, int); +void swab(const void *restrict, void *restrict, ssize_t); + + + + +int usleep(unsigned); +unsigned ualarm(unsigned, unsigned); + + + + + + +int brk(void *); +void *sbrk(intptr_t); +pid_t vfork(void); +int vhangup(void); +int chroot(const char *); +int getpagesize(void); +int getdtablesize(void); +int sethostname(const char *, size_t); +int getdomainname(char *, size_t); +int setdomainname(const char *, size_t); +int setgroups(size_t, const gid_t *); +char *getpass(const char *); +int daemon(int, int); +void setusershell(void); +void endusershell(void); +char *getusershell(void); +int acct(const char *); +long syscall(long, ...); +int execvpe(const char *, char *const [], char *const []); +int issetugid(void); +int getentropy(void *, size_t); +# 252 "/usr/include/unistd.h" 3 4 +# 1 "/usr/include/bits/posix.h" 1 3 4 +# 253 "/usr/include/unistd.h" 2 3 4 +# 4 "env1.c" 2 + + +# 5 "env1.c" +extern char **environ; +char **env ; +int main() +{ +env= environ; +while(*environ){ + puts(*environ); + environ++; +} + +char * p; +puts("----------------------\n"); +if((p=getenv("USER"))) +printf("USER =%s\n",p); +setenv("USER","test",1); +printf("USER=%s\n",getenv("USER")); + + +char * argv[]={"env2", +# 23 "env1.c" 3 4 + ((void*)0) +# 23 "env1.c" + }; +execve("./env2",argv,env); +return 0; +} diff --git a/testsuits_alpine/env1.o b/testsuits_alpine/env1.o new file mode 100644 index 0000000..e7cf24b Binary files /dev/null and b/testsuits_alpine/env1.o differ diff --git a/testsuits_alpine/env1.s b/testsuits_alpine/env1.s new file mode 100644 index 0000000..bcc7724 --- /dev/null +++ b/testsuits_alpine/env1.s @@ -0,0 +1,94 @@ + .file "env1.c" + .text + .comm env,8,8 + .section .rodata +.LC0: + .string "----------------------\n" +.LC1: + .string "USER" +.LC2: + .string "USER =%s\n" +.LC3: + .string "test" +.LC4: + .string "USER=%s\n" +.LC5: + .string "env2" +.LC6: + .string "./env2" + .text + .globl main + .type main, @function +main: +.LFB0: + .cfi_startproc + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + subq $48, %rsp + movq %fs:40, %rax + movq %rax, -8(%rbp) + xorl %eax, %eax + movq environ(%rip), %rax + movq %rax, env(%rip) + jmp .L2 +.L3: + movq environ(%rip), %rax + movq (%rax), %rax + movq %rax, %rdi + call puts@PLT + movq environ(%rip), %rax + addq $8, %rax + movq %rax, environ(%rip) +.L2: + movq environ(%rip), %rax + movq (%rax), %rax + testq %rax, %rax + jne .L3 + leaq .LC0(%rip), %rdi + call puts@PLT + leaq .LC1(%rip), %rdi + call getenv@PLT + movq %rax, -40(%rbp) + cmpq $0, -40(%rbp) + je .L4 + movq -40(%rbp), %rax + movq %rax, %rsi + leaq .LC2(%rip), %rdi + movl $0, %eax + call printf@PLT +.L4: + movl $1, %edx + leaq .LC3(%rip), %rsi + leaq .LC1(%rip), %rdi + call setenv@PLT + leaq .LC1(%rip), %rdi + call getenv@PLT + movq %rax, %rsi + leaq .LC4(%rip), %rdi + movl $0, %eax + call printf@PLT + leaq .LC5(%rip), %rax + movq %rax, -32(%rbp) + movq $0, -24(%rbp) + movq env(%rip), %rdx + leaq -32(%rbp), %rax + movq %rax, %rsi + leaq .LC6(%rip), %rdi + call execve@PLT + movl $0, %eax + movq -8(%rbp), %rcx + xorq %fs:40, %rcx + je .L6 + call __stack_chk_fail@PLT +.L6: + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size main, .-main + .ident "GCC: (Alpine 8.2.0) 8.2.0" + .section .note.GNU-stack,"",@progbits diff --git a/testsuits_alpine/env2 b/testsuits_alpine/env2 new file mode 100755 index 0000000..12cbcde Binary files /dev/null and b/testsuits_alpine/env2 differ diff --git a/testsuits_alpine/env2.c b/testsuits_alpine/env2.c new file mode 100644 index 0000000..9af5f6a --- /dev/null +++ b/testsuits_alpine/env2.c @@ -0,0 +1,25 @@ +#include +#include +#include + +//extern char **environ; +//char **env = environ; +int main(int argc, char * argv [] , char ** environ) +{ +puts("child, evn2----------------------\n"); +while(*environ){ + puts(*environ); + environ++; +} + +char * p; +puts("----------------------\n"); +if((p=getenv("USER"))) +printf("USER =%s\n",p); +setenv("USER","TEST",1); +printf("USER=%s\n",getenv("USER")); +unsetenv("USER"); +printf("USER=%s\n",getenv("USER")); +setenv("USER","TEST",1); +return 0; +} diff --git a/testsuits_alpine/env2.s b/testsuits_alpine/env2.s new file mode 100644 index 0000000..7de027f --- /dev/null +++ b/testsuits_alpine/env2.s @@ -0,0 +1,243 @@ + +env2: file format elf64-x86-64 + + +Disassembly of section .init: + +0000000000001000 <_init>: + 1000: 50 push %rax + 1001: e8 ad 01 00 00 callq 11b3 + 1006: e8 ce 02 00 00 callq 12d9 <__do_global_ctors_aux> + 100b: 58 pop %rax + 100c: c3 retq + +Disassembly of section .plt: + +0000000000001010 <.plt>: + 1010: ff 35 82 2f 00 00 pushq 0x2f82(%rip) # 3f98 <_GLOBAL_OFFSET_TABLE_+0x8> + 1016: ff 25 84 2f 00 00 jmpq *0x2f84(%rip) # 3fa0 <_GLOBAL_OFFSET_TABLE_+0x10> + 101c: 0f 1f 40 00 nopl 0x0(%rax) + +0000000000001020 : + 1020: ff 25 82 2f 00 00 jmpq *0x2f82(%rip) # 3fa8 + 1026: 68 00 00 00 00 pushq $0x0 + 102b: e9 e0 ff ff ff jmpq 1010 <.plt> + +0000000000001030 : + 1030: ff 25 7a 2f 00 00 jmpq *0x2f7a(%rip) # 3fb0 + 1036: 68 01 00 00 00 pushq $0x1 + 103b: e9 d0 ff ff ff jmpq 1010 <.plt> + +0000000000001040 : + 1040: ff 25 72 2f 00 00 jmpq *0x2f72(%rip) # 3fb8 + 1046: 68 02 00 00 00 pushq $0x2 + 104b: e9 c0 ff ff ff jmpq 1010 <.plt> + +0000000000001050 : + 1050: ff 25 6a 2f 00 00 jmpq *0x2f6a(%rip) # 3fc0 + 1056: 68 03 00 00 00 pushq $0x3 + 105b: e9 b0 ff ff ff jmpq 1010 <.plt> + +0000000000001060 : + 1060: ff 25 62 2f 00 00 jmpq *0x2f62(%rip) # 3fc8 + 1066: 68 04 00 00 00 pushq $0x4 + 106b: e9 a0 ff ff ff jmpq 1010 <.plt> + +0000000000001070 <__libc_start_main@plt>: + 1070: ff 25 5a 2f 00 00 jmpq *0x2f5a(%rip) # 3fd0 <__libc_start_main> + 1076: 68 05 00 00 00 pushq $0x5 + 107b: e9 90 ff ff ff jmpq 1010 <.plt> + +Disassembly of section .plt.got: + +0000000000001080 <__cxa_finalize@plt>: + 1080: ff 25 52 2f 00 00 jmpq *0x2f52(%rip) # 3fd8 <__cxa_finalize> + 1086: 66 90 xchg %ax,%ax + +0000000000001088 <__deregister_frame_info@plt>: + 1088: ff 25 52 2f 00 00 jmpq *0x2f52(%rip) # 3fe0 <__deregister_frame_info> + 108e: 66 90 xchg %ax,%ax + +0000000000001090 <__register_frame_info@plt>: + 1090: ff 25 62 2f 00 00 jmpq *0x2f62(%rip) # 3ff8 <__register_frame_info> + 1096: 66 90 xchg %ax,%ax + +Disassembly of section .text: + +0000000000001098 <_start>: + 1098: 48 31 ed xor %rbp,%rbp + 109b: 48 89 e7 mov %rsp,%rdi + 109e: 48 8d 35 6b 2d 00 00 lea 0x2d6b(%rip),%rsi # 3e10 <_DYNAMIC> + 10a5: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp + 10a9: e8 00 00 00 00 callq 10ae <_start_c> + +00000000000010ae <_start_c>: + 10ae: 50 push %rax + 10af: 48 8d 57 08 lea 0x8(%rdi),%rdx + 10b3: 48 8b 37 mov (%rdi),%rsi + 10b6: 45 31 c9 xor %r9d,%r9d + 10b9: 4c 8d 05 3b 02 00 00 lea 0x23b(%rip),%r8 # 12fb <_fini> + 10c0: 48 8d 0d 39 ff ff ff lea -0xc7(%rip),%rcx # 1000 <_init> + 10c7: 48 8d 3d 0c 01 00 00 lea 0x10c(%rip),%rdi # 11da
+ 10ce: e8 9d ff ff ff callq 1070 <__libc_start_main@plt> + +00000000000010d3 : + 10d3: 48 8d 3d 2e 2f 00 00 lea 0x2f2e(%rip),%rdi # 4008 <__TMC_END__> + 10da: 48 8d 05 27 2f 00 00 lea 0x2f27(%rip),%rax # 4008 <__TMC_END__> + 10e1: 48 39 f8 cmp %rdi,%rax + 10e4: 74 0e je 10f4 + 10e6: 48 8b 05 03 2f 00 00 mov 0x2f03(%rip),%rax # 3ff0 <_ITM_deregisterTMCloneTable> + 10ed: 48 85 c0 test %rax,%rax + 10f0: 74 02 je 10f4 + 10f2: ff e0 jmpq *%rax + 10f4: c3 retq + +00000000000010f5 : + 10f5: 48 8d 3d 0c 2f 00 00 lea 0x2f0c(%rip),%rdi # 4008 <__TMC_END__> + 10fc: 48 8d 35 05 2f 00 00 lea 0x2f05(%rip),%rsi # 4008 <__TMC_END__> + 1103: b9 02 00 00 00 mov $0x2,%ecx + 1108: 48 29 fe sub %rdi,%rsi + 110b: 48 c1 fe 03 sar $0x3,%rsi + 110f: 48 89 f0 mov %rsi,%rax + 1112: 48 99 cqto + 1114: 48 f7 f9 idiv %rcx + 1117: 48 89 c6 mov %rax,%rsi + 111a: 48 85 c0 test %rax,%rax + 111d: 74 0e je 112d + 111f: 48 8b 05 c2 2e 00 00 mov 0x2ec2(%rip),%rax # 3fe8 <_ITM_registerTMCloneTable> + 1126: 48 85 c0 test %rax,%rax + 1129: 74 02 je 112d + 112b: ff e0 jmpq *%rax + 112d: c3 retq + +000000000000112e <__do_global_dtors_aux>: + 112e: 80 3d eb 2e 00 00 00 cmpb $0x0,0x2eeb(%rip) # 4020 + 1135: 75 7b jne 11b2 <__do_global_dtors_aux+0x84> + 1137: 55 push %rbp + 1138: 48 83 3d 98 2e 00 00 cmpq $0x0,0x2e98(%rip) # 3fd8 <__cxa_finalize> + 113f: 00 + 1140: 48 89 e5 mov %rsp,%rbp + 1143: 41 54 push %r12 + 1145: 53 push %rbx + 1146: 74 0c je 1154 <__do_global_dtors_aux+0x26> + 1148: 48 8b 3d b1 2e 00 00 mov 0x2eb1(%rip),%rdi # 4000 <__dso_handle> + 114f: e8 2c ff ff ff callq 1080 <__cxa_finalize@plt> + 1154: 48 8d 05 a5 2c 00 00 lea 0x2ca5(%rip),%rax # 3e00 <__DTOR_LIST__> + 115b: 48 8d 1d a6 2c 00 00 lea 0x2ca6(%rip),%rbx # 3e08 <__DTOR_END__> + 1162: 48 29 c3 sub %rax,%rbx + 1165: 49 89 c4 mov %rax,%r12 + 1168: 48 c1 fb 03 sar $0x3,%rbx + 116c: 48 ff cb dec %rbx + 116f: 48 8b 05 b2 2e 00 00 mov 0x2eb2(%rip),%rax # 4028 + 1176: 48 39 d8 cmp %rbx,%rax + 1179: 73 10 jae 118b <__do_global_dtors_aux+0x5d> + 117b: 48 ff c0 inc %rax + 117e: 48 89 05 a3 2e 00 00 mov %rax,0x2ea3(%rip) # 4028 + 1185: 41 ff 14 c4 callq *(%r12,%rax,8) + 1189: eb e4 jmp 116f <__do_global_dtors_aux+0x41> + 118b: e8 43 ff ff ff callq 10d3 + 1190: 48 83 3d 48 2e 00 00 cmpq $0x0,0x2e48(%rip) # 3fe0 <__deregister_frame_info> + 1197: 00 + 1198: 74 0c je 11a6 <__do_global_dtors_aux+0x78> + 119a: 48 8d 3d 37 0f 00 00 lea 0xf37(%rip),%rdi # 20d8 <__EH_FRAME_BEGIN__> + 11a1: e8 e2 fe ff ff callq 1088 <__deregister_frame_info@plt> + 11a6: 5b pop %rbx + 11a7: 41 5c pop %r12 + 11a9: c6 05 70 2e 00 00 01 movb $0x1,0x2e70(%rip) # 4020 + 11b0: 5d pop %rbp + 11b1: c3 retq + 11b2: c3 retq + +00000000000011b3 : + 11b3: 48 83 3d 3d 2e 00 00 cmpq $0x0,0x2e3d(%rip) # 3ff8 <__register_frame_info> + 11ba: 00 + 11bb: 74 18 je 11d5 + 11bd: 55 push %rbp + 11be: 48 8d 35 7b 2e 00 00 lea 0x2e7b(%rip),%rsi # 4040 + 11c5: 48 8d 3d 0c 0f 00 00 lea 0xf0c(%rip),%rdi # 20d8 <__EH_FRAME_BEGIN__> + 11cc: 48 89 e5 mov %rsp,%rbp + 11cf: e8 bc fe ff ff callq 1090 <__register_frame_info@plt> + 11d4: 5d pop %rbp + 11d5: e9 1b ff ff ff jmpq 10f5 + +00000000000011da
: + 11da: 55 push %rbp + 11db: 48 89 e5 mov %rsp,%rbp + 11de: 48 83 ec 30 sub $0x30,%rsp + 11e2: 89 7d ec mov %edi,-0x14(%rbp) + 11e5: 48 89 75 e0 mov %rsi,-0x20(%rbp) + 11e9: 48 89 55 d8 mov %rdx,-0x28(%rbp) + 11ed: 48 8d 3d 0c 0e 00 00 lea 0xe0c(%rip),%rdi # 2000 <_fini+0xd05> + 11f4: e8 57 fe ff ff callq 1050 + 11f9: eb 14 jmp 120f + 11fb: 48 8b 45 d8 mov -0x28(%rbp),%rax + 11ff: 48 8b 00 mov (%rax),%rax + 1202: 48 89 c7 mov %rax,%rdi + 1205: e8 46 fe ff ff callq 1050 + 120a: 48 83 45 d8 08 addq $0x8,-0x28(%rbp) + 120f: 48 8b 45 d8 mov -0x28(%rbp),%rax + 1213: 48 8b 00 mov (%rax),%rax + 1216: 48 85 c0 test %rax,%rax + 1219: 75 e0 jne 11fb + 121b: 48 8d 3d 01 0e 00 00 lea 0xe01(%rip),%rdi # 2023 <_fini+0xd28> + 1222: e8 29 fe ff ff callq 1050 + 1227: 48 8d 3d 0d 0e 00 00 lea 0xe0d(%rip),%rdi # 203b <_fini+0xd40> + 122e: e8 0d fe ff ff callq 1040 + 1233: 48 89 45 f8 mov %rax,-0x8(%rbp) + 1237: 48 83 7d f8 00 cmpq $0x0,-0x8(%rbp) + 123c: 74 18 je 1256 + 123e: 48 8b 45 f8 mov -0x8(%rbp),%rax + 1242: 48 89 c6 mov %rax,%rsi + 1245: 48 8d 3d f4 0d 00 00 lea 0xdf4(%rip),%rdi # 2040 <_fini+0xd45> + 124c: b8 00 00 00 00 mov $0x0,%eax + 1251: e8 da fd ff ff callq 1030 + 1256: ba 01 00 00 00 mov $0x1,%edx + 125b: 48 8d 35 e8 0d 00 00 lea 0xde8(%rip),%rsi # 204a <_fini+0xd4f> + 1262: 48 8d 3d d2 0d 00 00 lea 0xdd2(%rip),%rdi # 203b <_fini+0xd40> + 1269: e8 f2 fd ff ff callq 1060 + 126e: 48 8d 3d c6 0d 00 00 lea 0xdc6(%rip),%rdi # 203b <_fini+0xd40> + 1275: e8 c6 fd ff ff callq 1040 + 127a: 48 89 c6 mov %rax,%rsi + 127d: 48 8d 3d cb 0d 00 00 lea 0xdcb(%rip),%rdi # 204f <_fini+0xd54> + 1284: b8 00 00 00 00 mov $0x0,%eax + 1289: e8 a2 fd ff ff callq 1030 + 128e: 48 8d 3d a6 0d 00 00 lea 0xda6(%rip),%rdi # 203b <_fini+0xd40> + 1295: e8 86 fd ff ff callq 1020 + 129a: 48 8d 3d 9a 0d 00 00 lea 0xd9a(%rip),%rdi # 203b <_fini+0xd40> + 12a1: e8 9a fd ff ff callq 1040 + 12a6: 48 89 c6 mov %rax,%rsi + 12a9: 48 8d 3d 9f 0d 00 00 lea 0xd9f(%rip),%rdi # 204f <_fini+0xd54> + 12b0: b8 00 00 00 00 mov $0x0,%eax + 12b5: e8 76 fd ff ff callq 1030 + 12ba: ba 01 00 00 00 mov $0x1,%edx + 12bf: 48 8d 35 84 0d 00 00 lea 0xd84(%rip),%rsi # 204a <_fini+0xd4f> + 12c6: 48 8d 3d 6e 0d 00 00 lea 0xd6e(%rip),%rdi # 203b <_fini+0xd40> + 12cd: e8 8e fd ff ff callq 1060 + 12d2: b8 00 00 00 00 mov $0x0,%eax + 12d7: c9 leaveq + 12d8: c3 retq + +00000000000012d9 <__do_global_ctors_aux>: + 12d9: 55 push %rbp + 12da: 48 89 e5 mov %rsp,%rbp + 12dd: 53 push %rbx + 12de: 48 8d 1d 0b 2b 00 00 lea 0x2b0b(%rip),%rbx # 3df0 <__CTOR_LIST__> + 12e5: 52 push %rdx + 12e6: 48 8b 03 mov (%rbx),%rax + 12e9: 48 83 f8 ff cmp $0xffffffffffffffff,%rax + 12ed: 74 08 je 12f7 <__do_global_ctors_aux+0x1e> + 12ef: ff d0 callq *%rax + 12f1: 48 83 eb 08 sub $0x8,%rbx + 12f5: eb ef jmp 12e6 <__do_global_ctors_aux+0xd> + 12f7: 58 pop %rax + 12f8: 5b pop %rbx + 12f9: 5d pop %rbp + 12fa: c3 retq + +Disassembly of section .fini: + +00000000000012fb <_fini>: + 12fb: 50 push %rax + 12fc: e8 2d fe ff ff callq 112e <__do_global_dtors_aux> + 1301: 58 pop %rax + 1302: c3 retq diff --git a/testsuits_alpine/exec b/testsuits_alpine/exec new file mode 100755 index 0000000..64359b4 Binary files /dev/null and b/testsuits_alpine/exec differ diff --git a/testsuits_alpine/exec.c b/testsuits_alpine/exec.c new file mode 100644 index 0000000..81f5128 --- /dev/null +++ b/testsuits_alpine/exec.c @@ -0,0 +1,32 @@ +#include +int main() +{ + int child, grandson; + char *sargs[] = { "/bin/echo", "Son ", "Hello", "World!", NULL}; + char *gargs[] = { "/bin/echo", "Grandson ", "Hello", "World!", NULL}; + + if (!(child = fork())) + { + /* child */ + printf("child:s1: pid %d: %d is my father\n", getpid(), getppid()); + if(!(grandson=fork())) + { + printf("grandson: pid %d: %d is my father\n", getpid(), getppid()); + execve("/bin/echo", gargs, NULL); + printf("pid %d: I am back, something is wrong!\n", getpid()); + }else{ + printf("child:s2: pid %d: %d is my father\n", getpid(), getppid()); + wait4(grandson, NULL, 0, NULL); + execve("/bin/echo", sargs, NULL); + printf("pid %d: I am back, something is wrong!\n", getpid()); + } + } + else + { + int myself = getpid(); + printf("parent: pid %d: %d is my son\n", myself, child); + wait4(child, NULL, 0, NULL); + printf("pid %d: done\n", myself); + } + return 0; +} diff --git a/testsuits_alpine/exec.static b/testsuits_alpine/exec.static new file mode 100755 index 0000000..cc84df2 Binary files /dev/null and b/testsuits_alpine/exec.static differ diff --git a/testsuits_alpine/forktree b/testsuits_alpine/forktree new file mode 100755 index 0000000..19b9a81 Binary files /dev/null and b/testsuits_alpine/forktree differ diff --git a/testsuits_alpine/forktree.c b/testsuits_alpine/forktree.c new file mode 100644 index 0000000..0a27b6a --- /dev/null +++ b/testsuits_alpine/forktree.c @@ -0,0 +1,38 @@ +#include +#include + +#define DEPTH 4 +#define SLEEP_TIME 1 +void forktree(const char *cur); + +void +forkchild(const char *cur, char branch) { + char nxt[DEPTH + 1]; + + if (strlen(cur) >= DEPTH) + return; + + snprintf(nxt, DEPTH + 1, "%s%c", cur, branch); + if (fork() == 0) { + forktree(nxt); + //yield(); + exit(0); + } +} + +void +forktree(const char *cur) { + printf("%04x: I am '%s'\n", getpid(), cur); + + forkchild(cur, '0'); + forkchild(cur, '1'); +} + +int +main(void) { + printf("forktree process will sleep %d ticks\n",SLEEP_TIME); + sleep(SLEEP_TIME); + forktree(""); + return 0; +} + diff --git a/testsuits_alpine/func.c b/testsuits_alpine/func.c new file mode 100644 index 0000000..27d33c6 --- /dev/null +++ b/testsuits_alpine/func.c @@ -0,0 +1,5 @@ +#include "func.h" +void func() +{ + printf("Hello World!\n"); +} diff --git a/testsuits_alpine/func.h b/testsuits_alpine/func.h new file mode 100644 index 0000000..8f449e6 --- /dev/null +++ b/testsuits_alpine/func.h @@ -0,0 +1,5 @@ +#ifndef __FUNC_H +#define __FUNC_H +#include +void func(); +#endif diff --git a/testsuits_alpine/func.o b/testsuits_alpine/func.o new file mode 100644 index 0000000..d91e5e0 Binary files /dev/null and b/testsuits_alpine/func.o differ diff --git a/testsuits_alpine/hello.go b/testsuits_alpine/hello.go new file mode 100644 index 0000000..f2482c1 --- /dev/null +++ b/testsuits_alpine/hello.go @@ -0,0 +1,5 @@ +package main +import "fmt" +func main() { + fmt.Println("hello world") +} diff --git a/testsuits_alpine/hello.lua b/testsuits_alpine/hello.lua new file mode 100644 index 0000000..ad35e5a --- /dev/null +++ b/testsuits_alpine/hello.lua @@ -0,0 +1 @@ +print("Hello World") diff --git a/testsuits_alpine/hello.py b/testsuits_alpine/hello.py new file mode 100644 index 0000000..18d9f87 --- /dev/null +++ b/testsuits_alpine/hello.py @@ -0,0 +1 @@ +print "Hello, World!" diff --git a/testsuits_alpine/hello.py3 b/testsuits_alpine/hello.py3 new file mode 100644 index 0000000..7df869a --- /dev/null +++ b/testsuits_alpine/hello.py3 @@ -0,0 +1 @@ +print("Hello, World!") diff --git a/testsuits_alpine/hello.rb b/testsuits_alpine/hello.rb new file mode 100644 index 0000000..61e0260 --- /dev/null +++ b/testsuits_alpine/hello.rb @@ -0,0 +1 @@ +puts "Hello, world" diff --git a/testsuits_alpine/hello.sh b/testsuits_alpine/hello.sh new file mode 100644 index 0000000..b4286e3 --- /dev/null +++ b/testsuits_alpine/hello.sh @@ -0,0 +1 @@ +echo Hello World from shell diff --git a/testsuits_alpine/libfunc.so b/testsuits_alpine/libfunc.so new file mode 100755 index 0000000..113f06d Binary files /dev/null and b/testsuits_alpine/libfunc.so differ diff --git a/testsuits_alpine/main.rs b/testsuits_alpine/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/testsuits_alpine/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/testsuits_alpine/main_rs_static b/testsuits_alpine/main_rs_static new file mode 100755 index 0000000..b029181 Binary files /dev/null and b/testsuits_alpine/main_rs_static differ diff --git a/testsuits_alpine/map b/testsuits_alpine/map new file mode 100755 index 0000000..4e7762f Binary files /dev/null and b/testsuits_alpine/map differ diff --git a/testsuits_alpine/map.c b/testsuits_alpine/map.c new file mode 100644 index 0000000..42e1b39 --- /dev/null +++ b/testsuits_alpine/map.c @@ -0,0 +1,19 @@ +#include +#include +int *temp[1024*1024]; +void test(int i) +{ +// char temp[1024*1024] = {0}; + char *loc; + temp[i]=malloc(1024*1024); + *temp[i] =i; + printf("%s %d num = %d!\r\n", __FUNCTION__, __LINE__, *temp[i]); + i++; + //if(i==10) return; + test(i++); +} +int main(void) +{ + test(0); + return 0; +} diff --git a/testsuits_alpine/pthread-cond b/testsuits_alpine/pthread-cond new file mode 100755 index 0000000..f24440b Binary files /dev/null and b/testsuits_alpine/pthread-cond differ diff --git a/testsuits_alpine/pthread-cond.c b/testsuits_alpine/pthread-cond.c new file mode 100644 index 0000000..2a5f8a0 --- /dev/null +++ b/testsuits_alpine/pthread-cond.c @@ -0,0 +1,77 @@ +#include +#include +#include + +pthread_mutex_t count_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER; + +void *functionCount1(); +void *functionCount2(); +int count = 0; +#define COUNT_DONE 10 +#define COUNT_HALT1 3 +#define COUNT_HALT2 6 + +main() +{ + pthread_t thread1, thread2; + + pthread_create( &thread1, NULL, &functionCount1, NULL); + pthread_create( &thread2, NULL, &functionCount2, NULL); + + pthread_join( thread1, NULL); + pthread_join( thread2, NULL); + + printf("Final count: %d\n",count); + + exit(EXIT_SUCCESS); +} + +// Write numbers 1-3 and 8-10 as permitted by functionCount2() + +void *functionCount1() +{ + for(;;) + { + // Lock mutex and then wait for signal to relase mutex + pthread_mutex_lock( &count_mutex ); + + // Wait while functionCount2() operates on count + // mutex unlocked if condition varialbe in functionCount2() signaled. + pthread_cond_wait( &condition_var, &count_mutex ); + count++; + printf("Counter value functionCount1: %d\n",count); + + pthread_mutex_unlock( &count_mutex ); + + if(count >= COUNT_DONE) return(NULL); + } +} + +// Write numbers 4-7 + +void *functionCount2() +{ + for(;;) + { + pthread_mutex_lock( &count_mutex ); + + if( count < COUNT_HALT1 || count > COUNT_HALT2 ) + { + // Condition of if statement has been met. + // Signal to free waiting thread by freeing the mutex. + // Note: functionCount1() is now permitted to modify "count". + pthread_cond_signal( &condition_var ); + } + else + { + count++; + printf("Counter value functionCount2: %d\n",count); + } + + pthread_mutex_unlock( &count_mutex ); + + if(count >= COUNT_DONE) return(NULL); + } + +} diff --git a/testsuits_alpine/pthread-create b/testsuits_alpine/pthread-create new file mode 100755 index 0000000..d1fc403 Binary files /dev/null and b/testsuits_alpine/pthread-create differ diff --git a/testsuits_alpine/pthread-create.c b/testsuits_alpine/pthread-create.c new file mode 100644 index 0000000..21bc840 --- /dev/null +++ b/testsuits_alpine/pthread-create.c @@ -0,0 +1,48 @@ +#include +#include +#include + +void *print_message_function( void *ptr ); + +main() +{ + pthread_t thread1, thread2; + const char *message1 = "Thread 1"; + const char *message2 = "Thread 2"; + int iret1, iret2; + + /* Create independent threads each of which will execute function */ + + iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1); + if(iret1) + { + fprintf(stderr,"Error - pthread_create() return code: %d\n",iret1); + exit(EXIT_FAILURE); + } + + iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2); + if(iret2) + { + fprintf(stderr,"Error - pthread_create() return code: %d\n",iret2); + exit(EXIT_FAILURE); + } + + printf("pthread_create() for thread 1 returns: %d\n",iret1); + printf("pthread_create() for thread 2 returns: %d\n",iret2); + + /* Wait till threads are complete before main continues. Unless we */ + /* wait we run the risk of executing an exit which will terminate */ + /* the process and all threads before the threads have completed. */ + + pthread_join( thread1, NULL); + pthread_join( thread2, NULL); + + exit(EXIT_SUCCESS); +} + +void *print_message_function( void *ptr ) +{ + char *message; + message = (char *) ptr; + printf("%s \n", message); +} diff --git a/testsuits_alpine/pthread-join b/testsuits_alpine/pthread-join new file mode 100755 index 0000000..bcf7f21 Binary files /dev/null and b/testsuits_alpine/pthread-join differ diff --git a/testsuits_alpine/pthread-join.c b/testsuits_alpine/pthread-join.c new file mode 100644 index 0000000..056ff32 --- /dev/null +++ b/testsuits_alpine/pthread-join.c @@ -0,0 +1,37 @@ +#include +#include + +#define NTHREADS 10 +void *thread_function(void *); +pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; +int counter = 0; + +main() +{ + pthread_t thread_id[NTHREADS]; + int i, j; + + for(i=0; i < NTHREADS; i++) + { + pthread_create( &thread_id[i], NULL, thread_function, NULL ); + } + + for(j=0; j < NTHREADS; j++) + { + pthread_join( thread_id[j], NULL); + } + + /* Now that all threads are complete I can print the final result. */ + /* Without the join I could be printing a value before all the threads */ + /* have been completed. */ + + printf("Final counter value: %d\n", counter); +} + +void *thread_function(void *dummyPtr) +{ + printf("Thread number %ld\n", pthread_self()); + pthread_mutex_lock( &mutex1 ); + counter++; + pthread_mutex_unlock( &mutex1 ); +} diff --git a/testsuits_alpine/pthread-mutex b/testsuits_alpine/pthread-mutex new file mode 100755 index 0000000..b21743a Binary files /dev/null and b/testsuits_alpine/pthread-mutex differ diff --git a/testsuits_alpine/pthread-mutex.c b/testsuits_alpine/pthread-mutex.c new file mode 100644 index 0000000..8394e87 --- /dev/null +++ b/testsuits_alpine/pthread-mutex.c @@ -0,0 +1,42 @@ +#include +#include +#include + +void *functionC(); +pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; +int counter = 0; + +main() +{ + int rc1, rc2; + pthread_t thread1, thread2; + + /* Create independent threads each of which will execute functionC */ + + if( (rc1=pthread_create( &thread1, NULL, &functionC, NULL)) ) + { + printf("Thread creation failed: %d\n", rc1); + } + + if( (rc2=pthread_create( &thread2, NULL, &functionC, NULL)) ) + { + printf("Thread creation failed: %d\n", rc2); + } + + /* Wait till threads are complete before main continues. Unless we */ + /* wait we run the risk of executing an exit which will terminate */ + /* the process and all threads before the threads have completed. */ + + pthread_join( thread1, NULL); + pthread_join( thread2, NULL); + + exit(EXIT_SUCCESS); +} + +void *functionC() +{ + pthread_mutex_lock( &mutex1 ); + counter++; + printf("Counter value: %d\n",counter); + pthread_mutex_unlock( &mutex1 ); +} diff --git a/testsuits_alpine/readfile b/testsuits_alpine/readfile new file mode 100755 index 0000000..49174b3 Binary files /dev/null and b/testsuits_alpine/readfile differ diff --git a/testsuits_alpine/readfile.c b/testsuits_alpine/readfile.c new file mode 100644 index 0000000..162817e --- /dev/null +++ b/testsuits_alpine/readfile.c @@ -0,0 +1,16 @@ +#include + +char a[4096]="\0"; +FILE *fp; +void main(int argc, char** argv){ + if (argc >1) { + fp = fopen(argv[1], "r"); + int i=0; + while (!feof(fp)) + { + fscanf(fp, "%c", &a[i]); + printf("%c",a[i]); + i++; + } + } +} diff --git a/testsuits_alpine/readv b/testsuits_alpine/readv new file mode 100755 index 0000000..393e656 Binary files /dev/null and b/testsuits_alpine/readv differ diff --git a/testsuits_alpine/readv.c b/testsuits_alpine/readv.c new file mode 100644 index 0000000..f808b4b --- /dev/null +++ b/testsuits_alpine/readv.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +char head[1024],foo[48], bar[51], baz[49]; +struct iovec iov[3]; +int main () +{ + + + ssize_t nr; + int fd, i; + + fd = open ("hello.sh", O_RDONLY); + if (fd==-1){ + perror ("open"); + return 1; + } + nr=read(fd, head, sizeof(head)); + if(nr==-1) { + perror("read"); + return 2; + } + + printf ("read size %d, head: %s\n", nr, (char *) head); + + /* set up our iovec structures */ + iov[0].iov_base = foo; + iov[0].iov_len = sizeof (foo); + iov[1].iov_base = bar; + iov[1].iov_len = sizeof (bar); + iov[2].iov_base = baz; + iov[2].iov_len = sizeof (baz); + + /* read into the structures with a single call */ + nr = readv (fd, iov, 3); + if (nr==-1) { + perror ("readv"); + return 1; + } + + for (i = 0; i < 3; i++) + printf ("IOV%d: size:%d %s\n", i, nr, (char *) iov[i].iov_base); + + if (close (fd)) { + perror ("close"); + return 1; + } + + return 0; +} diff --git a/testsuits_alpine/stack b/testsuits_alpine/stack new file mode 100755 index 0000000..6f00e82 Binary files /dev/null and b/testsuits_alpine/stack differ diff --git a/testsuits_alpine/stack.c b/testsuits_alpine/stack.c new file mode 100644 index 0000000..c34f1ab --- /dev/null +++ b/testsuits_alpine/stack.c @@ -0,0 +1,16 @@ +#include +#include +void test(int i) +{ + char temp[1024*1024] = {0}; + + temp[0] = i; + temp[0] ++; + printf("%s %d num = %d!\r\n", __FUNCTION__, __LINE__, temp[0]); + test(temp[0]); +} +int main(void) +{ + test(0); + return 0; +} diff --git a/ucore/CMakeLists.txt b/ucore/CMakeLists.txt index 0f393cc..6c53058 100644 --- a/ucore/CMakeLists.txt +++ b/ucore/CMakeLists.txt @@ -35,6 +35,8 @@ elseif (${ARCH} STREQUAL aarch64) set(PREFIX aarch64-elf-) endif () set(CMAKE_C_FLAGS "-mgeneral-regs-only") +elseif (${ARCH} STREQUAL mipsel) + set(PREFIX ${ARCH}-linux-musln32-) else() message("Unsupported arch: ${ARCH}") endif () diff --git a/ucore/src/arch/mipsel/arch.h b/ucore/src/arch/mipsel/arch.h new file mode 100644 index 0000000..f7fb742 --- /dev/null +++ b/ucore/src/arch/mipsel/arch.h @@ -0,0 +1,14 @@ +// See LICENSE for license details. + +#ifndef __LIBS_MIPSEL_H__ +#define __LIBS_MIPSEL_H__ + +#define do_div(n, base) \ + ({ \ + int __res; \ + __res = ((unsigned long)n) % (unsigned)base; \ + n = ((unsigned long)n) / (unsigned)base; \ + __res; \ + }) + +#endif diff --git a/ucore/src/arch/mipsel/atomic.h b/ucore/src/arch/mipsel/atomic.h new file mode 100644 index 0000000..bbbb8da --- /dev/null +++ b/ucore/src/arch/mipsel/atomic.h @@ -0,0 +1,75 @@ +#ifndef __LIBS_ATOMIC_H__ +#define __LIBS_ATOMIC_H__ + +// TODO: implement atomic operations for aarch64 + +/* Atomic operations that C can't guarantee us. Useful for resource counting etc.. */ + +static inline void set_bit(int nr, volatile void *addr) __attribute__((always_inline)); +static inline void clear_bit(int nr, volatile void *addr) __attribute__((always_inline)); +static inline void change_bit(int nr, volatile void *addr) __attribute__((always_inline)); +static inline bool test_and_set_bit(int nr, volatile void *addr) __attribute__((always_inline)); +static inline bool test_and_clear_bit(int nr, volatile void *addr) __attribute__((always_inline)); +static inline bool test_bit(int nr, volatile void *addr) __attribute__((always_inline)); + +/* * + * set_bit - Atomically set a bit in memory + * @nr: the bit to set + * @addr: the address to start counting from + * + * Note that @nr may be almost arbitrarily large; this function is not + * restricted to acting on a single-word quantity. + * */ +static inline void set_bit(int nr, volatile void *addr) { + /* unimplemented */ +} + +/* * + * clear_bit - Atomically clears a bit in memory + * @nr: the bit to clear + * @addr: the address to start counting from + * */ +static inline void clear_bit(int nr, volatile void *addr) { + /* unimplemented */ +} + +/* * + * change_bit - Atomically toggle a bit in memory + * @nr: the bit to change + * @addr: the address to start counting from + * */ +static inline void change_bit(int nr, volatile void *addr) { + /* unimplemented */ +} + +/* * + * test_bit - Determine whether a bit is set + * @nr: the bit to test + * @addr: the address to count from + * */ +static inline bool test_bit(int nr, volatile void *addr) { + /* unimplemented */ + return 0; +} + +/* * + * test_and_set_bit - Atomically set a bit and return its old value + * @nr: the bit to set + * @addr: the address to count from + * */ +static inline bool test_and_set_bit(int nr, volatile void *addr) { + /* unimplemented */ + return 0; +} + +/* * + * test_and_clear_bit - Atomically clear a bit and return its old value + * @nr: the bit to clear + * @addr: the address to count from + * */ +static inline bool test_and_clear_bit(int nr, volatile void *addr) { + /* unimplemented */ + return 0; +} + +#endif /* !__LIBS_ATOMIC_H__ */ diff --git a/ucore/src/arch/mipsel/initcode.S b/ucore/src/arch/mipsel/initcode.S new file mode 100644 index 0000000..9f01acd --- /dev/null +++ b/ucore/src/arch/mipsel/initcode.S @@ -0,0 +1,14 @@ +#include + +.text +.globl __start +.global _start + +# seems different toolchains look for different entry points +_start: +__start: + # call user-program function + lw a0, 0(sp) + addiu a1, sp, 8 + b umain + nop diff --git a/ucore/src/arch/mipsel/regdef.h b/ucore/src/arch/mipsel/regdef.h new file mode 100644 index 0000000..14721cb --- /dev/null +++ b/ucore/src/arch/mipsel/regdef.h @@ -0,0 +1,55 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1985 MIPS Computer Systems, Inc. + * Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle + * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc. + */ +#ifndef _ASM_REGDEF_H +#define _ASM_REGDEF_H + + + +/* + * Symbolic register names for 32 bit ABI + */ +#define zero $0 /* wired zero */ +#define AT $1 /* assembler temp - uppercase because of ".set at" */ +#define v0 $2 /* return value */ +#define v1 $3 +#define a0 $4 /* argument registers */ +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t0 $8 /* caller saved */ +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define s0 $16 /* callee saved */ +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define t8 $24 /* caller saved */ +#define t9 $25 +#define jp $25 /* PIC jump register */ +#define k0 $26 /* kernel scratch */ +#define k1 $27 +#define gp $28 /* global pointer */ +#define sp $29 /* stack pointer */ +#define fp $30 /* frame pointer */ +#define s8 $30 /* same like fp! */ +#define ra $31 /* return address */ + + + +#endif /* _ASM_REGDEF_H */ diff --git a/ucore/src/arch/i386/arch.h b/ucore/src/arch/x86_64/arch.h similarity index 100% rename from ucore/src/arch/i386/arch.h rename to ucore/src/arch/x86_64/arch.h diff --git a/ucore/src/arch/i386/atomic.h b/ucore/src/arch/x86_64/atomic.h similarity index 100% rename from ucore/src/arch/i386/atomic.h rename to ucore/src/arch/x86_64/atomic.h diff --git a/ucore/src/arch/i386/initcode.S b/ucore/src/arch/x86_64/initcode.S similarity index 61% rename from ucore/src/arch/i386/initcode.S rename to ucore/src/arch/x86_64/initcode.S index e6b4936..40e6ff4 100644 --- a/ucore/src/arch/i386/initcode.S +++ b/ucore/src/arch/x86_64/initcode.S @@ -4,21 +4,13 @@ _start: # set ebp for backtrace movl $0x0, %ebp - # load argc and argv - movl (%esp), %ebx - lea 0x4(%esp), %ecx - - # move down the esp register # since it may cause page fault in backtrace subl $0x20, %esp - # save argc and argv on stack - pushl %ecx - pushl %ebx - # call user-program function + # according to fastcall ABI, the first 6 parameters are in registes + # so we do not need to copy (argc, argv) as on i386 call umain -1: jmp 1b diff --git a/ucore/src/exit.c b/ucore/src/exit.c index c3ac5f8..d72c05e 100644 --- a/ucore/src/exit.c +++ b/ucore/src/exit.c @@ -24,8 +24,8 @@ main(void) { assert(pid > 0); cprintf("I am the parent, waiting now..\n"); - assert(waitpid(pid, &code) == 0 && code == magic); - assert(waitpid(pid, &code) != 0 && wait() != 0); + assert(waitpid(pid, &code) > 0 && code == magic); + assert(waitpid(pid, &code) <= 0 && wait() <= 0); cprintf("waitpid %d ok.\n", pid); cprintf("exit pass.\n"); diff --git a/ucore/src/forktest.c b/ucore/src/forktest.c index 3eda228..8227622 100644 --- a/ucore/src/forktest.c +++ b/ucore/src/forktest.c @@ -19,12 +19,12 @@ main(void) { } for (; n > 0; n --) { - if (wait() != 0) { + if (wait() <= 0) { panic("wait stopped early\n"); } } - if (wait() == 0) { + if (wait() > 0) { panic("wait got too many\n"); } diff --git a/ucore/src/libs/defs.h b/ucore/src/libs/defs.h index ad73668..2c66c6f 100644 --- a/ucore/src/libs/defs.h +++ b/ucore/src/libs/defs.h @@ -32,7 +32,7 @@ typedef unsigned long long uint64_t; #if __riscv_xlen == 64 || defined(__x86_64__) || defined(__aarch64__) typedef int64_t intptr_t; typedef uint64_t uintptr_t; -#elif __riscv_xlen == 32 || defined(__i386__) +#elif __riscv_xlen == 32 || defined(__i386__) || defined(__mips__) typedef int32_t intptr_t; typedef uint32_t uintptr_t; #endif diff --git a/ucore/src/libs/elf.h b/ucore/src/libs/elf.h index f8958d3..ed973ea 100644 --- a/ucore/src/libs/elf.h +++ b/ucore/src/libs/elf.h @@ -36,7 +36,7 @@ struct proghdr { uint64_t p_memsz; // size of segment in memory (bigger if contains bss) uint64_t p_align; // required alignment, invariably hardware page size }; -#elif __riscv_xlen == 32 || defined(__i386__) +#elif __riscv_xlen == 32 || defined(__i386__) || defined(__mipsel) struct proghdr { uint32_t p_type; // loadable code or data, dynamic linking info,etc. uint32_t p_offset; // file offset of segment diff --git a/ucore/src/libs/unistd.h b/ucore/src/libs/unistd.h index 1e2e833..0298890 100644 --- a/ucore/src/libs/unistd.h +++ b/ucore/src/libs/unistd.h @@ -33,6 +33,35 @@ /* ONLY FOR LAB6 */ #define SYS_set_priority 141 +#elif defined(__mips__) +#define MIPS_SYSCALL 4000 +#define SYS_exit (MIPS_SYSCALL + 1) +#define SYS_fork (MIPS_SYSCALL + 2) +#define SYS_wait (MIPS_SYSCALL + 114) +#define SYS_exec (MIPS_SYSCALL + 11) +#define SYS_clone (MIPS_SYSCALL + 120) +#define SYS_yield (MIPS_SYSCALL + 162) +#define SYS_sleep (MIPS_SYSCALL + 166) +#define SYS_kill (MIPS_SYSCALL + 37) +#define SYS_gettime (MIPS_SYSCALL + 78) +#define SYS_getpid (MIPS_SYSCALL + 20) +#define SYS_mmap (MIPS_SYSCALL + 90) +#define SYS_munmap (MIPS_SYSCALL + 91) +#define SYS_shmem (-1) +#define SYS_pgdir (-1) +#define SYS_openat (MIPS_SYSCALL + 288) +#define SYS_close (MIPS_SYSCALL + 6) +#define SYS_read (MIPS_SYSCALL + 3) +#define SYS_write (MIPS_SYSCALL + 4) +#define SYS_seek (MIPS_SYSCALL + 18) +#define SYS_fstat (MIPS_SYSCALL + 198) +#define SYS_fsync (MIPS_SYSCALL + 118) +#define SYS_getcwd (MIPS_SYSCALL + 203) +#define SYS_getdirentry64 (MIPS_SYSCALL + 219) +#define SYS_dup3 (MIPS_SYSCALL + 327) +/* ONLY FOR LAB6 */ +#define SYS_set_priority 141 + #else #define SYS_exit 93 diff --git a/ucore/src/matrix.c b/ucore/src/matrix.c index c5ec869..7bd203f 100644 --- a/ucore/src/matrix.c +++ b/ucore/src/matrix.c @@ -64,7 +64,7 @@ main(void) { cprintf("fork ok.\n"); for (i = 0; i < total; i ++) { - if (wait() != 0) { + if (wait() <= 0) { cprintf("wait failed.\n"); goto failed; } diff --git a/ucore/src/ulibs/syscall.c b/ucore/src/ulibs/syscall.c index bddd1ed..59aa563 100644 --- a/ucore/src/ulibs/syscall.c +++ b/ucore/src/ulibs/syscall.c @@ -65,6 +65,22 @@ syscall(int num, ...) { "m" (a[4]) : "cc", "memory" ); +#elif defined(__mips__) +// mips n32 abi + register long a0 __asm__("$4") = a[0]; + register long a1 __asm__("$5") = a[1]; + register long a2 __asm__("$6") = a[2]; + register long a3 __asm__("$7") = a[3]; + register long a4 __asm__("$8") = a[4]; + register long a5 __asm__("$9") = a[5]; + register long v0 __asm__("$2"); + __asm__ __volatile__ ( + "addu $2,$0,%2 ; syscall" + : "=&r"(v0), "=r"(a3) + : "ir"(num), "0"(v0), "1"(a3), "r"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5) + : "$1", "$3", "$10", "$11", "$12", "$13", + "$14", "$15", "$24", "$25", "hi", "lo", "memory"); + ret = a3 ? -v0 : v0; #endif return ret; }