diff --git a/.github/workflows/actions/setup-musl/action.yml b/.github/workflows/actions/setup-musl/action.yml index b8aee366..67062e05 100644 --- a/.github/workflows/actions/setup-musl/action.yml +++ b/.github/workflows/actions/setup-musl/action.yml @@ -11,7 +11,7 @@ runs: steps: - name: Cache musl id: cache-musl - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 with: path: ${{ inputs.arch }}-linux-musl-cross key: ${{ inputs.arch }}-linux-musl-cross @@ -22,7 +22,7 @@ runs: MUSL_PATH=${{ inputs.arch }}-linux-musl-cross wget https://musl.cc/${MUSL_PATH}.tgz tar -xf ${MUSL_PATH}.tgz - - uses: actions/cache/save@v3 + - uses: actions/cache/save@v4 if: steps.cache-musl.outputs.cache-hit != 'true' with: path: ${{ inputs.arch }}-linux-musl-cross diff --git a/.github/workflows/actions/setup-qemu/action.yml b/.github/workflows/actions/setup-qemu/action.yml index 0f8bc4d1..819fb087 100644 --- a/.github/workflows/actions/setup-qemu/action.yml +++ b/.github/workflows/actions/setup-qemu/action.yml @@ -11,7 +11,7 @@ runs: steps: - name: Cache QEMU id: cache-qemu - uses: actions/cache/restore@v3 + uses: actions/cache/restore@v4 with: path: qemu_build key: qemu-${{ inputs.qemu-version }}-slirp-1 @@ -22,13 +22,13 @@ runs: PREFIX: ${{ github.workspace }}/qemu_build shell: bash run: | - sudo apt-get update && sudo apt-get install -y ninja-build libslirp-dev + sudo apt-get update && sudo apt-get install -y ninja-build libslirp-dev libglib2.0-dev wget https://download.qemu.org/$QEMU_PATH.tar.xz && tar -xJf $QEMU_PATH.tar.xz cd $QEMU_PATH \ && ./configure --prefix=$PREFIX --target-list=x86_64-softmmu,riscv64-softmmu,aarch64-softmmu --enable-slirp \ && make -j > /dev/null 2>&1 \ && make install - - uses: actions/cache/save@v3 + - uses: actions/cache/save@v4 if: steps.cache-qemu.outputs.cache-hit != 'true' with: path: qemu_build diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bdff6770..d6b363ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,20 +9,24 @@ jobs: fail-fast: false matrix: rust-toolchain: [nightly] + targets: [x86_64-unknown-none, riscv64gc-unknown-none-elf, aarch64-unknown-none-softfloat] steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly + - uses: dtolnay/rust-toolchain@stable with: toolchain: ${{ matrix.rust-toolchain }} components: rust-src, clippy, rustfmt + targets: ${{ matrix.targets }} - name: Setup ArceOS run: ./scripts/get_deps.sh - name: Check rust version run: rustc --version --verbose - name: Check code format - run: cargo fmt -- --check + continue-on-error: ${{ matrix.rust-toolchain == 'nightly' }} + run: cargo fmt --all -- --check - name: Clippy - run: cargo clippy + continue-on-error: ${{ matrix.rust-toolchain == 'nightly' }} + run: cargo clippy --target ${{ matrix.targets }} --all-features -- -D warnings -A clippy::new_without_default build: runs-on: ${{ matrix.os }} @@ -30,7 +34,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - arch: [x86_64] + arch: [x86_64, riscv64, aarch64] rust-toolchain: [nightly] steps: - uses: actions/checkout@v4 @@ -38,25 +42,26 @@ jobs: with: toolchain: ${{ matrix.rust-toolchain }} components: rust-src, llvm-tools - targets: x86_64-unknown-none + targets: x86_64-unknown-none, riscv64gc-unknown-none-elf, aarch64-unknown-none, aarch64-unknown-none-softfloat - uses: Swatinem/rust-cache@v2 - run: cargo install cargo-binutils - run: ./scripts/get_deps.sh - name: Build for ${{ matrix.arch }} run: make ARCH=${{ matrix.arch }} - test: - runs-on: ubuntu-latest + test-musl: + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: + os: [ubuntu-latest] + arch: [x86_64, riscv64, aarch64] rust-toolchain: [nightly] - arch: [x86_64] env: qemu-version: 8.2.0 steps: - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly + - uses: dtolnay/rust-toolchain@stable with: toolchain: ${{ matrix.rust-toolchain }} components: rust-src, llvm-tools @@ -69,5 +74,8 @@ jobs: - uses: ./.github/workflows/actions/setup-qemu with: qemu-version: ${{ env.qemu-version }} - - name: Run tests + - name: Build rustup target + if: ${{ matrix.arch != 'riscv64' }} + run: rustup target add ${{ matrix.arch }}-unknown-linux-musl + - name: Run tests for musl applications run: make test ARCH=${{ matrix.arch }} \ No newline at end of file diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..e45f2582 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,34 @@ +name: Build & Deploy docs + +on: [push, pull_request] + +env: + rust-toolchain: nightly-2024-05-02 + +jobs: + doc: + runs-on: ubuntu-latest + strategy: + fail-fast: false + permissions: + contents: write + env: + default-branch: ${{ format('refs/heads/{0}', github.event.repository.default_branch) }} + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + with: + toolchain: ${{ env.rust-toolchain }} + - uses: Swatinem/rust-cache@v2 + - run: cargo install cargo-binutils + - run: ./scripts/get_deps.sh + - name: Build docs + continue-on-error: ${{ github.ref != env.default-branch && github.event_name != 'pull_request' }} + run: make doc_check_missing + - name: Deploy to Github Pages + if: ${{ github.ref == env.default-branch }} + uses: JamesIves/github-pages-deploy-action@v4 + with: + single-commit: true + branch: gh-pages + folder: target/doc diff --git a/.gitignore b/.gitignore index 88d381ee..de1214c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,9 @@ -/target /.vscode /.arceos /.cargo .DS_Store -Cargo.lock *.elf *.bin +apps/*/build/ +**/target/ +**/Cargo.lock \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 67996bf9..454b5c4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,14 +10,23 @@ repository = "https://github.com/arceos-org/starry-next" log = "0.4" linkme = "0.3" axerrno = "0.1" -memory_addr = "0.2" -xmas-elf = "0.8" +memory_addr = "0.3" +xmas-elf = "0.9" +bitflags = "2.6" +kernel-elf-parser = "0.1.0" +num_enum = { version = "0.7", default-features = false } +syscalls = { version = "0.6", default-features = false } axstd = { git = "https://github.com/arceos-org/arceos.git", features = ["paging"] } -arceos_posix_api = { git = "https://github.com/arceos-org/arceos.git" } - axhal = { git = "https://github.com/arceos-org/arceos.git", features = ["uspace"] } axmm = { git = "https://github.com/arceos-org/arceos.git" } axtask = { git = "https://github.com/arceos-org/arceos.git" } axsync = { git = "https://github.com/arceos-org/arceos.git" } axruntime = { git = "https://github.com/arceos-org/arceos.git", features = ["multitask"] } +arceos_posix_api = { git = "https://github.com/arceos-org/arceos.git" } + +[target.'cfg(target_arch = "x86_64")'.dependencies] +x86 = "0.52" + +[build-dependencies] +toml_edit = "0.22" \ No newline at end of file diff --git a/Makefile b/Makefile index 65372758..47dd712d 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,15 @@ AX_ROOT ?= $(PWD)/.arceos AX_TESTCASE ?= nimbos ARCH ?= x86_64 +AX_TESTCASES_LIST=$(shell cat ./apps/$(AX_TESTCASE)/testcase_list | tr '\n' ',') -export AX_TESTCASES_LIST=$(shell cat ./apps/$(AX_TESTCASE)/testcase_list | tr '\n' ',') +RUSTDOCFLAGS := -Z unstable-options --enable-index-page -D rustdoc::broken_intra_doc_links -D missing-docs + +ifneq ($(filter $(MAKECMDGOALS),doc_check_missing),) # make doc_check_missing + export RUSTDOCFLAGS +else ifeq ($(filter $(MAKECMDGOALS),clean user_apps ax_root),) # Not make clean, user_apps, ax_root + export AX_TESTCASES_LIST +endif all: build @@ -22,4 +29,7 @@ clean: ax_root @make -C $(AX_ROOT) A=$(PWD) clean @cargo clean +doc_check_missing: + @cargo doc --no-deps --all-features --workspace + .PHONY: all ax_root build run justrun debug disasm clean diff --git a/apps/libc/Makefile b/apps/libc/Makefile new file mode 100644 index 00000000..69a84be4 --- /dev/null +++ b/apps/libc/Makefile @@ -0,0 +1,76 @@ +# Build testcases for rust and c programs + +ARCH ?= x86_64 +# Whether cross-compiling +TARGET ?= musl + +# Build target for c programs +CC := $(ARCH)-linux-$(TARGET)-gcc + +# Build target for rust programs +ifeq ($(TARGET),musl) + CFLAGS := -static -no-pie + ifeq ($(ARCH),x86_64) + RUST_TARGET := x86_64-unknown-linux-musl + RUSTFLAGS := + else ifeq ($(ARCH),aarch64) + RUST_TARGET := aarch64-unknown-linux-musl + RUSTFLAGS := -C linker=aarch64-linux-musl-ld + else ifeq ($(ARCH),riscv64) + $(warning "Warn: Rust musl target not supported for riscv64") + RUST_TARGET := "" + RUSTFLAGS := + else + $(error "Unknown ARCH") + endif +else ifeq ($(TARGET),gnu) + CFLAGS := + ifeq ($(ARCH),x86_64) + RUST_TARGET := x86_64-unknown-linux-gnu + else ifeq ($(ARCH),aarch64) + RUST_TARGET := aarch64-unknown-linux-gnu + else ifeq ($(ARCH),riscv64) + RUST_TARGET := riscv64gc-unknown-linux-gnu + else + $(error "Unknown ARCH") + endif +else + $(error "Unknown TARGET") +endif + +$(info RUSTFLAGS: "$(RUSTFLAGS)") +export RUSTFLAGS + +all: build + +build: build_dir build_c build_rust + +build_dir: + @mkdir -p build + @mkdir -p build/$(ARCH) + +build_c: + @for app in $(wildcard c/*/*.c); do \ + echo "Building $${app%.c}"; \ + app_name=$$(basename $$(dirname $${app})); \ + $(CC) -o build/$(ARCH)/$${app_name}_c $${app} $(CFLAGS); \ + done + +build_rust: + if [ -n $(RUST_TARGET) ]; then \ + for app in $(shell find rust -name Cargo.toml); do \ + echo "Building $$(dirname $${app})"; \ + app_name=$$(basename $$(dirname $${app})); \ + cargo build --release --target $(RUST_TARGET) --manifest-path $${app} ; \ + cp $$(dirname $${app})/target/$(RUST_TARGET)/release/$${app_name} build/$(ARCH)/$${app_name}_rust ; \ + done \ + fi + +clean: + @rm -rf build + @for app in $(shell find rust -name Cargo.toml); do \ + app_name=$$(basename $$(dirname $${app})); \ + cargo clean --manifest-path $${app} ; \ + done + +.PHONY: all build_dir build_c build_rust clean \ No newline at end of file diff --git a/apps/libc/c/helloworld/helloworld.c b/apps/libc/c/helloworld/helloworld.c new file mode 100644 index 00000000..8321e25d --- /dev/null +++ b/apps/libc/c/helloworld/helloworld.c @@ -0,0 +1,6 @@ +#include + +int main() { + printf("Hello, World!\n"); + return 0; +} \ No newline at end of file diff --git a/apps/libc/c/sleep/sleep.c b/apps/libc/c/sleep/sleep.c new file mode 100644 index 00000000..9fcc493f --- /dev/null +++ b/apps/libc/c/sleep/sleep.c @@ -0,0 +1,9 @@ +#include + +int main() +{ + printf("Sleeping for 5 seconds...\n"); + sleep(5); + printf("Done!\n"); + return 0; +} \ No newline at end of file diff --git a/apps/libc/expect_off.out b/apps/libc/expect_off.out new file mode 100644 index 00000000..0904c268 --- /dev/null +++ b/apps/libc/expect_off.out @@ -0,0 +1,7 @@ +smp = 1 +build_mode = release +log_level = off + +Hello, World! +Sleeping for 5 seconds... +Done! \ No newline at end of file diff --git a/apps/libc/rust/helloworld/Cargo.toml b/apps/libc/rust/helloworld/Cargo.toml new file mode 100644 index 00000000..384b4e32 --- /dev/null +++ b/apps/libc/rust/helloworld/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "helloworld" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/apps/libc/rust/helloworld/src/main.rs b/apps/libc/rust/helloworld/src/main.rs new file mode 100644 index 00000000..3da8b6b6 --- /dev/null +++ b/apps/libc/rust/helloworld/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello world from Rust!"); +} diff --git a/apps/libc/rust/task/sleep/Cargo.toml b/apps/libc/rust/task/sleep/Cargo.toml new file mode 100644 index 00000000..10a7b124 --- /dev/null +++ b/apps/libc/rust/task/sleep/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "sleep" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/apps/libc/rust/task/sleep/src/main.rs b/apps/libc/rust/task/sleep/src/main.rs new file mode 100644 index 00000000..4c1c2769 --- /dev/null +++ b/apps/libc/rust/task/sleep/src/main.rs @@ -0,0 +1,6 @@ +fn main() { + println!("Sleep for 5 seconds from Rust!"); + let duration = std::time::Duration::from_secs(5); + std::thread::sleep(duration); + println!("Woke up from sleep!"); +} diff --git a/apps/libc/test_cmd b/apps/libc/test_cmd new file mode 100644 index 00000000..94095cf8 --- /dev/null +++ b/apps/libc/test_cmd @@ -0,0 +1 @@ +test_one "LOG=off FEATURES=fp_simd" "expect_off.out" diff --git a/apps/libc/testcase_list b/apps/libc/testcase_list new file mode 100644 index 00000000..4e02956a --- /dev/null +++ b/apps/libc/testcase_list @@ -0,0 +1,2 @@ +helloworld_c +sleep_c diff --git a/apps/nimbos/c/CMakeLists.txt b/apps/nimbos/c/CMakeLists.txt index b581ab7e..3a19a8a6 100644 --- a/apps/nimbos/c/CMakeLists.txt +++ b/apps/nimbos/c/CMakeLists.txt @@ -63,6 +63,6 @@ endforeach() add_custom_command( OUTPUT syscall_ids.h COMMAND sed ARGS -n -e s/__NR_/SYS_/p - < ${CMAKE_SOURCE_DIR}/lib/syscall_ids.h.in + < ${CMAKE_SOURCE_DIR}/${ARCH_DIR}/syscall_ids.h.in > ${CMAKE_SOURCE_DIR}/lib/syscall_ids.h -) +) \ No newline at end of file diff --git a/apps/nimbos/c/lib/arch/aarch64/syscall_ids.h.in b/apps/nimbos/c/lib/arch/aarch64/syscall_ids.h.in new file mode 100644 index 00000000..e1c9c7c5 --- /dev/null +++ b/apps/nimbos/c/lib/arch/aarch64/syscall_ids.h.in @@ -0,0 +1,11 @@ +#define __NR_read 63 +#define __NR_write 64 +#define __NR_exit 93 +#define __NR_yield 124 +#define __NR_getpid 172 +#define __NR_clone 220 +#define __NR_fork 220 +#define __NR_exec 221 +#define __NR_waitpid 260 +#define __NR_clock_gettime 403 +#define __NR_clock_nanosleep 407 diff --git a/apps/nimbos/c/lib/arch/riscv/syscall_ids.h.in b/apps/nimbos/c/lib/arch/riscv/syscall_ids.h.in new file mode 100644 index 00000000..e1c9c7c5 --- /dev/null +++ b/apps/nimbos/c/lib/arch/riscv/syscall_ids.h.in @@ -0,0 +1,11 @@ +#define __NR_read 63 +#define __NR_write 64 +#define __NR_exit 93 +#define __NR_yield 124 +#define __NR_getpid 172 +#define __NR_clone 220 +#define __NR_fork 220 +#define __NR_exec 221 +#define __NR_waitpid 260 +#define __NR_clock_gettime 403 +#define __NR_clock_nanosleep 407 diff --git a/apps/nimbos/c/lib/arch/x86_64/syscall_ids.h.in b/apps/nimbos/c/lib/arch/x86_64/syscall_ids.h.in new file mode 100644 index 00000000..9aeecc9f --- /dev/null +++ b/apps/nimbos/c/lib/arch/x86_64/syscall_ids.h.in @@ -0,0 +1,11 @@ +#define __NR_read 0 +#define __NR_write 1 +#define __NR_yield 24 +#define __NR_getpid 39 +#define __NR_clone 56 +#define __NR_fork 57 +#define __NR_exec 59 +#define __NR_exit 60 +#define __NR_waitpid 61 +#define __NR_clock_gettime 228 +#define __NR_clock_nanosleep 230 diff --git a/apps/nimbos/c/lib/syscall_ids.h.in b/apps/nimbos/c/lib/syscall_ids.h.in deleted file mode 100644 index 4631dbcf..00000000 --- a/apps/nimbos/c/lib/syscall_ids.h.in +++ /dev/null @@ -1,11 +0,0 @@ -#define __NR_read 0 -#define __NR_write 1 -#define __NR_yield 24 -#define __NR_getpid 39 -#define __NR_clone 56 -#define __NR_fork 57 -#define __NR_exec 59 -#define __NR_exit 60 -#define __NR_waitpid 61 -#define __NR_clock_gettime 228 -#define __NR_clock_nanosleep 230 diff --git a/apps/nimbos/rust/Cargo.toml b/apps/nimbos/rust/Cargo.toml index 57f99b2d..2a6d1dfb 100644 --- a/apps/nimbos/rust/Cargo.toml +++ b/apps/nimbos/rust/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +cfg-if = "1.0" \ No newline at end of file diff --git a/apps/nimbos/rust/src/syscall.rs b/apps/nimbos/rust/src/syscall.rs index c0f22134..25d32c55 100644 --- a/apps/nimbos/rust/src/syscall.rs +++ b/apps/nimbos/rust/src/syscall.rs @@ -3,17 +3,34 @@ use crate::arch::syscall; pub use crate::arch::sys_clone; -pub const SYSCALL_READ: usize = 0; -pub const SYSCALL_WRITE: usize = 1; -pub const SYSCALL_YIELD: usize = 24; -pub const SYSCALL_GETPID: usize = 39; -pub const SYSCALL_CLONE: usize = 56; -pub const SYSCALL_FORK: usize = 57; -pub const SYSCALL_EXEC: usize = 59; -pub const SYSCALL_EXIT: usize = 60; -pub const SYSCALL_WAITPID: usize = 61; -pub const SYSCALL_CLOCK_GETTIME: usize = 228; -pub const SYSCALL_CLOCK_NANOSLEEP: usize = 230; +cfg_if::cfg_if! { + if #[cfg(target_arch = "x86_64")] { + pub const SYSCALL_READ: usize = 0; + pub const SYSCALL_WRITE: usize = 1; + pub const SYSCALL_YIELD: usize = 24; + pub const SYSCALL_GETPID: usize = 39; + pub const SYSCALL_CLONE: usize = 56; + pub const SYSCALL_FORK: usize = 57; + pub const SYSCALL_EXEC: usize = 59; + pub const SYSCALL_EXIT: usize = 60; + pub const SYSCALL_WAITPID: usize = 61; + pub const SYSCALL_CLOCK_GETTIME: usize = 228; + pub const SYSCALL_CLOCK_NANOSLEEP: usize = 230; + } + else { + pub const SYSCALL_READ: usize = 63; + pub const SYSCALL_WRITE: usize = 64; + pub const SYSCALL_YIELD: usize = 124; + pub const SYSCALL_GETPID: usize = 172; + pub const SYSCALL_CLONE: usize = 220; + pub const SYSCALL_FORK: usize = 220; + pub const SYSCALL_EXEC: usize = 221; + pub const SYSCALL_EXIT: usize = 93; + pub const SYSCALL_WAITPID: usize = 260; + pub const SYSCALL_CLOCK_GETTIME: usize = 403; + pub const SYSCALL_CLOCK_NANOSLEEP: usize = 407; + } +} pub fn sys_read(fd: usize, buffer: &mut [u8]) -> isize { syscall( diff --git a/build.rs b/build.rs index ba989ae8..f78e66b1 100644 --- a/build.rs +++ b/build.rs @@ -2,12 +2,15 @@ use std::fs::{read_dir, File}; use std::io::{Result, Write}; use std::path::PathBuf; +use toml_edit::{DocumentMut, Item, Table}; + fn main() { println!("cargo:rerun-if-changed=./apps/c/src"); println!("cargo:rerun-if-changed=./apps/rust/src"); println!("cargo:rerun-if-changed=.makeargs"); let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); link_app_data(&arch).unwrap(); + gen_kernel_config(&arch).unwrap(); } fn link_app_data(arch: &str) -> Result<()> { @@ -70,3 +73,46 @@ _app_count: } Ok(()) } + +fn gen_kernel_config(arch: &str) -> Result<()> { + let config_path = PathBuf::from(format!("configs/{}.toml", arch)); + let config = std::fs::read_to_string(config_path)?; + let out_path = PathBuf::from(std::env::var("OUT_DIR").unwrap()).join("uspace_config.rs"); + let config_content = config + .parse::() + .expect("failed to parse config file") + .as_table() + .clone(); + + fn get_comments<'a>(config: &'a Table, key: &str) -> &'a str { + config + .key(key) + .and_then(|k| k.leaf_decor().prefix()) + .and_then(|s| s.as_str()) + .map(|s| s.trim()) + .unwrap_or_default() + } + + let mut f = File::create(out_path)?; + writeln!(f, "// Automatically generated by build.rs\n")?; + for (key, item) in config_content.iter() { + let comments = get_comments(&config_content, key).replace('#', "///"); + writeln!(f, "{}", comments)?; + if let Item::Value(value) = item { + writeln!(f, "#[allow(dead_code)]")?; + let key_name = key.to_uppercase().replace('-', "_"); + match value { + toml_edit::Value::Integer(i) => { + writeln!(f, "pub const {}: usize = {};", key_name, i)?; + } + toml_edit::Value::String(s) => { + writeln!(f, "pub const {}: &str = \"{}\";", key_name, s)?; + } + _ => { + panic!("Unsupported value type"); + } + } + } + } + Ok(()) +} diff --git a/configs/aarch64.toml b/configs/aarch64.toml new file mode 100644 index 00000000..2d0a05f2 --- /dev/null +++ b/configs/aarch64.toml @@ -0,0 +1,12 @@ +# The base address of the user space. +user-space-base = 0x1000 +# The size of the user space. +user-space-size = 0x7fff_ffff_f000 + +# The highest address of the user stack. +user-stack-top = 0x7fff_0000_0000 +# The size of the user stack. +user-stack-size = 0x1_0000 + +# The size of the kernel stack. +kernel-stack-size = 0x40000 \ No newline at end of file diff --git a/configs/riscv64.toml b/configs/riscv64.toml new file mode 100644 index 00000000..b278d055 --- /dev/null +++ b/configs/riscv64.toml @@ -0,0 +1,12 @@ +# The base address of the user space. +user-space-base = 0x1000 +# The size of the user space. +user-space-size = 0x3f_ffff_f000 + +# The highest address of the user stack. +user-stack-top = 0x4_0000_0000 +# The size of the user stack. +user-stack-size = 0x1_0000 + +# The size of the kernel stack. +kernel-stack-size = 0x40000 \ No newline at end of file diff --git a/configs/x86_64.toml b/configs/x86_64.toml new file mode 100644 index 00000000..2d0a05f2 --- /dev/null +++ b/configs/x86_64.toml @@ -0,0 +1,12 @@ +# The base address of the user space. +user-space-base = 0x1000 +# The size of the user space. +user-space-size = 0x7fff_ffff_f000 + +# The highest address of the user stack. +user-stack-top = 0x7fff_0000_0000 +# The size of the user stack. +user-stack-size = 0x1_0000 + +# The size of the kernel stack. +kernel-stack-size = 0x40000 \ No newline at end of file diff --git a/debug.S b/debug.S new file mode 100644 index 00000000..8b62dac4 --- /dev/null +++ b/debug.S @@ -0,0 +1,1443 @@ + +apps/libc/build/x86_64/helloworld_c: file format elf64-x86-64 + + +Disassembly of section .init: + +0000000000401000 <_init>: + 401000: 50 push %rax + 401001: 58 pop %rax + 401002: c3 ret + +Disassembly of section .text: + +0000000000401010 : + 401010: f3 0f 1e fa endbr64 + 401014: 55 push %rbp + 401015: 89 fd mov %edi,%ebp + 401017: e8 54 04 00 00 call 401470 <__funcs_on_exit> + 40101c: e8 5f 04 00 00 call 401480 <__libc_exit_fini> + 401021: 31 c0 xor %eax,%eax + 401023: e8 88 0f 00 00 call 401fb0 <__stdio_exit> + 401028: 89 ef mov %ebp,%edi + 40102a: e8 81 08 00 00 call 4018b0 <_Exit> + +000000000040102f <_start>: + 40102f: 48 31 ed xor %rbp,%rbp + 401032: 48 89 e7 mov %rsp,%rdi + 401035: 48 8d 35 c4 ef bf ff lea -0x40103c(%rip),%rsi # 0 <_init-0x401000> + 40103c: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp + 401040: e8 0b 00 00 00 call 401050 <_start_c> + 401045: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 40104c: 00 00 00 + 40104f: 90 nop + +0000000000401050 <_start_c>: + 401050: f3 0f 1e fa endbr64 + 401054: 8b 37 mov (%rdi),%esi + 401056: 48 8d 57 08 lea 0x8(%rdi),%rdx + 40105a: 49 c7 c0 b2 22 40 00 mov $0x4022b2,%r8 + 401061: 45 31 c9 xor %r9d,%r9d + 401064: 48 c7 c1 00 10 40 00 mov $0x401000,%rcx + 40106b: 48 c7 c7 39 11 40 00 mov $0x401139,%rdi + 401072: e9 b9 03 00 00 jmp 401430 <__libc_start_main> + 401077: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) + 40107e: 00 00 + +0000000000401080 : + 401080: 48 8d 3d a9 40 00 00 lea 0x40a9(%rip),%rdi # 405130 <__TMC_END__> + 401087: 48 8d 05 a2 40 00 00 lea 0x40a2(%rip),%rax # 405130 <__TMC_END__> + 40108e: 48 39 f8 cmp %rdi,%rax + 401091: 74 15 je 4010a8 + 401093: 48 c7 c0 00 00 00 00 mov $0x0,%rax + 40109a: 48 85 c0 test %rax,%rax + 40109d: 74 09 je 4010a8 + 40109f: ff e0 jmp *%rax + 4010a1: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + 4010a8: c3 ret + 4010a9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + +00000000004010b0 : + 4010b0: 48 8d 3d 79 40 00 00 lea 0x4079(%rip),%rdi # 405130 <__TMC_END__> + 4010b7: 48 8d 35 72 40 00 00 lea 0x4072(%rip),%rsi # 405130 <__TMC_END__> + 4010be: 48 29 fe sub %rdi,%rsi + 4010c1: 48 89 f0 mov %rsi,%rax + 4010c4: 48 c1 ee 3f shr $0x3f,%rsi + 4010c8: 48 c1 f8 03 sar $0x3,%rax + 4010cc: 48 01 c6 add %rax,%rsi + 4010cf: 48 d1 fe sar %rsi + 4010d2: 74 14 je 4010e8 + 4010d4: 48 c7 c0 00 00 00 00 mov $0x0,%rax + 4010db: 48 85 c0 test %rax,%rax + 4010de: 74 08 je 4010e8 + 4010e0: ff e0 jmp *%rax + 4010e2: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + 4010e8: c3 ret + 4010e9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + +00000000004010f0 <__do_global_dtors_aux>: + 4010f0: f3 0f 1e fa endbr64 + 4010f4: 80 3d 45 40 00 00 00 cmpb $0x0,0x4045(%rip) # 405140 + 4010fb: 75 2b jne 401128 <__do_global_dtors_aux+0x38> + 4010fd: 55 push %rbp + 4010fe: 48 83 3d f2 3e 00 00 cmpq $0x0,0x3ef2(%rip) # 404ff8 <__stdio_ofl_lockptr+0x8> + 401105: 00 + 401106: 48 89 e5 mov %rsp,%rbp + 401109: 74 0c je 401117 <__do_global_dtors_aux+0x27> + 40110b: 48 8b 3d 0e 3f 00 00 mov 0x3f0e(%rip),%rdi # 405020 <__dso_handle> + 401112: e8 e9 ee bf ff call 0 <_init-0x401000> + 401117: e8 64 ff ff ff call 401080 + 40111c: c6 05 1d 40 00 00 01 movb $0x1,0x401d(%rip) # 405140 + 401123: 5d pop %rbp + 401124: c3 ret + 401125: 0f 1f 00 nopl (%rax) + 401128: c3 ret + 401129: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + +0000000000401130 : + 401130: f3 0f 1e fa endbr64 + 401134: e9 77 ff ff ff jmp 4010b0 + +0000000000401139
: + 401139: f3 0f 1e fa endbr64 + 40113d: 55 push %rbp + 40113e: 48 89 e5 mov %rsp,%rbp + 401141: 48 8d 05 b8 1e 00 00 lea 0x1eb8(%rip),%rax # 403000 <_fini+0xd4e> + 401148: 48 89 c7 mov %rax,%rdi + 40114b: e8 70 03 00 00 call 4014c0 + 401150: b8 00 00 00 00 mov $0x0,%eax + 401155: 5d pop %rbp + 401156: c3 ret + 401157: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) + 40115e: 00 00 + +0000000000401160 : + 401160: f3 0f 1e fa endbr64 + 401164: c3 ret + 401165: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 40116c: 00 00 00 + 40116f: 90 nop + +0000000000401170 : + 401170: f3 0f 1e fa endbr64 + 401174: c3 ret + 401175: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 40117c: 00 00 00 + 40117f: 90 nop + +0000000000401180 <__init_libc>: + 401180: f3 0f 1e fa endbr64 + 401184: 48 81 ec 58 01 00 00 sub $0x158,%rsp + 40118b: 48 89 fa mov %rdi,%rdx + 40118e: 31 c0 xor %eax,%eax + 401190: b9 26 00 00 00 mov $0x26,%ecx + 401195: 4c 8d 44 24 20 lea 0x20(%rsp),%r8 + 40119a: 48 83 3a 00 cmpq $0x0,(%rdx) + 40119e: 4c 89 c7 mov %r8,%rdi + 4011a1: f3 48 ab rep stos %rax,%es:(%rdi) + 4011a4: 48 c7 c0 08 56 40 00 mov $0x405608,%rax + 4011ab: 48 89 10 mov %rdx,(%rax) + 4011ae: 0f 84 cc 01 00 00 je 401380 <__init_libc+0x200> + 4011b4: 31 c0 xor %eax,%eax + 4011b6: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 4011bd: 00 00 00 + 4011c0: 48 89 c1 mov %rax,%rcx + 4011c3: 48 83 c0 01 add $0x1,%rax + 4011c7: 48 83 3c c2 00 cmpq $0x0,(%rdx,%rax,8) + 4011cc: 75 f2 jne 4011c0 <__init_libc+0x40> + 4011ce: 48 8d 04 cd 10 00 00 lea 0x10(,%rcx,8),%rax + 4011d5: 00 + 4011d6: 48 01 d0 add %rdx,%rax + 4011d9: 48 8b 10 mov (%rax),%rdx + 4011dc: 48 89 05 a5 3f 00 00 mov %rax,0x3fa5(%rip) # 405188 <__libc+0x8> + 4011e3: 48 83 c0 08 add $0x8,%rax + 4011e7: 48 85 d2 test %rdx,%rdx + 4011ea: 0f 84 a0 01 00 00 je 401390 <__init_libc+0x210> + 4011f0: 48 83 fa 25 cmp $0x25,%rdx + 4011f4: 77 08 ja 4011fe <__init_libc+0x7e> + 4011f6: 48 8b 08 mov (%rax),%rcx + 4011f9: 48 89 4c d4 20 mov %rcx,0x20(%rsp,%rdx,8) + 4011fe: 48 8b 50 08 mov 0x8(%rax),%rdx + 401202: 48 83 c0 10 add $0x10,%rax + 401206: 48 85 d2 test %rdx,%rdx + 401209: 75 e5 jne 4011f0 <__init_libc+0x70> + 40120b: 48 8b 8c 24 a0 00 00 mov 0xa0(%rsp),%rcx + 401212: 00 + 401213: 48 8b 84 24 20 01 00 mov 0x120(%rsp),%rax + 40121a: 00 + 40121b: 48 8b 54 24 50 mov 0x50(%rsp),%rdx + 401220: 48 89 0d 39 3f 00 00 mov %rcx,0x3f39(%rip) # 405160 <__hwcap> + 401227: 48 85 c0 test %rax,%rax + 40122a: 74 07 je 401233 <__init_libc+0xb3> + 40122c: 48 89 05 15 3f 00 00 mov %rax,0x3f15(%rip) # 405148 <__sysinfo> + 401233: 48 89 15 76 3f 00 00 mov %rdx,0x3f76(%rip) # 4051b0 <__libc+0x30> + 40123a: 48 85 f6 test %rsi,%rsi + 40123d: 0f 84 0d 01 00 00 je 401350 <__init_libc+0x1d0> + 401243: 48 c7 c0 50 51 40 00 mov $0x405150,%rax + 40124a: 48 c7 c1 58 51 40 00 mov $0x405158,%rcx + 401251: 48 89 30 mov %rsi,(%rax) + 401254: 48 89 31 mov %rsi,(%rcx) + 401257: 0f b6 16 movzbl (%rsi),%edx + 40125a: 84 d2 test %dl,%dl + 40125c: 74 1d je 40127b <__init_libc+0xfb> + 40125e: 48 8d 46 01 lea 0x1(%rsi),%rax + 401262: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + 401268: 80 fa 2f cmp $0x2f,%dl + 40126b: 75 03 jne 401270 <__init_libc+0xf0> + 40126d: 48 89 01 mov %rax,(%rcx) + 401270: 0f b6 10 movzbl (%rax),%edx + 401273: 48 83 c0 01 add $0x1,%rax + 401277: 84 d2 test %dl,%dl + 401279: 75 ed jne 401268 <__init_libc+0xe8> + 40127b: 4c 89 c7 mov %r8,%rdi + 40127e: e8 0d 04 00 00 call 401690 <__init_tls> + 401283: 48 8b bc 24 e8 00 00 mov 0xe8(%rsp),%rdi + 40128a: 00 + 40128b: e8 10 0c 00 00 call 401ea0 <__init_ssp> + 401290: 48 8b 84 24 80 00 00 mov 0x80(%rsp),%rax + 401297: 00 + 401298: 48 39 44 24 78 cmp %rax,0x78(%rsp) + 40129d: 0f 84 7d 00 00 00 je 401320 <__init_libc+0x1a0> + 4012a3: 66 0f ef c0 pxor %xmm0,%xmm0 + 4012a7: 48 89 e7 mov %rsp,%rdi + 4012aa: b8 07 00 00 00 mov $0x7,%eax + 4012af: 31 d2 xor %edx,%edx + 4012b1: 48 c7 44 24 10 00 00 movq $0x0,0x10(%rsp) + 4012b8: 00 00 + 4012ba: be 03 00 00 00 mov $0x3,%esi + 4012bf: 0f 29 04 24 movaps %xmm0,(%rsp) + 4012c3: c7 44 24 10 02 00 00 movl $0x2,0x10(%rsp) + 4012ca: 00 + 4012cb: c7 44 24 08 01 00 00 movl $0x1,0x8(%rsp) + 4012d2: 00 + 4012d3: 0f 05 syscall + 4012d5: 85 c0 test %eax,%eax + 4012d7: 79 01 jns 4012da <__init_libc+0x15a> + 4012d9: f4 hlt + 4012da: 48 89 fa mov %rdi,%rdx + 4012dd: 4c 8d 44 24 18 lea 0x18(%rsp),%r8 + 4012e2: 41 b9 02 00 00 00 mov $0x2,%r9d + 4012e8: be 02 80 00 00 mov $0x8002,%esi + 4012ed: 48 8d 3d 1a 1d 00 00 lea 0x1d1a(%rip),%rdi # 40300e <_fini+0xd5c> + 4012f4: f6 42 06 20 testb $0x20,0x6(%rdx) + 4012f8: 74 0b je 401305 <__init_libc+0x185> + 4012fa: 4c 89 c8 mov %r9,%rax + 4012fd: 0f 05 syscall + 4012ff: 48 85 c0 test %rax,%rax + 401302: 79 01 jns 401305 <__init_libc+0x185> + 401304: f4 hlt + 401305: 48 83 c2 08 add $0x8,%rdx + 401309: 4c 39 c2 cmp %r8,%rdx + 40130c: 75 e6 jne 4012f4 <__init_libc+0x174> + 40130e: c6 05 6d 3e 00 00 01 movb $0x1,0x3e6d(%rip) # 405182 <__libc+0x2> + 401315: 48 81 c4 58 01 00 00 add $0x158,%rsp + 40131c: c3 ret + 40131d: 0f 1f 00 nopl (%rax) + 401320: 48 8b 84 24 90 00 00 mov 0x90(%rsp),%rax + 401327: 00 + 401328: 48 39 84 24 88 00 00 cmp %rax,0x88(%rsp) + 40132f: 00 + 401330: 0f 85 6d ff ff ff jne 4012a3 <__init_libc+0x123> + 401336: 48 83 bc 24 d8 00 00 cmpq $0x0,0xd8(%rsp) + 40133d: 00 00 + 40133f: 0f 85 5e ff ff ff jne 4012a3 <__init_libc+0x123> + 401345: eb ce jmp 401315 <__init_libc+0x195> + 401347: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) + 40134e: 00 00 + 401350: 48 8b 84 24 18 01 00 mov 0x118(%rsp),%rax + 401357: 00 + 401358: 48 85 c0 test %rax,%rax + 40135b: 75 43 jne 4013a0 <__init_libc+0x220> + 40135d: 48 c7 c2 50 51 40 00 mov $0x405150,%rdx + 401364: 48 8d 05 ac 1c 00 00 lea 0x1cac(%rip),%rax # 403017 <_fini+0xd65> + 40136b: 48 89 02 mov %rax,(%rdx) + 40136e: 48 c7 c2 58 51 40 00 mov $0x405158,%rdx + 401375: 48 89 02 mov %rax,(%rdx) + 401378: e9 fe fe ff ff jmp 40127b <__init_libc+0xfb> + 40137d: 0f 1f 00 nopl (%rax) + 401380: b8 08 00 00 00 mov $0x8,%eax + 401385: e9 4c fe ff ff jmp 4011d6 <__init_libc+0x56> + 40138a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + 401390: 48 c7 05 c5 3d 00 00 movq $0x0,0x3dc5(%rip) # 405160 <__hwcap> + 401397: 00 00 00 00 + 40139b: e9 93 fe ff ff jmp 401233 <__init_libc+0xb3> + 4013a0: 48 89 c6 mov %rax,%rsi + 4013a3: e9 9b fe ff ff jmp 401243 <__init_libc+0xc3> + 4013a8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) + 4013af: 00 + +00000000004013b0 <__libc_start_init>: + 4013b0: f3 0f 1e fa endbr64 + 4013b4: 55 push %rbp + 4013b5: 53 push %rbx + 4013b6: 48 83 ec 08 sub $0x8,%rsp + 4013ba: e8 41 fc ff ff call 401000 <_init> + 4013bf: 48 c7 c3 d8 4f 40 00 mov $0x404fd8,%rbx + 4013c6: 48 c7 c5 e0 4f 40 00 mov $0x404fe0,%rbp + 4013cd: 48 39 eb cmp %rbp,%rbx + 4013d0: 73 11 jae 4013e3 <__libc_start_init+0x33> + 4013d2: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + 4013d8: ff 13 call *(%rbx) + 4013da: 48 83 c3 08 add $0x8,%rbx + 4013de: 48 39 eb cmp %rbp,%rbx + 4013e1: 72 f5 jb 4013d8 <__libc_start_init+0x28> + 4013e3: 48 83 c4 08 add $0x8,%rsp + 4013e7: 5b pop %rbx + 4013e8: 5d pop %rbp + 4013e9: c3 ret + 4013ea: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + +00000000004013f0 : + 4013f0: f3 0f 1e fa endbr64 + 4013f4: 41 55 push %r13 + 4013f6: 48 63 c6 movslq %esi,%rax + 4013f9: 41 54 push %r12 + 4013fb: 4c 8d 6c c2 08 lea 0x8(%rdx,%rax,8),%r13 + 401400: 49 89 d4 mov %rdx,%r12 + 401403: 55 push %rbp + 401404: 48 89 c5 mov %rax,%rbp + 401407: 53 push %rbx + 401408: 48 89 fb mov %rdi,%rbx + 40140b: 48 83 ec 08 sub $0x8,%rsp + 40140f: e8 9c ff ff ff call 4013b0 <__libc_start_init> + 401414: 89 ef mov %ebp,%edi + 401416: 4c 89 ea mov %r13,%rdx + 401419: 4c 89 e6 mov %r12,%rsi + 40141c: ff d3 call *%rbx + 40141e: 89 c7 mov %eax,%edi + 401420: e8 eb fb ff ff call 401010 + 401425: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 40142c: 00 00 00 + 40142f: 90 nop + +0000000000401430 <__libc_start_main>: + 401430: f3 0f 1e fa endbr64 + 401434: 41 55 push %r13 + 401436: 48 63 c6 movslq %esi,%rax + 401439: 49 89 fd mov %rdi,%r13 + 40143c: 41 54 push %r12 + 40143e: 48 8d 7c c2 08 lea 0x8(%rdx,%rax,8),%rdi + 401443: 49 89 d4 mov %rdx,%r12 + 401446: 55 push %rbp + 401447: 48 8b 32 mov (%rdx),%rsi + 40144a: 48 89 c5 mov %rax,%rbp + 40144d: e8 2e fd ff ff call 401180 <__init_libc> + 401452: 4c 89 e2 mov %r12,%rdx + 401455: 89 ee mov %ebp,%esi + 401457: 4c 89 ef mov %r13,%rdi + 40145a: 48 8d 05 8f ff ff ff lea -0x71(%rip),%rax # 4013f0 + 401461: 5d pop %rbp + 401462: 41 5c pop %r12 + 401464: 41 5d pop %r13 + 401466: ff e0 jmp *%rax + 401468: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) + 40146f: 00 + +0000000000401470 <__funcs_on_exit>: + 401470: f3 0f 1e fa endbr64 + 401474: c3 ret + 401475: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 40147c: 00 00 00 + 40147f: 90 nop + +0000000000401480 <__libc_exit_fini>: + 401480: f3 0f 1e fa endbr64 + 401484: 55 push %rbp + 401485: 53 push %rbx + 401486: 48 83 ec 08 sub $0x8,%rsp + 40148a: 48 c7 c3 e8 4f 40 00 mov $0x404fe8,%rbx + 401491: 48 c7 c5 e0 4f 40 00 mov $0x404fe0,%rbp + 401498: 48 39 eb cmp %rbp,%rbx + 40149b: 76 10 jbe 4014ad <__libc_exit_fini+0x2d> + 40149d: 0f 1f 00 nopl (%rax) + 4014a0: 48 83 eb 08 sub $0x8,%rbx + 4014a4: 31 c0 xor %eax,%eax + 4014a6: ff 13 call *(%rbx) + 4014a8: 48 39 eb cmp %rbp,%rbx + 4014ab: 77 f3 ja 4014a0 <__libc_exit_fini+0x20> + 4014ad: 48 83 c4 08 add $0x8,%rsp + 4014b1: 31 c0 xor %eax,%eax + 4014b3: 5b pop %rbx + 4014b4: 5d pop %rbp + 4014b5: e9 f8 0d 00 00 jmp 4022b2 <_fini> + 4014ba: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + +00000000004014c0 : + 4014c0: f3 0f 1e fa endbr64 + 4014c4: 41 55 push %r13 + 4014c6: 4c 8d 2d 73 3b 00 00 lea 0x3b73(%rip),%r13 # 405040 <__stdout_FILE> + 4014cd: 41 54 push %r12 + 4014cf: 55 push %rbp + 4014d0: 48 89 fd mov %rdi,%rbp + 4014d3: 53 push %rbx + 4014d4: 48 83 ec 08 sub $0x8,%rsp + 4014d8: 8b 05 ee 3b 00 00 mov 0x3bee(%rip),%eax # 4050cc <__stdout_FILE+0x8c> + 4014de: 85 c0 test %eax,%eax + 4014e0: 79 76 jns 401558 + 4014e2: 4c 89 ee mov %r13,%rsi + 4014e5: 41 bc ff ff ff ff mov $0xffffffff,%r12d + 4014eb: 31 db xor %ebx,%ebx + 4014ed: e8 0e 07 00 00 call 401c00 + 4014f2: 85 c0 test %eax,%eax + 4014f4: 78 36 js 40152c + 4014f6: 83 3d d3 3b 00 00 0a cmpl $0xa,0x3bd3(%rip) # 4050d0 <__stdout_FILE+0x90> + 4014fd: 74 41 je 401540 + 4014ff: 48 8b 05 62 3b 00 00 mov 0x3b62(%rip),%rax # 405068 <__stdout_FILE+0x28> + 401506: 48 3b 05 53 3b 00 00 cmp 0x3b53(%rip),%rax # 405060 <__stdout_FILE+0x20> + 40150d: 74 31 je 401540 + 40150f: 48 8d 50 01 lea 0x1(%rax),%rdx + 401513: 45 31 e4 xor %r12d,%r12d + 401516: 48 89 15 4b 3b 00 00 mov %rdx,0x3b4b(%rip) # 405068 <__stdout_FILE+0x28> + 40151d: c6 00 0a movb $0xa,(%rax) + 401520: 85 db test %ebx,%ebx + 401522: 74 08 je 40152c + 401524: 4c 89 ef mov %r13,%rdi + 401527: e8 84 04 00 00 call 4019b0 <__unlockfile> + 40152c: 48 83 c4 08 add $0x8,%rsp + 401530: 44 89 e0 mov %r12d,%eax + 401533: 5b pop %rbx + 401534: 5d pop %rbp + 401535: 41 5c pop %r12 + 401537: 41 5d pop %r13 + 401539: c3 ret + 40153a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + 401540: be 0a 00 00 00 mov $0xa,%esi + 401545: 4c 89 ef mov %r13,%rdi + 401548: e8 b3 04 00 00 call 401a00 <__overflow> + 40154d: c1 f8 1f sar $0x1f,%eax + 401550: 41 89 c4 mov %eax,%r12d + 401553: eb cb jmp 401520 + 401555: 0f 1f 00 nopl (%rax) + 401558: 4c 89 ef mov %r13,%rdi + 40155b: 41 bc ff ff ff ff mov $0xffffffff,%r12d + 401561: e8 6a 03 00 00 call 4018d0 <__lockfile> + 401566: 4c 89 ee mov %r13,%rsi + 401569: 48 89 ef mov %rbp,%rdi + 40156c: 89 c3 mov %eax,%ebx + 40156e: e8 8d 06 00 00 call 401c00 + 401573: 85 c0 test %eax,%eax + 401575: 78 a9 js 401520 + 401577: 83 3d 52 3b 00 00 0a cmpl $0xa,0x3b52(%rip) # 4050d0 <__stdout_FILE+0x90> + 40157e: 0f 85 7b ff ff ff jne 4014ff + 401584: eb ba jmp 401540 + 401586: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 40158d: 00 00 00 + +0000000000401590 <__init_tp>: + 401590: f3 0f 1e fa endbr64 + 401594: 53 push %rbx + 401595: 48 89 fb mov %rdi,%rbx + 401598: 48 89 3f mov %rdi,(%rdi) + 40159b: e8 cf 08 00 00 call 401e6f <__set_thread_area> + 4015a0: 85 c0 test %eax,%eax + 4015a2: 78 54 js 4015f8 <__init_tp+0x68> + 4015a4: 75 07 jne 4015ad <__init_tp+0x1d> + 4015a6: c6 05 d3 3b 00 00 01 movb $0x1,0x3bd3(%rip) # 405180 <__libc> + 4015ad: c7 43 38 02 00 00 00 movl $0x2,0x38(%rbx) + 4015b4: b8 da 00 00 00 mov $0xda,%eax + 4015b9: 48 8d 3d f0 41 00 00 lea 0x41f0(%rip),%rdi # 4057b0 <__thread_list_lock> + 4015c0: 0f 05 syscall + 4015c2: 89 43 30 mov %eax,0x30(%rbx) + 4015c5: 48 8d 05 ec 3b 00 00 lea 0x3bec(%rip),%rax # 4051b8 <__libc+0x38> + 4015cc: 48 89 83 a8 00 00 00 mov %rax,0xa8(%rbx) + 4015d3: 48 8d 83 88 00 00 00 lea 0x88(%rbx),%rax + 4015da: 48 89 83 88 00 00 00 mov %rax,0x88(%rbx) + 4015e1: 48 8b 05 60 3b 00 00 mov 0x3b60(%rip),%rax # 405148 <__sysinfo> + 4015e8: 48 89 5b 10 mov %rbx,0x10(%rbx) + 4015ec: 48 89 43 20 mov %rax,0x20(%rbx) + 4015f0: 31 c0 xor %eax,%eax + 4015f2: 48 89 5b 18 mov %rbx,0x18(%rbx) + 4015f6: 5b pop %rbx + 4015f7: c3 ret + 4015f8: b8 ff ff ff ff mov $0xffffffff,%eax + 4015fd: 5b pop %rbx + 4015fe: c3 ret + 4015ff: 90 nop + +0000000000401600 <__copy_tls>: + 401600: f3 0f 1e fa endbr64 + 401604: 41 55 push %r13 + 401606: 49 89 fd mov %rdi,%r13 + 401609: 41 54 push %r12 + 40160b: 55 push %rbp + 40160c: 53 push %rbx + 40160d: 48 83 ec 08 sub $0x8,%rsp + 401611: 48 8b 05 80 3b 00 00 mov 0x3b80(%rip),%rax # 405198 <__libc+0x18> + 401618: 4c 8b 25 81 3b 00 00 mov 0x3b81(%rip),%r12 # 4051a0 <__libc+0x20> + 40161f: 48 8b 1d 6a 3b 00 00 mov 0x3b6a(%rip),%rbx # 405190 <__libc+0x10> + 401626: 48 8d 84 07 38 ff ff lea -0xc8(%rdi,%rax,1),%rax + 40162d: ff + 40162e: 49 f7 dc neg %r12 + 401631: 49 21 c4 and %rax,%r12 + 401634: 48 85 db test %rbx,%rbx + 401637: 74 32 je 40166b <__copy_tls+0x6b> + 401639: 48 8d 6f 08 lea 0x8(%rdi),%rbp + 40163d: 0f 1f 00 nopl (%rax) + 401640: 4c 89 e0 mov %r12,%rax + 401643: 48 2b 43 28 sub 0x28(%rbx),%rax + 401647: 48 8b 73 08 mov 0x8(%rbx),%rsi + 40164b: 4c 89 e7 mov %r12,%rdi + 40164e: 48 89 45 00 mov %rax,0x0(%rbp) + 401652: 48 8b 53 10 mov 0x10(%rbx),%rdx + 401656: 48 83 c5 08 add $0x8,%rbp + 40165a: 48 2b 7b 28 sub 0x28(%rbx),%rdi + 40165e: e8 da 07 00 00 call 401e3d + 401663: 48 8b 1b mov (%rbx),%rbx + 401666: 48 85 db test %rbx,%rbx + 401669: 75 d5 jne 401640 <__copy_tls+0x40> + 40166b: 48 8b 05 36 3b 00 00 mov 0x3b36(%rip),%rax # 4051a8 <__libc+0x28> + 401672: 49 89 45 00 mov %rax,0x0(%r13) + 401676: 4c 89 e0 mov %r12,%rax + 401679: 4d 89 6c 24 08 mov %r13,0x8(%r12) + 40167e: 48 83 c4 08 add $0x8,%rsp + 401682: 5b pop %rbx + 401683: 5d pop %rbp + 401684: 41 5c pop %r12 + 401686: 41 5d pop %r13 + 401688: c3 ret + 401689: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + +0000000000401690 <__init_tls>: + 401690: f3 0f 1e fa endbr64 + 401694: 53 push %rbx + 401695: 48 8b 4f 28 mov 0x28(%rdi),%rcx + 401699: 4c 8b 5f 18 mov 0x18(%rdi),%r11 + 40169d: 48 85 c9 test %rcx,%rcx + 4016a0: 0f 84 ea 01 00 00 je 401890 <__init_tls+0x200> + 4016a6: 44 8b 05 7f 3a 00 00 mov 0x3a7f(%rip),%r8d # 40512c <__default_stacksize> + 4016ad: 48 8b 7f 20 mov 0x20(%rdi),%rdi + 4016b1: 4c 89 d8 mov %r11,%rax + 4016b4: 31 db xor %ebx,%ebx + 4016b6: 31 f6 xor %esi,%esi + 4016b8: 45 31 c9 xor %r9d,%r9d + 4016bb: eb 21 jmp 4016de <__init_tls+0x4e> + 4016bd: 0f 1f 00 nopl (%rax) + 4016c0: 83 fa 02 cmp $0x2,%edx + 4016c3: 0f 84 a7 01 00 00 je 401870 <__init_tls+0x1e0> + 4016c9: 83 fa 07 cmp $0x7,%edx + 4016cc: 0f 85 68 01 00 00 jne 40183a <__init_tls+0x1aa> + 4016d2: 49 89 c1 mov %rax,%r9 + 4016d5: 48 01 f8 add %rdi,%rax + 4016d8: 48 83 e9 01 sub $0x1,%rcx + 4016dc: 74 17 je 4016f5 <__init_tls+0x65> + 4016de: 8b 10 mov (%rax),%edx + 4016e0: 83 fa 06 cmp $0x6,%edx + 4016e3: 75 db jne 4016c0 <__init_tls+0x30> + 4016e5: 4c 89 de mov %r11,%rsi + 4016e8: 48 2b 70 10 sub 0x10(%rax),%rsi + 4016ec: 48 01 f8 add %rdi,%rax + 4016ef: 48 83 e9 01 sub $0x1,%rcx + 4016f3: 75 e9 jne 4016de <__init_tls+0x4e> + 4016f5: 84 db test %bl,%bl + 4016f7: 74 07 je 401700 <__init_tls+0x70> + 4016f9: 44 89 05 2c 3a 00 00 mov %r8d,0x3a2c(%rip) # 40512c <__default_stacksize> + 401700: 4d 85 c9 test %r9,%r9 + 401703: 0f 84 87 01 00 00 je 401890 <__init_tls+0x200> + 401709: 49 8b 41 20 mov 0x20(%r9),%rax + 40170d: 49 03 71 10 add 0x10(%r9),%rsi + 401711: 48 8d 0d 08 3f 00 00 lea 0x3f08(%rip),%rcx # 405620 + 401718: 49 8b 51 28 mov 0x28(%r9),%rdx + 40171c: 48 89 35 05 3f 00 00 mov %rsi,0x3f05(%rip) # 405628 + 401723: 48 89 05 06 3f 00 00 mov %rax,0x3f06(%rip) # 405630 + 40172a: 49 8b 41 30 mov 0x30(%r9),%rax + 40172e: 48 c7 05 6f 3a 00 00 movq $0x1,0x3a6f(%rip) # 4051a8 <__libc+0x28> + 401735: 01 00 00 00 + 401739: 48 89 05 00 3f 00 00 mov %rax,0x3f00(%rip) # 405640 + 401740: 48 89 0d 49 3a 00 00 mov %rcx,0x3a49(%rip) # 405190 <__libc+0x10> + 401747: 48 01 d6 add %rdx,%rsi + 40174a: 48 8d 48 ff lea -0x1(%rax),%rcx + 40174e: 48 f7 de neg %rsi + 401751: 48 21 ce and %rcx,%rsi + 401754: 48 01 d6 add %rdx,%rsi + 401757: 48 8d 90 df 00 00 00 lea 0xdf(%rax),%rdx + 40175e: 48 89 35 d3 3e 00 00 mov %rsi,0x3ed3(%rip) # 405638 + 401765: 48 89 35 dc 3e 00 00 mov %rsi,0x3edc(%rip) # 405648 + 40176c: 48 83 f8 07 cmp $0x7,%rax + 401770: 77 15 ja 401787 <__init_tls+0xf7> + 401772: 48 c7 05 c3 3e 00 00 movq $0x8,0x3ec3(%rip) # 405640 + 401779: 08 00 00 00 + 40177d: ba e7 00 00 00 mov $0xe7,%edx + 401782: b8 08 00 00 00 mov $0x8,%eax + 401787: 48 01 d6 add %rdx,%rsi + 40178a: 48 89 05 0f 3a 00 00 mov %rax,0x3a0f(%rip) # 4051a0 <__libc+0x20> + 401791: 48 8d 3d c8 3e 00 00 lea 0x3ec8(%rip),%rdi # 405660 + 401798: 48 83 e6 f8 and $0xfffffffffffffff8,%rsi + 40179c: 48 89 35 f5 39 00 00 mov %rsi,0x39f5(%rip) # 405198 <__libc+0x18> + 4017a3: 48 81 fe 50 01 00 00 cmp $0x150,%rsi + 4017aa: 76 21 jbe 4017cd <__init_tls+0x13d> + 4017ac: 41 ba 22 00 00 00 mov $0x22,%r10d + 4017b2: 45 31 c9 xor %r9d,%r9d + 4017b5: b8 09 00 00 00 mov $0x9,%eax + 4017ba: 31 ff xor %edi,%edi + 4017bc: 49 c7 c0 ff ff ff ff mov $0xffffffffffffffff,%r8 + 4017c3: ba 03 00 00 00 mov $0x3,%edx + 4017c8: 0f 05 syscall + 4017ca: 48 89 c7 mov %rax,%rdi + 4017cd: e8 2e fe ff ff call 401600 <__copy_tls> + 4017d2: 48 89 00 mov %rax,(%rax) + 4017d5: 48 89 c7 mov %rax,%rdi + 4017d8: 48 89 c3 mov %rax,%rbx + 4017db: e8 8f 06 00 00 call 401e6f <__set_thread_area> + 4017e0: 85 c0 test %eax,%eax + 4017e2: 0f 88 a4 00 00 00 js 40188c <__init_tls+0x1fc> + 4017e8: 75 07 jne 4017f1 <__init_tls+0x161> + 4017ea: c6 05 8f 39 00 00 01 movb $0x1,0x398f(%rip) # 405180 <__libc> + 4017f1: c7 43 38 02 00 00 00 movl $0x2,0x38(%rbx) + 4017f8: b8 da 00 00 00 mov $0xda,%eax + 4017fd: 48 8d 3d ac 3f 00 00 lea 0x3fac(%rip),%rdi # 4057b0 <__thread_list_lock> + 401804: 0f 05 syscall + 401806: 89 43 30 mov %eax,0x30(%rbx) + 401809: 48 8d 05 a8 39 00 00 lea 0x39a8(%rip),%rax # 4051b8 <__libc+0x38> + 401810: 48 89 83 a8 00 00 00 mov %rax,0xa8(%rbx) + 401817: 48 8d 83 88 00 00 00 lea 0x88(%rbx),%rax + 40181e: 48 89 83 88 00 00 00 mov %rax,0x88(%rbx) + 401825: 48 8b 05 1c 39 00 00 mov 0x391c(%rip),%rax # 405148 <__sysinfo> + 40182c: 48 89 5b 10 mov %rbx,0x10(%rbx) + 401830: 48 89 43 20 mov %rax,0x20(%rbx) + 401834: 48 89 5b 18 mov %rbx,0x18(%rbx) + 401838: 5b pop %rbx + 401839: c3 ret + 40183a: 81 fa 51 e5 74 64 cmp $0x6474e551,%edx + 401840: 0f 85 8f fe ff ff jne 4016d5 <__init_tls+0x45> + 401846: 48 8b 50 28 mov 0x28(%rax),%rdx + 40184a: 45 89 c2 mov %r8d,%r10d + 40184d: 4c 39 d2 cmp %r10,%rdx + 401850: 0f 86 7f fe ff ff jbe 4016d5 <__init_tls+0x45> + 401856: 41 b8 00 00 80 00 mov $0x800000,%r8d + 40185c: bb 01 00 00 00 mov $0x1,%ebx + 401861: 4c 39 c2 cmp %r8,%rdx + 401864: 4c 0f 46 c2 cmovbe %rdx,%r8 + 401868: e9 68 fe ff ff jmp 4016d5 <__init_tls+0x45> + 40186d: 0f 1f 00 nopl (%rax) + 401870: 48 c7 c2 00 00 00 00 mov $0x0,%rdx + 401877: 48 85 d2 test %rdx,%rdx + 40187a: 0f 84 55 fe ff ff je 4016d5 <__init_tls+0x45> + 401880: 48 89 d6 mov %rdx,%rsi + 401883: 48 2b 70 10 sub 0x10(%rax),%rsi + 401887: e9 49 fe ff ff jmp 4016d5 <__init_tls+0x45> + 40188c: f4 hlt + 40188d: 5b pop %rbx + 40188e: c3 ret + 40188f: 90 nop + 401890: 48 8b 15 a1 3d 00 00 mov 0x3da1(%rip),%rdx # 405638 + 401897: 48 8b 35 8a 3d 00 00 mov 0x3d8a(%rip),%rsi # 405628 + 40189e: 48 8b 05 9b 3d 00 00 mov 0x3d9b(%rip),%rax # 405640 + 4018a5: e9 9d fe ff ff jmp 401747 <__init_tls+0xb7> + 4018aa: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + +00000000004018b0 <_Exit>: + 4018b0: f3 0f 1e fa endbr64 + 4018b4: 48 63 ff movslq %edi,%rdi + 4018b7: b8 e7 00 00 00 mov $0xe7,%eax + 4018bc: 0f 05 syscall + 4018be: ba 3c 00 00 00 mov $0x3c,%edx + 4018c3: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) + 4018c8: 48 89 d0 mov %rdx,%rax + 4018cb: 0f 05 syscall + 4018cd: eb f9 jmp 4018c8 <_Exit+0x18> + 4018cf: 90 nop + +00000000004018d0 <__lockfile>: + 4018d0: f3 0f 1e fa endbr64 + 4018d4: 8b 87 8c 00 00 00 mov 0x8c(%rdi),%eax + 4018da: 45 31 c0 xor %r8d,%r8d + 4018dd: 64 48 8b 0c 25 00 00 mov %fs:0x0,%rcx + 4018e4: 00 00 + 4018e6: 44 8b 49 30 mov 0x30(%rcx),%r9d + 4018ea: 25 ff ff ff bf and $0xbfffffff,%eax + 4018ef: 44 39 c8 cmp %r9d,%eax + 4018f2: 0f 84 ae 00 00 00 je 4019a6 <__lockfile+0xd6> + 4018f8: 48 89 fa mov %rdi,%rdx + 4018fb: 44 89 c0 mov %r8d,%eax + 4018fe: 48 8d bf 8c 00 00 00 lea 0x8c(%rdi),%rdi + 401905: f0 44 0f b1 8a 8c 00 lock cmpxchg %r9d,0x8c(%rdx) + 40190c: 00 00 + 40190e: 85 c0 test %eax,%eax + 401910: 0f 84 8a 00 00 00 je 4019a0 <__lockfile+0xd0> + 401916: 41 81 c9 00 00 00 40 or $0x40000000,%r9d + 40191d: 44 89 c0 mov %r8d,%eax + 401920: f0 44 0f b1 8a 8c 00 lock cmpxchg %r9d,0x8c(%rdx) + 401927: 00 00 + 401929: 89 c1 mov %eax,%ecx + 40192b: 85 c0 test %eax,%eax + 40192d: 74 71 je 4019a0 <__lockfile+0xd0> + 40192f: 55 push %rbp + 401930: 45 31 c0 xor %r8d,%r8d + 401933: bd 80 00 00 00 mov $0x80,%ebp + 401938: 53 push %rbx + 401939: bb ca 00 00 00 mov $0xca,%ebx + 40193e: eb 18 jmp 401958 <__lockfile+0x88> + 401940: 89 c8 mov %ecx,%eax + 401942: f0 0f b1 17 lock cmpxchg %edx,(%rdi) + 401946: 39 c8 cmp %ecx,%eax + 401948: 74 1e je 401968 <__lockfile+0x98> + 40194a: 44 89 c0 mov %r8d,%eax + 40194d: f0 44 0f b1 0f lock cmpxchg %r9d,(%rdi) + 401952: 89 c1 mov %eax,%ecx + 401954: 85 c0 test %eax,%eax + 401956: 74 38 je 401990 <__lockfile+0xc0> + 401958: 89 ca mov %ecx,%edx + 40195a: 81 ca 00 00 00 40 or $0x40000000,%edx + 401960: f7 c1 00 00 00 40 test $0x40000000,%ecx + 401966: 74 d8 je 401940 <__lockfile+0x70> + 401968: 48 63 d2 movslq %edx,%rdx + 40196b: 45 31 d2 xor %r10d,%r10d + 40196e: 48 89 d8 mov %rbx,%rax + 401971: 48 89 ee mov %rbp,%rsi + 401974: 0f 05 syscall + 401976: 48 83 f8 da cmp $0xffffffffffffffda,%rax + 40197a: 75 ce jne 40194a <__lockfile+0x7a> + 40197c: 45 31 d2 xor %r10d,%r10d + 40197f: 31 f6 xor %esi,%esi + 401981: 48 89 d8 mov %rbx,%rax + 401984: 0f 05 syscall + 401986: eb c2 jmp 40194a <__lockfile+0x7a> + 401988: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) + 40198f: 00 + 401990: b8 01 00 00 00 mov $0x1,%eax + 401995: 5b pop %rbx + 401996: 5d pop %rbp + 401997: c3 ret + 401998: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) + 40199f: 00 + 4019a0: 41 b8 01 00 00 00 mov $0x1,%r8d + 4019a6: 44 89 c0 mov %r8d,%eax + 4019a9: c3 ret + 4019aa: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + +00000000004019b0 <__unlockfile>: + 4019b0: f3 0f 1e fa endbr64 + 4019b4: 48 89 fa mov %rdi,%rdx + 4019b7: 31 c0 xor %eax,%eax + 4019b9: 48 8d bf 8c 00 00 00 lea 0x8c(%rdi),%rdi + 4019c0: 87 82 8c 00 00 00 xchg %eax,0x8c(%rdx) + 4019c6: a9 00 00 00 40 test $0x40000000,%eax + 4019cb: 74 1b je 4019e8 <__unlockfile+0x38> + 4019cd: 41 b8 ca 00 00 00 mov $0xca,%r8d + 4019d3: ba 01 00 00 00 mov $0x1,%edx + 4019d8: be 81 00 00 00 mov $0x81,%esi + 4019dd: 4c 89 c0 mov %r8,%rax + 4019e0: 0f 05 syscall + 4019e2: 48 83 f8 da cmp $0xffffffffffffffda,%rax + 4019e6: 74 08 je 4019f0 <__unlockfile+0x40> + 4019e8: c3 ret + 4019e9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + 4019f0: 4c 89 c0 mov %r8,%rax + 4019f3: 48 89 d6 mov %rdx,%rsi + 4019f6: 0f 05 syscall + 4019f8: c3 ret + 4019f9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + +0000000000401a00 <__overflow>: + 401a00: f3 0f 1e fa endbr64 + 401a04: 53 push %rbx + 401a05: 48 89 fb mov %rdi,%rbx + 401a08: 48 83 ec 10 sub $0x10,%rsp + 401a0c: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax + 401a13: 00 00 + 401a15: 48 89 44 24 08 mov %rax,0x8(%rsp) + 401a1a: 31 c0 xor %eax,%eax + 401a1c: 48 8b 47 20 mov 0x20(%rdi),%rax + 401a20: 40 88 74 24 07 mov %sil,0x7(%rsp) + 401a25: 48 85 c0 test %rax,%rax + 401a28: 74 5e je 401a88 <__overflow+0x88> + 401a2a: 48 8b 53 28 mov 0x28(%rbx),%rdx + 401a2e: 48 39 c2 cmp %rax,%rdx + 401a31: 74 0d je 401a40 <__overflow+0x40> + 401a33: 0f b6 44 24 07 movzbl 0x7(%rsp),%eax + 401a38: 3b 83 90 00 00 00 cmp 0x90(%rbx),%eax + 401a3e: 75 38 jne 401a78 <__overflow+0x78> + 401a40: 48 8d 74 24 07 lea 0x7(%rsp),%rsi + 401a45: ba 01 00 00 00 mov $0x1,%edx + 401a4a: 48 89 df mov %rbx,%rdi + 401a4d: ff 53 48 call *0x48(%rbx) + 401a50: 48 83 f8 01 cmp $0x1,%rax + 401a54: 75 4a jne 401aa0 <__overflow+0xa0> + 401a56: 0f b6 44 24 07 movzbl 0x7(%rsp),%eax + 401a5b: 48 8b 54 24 08 mov 0x8(%rsp),%rdx + 401a60: 64 48 2b 14 25 28 00 sub %fs:0x28,%rdx + 401a67: 00 00 + 401a69: 75 3c jne 401aa7 <__overflow+0xa7> + 401a6b: 48 83 c4 10 add $0x10,%rsp + 401a6f: 5b pop %rbx + 401a70: c3 ret + 401a71: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + 401a78: 48 8d 72 01 lea 0x1(%rdx),%rsi + 401a7c: 48 89 73 28 mov %rsi,0x28(%rbx) + 401a80: 88 02 mov %al,(%rdx) + 401a82: eb d7 jmp 401a5b <__overflow+0x5b> + 401a84: 0f 1f 40 00 nopl 0x0(%rax) + 401a88: e8 03 01 00 00 call 401b90 <__towrite> + 401a8d: 85 c0 test %eax,%eax + 401a8f: 75 0f jne 401aa0 <__overflow+0xa0> + 401a91: 48 8b 43 20 mov 0x20(%rbx),%rax + 401a95: eb 93 jmp 401a2a <__overflow+0x2a> + 401a97: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) + 401a9e: 00 00 + 401aa0: b8 ff ff ff ff mov $0xffffffff,%eax + 401aa5: eb b4 jmp 401a5b <__overflow+0x5b> + 401aa7: e8 44 04 00 00 call 401ef0 <__stack_chk_fail> + 401aac: 0f 1f 40 00 nopl 0x0(%rax) + +0000000000401ab0 <__aio_close>: + 401ab0: f3 0f 1e fa endbr64 + 401ab4: 89 f8 mov %edi,%eax + 401ab6: c3 ret + 401ab7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) + 401abe: 00 00 + +0000000000401ac0 <__stdio_close>: + 401ac0: f3 0f 1e fa endbr64 + 401ac4: 48 83 ec 08 sub $0x8,%rsp + 401ac8: 8b 7f 78 mov 0x78(%rdi),%edi + 401acb: e8 e0 ff ff ff call 401ab0 <__aio_close> + 401ad0: 48 63 f8 movslq %eax,%rdi + 401ad3: b8 03 00 00 00 mov $0x3,%eax + 401ad8: 0f 05 syscall + 401ada: 48 89 c7 mov %rax,%rdi + 401add: e8 1e 04 00 00 call 401f00 <__syscall_ret> + 401ae2: 48 83 c4 08 add $0x8,%rsp + 401ae6: c3 ret + 401ae7: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) + 401aee: 00 00 + +0000000000401af0 <__stdio_seek>: + 401af0: f3 0f 1e fa endbr64 + 401af4: 8b 7f 78 mov 0x78(%rdi),%edi + 401af7: e9 84 03 00 00 jmp 401e80 <__lseek> + 401afc: 0f 1f 40 00 nopl 0x0(%rax) + +0000000000401b00 <__stdout_write>: + 401b00: f3 0f 1e fa endbr64 + 401b04: 48 83 ec 18 sub $0x18,%rsp + 401b08: 49 89 f8 mov %rdi,%r8 + 401b0b: 49 89 f1 mov %rsi,%r9 + 401b0e: 49 89 d2 mov %rdx,%r10 + 401b11: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax + 401b18: 00 00 + 401b1a: 48 89 44 24 08 mov %rax,0x8(%rsp) + 401b1f: 48 8d 05 da 04 00 00 lea 0x4da(%rip),%rax # 402000 <__stdio_write> + 401b26: 48 89 47 48 mov %rax,0x48(%rdi) + 401b2a: f6 07 40 testb $0x40,(%rdi) + 401b2d: 75 18 jne 401b47 <__stdout_write+0x47> + 401b2f: 48 63 7f 78 movslq 0x78(%rdi),%rdi + 401b33: 48 89 e2 mov %rsp,%rdx + 401b36: b8 10 00 00 00 mov $0x10,%eax + 401b3b: be 13 54 00 00 mov $0x5413,%esi + 401b40: 0f 05 syscall + 401b42: 48 85 c0 test %rax,%rax + 401b45: 75 29 jne 401b70 <__stdout_write+0x70> + 401b47: 4c 89 d2 mov %r10,%rdx + 401b4a: 4c 89 ce mov %r9,%rsi + 401b4d: 4c 89 c7 mov %r8,%rdi + 401b50: e8 ab 04 00 00 call 402000 <__stdio_write> + 401b55: 48 8b 54 24 08 mov 0x8(%rsp),%rdx + 401b5a: 64 48 2b 14 25 28 00 sub %fs:0x28,%rdx + 401b61: 00 00 + 401b63: 75 18 jne 401b7d <__stdout_write+0x7d> + 401b65: 48 83 c4 18 add $0x18,%rsp + 401b69: c3 ret + 401b6a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + 401b70: 41 c7 80 90 00 00 00 movl $0xffffffff,0x90(%r8) + 401b77: ff ff ff ff + 401b7b: eb ca jmp 401b47 <__stdout_write+0x47> + 401b7d: e8 6e 03 00 00 call 401ef0 <__stack_chk_fail> + 401b82: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 401b89: 00 00 00 + 401b8c: 0f 1f 40 00 nopl 0x0(%rax) + +0000000000401b90 <__towrite>: + 401b90: f3 0f 1e fa endbr64 + 401b94: 8b 97 88 00 00 00 mov 0x88(%rdi),%edx + 401b9a: 8d 42 ff lea -0x1(%rdx),%eax + 401b9d: 09 d0 or %edx,%eax + 401b9f: 89 87 88 00 00 00 mov %eax,0x88(%rdi) + 401ba5: 8b 07 mov (%rdi),%eax + 401ba7: a8 08 test $0x8,%al + 401ba9: 75 2d jne 401bd8 <__towrite+0x48> + 401bab: 48 8b 47 58 mov 0x58(%rdi),%rax + 401baf: 48 c7 47 10 00 00 00 movq $0x0,0x10(%rdi) + 401bb6: 00 + 401bb7: 48 c7 47 08 00 00 00 movq $0x0,0x8(%rdi) + 401bbe: 00 + 401bbf: 48 89 47 38 mov %rax,0x38(%rdi) + 401bc3: 48 89 47 28 mov %rax,0x28(%rdi) + 401bc7: 48 03 47 60 add 0x60(%rdi),%rax + 401bcb: 48 89 47 20 mov %rax,0x20(%rdi) + 401bcf: 31 c0 xor %eax,%eax + 401bd1: c3 ret + 401bd2: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + 401bd8: 83 c8 20 or $0x20,%eax + 401bdb: 89 07 mov %eax,(%rdi) + 401bdd: b8 ff ff ff ff mov $0xffffffff,%eax + 401be2: c3 ret + 401be3: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 401bea: 00 00 00 + 401bed: 0f 1f 00 nopl (%rax) + +0000000000401bf0 <__towrite_needs_stdio_exit>: + 401bf0: f3 0f 1e fa endbr64 + 401bf4: e9 b7 03 00 00 jmp 401fb0 <__stdio_exit> + 401bf9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + +0000000000401c00 : + 401c00: f3 0f 1e fa endbr64 + 401c04: 41 54 push %r12 + 401c06: 49 89 f4 mov %rsi,%r12 + 401c09: 55 push %rbp + 401c0a: 48 89 fd mov %rdi,%rbp + 401c0d: 53 push %rbx + 401c0e: e8 ad 01 00 00 call 401dc0 + 401c13: 4c 89 e1 mov %r12,%rcx + 401c16: 48 89 ef mov %rbp,%rdi + 401c19: be 01 00 00 00 mov $0x1,%esi + 401c1e: 48 89 c2 mov %rax,%rdx + 401c21: 48 89 c3 mov %rax,%rbx + 401c24: e8 f7 00 00 00 call 401d20 + 401c29: 48 39 d8 cmp %rbx,%rax + 401c2c: 5b pop %rbx + 401c2d: 5d pop %rbp + 401c2e: 0f 95 c0 setne %al + 401c31: 41 5c pop %r12 + 401c33: 0f b6 c0 movzbl %al,%eax + 401c36: f7 d8 neg %eax + 401c38: c3 ret + 401c39: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + +0000000000401c40 <__fwritex>: + 401c40: f3 0f 1e fa endbr64 + 401c44: 41 56 push %r14 + 401c46: 41 55 push %r13 + 401c48: 49 89 f5 mov %rsi,%r13 + 401c4b: 41 54 push %r12 + 401c4d: 49 89 d4 mov %rdx,%r12 + 401c50: 55 push %rbp + 401c51: 48 89 fd mov %rdi,%rbp + 401c54: 53 push %rbx + 401c55: 48 8b 42 20 mov 0x20(%rdx),%rax + 401c59: 48 85 c0 test %rax,%rax + 401c5c: 0f 84 96 00 00 00 je 401cf8 <__fwritex+0xb8> + 401c62: 49 8b 7c 24 28 mov 0x28(%r12),%rdi + 401c67: 48 29 f8 sub %rdi,%rax + 401c6a: 4c 39 e8 cmp %r13,%rax + 401c6d: 72 49 jb 401cb8 <__fwritex+0x78> + 401c6f: 41 8b 84 24 90 00 00 mov 0x90(%r12),%eax + 401c76: 00 + 401c77: 4c 89 eb mov %r13,%rbx + 401c7a: 85 c0 test %eax,%eax + 401c7c: 79 30 jns 401cae <__fwritex+0x6e> + 401c7e: 4d 89 ee mov %r13,%r14 + 401c81: 4c 89 f2 mov %r14,%rdx + 401c84: 48 89 ee mov %rbp,%rsi + 401c87: e8 b1 01 00 00 call 401e3d + 401c8c: 4d 01 74 24 28 add %r14,0x28(%r12) + 401c91: 4c 89 e8 mov %r13,%rax + 401c94: 5b pop %rbx + 401c95: 5d pop %rbp + 401c96: 41 5c pop %r12 + 401c98: 41 5d pop %r13 + 401c9a: 41 5e pop %r14 + 401c9c: c3 ret + 401c9d: 0f 1f 00 nopl (%rax) + 401ca0: 80 7c 1d ff 0a cmpb $0xa,-0x1(%rbp,%rbx,1) + 401ca5: 48 8d 43 ff lea -0x1(%rbx),%rax + 401ca9: 74 25 je 401cd0 <__fwritex+0x90> + 401cab: 48 89 c3 mov %rax,%rbx + 401cae: 48 85 db test %rbx,%rbx + 401cb1: 75 ed jne 401ca0 <__fwritex+0x60> + 401cb3: eb c9 jmp 401c7e <__fwritex+0x3e> + 401cb5: 0f 1f 00 nopl (%rax) + 401cb8: 5b pop %rbx + 401cb9: 49 8b 44 24 48 mov 0x48(%r12),%rax + 401cbe: 4c 89 ea mov %r13,%rdx + 401cc1: 48 89 ee mov %rbp,%rsi + 401cc4: 4c 89 e7 mov %r12,%rdi + 401cc7: 5d pop %rbp + 401cc8: 41 5c pop %r12 + 401cca: 41 5d pop %r13 + 401ccc: 41 5e pop %r14 + 401cce: ff e0 jmp *%rax + 401cd0: 48 89 da mov %rbx,%rdx + 401cd3: 48 89 ee mov %rbp,%rsi + 401cd6: 4c 89 e7 mov %r12,%rdi + 401cd9: 41 ff 54 24 48 call *0x48(%r12) + 401cde: 48 39 c3 cmp %rax,%rbx + 401ce1: 77 b1 ja 401c94 <__fwritex+0x54> + 401ce3: 4d 89 ee mov %r13,%r14 + 401ce6: 49 8b 7c 24 28 mov 0x28(%r12),%rdi + 401ceb: 48 01 dd add %rbx,%rbp + 401cee: 49 29 de sub %rbx,%r14 + 401cf1: eb 8e jmp 401c81 <__fwritex+0x41> + 401cf3: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) + 401cf8: 48 89 d7 mov %rdx,%rdi + 401cfb: e8 90 fe ff ff call 401b90 <__towrite> + 401d00: 85 c0 test %eax,%eax + 401d02: 75 0c jne 401d10 <__fwritex+0xd0> + 401d04: 49 8b 44 24 20 mov 0x20(%r12),%rax + 401d09: e9 54 ff ff ff jmp 401c62 <__fwritex+0x22> + 401d0e: 66 90 xchg %ax,%ax + 401d10: 31 c0 xor %eax,%eax + 401d12: eb 80 jmp 401c94 <__fwritex+0x54> + 401d14: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 401d1b: 00 00 00 + 401d1e: 66 90 xchg %ax,%ax + +0000000000401d20 : + 401d20: f3 0f 1e fa endbr64 + 401d24: 41 57 push %r15 + 401d26: 31 c0 xor %eax,%eax + 401d28: 41 56 push %r14 + 401d2a: 49 89 f6 mov %rsi,%r14 + 401d2d: 41 55 push %r13 + 401d2f: 4c 0f af f2 imul %rdx,%r14 + 401d33: 49 89 fd mov %rdi,%r13 + 401d36: 41 54 push %r12 + 401d38: 49 89 cc mov %rcx,%r12 + 401d3b: 55 push %rbp + 401d3c: 48 89 f5 mov %rsi,%rbp + 401d3f: 53 push %rbx + 401d40: 48 89 d3 mov %rdx,%rbx + 401d43: 48 83 ec 08 sub $0x8,%rsp + 401d47: 48 85 f6 test %rsi,%rsi + 401d4a: 48 0f 44 d8 cmove %rax,%rbx + 401d4e: 8b 81 8c 00 00 00 mov 0x8c(%rcx),%eax + 401d54: 85 c0 test %eax,%eax + 401d56: 79 30 jns 401d88 + 401d58: 48 89 ca mov %rcx,%rdx + 401d5b: 4c 89 f6 mov %r14,%rsi + 401d5e: e8 dd fe ff ff call 401c40 <__fwritex> + 401d63: 49 89 c5 mov %rax,%r13 + 401d66: 48 89 d8 mov %rbx,%rax + 401d69: 4d 39 ee cmp %r13,%r14 + 401d6c: 74 08 je 401d76 + 401d6e: 4c 89 e8 mov %r13,%rax + 401d71: 31 d2 xor %edx,%edx + 401d73: 48 f7 f5 div %rbp + 401d76: 48 83 c4 08 add $0x8,%rsp + 401d7a: 5b pop %rbx + 401d7b: 5d pop %rbp + 401d7c: 41 5c pop %r12 + 401d7e: 41 5d pop %r13 + 401d80: 41 5e pop %r14 + 401d82: 41 5f pop %r15 + 401d84: c3 ret + 401d85: 0f 1f 00 nopl (%rax) + 401d88: 48 89 cf mov %rcx,%rdi + 401d8b: e8 40 fb ff ff call 4018d0 <__lockfile> + 401d90: 4c 89 ef mov %r13,%rdi + 401d93: 4c 89 e2 mov %r12,%rdx + 401d96: 4c 89 f6 mov %r14,%rsi + 401d99: 41 89 c7 mov %eax,%r15d + 401d9c: e8 9f fe ff ff call 401c40 <__fwritex> + 401da1: 49 89 c5 mov %rax,%r13 + 401da4: 45 85 ff test %r15d,%r15d + 401da7: 74 bd je 401d66 + 401da9: 4c 89 e7 mov %r12,%rdi + 401dac: e8 ff fb ff ff call 4019b0 <__unlockfile> + 401db1: eb b3 jmp 401d66 + 401db3: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 401dba: 00 00 00 + 401dbd: 0f 1f 00 nopl (%rax) + +0000000000401dc0 : + 401dc0: f3 0f 1e fa endbr64 + 401dc4: 48 89 f8 mov %rdi,%rax + 401dc7: 40 f6 c7 07 test $0x7,%dil + 401dcb: 75 0b jne 401dd8 + 401dcd: eb 19 jmp 401de8 + 401dcf: 90 nop + 401dd0: 48 83 c0 01 add $0x1,%rax + 401dd4: a8 07 test $0x7,%al + 401dd6: 74 10 je 401de8 + 401dd8: 80 38 00 cmpb $0x0,(%rax) + 401ddb: 75 f3 jne 401dd0 + 401ddd: 48 29 f8 sub %rdi,%rax + 401de0: c3 ret + 401de1: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + 401de8: 49 b8 ff fe fe fe fe movabs $0xfefefefefefefeff,%r8 + 401def: fe fe fe + 401df2: 48 8b 10 mov (%rax),%rdx + 401df5: 48 be 80 80 80 80 80 movabs $0x8080808080808080,%rsi + 401dfc: 80 80 80 + 401dff: 4a 8d 0c 02 lea (%rdx,%r8,1),%rcx + 401e03: 48 f7 d2 not %rdx + 401e06: 48 21 ca and %rcx,%rdx + 401e09: 48 85 f2 test %rsi,%rdx + 401e0c: 75 26 jne 401e34 + 401e0e: 66 90 xchg %ax,%ax + 401e10: 48 8b 50 08 mov 0x8(%rax),%rdx + 401e14: 48 83 c0 08 add $0x8,%rax + 401e18: 4a 8d 0c 02 lea (%rdx,%r8,1),%rcx + 401e1c: 48 f7 d2 not %rdx + 401e1f: 48 21 ca and %rcx,%rdx + 401e22: 48 85 f2 test %rsi,%rdx + 401e25: 74 e9 je 401e10 + 401e27: eb 0b jmp 401e34 + 401e29: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + 401e30: 48 83 c0 01 add $0x1,%rax + 401e34: 80 38 00 cmpb $0x0,(%rax) + 401e37: 75 f7 jne 401e30 + 401e39: 48 29 f8 sub %rdi,%rax + 401e3c: c3 ret + +0000000000401e3d : + 401e3d: 48 89 f8 mov %rdi,%rax + 401e40: 48 83 fa 08 cmp $0x8,%rdx + 401e44: 72 14 jb 401e5a + 401e46: f7 c7 07 00 00 00 test $0x7,%edi + 401e4c: 74 0c je 401e5a + 401e4e: a4 movsb %ds:(%rsi),%es:(%rdi) + 401e4f: 48 ff ca dec %rdx + 401e52: f7 c7 07 00 00 00 test $0x7,%edi + 401e58: 75 f4 jne 401e4e + 401e5a: 48 89 d1 mov %rdx,%rcx + 401e5d: 48 c1 e9 03 shr $0x3,%rcx + 401e61: f3 48 a5 rep movsq %ds:(%rsi),%es:(%rdi) + 401e64: 83 e2 07 and $0x7,%edx + 401e67: 74 05 je 401e6e + 401e69: a4 movsb %ds:(%rsi),%es:(%rdi) + 401e6a: ff ca dec %edx + 401e6c: 75 fb jne 401e69 + 401e6e: c3 ret + +0000000000401e6f <__set_thread_area>: + 401e6f: 48 89 fe mov %rdi,%rsi + 401e72: bf 02 10 00 00 mov $0x1002,%edi + 401e77: b8 9e 00 00 00 mov $0x9e,%eax + 401e7c: 0f 05 syscall + 401e7e: c3 ret + 401e7f: 90 nop + +0000000000401e80 <__lseek>: + 401e80: f3 0f 1e fa endbr64 + 401e84: 48 63 ff movslq %edi,%rdi + 401e87: 48 63 d2 movslq %edx,%rdx + 401e8a: b8 08 00 00 00 mov $0x8,%eax + 401e8f: 0f 05 syscall + 401e91: 48 89 c7 mov %rax,%rdi + 401e94: e9 67 00 00 00 jmp 401f00 <__syscall_ret> + 401e99: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + +0000000000401ea0 <__init_ssp>: + 401ea0: f3 0f 1e fa endbr64 + 401ea4: 53 push %rbx + 401ea5: 48 85 ff test %rdi,%rdi + 401ea8: 74 2e je 401ed8 <__init_ssp+0x38> + 401eaa: 48 c7 c3 b8 57 40 00 mov $0x4057b8,%rbx + 401eb1: 48 89 fe mov %rdi,%rsi + 401eb4: ba 08 00 00 00 mov $0x8,%edx + 401eb9: 48 89 df mov %rbx,%rdi + 401ebc: e8 7c ff ff ff call 401e3d + 401ec1: 48 8b 03 mov (%rbx),%rax + 401ec4: 64 48 8b 14 25 00 00 mov %fs:0x0,%rdx + 401ecb: 00 00 + 401ecd: 48 89 42 28 mov %rax,0x28(%rdx) + 401ed1: 5b pop %rbx + 401ed2: c3 ret + 401ed3: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) + 401ed8: 48 c7 c2 b8 57 40 00 mov $0x4057b8,%rdx + 401edf: 48 69 c2 6d 4e c6 41 imul $0x41c64e6d,%rdx,%rax + 401ee6: 48 89 02 mov %rax,(%rdx) + 401ee9: eb d9 jmp 401ec4 <__init_ssp+0x24> + 401eeb: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) + +0000000000401ef0 <__stack_chk_fail>: + 401ef0: f3 0f 1e fa endbr64 + 401ef4: f4 hlt + 401ef5: c3 ret + 401ef6: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 401efd: 00 00 00 + +0000000000401f00 <__syscall_ret>: + 401f00: f3 0f 1e fa endbr64 + 401f04: 48 81 ff 00 f0 ff ff cmp $0xfffffffffffff000,%rdi + 401f0b: 77 0b ja 401f18 <__syscall_ret+0x18> + 401f0d: 48 89 f8 mov %rdi,%rax + 401f10: c3 ret + 401f11: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + 401f18: 48 83 ec 18 sub $0x18,%rsp + 401f1c: 48 89 7c 24 08 mov %rdi,0x8(%rsp) + 401f21: e8 7a 03 00 00 call 4022a0 <__errno_location> + 401f26: 48 8b 7c 24 08 mov 0x8(%rsp),%rdi + 401f2b: f7 df neg %edi + 401f2d: 89 38 mov %edi,(%rax) + 401f2f: 48 c7 c0 ff ff ff ff mov $0xffffffffffffffff,%rax + 401f36: 48 83 c4 18 add $0x18,%rsp + 401f3a: c3 ret + 401f3b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) + +0000000000401f40 : + 401f40: 48 85 ff test %rdi,%rdi + 401f43: 74 63 je 401fa8 + 401f45: 55 push %rbp + 401f46: 8b 87 8c 00 00 00 mov 0x8c(%rdi),%eax + 401f4c: 48 89 fd mov %rdi,%rbp + 401f4f: 85 c0 test %eax,%eax + 401f51: 79 3d jns 401f90 + 401f53: 48 8b 45 38 mov 0x38(%rbp),%rax + 401f57: 48 39 45 28 cmp %rax,0x28(%rbp) + 401f5b: 74 0a je 401f67 + 401f5d: 31 d2 xor %edx,%edx + 401f5f: 31 f6 xor %esi,%esi + 401f61: 48 89 ef mov %rbp,%rdi + 401f64: ff 55 48 call *0x48(%rbp) + 401f67: 48 8b 75 08 mov 0x8(%rbp),%rsi + 401f6b: 48 8b 45 10 mov 0x10(%rbp),%rax + 401f6f: 48 39 c6 cmp %rax,%rsi + 401f72: 74 2c je 401fa0 + 401f74: 48 29 c6 sub %rax,%rsi + 401f77: 48 89 ef mov %rbp,%rdi + 401f7a: 48 8b 45 50 mov 0x50(%rbp),%rax + 401f7e: ba 01 00 00 00 mov $0x1,%edx + 401f83: 5d pop %rbp + 401f84: ff e0 jmp *%rax + 401f86: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 401f8d: 00 00 00 + 401f90: e8 3b f9 ff ff call 4018d0 <__lockfile> + 401f95: eb bc jmp 401f53 + 401f97: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) + 401f9e: 00 00 + 401fa0: 5d pop %rbp + 401fa1: c3 ret + 401fa2: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + 401fa8: c3 ret + 401fa9: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + +0000000000401fb0 <__stdio_exit>: + 401fb0: f3 0f 1e fa endbr64 + 401fb4: 53 push %rbx + 401fb5: e8 76 01 00 00 call 402130 <__ofl_lock> + 401fba: 48 8b 18 mov (%rax),%rbx + 401fbd: 48 85 db test %rbx,%rbx + 401fc0: 74 17 je 401fd9 <__stdio_exit+0x29> + 401fc2: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) + 401fc8: 48 89 df mov %rbx,%rdi + 401fcb: e8 70 ff ff ff call 401f40 + 401fd0: 48 8b 5b 70 mov 0x70(%rbx),%rbx + 401fd4: 48 85 db test %rbx,%rbx + 401fd7: 75 ef jne 401fc8 <__stdio_exit+0x18> + 401fd9: 48 8b 3d e0 37 00 00 mov 0x37e0(%rip),%rdi # 4057c0 <__stderr_used> + 401fe0: e8 5b ff ff ff call 401f40 + 401fe5: 48 8b 3d 3c 30 00 00 mov 0x303c(%rip),%rdi # 405028 <__stdout_used> + 401fec: e8 4f ff ff ff call 401f40 + 401ff1: 48 8b 3d c8 37 00 00 mov 0x37c8(%rip),%rdi # 4057c0 <__stderr_used> + 401ff8: 5b pop %rbx + 401ff9: e9 42 ff ff ff jmp 401f40 + 401ffe: 66 90 xchg %ax,%ax + +0000000000402000 <__stdio_write>: + 402000: f3 0f 1e fa endbr64 + 402004: 41 57 push %r15 + 402006: 49 89 ff mov %rdi,%r15 + 402009: 41 56 push %r14 + 40200b: 41 55 push %r13 + 40200d: 41 54 push %r12 + 40200f: 41 bc 14 00 00 00 mov $0x14,%r12d + 402015: 55 push %rbp + 402016: bd 02 00 00 00 mov $0x2,%ebp + 40201b: 53 push %rbx + 40201c: bb 02 00 00 00 mov $0x2,%ebx + 402021: 48 83 ec 48 sub $0x48,%rsp + 402025: 4c 8b 77 28 mov 0x28(%rdi),%r14 + 402029: 48 89 54 24 08 mov %rdx,0x8(%rsp) + 40202e: 4c 8d 6c 24 10 lea 0x10(%rsp),%r13 + 402033: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax + 40203a: 00 00 + 40203c: 48 89 44 24 38 mov %rax,0x38(%rsp) + 402041: 48 8b 47 38 mov 0x38(%rdi),%rax + 402045: 48 89 74 24 20 mov %rsi,0x20(%rsp) + 40204a: 48 89 54 24 28 mov %rdx,0x28(%rsp) + 40204f: 49 29 c6 sub %rax,%r14 + 402052: 48 89 44 24 10 mov %rax,0x10(%rsp) + 402057: 4c 89 74 24 18 mov %r14,0x18(%rsp) + 40205c: 49 01 d6 add %rdx,%r14 + 40205f: eb 38 jmp 402099 <__stdio_write+0x99> + 402061: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + 402068: 48 85 c0 test %rax,%rax + 40206b: 0f 88 7f 00 00 00 js 4020f0 <__stdio_write+0xf0> + 402071: 49 8b 55 08 mov 0x8(%r13),%rdx + 402075: 49 29 c6 sub %rax,%r14 + 402078: 48 39 d0 cmp %rdx,%rax + 40207b: 76 11 jbe 40208e <__stdio_write+0x8e> + 40207d: 83 ed 01 sub $0x1,%ebp + 402080: 48 29 d0 sub %rdx,%rax + 402083: 49 83 c5 10 add $0x10,%r13 + 402087: 49 8b 55 08 mov 0x8(%r13),%rdx + 40208b: 48 63 dd movslq %ebp,%rbx + 40208e: 48 29 c2 sub %rax,%rdx + 402091: 49 01 45 00 add %rax,0x0(%r13) + 402095: 49 89 55 08 mov %rdx,0x8(%r13) + 402099: 49 63 7f 78 movslq 0x78(%r15),%rdi + 40209d: 4c 89 e0 mov %r12,%rax + 4020a0: 4c 89 ee mov %r13,%rsi + 4020a3: 48 89 da mov %rbx,%rdx + 4020a6: 0f 05 syscall + 4020a8: 48 89 c7 mov %rax,%rdi + 4020ab: e8 50 fe ff ff call 401f00 <__syscall_ret> + 4020b0: 49 39 c6 cmp %rax,%r14 + 4020b3: 75 b3 jne 402068 <__stdio_write+0x68> + 4020b5: 49 8b 47 58 mov 0x58(%r15),%rax + 4020b9: 49 8b 57 60 mov 0x60(%r15),%rdx + 4020bd: 48 01 c2 add %rax,%rdx + 4020c0: 49 89 47 38 mov %rax,0x38(%r15) + 4020c4: 49 89 57 20 mov %rdx,0x20(%r15) + 4020c8: 49 89 47 28 mov %rax,0x28(%r15) + 4020cc: 48 8b 44 24 08 mov 0x8(%rsp),%rax + 4020d1: 48 8b 54 24 38 mov 0x38(%rsp),%rdx + 4020d6: 64 48 2b 14 25 28 00 sub %fs:0x28,%rdx + 4020dd: 00 00 + 4020df: 75 3d jne 40211e <__stdio_write+0x11e> + 4020e1: 48 83 c4 48 add $0x48,%rsp + 4020e5: 5b pop %rbx + 4020e6: 5d pop %rbp + 4020e7: 41 5c pop %r12 + 4020e9: 41 5d pop %r13 + 4020eb: 41 5e pop %r14 + 4020ed: 41 5f pop %r15 + 4020ef: c3 ret + 4020f0: 41 83 0f 20 orl $0x20,(%r15) + 4020f4: 31 c0 xor %eax,%eax + 4020f6: 49 c7 47 20 00 00 00 movq $0x0,0x20(%r15) + 4020fd: 00 + 4020fe: 49 c7 47 38 00 00 00 movq $0x0,0x38(%r15) + 402105: 00 + 402106: 49 c7 47 28 00 00 00 movq $0x0,0x28(%r15) + 40210d: 00 + 40210e: 83 fd 02 cmp $0x2,%ebp + 402111: 74 be je 4020d1 <__stdio_write+0xd1> + 402113: 48 8b 44 24 08 mov 0x8(%rsp),%rax + 402118: 49 2b 45 08 sub 0x8(%r13),%rax + 40211c: eb b3 jmp 4020d1 <__stdio_write+0xd1> + 40211e: e8 cd fd ff ff call 401ef0 <__stack_chk_fail> + 402123: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 40212a: 00 00 00 + 40212d: 0f 1f 00 nopl (%rax) + +0000000000402130 <__ofl_lock>: + 402130: f3 0f 1e fa endbr64 + 402134: 48 83 ec 08 sub $0x8,%rsp + 402138: 48 8d 3d 89 36 00 00 lea 0x3689(%rip),%rdi # 4057c8 + 40213f: e8 1c 00 00 00 call 402160 <__lock> + 402144: 48 8d 05 85 36 00 00 lea 0x3685(%rip),%rax # 4057d0 + 40214b: 48 83 c4 08 add $0x8,%rsp + 40214f: c3 ret + +0000000000402150 <__ofl_unlock>: + 402150: f3 0f 1e fa endbr64 + 402154: 48 8d 3d 6d 36 00 00 lea 0x366d(%rip),%rdi # 4057c8 + 40215b: e9 f0 00 00 00 jmp 402250 <__unlock> + +0000000000402160 <__lock>: + 402160: f3 0f 1e fa endbr64 + 402164: 0f be 0d 18 30 00 00 movsbl 0x3018(%rip),%ecx # 405183 <__libc+0x3> + 40216b: 85 c9 test %ecx,%ecx + 40216d: 74 51 je 4021c0 <__lock+0x60> + 40216f: 31 c0 xor %eax,%eax + 402171: ba 01 00 00 80 mov $0x80000001,%edx + 402176: f0 0f b1 17 lock cmpxchg %edx,(%rdi) + 40217a: 89 c2 mov %eax,%edx + 40217c: 85 c9 test %ecx,%ecx + 40217e: 78 48 js 4021c8 <__lock+0x68> + 402180: 85 c0 test %eax,%eax + 402182: 74 3c je 4021c0 <__lock+0x60> + 402184: 41 b8 0a 00 00 00 mov $0xa,%r8d + 40218a: eb 1e jmp 4021aa <__lock+0x4a> + 40218c: 0f 1f 40 00 nopl 0x0(%rax) + 402190: 8d b2 01 00 00 80 lea -0x7fffffff(%rdx),%esi + 402196: 89 d1 mov %edx,%ecx + 402198: 89 c8 mov %ecx,%eax + 40219a: f0 0f b1 37 lock cmpxchg %esi,(%rdi) + 40219e: 89 c2 mov %eax,%edx + 4021a0: 39 c1 cmp %eax,%ecx + 4021a2: 74 1c je 4021c0 <__lock+0x60> + 4021a4: 41 83 e8 01 sub $0x1,%r8d + 4021a8: 74 2e je 4021d8 <__lock+0x78> + 4021aa: 85 d2 test %edx,%edx + 4021ac: 79 e2 jns 402190 <__lock+0x30> + 4021ae: 8d 8a ff ff ff 7f lea 0x7fffffff(%rdx),%ecx + 4021b4: 89 d6 mov %edx,%esi + 4021b6: eb e0 jmp 402198 <__lock+0x38> + 4021b8: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) + 4021bf: 00 + 4021c0: c3 ret + 4021c1: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + 4021c8: c6 05 b4 2f 00 00 00 movb $0x0,0x2fb4(%rip) # 405183 <__libc+0x3> + 4021cf: 85 c0 test %eax,%eax + 4021d1: 75 b1 jne 402184 <__lock+0x24> + 4021d3: eb eb jmp 4021c0 <__lock+0x60> + 4021d5: 0f 1f 00 nopl (%rax) + 4021d8: 53 push %rbx + 4021d9: 41 b8 01 00 00 00 mov $0x1,%r8d + 4021df: f0 44 0f c1 07 lock xadd %r8d,(%rdi) + 4021e4: 41 b9 ca 00 00 00 mov $0xca,%r9d + 4021ea: 41 83 c0 01 add $0x1,%r8d + 4021ee: bb 80 00 00 00 mov $0x80,%ebx + 4021f3: eb 18 jmp 40220d <__lock+0xad> + 4021f5: 0f 1f 00 nopl (%rax) + 4021f8: 44 8d 82 00 00 00 80 lea -0x80000000(%rdx),%r8d + 4021ff: 89 d0 mov %edx,%eax + 402201: f0 44 0f b1 07 lock cmpxchg %r8d,(%rdi) + 402206: 41 89 c0 mov %eax,%r8d + 402209: 39 c2 cmp %eax,%edx + 40220b: 74 33 je 402240 <__lock+0xe0> + 40220d: 44 89 c2 mov %r8d,%edx + 402210: 45 85 c0 test %r8d,%r8d + 402213: 79 e3 jns 4021f8 <__lock+0x98> + 402215: 49 63 d0 movslq %r8d,%rdx + 402218: 45 31 d2 xor %r10d,%r10d + 40221b: 4c 89 c8 mov %r9,%rax + 40221e: 48 89 de mov %rbx,%rsi + 402221: 0f 05 syscall + 402223: 48 83 f8 da cmp $0xffffffffffffffda,%rax + 402227: 75 07 jne 402230 <__lock+0xd0> + 402229: 31 f6 xor %esi,%esi + 40222b: 4c 89 c8 mov %r9,%rax + 40222e: 0f 05 syscall + 402230: 41 8d 90 ff ff ff 7f lea 0x7fffffff(%r8),%edx + 402237: eb bf jmp 4021f8 <__lock+0x98> + 402239: 0f 1f 80 00 00 00 00 nopl 0x0(%rax) + 402240: 5b pop %rbx + 402241: c3 ret + 402242: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 402249: 00 00 00 + 40224c: 0f 1f 40 00 nopl 0x0(%rax) + +0000000000402250 <__unlock>: + 402250: f3 0f 1e fa endbr64 + 402254: 8b 07 mov (%rdi),%eax + 402256: 85 c0 test %eax,%eax + 402258: 78 06 js 402260 <__unlock+0x10> + 40225a: c3 ret + 40225b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) + 402260: b8 ff ff ff 7f mov $0x7fffffff,%eax + 402265: f0 0f c1 07 lock xadd %eax,(%rdi) + 402269: 3d 01 00 00 80 cmp $0x80000001,%eax + 40226e: 74 ea je 40225a <__unlock+0xa> + 402270: 41 b8 ca 00 00 00 mov $0xca,%r8d + 402276: ba 01 00 00 00 mov $0x1,%edx + 40227b: be 81 00 00 00 mov $0x81,%esi + 402280: 4c 89 c0 mov %r8,%rax + 402283: 0f 05 syscall + 402285: 48 83 f8 da cmp $0xffffffffffffffda,%rax + 402289: 75 cf jne 40225a <__unlock+0xa> + 40228b: 4c 89 c0 mov %r8,%rax + 40228e: 48 89 d6 mov %rdx,%rsi + 402291: 0f 05 syscall + 402293: c3 ret + 402294: 66 2e 0f 1f 84 00 00 cs nopw 0x0(%rax,%rax,1) + 40229b: 00 00 00 + 40229e: 66 90 xchg %ax,%ax + +00000000004022a0 <__errno_location>: + 4022a0: f3 0f 1e fa endbr64 + 4022a4: 64 48 8b 04 25 00 00 mov %fs:0x0,%rax + 4022ab: 00 00 + 4022ad: 48 83 c0 34 add $0x34,%rax + 4022b1: c3 ret + +Disassembly of section .fini: + +00000000004022b2 <_fini>: + 4022b2: 50 push %rax + 4022b3: 58 pop %rax + 4022b4: c3 ret diff --git a/scripts/app_test.sh b/scripts/app_test.sh index 408800c7..700d435c 100755 --- a/scripts/app_test.sh +++ b/scripts/app_test.sh @@ -52,7 +52,7 @@ function run_and_compare() { echo -ne " run with \"${BLOD_C}$args${END_C}\": " - make -C "$ROOT" A="$APP" $args > "$actual" 2>&1 + make -C "$ROOT" AX_TESTCASE=$APP $args > "$actual" 2>&1 if [ $? -ne 0 ]; then return $S_BUILD_FAILED fi @@ -77,8 +77,8 @@ function run_and_compare() { function test_one() { local args=$1 - local expect="$APP/$2" - local actual="$APP/actual.out" + local expect="$APP_DIR/$2" + local actual="$APP_DIR/actual.out" args="$args ARCH=$ARCH ACCEL=n" rm -f "$actual" @@ -109,13 +109,15 @@ function test_one() { # TODO: add more testcases test_list=( "nimbos" + "libc" ) for t in ${test_list[@]}; do - APP=$(realpath "$(pwd)/apps/$t") + APP=$t + APP_DIR=$(realpath "$(pwd)/apps/$t") make -C "$ROOT" user_apps AX_TESTCASE=$t echo -e "${CYAN_C}Testing${END_C} $t:" - source "$APP/test_cmd" + source "$APP_DIR/test_cmd" done echo -e "test script exited with: $EXIT_STATUS" diff --git a/src/loader.rs b/src/loader.rs index 5fb44f26..a9a62a64 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -3,11 +3,11 @@ //! It will read and parse ELF files. //! //! Now these apps are loaded into memory as a part of the kernel image. +use alloc::{collections::btree_map::BTreeMap, vec::Vec}; use core::arch::global_asm; -use alloc::vec::Vec; use axhal::paging::MappingFlags; -use memory_addr::VirtAddr; +use memory_addr::{MemoryAddr, VirtAddr}; global_asm!(include_str!(concat!(env!("OUT_DIR"), "/link_app.S"))); @@ -85,6 +85,8 @@ pub struct ELFInfo { pub entry: VirtAddr, /// The segments of the ELF file pub segments: Vec, + /// The auxiliary vectors of the ELF file + pub auxv: BTreeMap, } /// Load the ELF files by the given app name and return @@ -92,10 +94,11 @@ pub struct ELFInfo { /// /// # Arguments /// * `name` - The name of the app +/// * `base_addr` - The minimal address of user space /// /// # Returns /// Entry and information about segments of the given ELF file -pub(crate) fn load_user_app(name: &str) -> ELFInfo { +pub(crate) fn load_elf(name: &str, base_addr: VirtAddr) -> ELFInfo { use xmas_elf::program::{Flags, SegmentData}; use xmas_elf::{header, ElfFile}; @@ -105,15 +108,7 @@ pub(crate) fn load_user_app(name: &str) -> ELFInfo { .expect("invalid ELF file"); let elf_header = elf.header; - let elf_magic_number = elf_header.pt1.magic; - - assert_eq!(elf_magic_number, *b"\x7fELF", "invalid elf!"); - - assert_eq!( - elf.header.pt2.type_().as_type(), - header::Type::Executable, - "ELF is not an executable object" - ); + assert_eq!(elf_header.pt1.magic, *b"\x7fELF", "invalid elf!"); let expect_arch = if cfg!(target_arch = "x86_64") { header::Machine::X86_64 @@ -145,14 +140,22 @@ pub(crate) fn load_user_app(name: &str) -> ELFInfo { } let mut segments = Vec::new(); + + let elf_offset = kernel_elf_parser::get_elf_base_addr(&elf, base_addr.as_usize()).unwrap(); + assert!( + memory_addr::is_aligned_4k(elf_offset), + "ELF base address must be aligned to 4k" + ); + elf.program_iter() .filter(|ph| ph.get_type() == Ok(xmas_elf::program::Type::Load)) .for_each(|ph| { // align the segment to 4k - let st_vaddr = VirtAddr::from(ph.virtual_addr() as usize); + let st_vaddr = VirtAddr::from(ph.virtual_addr() as usize) + elf_offset; let st_vaddr_align: VirtAddr = st_vaddr.align_down_4k(); - let ed_vaddr_align = - VirtAddr::from((ph.virtual_addr() + ph.mem_size()) as usize).align_up_4k(); + let ed_vaddr_align = VirtAddr::from((ph.virtual_addr() + ph.mem_size()) as usize) + .align_up_4k() + + elf_offset; let data = match ph.get_data(&elf).unwrap() { SegmentData::Undefined(data) => data, _ => panic!("failed to get ELF segment data"), @@ -166,7 +169,8 @@ pub(crate) fn load_user_app(name: &str) -> ELFInfo { }); }); ELFInfo { - entry: VirtAddr::from(elf.header.pt2.entry_point() as usize), + entry: VirtAddr::from(elf.header.pt2.entry_point() as usize + elf_offset), segments, + auxv: kernel_elf_parser::get_auxv_vector(&elf, elf_offset), } } diff --git a/src/main.rs b/src/main.rs index 155487d1..1c05cb3d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,23 +1,26 @@ #![no_std] #![no_main] +#![doc = include_str!("../README.md")] #[macro_use] extern crate log; extern crate alloc; extern crate axstd; +#[rustfmt::skip] +mod config { + include!(concat!(env!("OUT_DIR"), "/uspace_config.rs")); +} mod loader; mod mm; -mod syscall; +mod syscall_imp; mod task; + use alloc::sync::Arc; use axhal::arch::UspaceContext; use axsync::Mutex; -const USER_STACK_SIZE: usize = 0x10000; -const KERNEL_STACK_SIZE: usize = 0x40000; // 256 KiB - #[no_mangle] fn main() { loader::list_apps(); @@ -26,6 +29,7 @@ fn main() { .split(',') .filter(|&x| !x.is_empty()); for testcase in testcases { + info!("Running testcase: {}", testcase); let (entry_vaddr, ustack_top, uspace) = mm::load_user_app(testcase).unwrap(); let user_task = task::spawn_user_task( Arc::new(Mutex::new(uspace)), diff --git a/src/mm.rs b/src/mm.rs index 7e98440c..1933d409 100644 --- a/src/mm.rs +++ b/src/mm.rs @@ -1,18 +1,28 @@ -use axerrno::AxResult; -use memory_addr::VirtAddr; +use alloc::string::ToString; -use axhal::mem::phys_to_virt; -use axhal::paging::MappingFlags; -use axhal::trap::{register_trap_handler, PAGE_FAULT}; +use axerrno::AxResult; +use axhal::{ + paging::MappingFlags, + trap::{register_trap_handler, PAGE_FAULT}, +}; use axmm::AddrSpace; use axtask::TaskExtRef; +use memory_addr::VirtAddr; -use crate::loader; +use crate::{config, loader}; +/// Load a user app. +/// +/// # Returns +/// - The first return value is the entry point of the user app. +/// - The second return value is the top of the user stack. +/// - The third return value is the address space of the user app. pub fn load_user_app(app_name: &str) -> AxResult<(VirtAddr, VirtAddr, AddrSpace)> { - let elf_info = loader::load_user_app(app_name); - - let mut uspace = axmm::new_user_aspace()?; + let mut uspace = axmm::new_user_aspace( + VirtAddr::from_usize(config::USER_SPACE_BASE), + config::USER_SPACE_SIZE, + )?; + let elf_info = loader::load_elf(app_name, uspace.base()); for segement in elf_info.segments { debug!( "Mapping ELF segment: [{:#x?}, {:#x?}) flags: {:#x?}", @@ -26,67 +36,39 @@ pub fn load_user_app(app_name: &str) -> AxResult<(VirtAddr, VirtAddr, AddrSpace) continue; } - let segement_page_iter = memory_addr::PageIter4K::new( - segement.start_vaddr, - segement.start_vaddr + segement.size, - ) - .expect("Failed to create page iterator"); - - let mut segement_data_offset = 0; + uspace.write(segement.start_vaddr + segement.offset, segement.data)?; - for (idx, vaddr) in segement_page_iter.enumerate() { - let (paddr, _, _) = uspace - .page_table() - .query(vaddr) - .unwrap_or_else(|_| panic!("Mapping failed for segment: {:#x?}", vaddr)); - - let (start_paddr, copied_size) = if idx == 0 { - // Align the start of the segment to the start of the page - ( - paddr + segement.offset, - memory_addr::PAGE_SIZE_4K - segement.offset, - ) - } else { - (paddr, memory_addr::PAGE_SIZE_4K) - }; - - debug!( - "Copying segment data: {:#x?} -> {:#x?} size: {:#x?}", - segement.start_vaddr + segement_data_offset + segement.offset, - start_paddr, - copied_size - ); - - unsafe { - core::ptr::copy_nonoverlapping( - segement.data.as_ptr().add(segement_data_offset), - phys_to_virt(start_paddr).as_mut_ptr(), - copied_size, - ); - } - - segement_data_offset += copied_size; - if segement_data_offset >= segement.data.len() { - break; - } - } // TDOO: flush the I-cache } - let ustack_top = uspace.end(); - let ustack_vaddr = ustack_top - crate::USER_STACK_SIZE; + // The user stack is divided into two parts: + // `ustack_start` -> `ustack_pointer`: It is the stack space that users actually read and write. + // `ustack_pointer` -> `ustack_end`: It is the space that contains the arguments, environment variables and auxv passed to the app. + // When the app starts running, the stack pointer points to `ustack_pointer`. + let ustack_end = VirtAddr::from_usize(config::USER_STACK_TOP); + let ustack_size = config::USER_STACK_SIZE; + let ustack_start = ustack_end - ustack_size; debug!( "Mapping user stack: {:#x?} -> {:#x?}", - ustack_vaddr, ustack_top + ustack_start, ustack_end + ); + // FIXME: Add more arguments and environment variables + let (stack_data, ustack_pointer) = kernel_elf_parser::get_app_stack_region( + &[app_name.to_string()], + &[], + &elf_info.auxv, + ustack_start, + ustack_size, ); uspace.map_alloc( - ustack_vaddr, - crate::USER_STACK_SIZE, + ustack_start, + ustack_size, MappingFlags::READ | MappingFlags::WRITE | MappingFlags::USER, - false, + true, )?; - info!("New user address space: {:#x?}", uspace); - Ok((elf_info.entry, ustack_top, uspace)) + + uspace.write(VirtAddr::from_usize(ustack_pointer), stack_data.as_slice())?; + Ok((elf_info.entry, VirtAddr::from(ustack_pointer), uspace)) } #[register_trap_handler(PAGE_FAULT)] @@ -98,7 +80,11 @@ fn handle_page_fault(vaddr: VirtAddr, access_flags: MappingFlags, is_user: bool) .lock() .handle_page_fault(vaddr, access_flags) { - warn!("{}: segmentation fault, exit!", axtask::current().id_name()); + warn!( + "{}: segmentation fault at {:#x}, exit!", + axtask::current().id_name(), + vaddr + ); axtask::exit(-1); } true diff --git a/src/syscall.rs b/src/syscall.rs deleted file mode 100644 index bc0fceb4..00000000 --- a/src/syscall.rs +++ /dev/null @@ -1,45 +0,0 @@ -#![allow(dead_code)] - -use arceos_posix_api as api; -use axerrno::LinuxError; -use axhal::arch::{TrapFrame, UspaceContext}; -use axhal::trap::{register_trap_handler, SYSCALL}; -use axtask::TaskExtRef; - -const SYS_READ: usize = 0; -const SYS_WRITE: usize = 1; -const SYS_SCHED_YIELD: usize = 24; -const SYS_GETPID: usize = 39; -const SYS_CLONE: usize = 56; -const SYS_FORK: usize = 57; -const SYS_EXECVE: usize = 59; -const SYS_EXIT: usize = 60; -const SYS_CLOCK_GETTIME: usize = 228; -const SYS_NANOSLEEP: usize = 230; - -fn sys_clone(tf: &TrapFrame, newsp: usize) -> usize { - let aspace = axtask::current().task_ext().aspace.clone(); - let mut uctx = UspaceContext::from(tf); - uctx.set_sp(newsp); - uctx.set_retval(0); - let new_task = crate::task::spawn_user_task(aspace, uctx); - new_task.id().as_u64() as usize -} - -#[register_trap_handler(SYSCALL)] -fn handle_syscall(tf: &TrapFrame, syscall_num: usize) -> isize { - let ret = match syscall_num { - SYS_READ => api::sys_read(tf.arg0() as _, tf.arg1() as _, tf.arg2() as _), - SYS_WRITE => api::sys_write(tf.arg0() as _, tf.arg1() as _, tf.arg2() as _), - SYS_SCHED_YIELD => api::sys_sched_yield() as isize, - SYS_GETPID => api::sys_getpid() as isize, - SYS_EXIT => axtask::exit(tf.arg0() as _), - SYS_CLOCK_GETTIME => unsafe { api::sys_clock_gettime(tf.arg0() as _, tf.arg1() as _) as _ }, - SYS_NANOSLEEP => unsafe { api::sys_nanosleep(tf.arg0() as _, tf.arg1() as _) as _ }, - _ => { - warn!("Unimplemented syscall: {}", syscall_num); - -LinuxError::ENOSYS.code() as _ - } - }; - ret -} diff --git a/src/syscall_imp/fs/ctl.rs b/src/syscall_imp/fs/ctl.rs new file mode 100644 index 00000000..2aa36dad --- /dev/null +++ b/src/syscall_imp/fs/ctl.rs @@ -0,0 +1,18 @@ +use core::ffi::c_void; + +use crate::syscall_body; + +/// The ioctl() system call manipulates the underlying device parameters +/// of special files. +/// +/// # Arguments +/// * `fd` - The file descriptor +/// * `op` - The request code. It is of type unsigned long in glibc and BSD, +/// and of type int in musl and other UNIX systems. +/// * `argp` - The argument to the request. It is a pointer to a memory location +pub(crate) fn sys_ioctl(_fd: i32, _op: usize, _argp: *mut c_void) -> i32 { + syscall_body!(sys_ioctl, { + warn!("Unimplemented syscall: SYS_IOCTL"); + Ok(0) + }) +} diff --git a/src/syscall_imp/fs/io.rs b/src/syscall_imp/fs/io.rs new file mode 100644 index 00000000..eea5e77c --- /dev/null +++ b/src/syscall_imp/fs/io.rs @@ -0,0 +1,15 @@ +use core::ffi::c_void; + +use arceos_posix_api as api; + +pub(crate) fn sys_read(fd: i32, buf: *mut c_void, count: usize) -> isize { + api::sys_read(fd, buf, count) +} + +pub(crate) fn sys_write(fd: i32, buf: *const c_void, count: usize) -> isize { + api::sys_write(fd, buf, count) +} + +pub(crate) fn sys_writev(fd: i32, iov: *const api::ctypes::iovec, iocnt: i32) -> isize { + unsafe { api::sys_writev(fd, iov, iocnt) } +} diff --git a/src/syscall_imp/fs/mod.rs b/src/syscall_imp/fs/mod.rs new file mode 100644 index 00000000..3e925036 --- /dev/null +++ b/src/syscall_imp/fs/mod.rs @@ -0,0 +1,5 @@ +mod ctl; +mod io; + +pub(crate) use self::ctl::*; +pub(crate) use self::io::*; diff --git a/src/syscall_imp/mm/mmap.rs b/src/syscall_imp/mm/mmap.rs new file mode 100644 index 00000000..de2e01c3 --- /dev/null +++ b/src/syscall_imp/mm/mmap.rs @@ -0,0 +1,98 @@ +use axerrno::LinuxError; +use axhal::paging::MappingFlags; +use axtask::{current, TaskExtRef}; +use memory_addr::{VirtAddr, VirtAddrRange}; + +use crate::syscall_body; + +bitflags::bitflags! { + /// permissions for sys_mmap + /// + /// See + #[derive(Debug)] + struct MmapProt: i32 { + /// Page can be read. + const PROT_READ = 1 << 0; + /// Page can be written. + const PROT_WRITE = 1 << 1; + /// Page can be executed. + const PROT_EXEC = 1 << 2; + } +} + +impl From for MappingFlags { + fn from(value: MmapProt) -> Self { + let mut flags = MappingFlags::USER; + if value.contains(MmapProt::PROT_READ) { + flags |= MappingFlags::READ; + } + if value.contains(MmapProt::PROT_WRITE) { + flags |= MappingFlags::WRITE; + } + if value.contains(MmapProt::PROT_EXEC) { + flags |= MappingFlags::EXECUTE; + } + flags + } +} + +bitflags::bitflags! { + /// flags for sys_mmap + /// + /// See + #[derive(Debug)] + struct MmapFlags: i32 { + /// Share changes + const MAP_SHARED = 1 << 0; + /// Changes private; copy pages on write. + const MAP_PRIVATE = 1 << 1; + /// Map address must be exactly as requested, no matter whether it is available. + const MAP_FIXED = 1 << 4; + /// Don't use a file. + const MAP_ANONYMOUS = 1 << 5; + /// Don't check for reservations. + const MAP_NORESERVE = 1 << 14; + /// Allocation is for a stack. + const MAP_STACK = 0x20000; + } +} + +pub(crate) fn sys_mmap( + addr: *mut usize, + length: usize, + prot: i32, + flags: i32, + _fd: i32, + _offset: isize, +) -> usize { + syscall_body!(sys_mmap, { + let curr = current(); + let curr_ext = curr.task_ext(); + let mut aspace = curr_ext.aspace.lock(); + let permission_flags = MmapProt::from_bits_truncate(prot); + // TODO: check illegal flags for mmap + // An example is the flags contained none of MAP_PRIVATE, MAP_SHARED, or MAP_SHARED_VALIDATE. + let map_flags = MmapFlags::from_bits_truncate(flags); + + let start_addr = if map_flags.contains(MmapFlags::MAP_FIXED) { + VirtAddr::from(addr as usize) + } else { + aspace + .find_free_area( + VirtAddr::from(addr as usize), + length, + VirtAddrRange::new(aspace.base(), aspace.end()), + ) + .or(aspace.find_free_area( + aspace.base(), + length, + VirtAddrRange::new(aspace.base(), aspace.end()), + )) + .ok_or(LinuxError::ENOMEM)? + }; + + aspace.map_alloc(start_addr, length, permission_flags.into(), false)?; + + Ok(start_addr.as_usize()) + }) +} diff --git a/src/syscall_imp/mm/mod.rs b/src/syscall_imp/mm/mod.rs new file mode 100644 index 00000000..7c73ad37 --- /dev/null +++ b/src/syscall_imp/mm/mod.rs @@ -0,0 +1,3 @@ +mod mmap; + +pub(crate) use self::mmap::*; diff --git a/src/syscall_imp/mod.rs b/src/syscall_imp/mod.rs new file mode 100644 index 00000000..3517fca4 --- /dev/null +++ b/src/syscall_imp/mod.rs @@ -0,0 +1,69 @@ +mod fs; +mod mm; +mod task; +mod time; + +use axerrno::LinuxError; +use axhal::{ + arch::TrapFrame, + trap::{register_trap_handler, SYSCALL}, +}; +use syscalls::Sysno; + +use self::fs::*; +use self::mm::*; +use self::task::*; +use self::time::*; + +/// Macro to generate syscall body +/// +/// It will receive a function which return Result<_, LinuxError> and convert it to +/// the type which is specified by the caller. +#[macro_export] +macro_rules! syscall_body { + ($fn: ident, $($stmt: tt)*) => {{ + #[allow(clippy::redundant_closure_call)] + let res = (|| -> axerrno::LinuxResult<_> { $($stmt)* })(); + match res { + Ok(_) | Err(axerrno::LinuxError::EAGAIN) => debug!(concat!(stringify!($fn), " => {:?}"), res), + Err(_) => info!(concat!(stringify!($fn), " => {:?}"), res), + } + match res { + Ok(v) => v as _, + Err(e) => { + -e.code() as _ + } + } + }}; +} + +#[register_trap_handler(SYSCALL)] +fn handle_syscall(tf: &TrapFrame, syscall_num: usize) -> isize { + match Sysno::from(syscall_num as u32) { + Sysno::read => sys_read(tf.arg0() as _, tf.arg1() as _, tf.arg2() as _), + Sysno::write => sys_write(tf.arg0() as _, tf.arg1() as _, tf.arg2() as _), + Sysno::mmap => sys_mmap( + tf.arg0() as _, + tf.arg1() as _, + tf.arg2() as _, + tf.arg3() as _, + tf.arg4() as _, + tf.arg5() as _, + ) as _, + Sysno::ioctl => sys_ioctl(tf.arg0() as _, tf.arg1() as _, tf.arg2() as _) as _, + Sysno::writev => sys_writev(tf.arg0() as _, tf.arg1() as _, tf.arg2() as _), + Sysno::sched_yield => sys_sched_yield() as isize, + Sysno::nanosleep => sys_nanosleep(tf.arg0() as _, tf.arg1() as _) as _, + Sysno::getpid => sys_getpid() as isize, + Sysno::exit => sys_exit(tf.arg0() as _), + #[cfg(target_arch = "x86_64")] + Sysno::arch_prctl => sys_arch_prctl(tf.arg0() as _, tf.arg1() as _), + Sysno::set_tid_address => sys_set_tid_address(tf.arg0() as _), + Sysno::clock_gettime => sys_clock_gettime(tf.arg0() as _, tf.arg1() as _) as _, + Sysno::exit_group => sys_exit_group(tf.arg0() as _), + _ => { + warn!("Unimplemented syscall: {}", syscall_num); + axtask::exit(LinuxError::ENOSYS as _) + } + } +} diff --git a/src/syscall_imp/task/mod.rs b/src/syscall_imp/task/mod.rs new file mode 100644 index 00000000..cf6192c3 --- /dev/null +++ b/src/syscall_imp/task/mod.rs @@ -0,0 +1,5 @@ +mod schedule; +mod thread; + +pub(crate) use self::schedule::*; +pub(crate) use self::thread::*; diff --git a/src/syscall_imp/task/schedule.rs b/src/syscall_imp/task/schedule.rs new file mode 100644 index 00000000..5de19b38 --- /dev/null +++ b/src/syscall_imp/task/schedule.rs @@ -0,0 +1,12 @@ +use arceos_posix_api as api; + +pub(crate) fn sys_sched_yield() -> i32 { + api::sys_sched_yield() +} + +pub(crate) fn sys_nanosleep( + req: *const api::ctypes::timespec, + rem: *mut api::ctypes::timespec, +) -> i32 { + unsafe { api::sys_nanosleep(req, rem) } +} diff --git a/src/syscall_imp/task/thread.rs b/src/syscall_imp/task/thread.rs new file mode 100644 index 00000000..28ea27b3 --- /dev/null +++ b/src/syscall_imp/task/thread.rs @@ -0,0 +1,95 @@ +use arceos_posix_api::{self as api}; +use axtask::{current, TaskExtRef}; +use num_enum::TryFromPrimitive; + +use crate::syscall_body; + +/// ARCH_PRCTL codes +/// +/// It is only avaliable on x86_64, and is not convenient +/// to generate automatically via c_to_rust binding. +#[derive(Debug, Eq, PartialEq, TryFromPrimitive)] +#[repr(i32)] +enum ArchPrctlCode { + /// Set the GS segment base + SetGs = 0x1001, + /// Set the FS segment base + SetFs = 0x1002, + /// Get the FS segment base + GetFs = 0x1003, + /// Get the GS segment base + GetGs = 0x1004, + /// The setting of the flag manipulated by ARCH_SET_CPUID + GetCpuid = 0x1011, + /// Enable (addr != 0) or disable (addr == 0) the cpuid instruction for the calling thread. + SetCpuid = 0x1012, +} + +pub(crate) fn sys_getpid() -> i32 { + api::sys_getpid() +} + +pub(crate) fn sys_exit(status: i32) -> ! { + let curr = current(); + let clear_child_tid = curr.task_ext().clear_child_tid() as *mut i32; + if !clear_child_tid.is_null() { + // TODO: check whether the address is valid + unsafe { + // TODO: Encapsulate all operations that access user-mode memory into a unified function + *(clear_child_tid) = 0; + } + // TODO: wake up threads, which are blocked by futex, and waiting for the address pointed by clear_child_tid + } + axtask::exit(status); +} + +pub(crate) fn sys_exit_group(status: i32) -> ! { + warn!("Temporarily replace sys_exit_group with sys_exit"); + axtask::exit(status); +} + +/// To set the clear_child_tid field in the task extended data. +/// +/// The set_tid_address() always succeeds +pub(crate) fn sys_set_tid_address(tid_ptd: *const i32) -> isize { + syscall_body!(sys_set_tid_address, { + let curr = current(); + curr.task_ext().set_clear_child_tid(tid_ptd as _); + Ok(curr.id().as_u64() as isize) + }) +} + +#[cfg(target_arch = "x86_64")] +pub(crate) fn sys_arch_prctl(code: i32, addr: u64) -> isize { + use axerrno::LinuxError; + syscall_body!(sys_arch_prctl, { + match ArchPrctlCode::try_from(code) { + // TODO: check the legality of the address + Ok(ArchPrctlCode::SetFs) => { + unsafe { + axhal::arch::write_thread_pointer(addr as usize); + } + Ok(0) + } + Ok(ArchPrctlCode::GetFs) => { + unsafe { + *(addr as *mut u64) = axhal::arch::read_thread_pointer() as u64; + } + Ok(0) + } + Ok(ArchPrctlCode::SetGs) => { + unsafe { + x86::msr::wrmsr(x86::msr::IA32_KERNEL_GSBASE, addr); + } + Ok(0) + } + Ok(ArchPrctlCode::GetGs) => { + unsafe { + *(addr as *mut u64) = x86::msr::rdmsr(x86::msr::IA32_KERNEL_GSBASE); + } + Ok(0) + } + _ => Err(LinuxError::ENOSYS), + } + }) +} diff --git a/src/syscall_imp/time.rs b/src/syscall_imp/time.rs new file mode 100644 index 00000000..80aa6438 --- /dev/null +++ b/src/syscall_imp/time.rs @@ -0,0 +1,5 @@ +use arceos_posix_api as api; + +pub(crate) fn sys_clock_gettime(clock_id: i32, tp: *mut api::ctypes::timespec) -> i32 { + unsafe { api::sys_clock_gettime(clock_id, tp) } +} diff --git a/src/task.rs b/src/task.rs index 7b9382c5..34434f41 100644 --- a/src/task.rs +++ b/src/task.rs @@ -1,4 +1,5 @@ use alloc::sync::Arc; +use core::sync::atomic::AtomicU64; use axhal::arch::UspaceContext; use axmm::AddrSpace; @@ -9,6 +10,12 @@ use axtask::{AxTaskRef, TaskExtRef, TaskInner}; pub struct TaskExt { /// The process ID. pub proc_id: usize, + /// The clear thread tid field + /// + /// See + /// + /// When the thread exits, the kernel clears the word at this address if it is not NULL. + clear_child_tid: AtomicU64, /// The user space context. pub uctx: UspaceContext, /// The virtual memory address space. @@ -20,9 +27,20 @@ impl TaskExt { Self { proc_id: 233, uctx, + clear_child_tid: AtomicU64::new(0), aspace, } } + + pub(crate) fn clear_child_tid(&self) -> u64 { + self.clear_child_tid + .load(core::sync::atomic::Ordering::Relaxed) + } + + pub(crate) fn set_clear_child_tid(&self, clear_child_tid: u64) { + self.clear_child_tid + .store(clear_child_tid, core::sync::atomic::Ordering::Relaxed); + } } axtask::def_task_ext!(TaskExt); @@ -41,7 +59,7 @@ pub fn spawn_user_task(aspace: Arc>, uctx: UspaceContext) -> Ax unsafe { curr.task_ext().uctx.enter_uspace(kstack_top) }; }, "userboot".into(), - crate::KERNEL_STACK_SIZE, + crate::config::KERNEL_STACK_SIZE, ); task.ctx_mut() .set_page_table_root(aspace.lock().page_table_root());