From 599a8e730dd7b50fe863421cce199a90489333c5 Mon Sep 17 00:00:00 2001 From: csd4ni3l Date: Tue, 7 Apr 2026 22:58:16 +0200 Subject: [PATCH] remove libxunil folder to make it a submodule --- user/libxunil/.cargo/config.toml | 4 - user/libxunil/.gitignore | 1 - user/libxunil/Cargo.lock | 34 -- user/libxunil/Cargo.toml | 18 - user/libxunil/include/inttypes.h | 1 - user/libxunil/include/stdio.h | 44 -- user/libxunil/include/stdlib.h | 24 -- user/libxunil/include/string.h | 22 - user/libxunil/include/strings.h | 8 - user/libxunil/rust-toolchain.toml | 8 - user/libxunil/src/file.rs | 255 ------------ user/libxunil/src/heap.rs | 109 ----- user/libxunil/src/lib.rs | 662 ------------------------------ user/libxunil/src/mem.rs | 258 ------------ user/libxunil/src/syscall.rs | 77 ---- user/libxunil/src/time.rs | 38 -- user/libxunil/src/util.rs | 20 - user/libxunil/to_implement.txt | 45 -- 18 files changed, 1628 deletions(-) delete mode 100644 user/libxunil/.cargo/config.toml delete mode 100644 user/libxunil/.gitignore delete mode 100644 user/libxunil/Cargo.lock delete mode 100644 user/libxunil/Cargo.toml delete mode 100644 user/libxunil/include/inttypes.h delete mode 100644 user/libxunil/include/stdio.h delete mode 100644 user/libxunil/include/stdlib.h delete mode 100644 user/libxunil/include/string.h delete mode 100644 user/libxunil/include/strings.h delete mode 100644 user/libxunil/rust-toolchain.toml delete mode 100644 user/libxunil/src/file.rs delete mode 100644 user/libxunil/src/heap.rs delete mode 100644 user/libxunil/src/lib.rs delete mode 100644 user/libxunil/src/mem.rs delete mode 100644 user/libxunil/src/syscall.rs delete mode 100644 user/libxunil/src/time.rs delete mode 100644 user/libxunil/src/util.rs delete mode 100644 user/libxunil/to_implement.txt diff --git a/user/libxunil/.cargo/config.toml b/user/libxunil/.cargo/config.toml deleted file mode 100644 index 7dc1635..0000000 --- a/user/libxunil/.cargo/config.toml +++ /dev/null @@ -1,4 +0,0 @@ -[unstable] - json-target-spec = true - build-std-features = ["compiler-builtins-mem"] - build-std = ["core", "compiler_builtins", "alloc"] diff --git a/user/libxunil/.gitignore b/user/libxunil/.gitignore deleted file mode 100644 index ea8c4bf..0000000 --- a/user/libxunil/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/target diff --git a/user/libxunil/Cargo.lock b/user/libxunil/Cargo.lock deleted file mode 100644 index 13f6007..0000000 --- a/user/libxunil/Cargo.lock +++ /dev/null @@ -1,34 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "libxunil" -version = "0.1.0" -dependencies = [ - "spin", -] - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "spin" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" -dependencies = [ - "lock_api", -] diff --git a/user/libxunil/Cargo.toml b/user/libxunil/Cargo.toml deleted file mode 100644 index eadb2ff..0000000 --- a/user/libxunil/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "libxunil" -version = "0.1.0" -edition = "2024" - -[lib] -name = "xunil" -crate-type = ["staticlib"] - -[profile.release] -panic = "abort" -opt-level = "s" - -[dependencies] -spin = "0.10.0" - -[profile.dev] -panic = "abort" diff --git a/user/libxunil/include/inttypes.h b/user/libxunil/include/inttypes.h deleted file mode 100644 index 9a6118b..0000000 --- a/user/libxunil/include/inttypes.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/user/libxunil/include/stdio.h b/user/libxunil/include/stdio.h deleted file mode 100644 index dbfb286..0000000 --- a/user/libxunil/include/stdio.h +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once -#include -#include -#include - -typedef struct FILE FILE; - -extern FILE *stdin; -extern FILE *stdout; -extern FILE *stderr; - -#define EOF (-1) - -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 - -FILE *fopen(const char *path, const char *mode); -int fclose(FILE *fp); -size_t fread(void *ptr, size_t size, size_t nmemb, FILE *fp); -size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *fp); -int fseek(FILE *fp, long offset, int whence); -long ftell(FILE *fp); -int fflush(FILE *fp); -char *fgets(char *s, int size, FILE *fp); -int fputs(const char *s, FILE *fp); -int feof(FILE *fp); -int ferror(FILE *fp); -int remove(const char *path); -int rename(const char *path, const char *new_path); - -int printf(const char *fmt, ...); -int puts(const char *s); -int putchar(int c); - -int fprintf(FILE *fp, const char *fmt, ...); -int sprintf(char *buf, const char *fmt, ...); -int snprintf(char *buf, size_t size, const char *fmt, ...); -int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap); -int vfprintf(FILE *fp, const char *fmt, va_list ap); -ssize_t write(int fd, const void *buf, size_t count); -void exit(int code); - -int sscanf(const char *str, const char *format, ...); diff --git a/user/libxunil/include/stdlib.h b/user/libxunil/include/stdlib.h deleted file mode 100644 index b32dd28..0000000 --- a/user/libxunil/include/stdlib.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include -#include - -void *malloc(size_t size); -void *calloc(size_t nmemb, size_t size); -void *realloc(void *ptr, size_t size); -void free(void *ptr); - -void exit(int status); -void abort(void); - -int atoi(const char *s); -long atol(const char *s); -double atof(const char *s); -long strtol(const char *s, char **endptr, int base); -double strtod(const char *s, char **endptr); - -char *getenv(const char *name); -void qsort(void *base, size_t nmemb, size_t size, int (*cmp)(const void *, const void *)); -int abs(int x); -int system(const char *cmd); -int draw_pixel(uint32_t x, uint32_t y, uint32_t color); -int framebuffer_swap(); diff --git a/user/libxunil/include/string.h b/user/libxunil/include/string.h deleted file mode 100644 index c4209c4..0000000 --- a/user/libxunil/include/string.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include - -void *memset(void *s, int c, size_t n); -void *memcpy(void *dst, const void *src, size_t n); -void *memmove(void *dst, const void *src, size_t n); -int memcmp(const void *s1, const void *s2, size_t n); -void *memchr(const void *s, int c, size_t n); - -size_t strlen(const char *s); -char *strcpy(char *dst, const char *src); -char *strncpy(char *dst, const char *src, size_t n); -char *strcat(char *dst, const char *src); -char *strncat(char *dst, const char *src, size_t n); -int strcmp(const char *s1, const char *s2); -int strncmp(const char *s1, const char *s2, size_t n); -char *strchr(const char *s, int c); -char *strrchr(const char *s, int c); -char *strstr(const char *haystack, const char *needle); -char *strtok(char *str, const char *delim); -char *strdup(const char *s); -char *strerror(int errnum); diff --git a/user/libxunil/include/strings.h b/user/libxunil/include/strings.h deleted file mode 100644 index 5abbdee..0000000 --- a/user/libxunil/include/strings.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once -#include - -int strcasecmp(const char *s1, const char *s2); -int strncasecmp(const char *s1, const char *s2, size_t n); -void bzero(void *s, size_t n); -void bcopy(const void *src, void *dest, size_t n); -int bcmp(const void *s1, const void *s2, size_t n); diff --git a/user/libxunil/rust-toolchain.toml b/user/libxunil/rust-toolchain.toml deleted file mode 100644 index 66a0077..0000000 --- a/user/libxunil/rust-toolchain.toml +++ /dev/null @@ -1,8 +0,0 @@ -[toolchain] -channel = "nightly" -targets = [ - "x86_64-unknown-none", - # "aarch64-unknown-none", - # "riscv64gc-unknown-none-elf", - # "loongarch64-unknown-none", -] diff --git a/user/libxunil/src/file.rs b/user/libxunil/src/file.rs deleted file mode 100644 index 2a87d75..0000000 --- a/user/libxunil/src/file.rs +++ /dev/null @@ -1,255 +0,0 @@ -use core::{ - ffi::CStr, - ptr::{null, null_mut}, -}; - -use crate::{mem::free, printf, puts}; - -#[repr(C)] -#[derive(Clone, Copy)] -pub struct FILE { - pub data: *const u8, // pointer to the file's data - pub size: usize, // total size - pub cursor: usize, // current position - pub writable: bool, // is this a write buffer? - pub write_buf: *mut u8, // for writable fake files - pub write_cap: usize, - pub fd: i64, -} - -impl FILE { - pub const fn zeroed() -> FILE { - FILE { - data: null(), - size: 0, - cursor: 0, - writable: false, - write_buf: null_mut(), - write_cap: 0, - fd: -1, - } - } -} - -struct FakeFileEntry { - name: &'static str, - data: &'static [u8], -} - -#[repr(C, align(8))] -struct AlignedWAD([u8; include_bytes!("../../../assets/doom1.wad").len()]); -static TEST_WAD: AlignedWAD = AlignedWAD(*include_bytes!("../../../assets/doom1.wad")); -static TEST_WAD_BYTES: &[u8] = &TEST_WAD.0; - -static FILES: &[FakeFileEntry] = &[ - FakeFileEntry { - name: "doom1.wad", - data: TEST_WAD_BYTES, - }, - FakeFileEntry { - name: "default.cfg", - data: b"", - }, - FakeFileEntry { - name: "doom.cfg", - data: b"", - }, -]; - -static mut FILE_POOL: [FILE; 16] = [FILE::zeroed(); 16]; -static mut FILE_POOL_USED: [bool; 16] = [false; 16]; -static mut STDERR_FILE: FILE = FILE::zeroed(); -static mut STDOUT_FILE: FILE = FILE::zeroed(); -static mut STDIN_FILE: FILE = FILE::zeroed(); - -#[unsafe(no_mangle)] -pub static mut stderr: *mut FILE = unsafe { &raw mut STDERR_FILE }; -#[unsafe(no_mangle)] -pub static mut stdin: *mut FILE = unsafe { &raw mut STDIN_FILE }; -#[unsafe(no_mangle)] -pub static mut stdout: *mut FILE = unsafe { &raw mut STDOUT_FILE }; - -pub unsafe fn get_file_pool_slot() -> (*mut FILE, i64) { - unsafe { - for i in 0..16 { - if !FILE_POOL_USED[i] { - FILE_POOL_USED[i] = true; - return (&mut FILE_POOL[i], i as i64); - } - } - - (null_mut(), -1) - } -} - -#[unsafe(no_mangle)] -extern "C" fn fopen(path: *const i8, mode: *const i8) -> *mut FILE { - if path.is_null() || mode.is_null() { - return null_mut(); - } - - unsafe { - let name = CStr::from_ptr(path).to_str().unwrap_or(""); - - for entry in FILES { - if name.contains(entry.name) { - let (slot, fd) = get_file_pool_slot(); - - if slot.is_null() { - return null_mut(); - } - - (*slot).data = entry.data.as_ptr(); - (*slot).size = entry.data.len(); - (*slot).cursor = 0; - (*slot).writable = false; - (*slot).write_buf = null_mut(); - (*slot).write_cap = 0; - (*slot).fd = fd; - return slot; - } - } - } - - null_mut() -} - -#[unsafe(no_mangle)] -extern "C" fn fclose(file_ptr: *mut FILE) -> i32 { - if file_ptr.is_null() || unsafe { (*file_ptr).fd < 0 || (*file_ptr).fd >= 16 } { - return -1; - } - - unsafe { FILE_POOL_USED[(*file_ptr).fd as usize] = false }; - unsafe { *file_ptr = FILE::zeroed() }; - - 0 -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn fprintf(file_ptr: *mut FILE, fmt: *const u8, args: ...) -> i32 { - if fmt.is_null() || file_ptr.is_null() || unsafe { (*file_ptr).fd < 0 || (*file_ptr).fd >= 16 } - { - return -1; - } - - 0 -} - -#[unsafe(no_mangle)] -extern "C" fn fread(ptr: *mut u8, size: usize, nmemb: usize, fp: *mut FILE) -> usize { - if size == 0 - || nmemb == 0 - || ptr.is_null() - || fp.is_null() - || unsafe { (*fp).fd < 0 || (*fp).fd >= 16 } - { - return 0; - } - - let total = match size.checked_mul(nmemb) { - Some(t) => t, - None => return 0, - }; - - unsafe { - let f = &mut *fp; - if f.cursor > f.size { - puts(b"failed to read\0".as_ptr()); - return 0; - } - - let available = f.size - f.cursor; - let to_read = total.min(available); - - if to_read > 0 { - core::ptr::copy_nonoverlapping(f.data.add(f.cursor), ptr, to_read); - f.cursor = f.cursor.saturating_add(to_read); - } - - to_read / size - } -} - -#[unsafe(no_mangle)] -extern "C" fn fseek(stream: *mut FILE, offset: i64, whence: i32) -> i32 { - if stream.is_null() || unsafe { (*stream).fd } == -1 { - return -1; - } - - let f = unsafe { &mut *stream }; - - let new_pos = match whence { - 0 => { - if offset < 0 { - return -1; - } - offset as usize - } - 1 => { - let cur = f.cursor as i64; - let pos = cur.saturating_add(offset); - if pos < 0 { - return -1; - } - pos as usize - } - 2 => { - let end = f.size as i64; - let pos = end.saturating_add(offset); - if pos < 0 { - return -1; - } - pos as usize - } - _ => return -1, - }; - - if new_pos > f.size { - return -1; - } - - f.cursor = new_pos; - 0 -} - -#[unsafe(no_mangle)] -extern "C" fn fwrite(ptr: *mut u8, size: usize, count: usize, fp: *mut FILE) -> usize { - if ptr.is_null() || fp.is_null() || unsafe { (*fp).fd < 0 || (*fp).fd >= 16 } { - return 0; - } - count -} - -#[unsafe(no_mangle)] -extern "C" fn ftell(stream: *mut FILE) -> i64 { - if stream.is_null() || unsafe { (*stream).fd < 0 || (*stream).fd >= 16 } { - return -1; - } - unsafe { (*stream).cursor as i64 } -} - -#[unsafe(no_mangle)] -extern "C" fn fflush(file_ptr: *mut FILE) -> i32 { - 0 -} - -#[unsafe(no_mangle)] -extern "C" fn mkdir(path: *const u8, mode: *const u8) -> i32 { - 0 -} - -#[unsafe(no_mangle)] -extern "C" fn remove(path: *const i8) -> i32 { - 0 -} - -#[unsafe(no_mangle)] -extern "C" fn rename(path: *const u8, new_path: *const u8) -> i32 { - 0 -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn vfprintf(stream: *const u8, format: *const u8, args: ...) -> i32 { - 0 -} diff --git a/user/libxunil/src/heap.rs b/user/libxunil/src/heap.rs deleted file mode 100644 index 88355e7..0000000 --- a/user/libxunil/src/heap.rs +++ /dev/null @@ -1,109 +0,0 @@ -use spin::mutex::Mutex; - -use crate::util::align_up; - -pub struct LinkedNode { - pub size: usize, - pub next: Option<&'static mut LinkedNode>, -} - -impl LinkedNode { - pub const fn new(size: usize) -> LinkedNode { - LinkedNode { size, next: None } - } - - pub fn start_addr(&self) -> usize { - self as *const Self as usize - } - - pub fn end_addr(&self) -> usize { - self.start_addr() + self.size - } -} - -pub struct LinkedListAllocator { - head: LinkedNode, -} - -#[derive(Clone, Copy)] -pub struct Allocation { - pub start: usize, - pub end: usize, -} - -impl LinkedListAllocator { - pub const fn new() -> LinkedListAllocator { - Self { - head: LinkedNode::new(0), - } - } - - pub unsafe fn add_free_memory_region(&mut self, start: usize, size: usize) { - unsafe { - assert_eq!(align_up(start, 16), start); - assert!(size >= core::mem::size_of::()); - - let mut node = LinkedNode::new(size); - node.next = self.head.next.take(); - - let node_ptr = start as *mut LinkedNode; - node_ptr.write(node); - self.head.next = Some(&mut *node_ptr); - } - } - - pub fn find_region(&mut self, size: usize) -> Option { - let mut current = &mut self.head; - - while let Some(ref region) = current.next { - let mut alloc = match Self::alloc_from_region(region, size) { - Ok(a) => a, - Err(()) => { - current = current.next.as_mut().unwrap(); - continue; - } - }; - - let taken = current.next.take().unwrap(); - let region_end = taken.end_addr(); - - let old_next = unsafe { - let node_ptr = taken as *mut LinkedNode; - let next_ptr = core::ptr::addr_of_mut!((*node_ptr).next); - core::ptr::read(next_ptr) - }; - - let excess_size = region_end - alloc.end; - - if excess_size >= core::mem::size_of::() { - unsafe { - let remainder_ptr = alloc.end as *mut LinkedNode; - remainder_ptr.write(LinkedNode { - size: excess_size, - next: old_next, - }); - current.next = Some(&mut *remainder_ptr); - } - } else { - alloc.end = region_end; - current.next = old_next; - } - - return Some(alloc); - } - - None - } - - fn alloc_from_region(region: &LinkedNode, size: usize) -> Result { - let start = region.start_addr(); - let end_unaligned = start.checked_add(size).ok_or(())?; - let end = align_up(end_unaligned, 16); - if end > region.end_addr() { - return Err(()); - } - Ok(Allocation { start, end }) - } -} - -pub static ALLOCATOR: Mutex = Mutex::new(LinkedListAllocator::new()); diff --git a/user/libxunil/src/lib.rs b/user/libxunil/src/lib.rs deleted file mode 100644 index a55ea5c..0000000 --- a/user/libxunil/src/lib.rs +++ /dev/null @@ -1,662 +0,0 @@ -#![no_std] -#![feature(c_variadic)] -use core::{ - ffi::VaList, - fmt::{Error, Result, Write}, - ptr::{addr_of_mut, null, null_mut}, - usize, -}; - -use crate::{ - mem::{malloc, memcpy}, - syscall::{DRAW_BUFFER, DRAW_PIXEL, EXIT, FRAMEBUFFER_SWAP, WRITE, syscall0, syscall3}, -}; - -pub mod file; -pub mod heap; -pub mod mem; -pub mod syscall; -pub mod time; -pub mod util; - -static mut ERRNO: core::ffi::c_int = 0; - -static TOUPPER_TABLE: [i32; 384] = { - let mut table = [0i32; 384]; - let mut i = 0usize; - while i < 384 { - let c = i.wrapping_sub(128) as u8; - table[i] = if c.is_ascii_lowercase() { - (c - 0x20) as i32 - } else { - c as i32 - }; - i += 1; - } - table -}; - -#[unsafe(no_mangle)] -extern "C" fn write(fd: i32, buf: *const u8, count: usize) -> isize { - unsafe { syscall3(WRITE, fd as isize, buf as isize, count as isize) } -} - -#[unsafe(no_mangle)] -extern "C" fn exit(code: i32) -> ! { - unsafe { syscall3(EXIT, code as isize, 0, 0) }; - loop { - unsafe { core::arch::asm!("nop") }; - } -} - -#[unsafe(no_mangle)] -extern "C" fn strlen(s: *const u8) -> usize { - let mut len = 0usize; - while unsafe { *s.add(len) } != 0 { - len += 1; - } - len -} - -#[unsafe(no_mangle)] -extern "C" fn puts(s: *const u8) -> i32 { - write(1, s, strlen(s)); - write(1, b"\n\0".as_ptr(), 1); - - 0 -} - -#[unsafe(no_mangle)] -extern "C" fn putchar(c: i32) -> i32 { - let b = c as u8; - write(1, core::ptr::addr_of!(b), 1); - - 0 -} - -#[unsafe(no_mangle)] -extern "C" fn abs(n: i32) -> i32 { - n.abs() -} - -struct BufWriter { - buf: *mut u8, - max: usize, - pos: usize, -} - -impl Write for BufWriter { - fn write_str(&mut self, s: &str) -> Result { - for byte in s.bytes() { - if self.pos >= self.max { - return Err(Error); - } - unsafe { - *self.buf.add(self.pos) = byte; - } - self.pos += 1; - } - Ok(()) - } -} - -struct StdoutWriter { - size: usize, -} - -impl Write for StdoutWriter { - fn write_str(&mut self, s: &str) -> Result { - self.size += s.len(); - write(1, s.as_ptr(), s.len()); - Ok(()) - } -} - -pub unsafe fn write_c_formatted(fmt: *const u8, args: &mut VaList, writer: &mut impl Write) { - let mut fi = 0usize; - - loop { - let ch = unsafe { *fmt.add(fi) }; - fi += 1; - if ch == 0 { - break; - } - - if ch != b'%' { - let _ = writer.write_char(ch as char); - continue; - } - - let mut precision: Option = None; - let mut next_byte = unsafe { *fmt.add(fi) }; - - if next_byte == b'.' { - fi += 1; - let mut p_val = 0usize; - loop { - let digit = unsafe { *fmt.add(fi) }; - if digit >= b'0' && digit <= b'9' { - p_val = p_val * 10 + (digit - b'0') as usize; - fi += 1; - } else { - break; - } - } - precision = Some(p_val); - next_byte = unsafe { *fmt.add(fi) }; - } - - let spec = next_byte; - fi += 1; - - unsafe { - match spec { - b'd' | b'i' => { - let v: i32 = args.arg(); - if let Some(p) = precision { - let _ = write!(writer, "{:01$}", v, p); - } else { - let _ = write!(writer, "{}", v); - } - } - b'u' => { - let v: u32 = args.arg(); - if let Some(p) = precision { - let _ = write!(writer, "{:01$}", v, p); - } else { - let _ = write!(writer, "{}", v); - } - } - b'x' => { - let v: u32 = args.arg(); - if let Some(p) = precision { - let _ = write!(writer, "{:01$x}", v, p); - } else { - let _ = write!(writer, "{:x}", v); - } - } - b'X' => { - let v: u32 = args.arg(); - if let Some(p) = precision { - let _ = write!(writer, "{:01$X}", v, p); - } else { - let _ = write!(writer, "{:X}", v); - } - } - b'o' => { - let v: u32 = args.arg(); - if let Some(p) = precision { - let _ = write!(writer, "{:01$o}", v, p); - } else { - let _ = write!(writer, "{:o}", v); - } - } - b'p' => { - let v: *const u8 = args.arg(); - if v.is_null() { - let _ = writer.write_str("(null)"); - } else { - let _ = write!(writer, "0x{:x}", v as usize); - } - } - b'c' => { - let v: i32 = args.arg(); - let _ = writer.write_char((v as u8) as char); - } - b's' => { - let ptr: *const u8 = args.arg(); - if ptr.is_null() { - let _ = writer.write_str("(null)"); - } else { - let mut si = 0usize; - loop { - let c = *ptr.add(si); - if c == 0 { - break; - } - if let Some(p) = precision { - if si >= p { - break; - } - } - let _ = writer.write_char(c as char); - si += 1; - } - } - } - b'f' | b'F' | b'g' | b'G' => { - let v: f64 = args.arg(); - if let Some(p) = precision { - let _ = write!(writer, "{:.*}", p, v); - } else { - let _ = write!(writer, "{}", v); - } - } - b'l' => { - let next_spec = *fmt.add(fi); - fi += 1; - match next_spec { - b'd' | b'i' => { - let v: i64 = args.arg(); - if let Some(p) = precision { - let _ = write!(writer, "{:01$}", v, p); - } else { - let _ = write!(writer, "{}", v); - } - } - b'u' => { - let v: u64 = args.arg(); - if let Some(p) = precision { - let _ = write!(writer, "{:01$}", v, p); - } else { - let _ = write!(writer, "{}", v); - } - } - _ => { - let _ = writer.write_char('%'); - let _ = writer.write_char('l'); - let _ = writer.write_char(next_spec as char); - } - } - } - b'%' => { - let _ = writer.write_char('%'); - } - _ => { - let _ = writer.write_char('%'); - let _ = writer.write_char(spec as char); - } - } - } - } -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn printf(fmt: *const u8, mut args: ...) -> i32 { - let mut writer = StdoutWriter { size: 0 }; - - unsafe { write_c_formatted(fmt, &mut args, &mut writer) }; - - writer.size as i32 -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn vsnprintf( - buf: *mut u8, - size: usize, - fmt: *const u8, - mut args: VaList, -) -> i32 { - if buf.is_null() || size == 0 || fmt.is_null() { - return -1; - } - - let max = size - 1; - let mut writer = BufWriter { buf, max, pos: 0 }; - - unsafe { write_c_formatted(fmt, &mut args, &mut writer) }; - - unsafe { - *buf.add(writer.pos) = 0; - } - - writer.pos as i32 -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn snprintf(buf: *mut u8, size: usize, fmt: *const u8, mut args: ...) -> i32 { - if buf.is_null() || size == 0 || fmt.is_null() { - return -1; - } - - let max = size - 1; - let mut writer = BufWriter { buf, max, pos: 0 }; - - unsafe { write_c_formatted(fmt, &mut args, &mut writer) }; - - unsafe { - *buf.add(writer.pos) = 0; - } - - writer.pos as i32 -} - -unsafe extern "C" { - fn main(argc: i32, argv: *const *const u8) -> i32; -} - -#[unsafe(no_mangle)] -pub extern "C" fn __stack_chk_fail() -> ! { - exit(127) -} - -#[unsafe(no_mangle)] -pub extern "C" fn __stack_chk_fail_local() -> ! { - __stack_chk_fail() -} - -#[unsafe(no_mangle)] -pub extern "C" fn _start() -> ! { - let code = unsafe { main(0, null()) }; - - exit(code as i32); -} -#[unsafe(no_mangle)] -extern "C" fn atoi(mut c: *const u8) -> i32 { - let mut value: i32 = 0; - let mut sign: i32 = 1; - unsafe { - while (*c).is_ascii_whitespace() { - c = c.add(1); - } - - if (*c) == b'+' || (*c) == b'-' { - if *c == b'-' { - sign = -1; - } - c = c.add(1); - } - while (*c).is_ascii_digit() { - value *= 10; - value += ((*c) - b'0') as i32; - c = c.add(1); - } - } - - value * sign -} - -#[inline] -fn pow10_i32(exp: i32) -> f64 { - let mut e = exp; - let mut scale: f64 = 1.0; - - if e > 0 { - while e > 0 { - scale *= 10.0; - e -= 1; - } - } else if e < 0 { - while e < 0 { - scale *= 0.1; - e += 1; - } - } - - scale -} - -#[unsafe(no_mangle)] -extern "C" fn atof(mut c: *const u8) -> f64 { - let mut sign: f64 = 1.0; - unsafe { - while (*c).is_ascii_whitespace() { - c = c.add(1); - } - - if (*c) == b'+' || (*c) == b'-' { - if *c == b'-' { - sign = -1.0; - } - c = c.add(1); - } - - let mut int_part: i64 = 0; - while (*c).is_ascii_digit() { - int_part = int_part * 10 + ((*c) - b'0') as i64; - c = c.add(1); - } - - let mut result: f64 = int_part as f64; - - if *c == b'.' { - c = c.add(1); - let mut factor = 0.1; - while (*c).is_ascii_digit() { - result += ((*c) - b'0') as f64 * factor; - factor *= 0.1; - c = c.add(1); - } - } - - if *c == b'e' || *c == b'E' { - c = c.add(1); - - let mut exp_sign = 1; - let mut exp_value = 0; - - if (*c) == b'+' || (*c) == b'-' { - if *c == b'-' { - exp_sign = -1; - } - c = c.add(1); - } - - while (*c).is_ascii_digit() { - exp_value *= 10; - exp_value += ((*c) - b'0') as i64; - c = c.add(1); - } - - result *= pow10_i32((exp_sign * exp_value) as i32); - } - - sign * result - } -} - -pub fn compare_str(str_1: *const u8, str_2: *const u8, ignore_case: bool, n: usize) -> i32 { - let mut len = 0; - while len < n { - let mut c_1 = unsafe { *str_1.add(len) }; - let mut c_2 = unsafe { *str_2.add(len) }; - if ignore_case { - c_1 = c_1.to_ascii_lowercase(); - c_2 = c_2.to_ascii_lowercase(); - } - if c_1 != c_2 { - return (c_1 as i32) - (c_2 as i32); - } - if c_1 == 0 { - return 0; - } - len += 1; - } - 0 -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strcasecmp(str_1: *const u8, str_2: *const u8) -> i32 { - compare_str(str_1, str_2, true, usize::MAX) -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strcmp(str_1: *const u8, str_2: *const u8) -> i32 { - compare_str(str_1, str_2, false, usize::MAX) -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strncasecmp(str_1: *const u8, str_2: *const u8, n: usize) -> i32 { - compare_str(str_1, str_2, true, n) -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strncmp(str_1: *const u8, str_2: *const u8, n: usize) -> i32 { - compare_str(str_1, str_2, false, n) -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn draw_pixel(x: u32, y: u32, color: u32) -> i32 { - unsafe { - return syscall3(DRAW_PIXEL, x as isize, y as isize, color as isize) as i32; - } -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn draw_buffer(buffer: *const u32, width: u32, height: u32) -> i32 { - unsafe { - return syscall3( - DRAW_BUFFER, - buffer as isize, - width as isize, - height as isize, - ) as i32; - } -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn framebuffer_swap() -> i32 { - unsafe { - return syscall0(FRAMEBUFFER_SWAP) as i32; - } -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn strncpy(dest: *mut u8, source: *const u8, n: usize) -> *mut u8 { - let mut i = 0usize; - while i < n { - let b = unsafe { *source.add(i) }; - unsafe { *dest.add(i) = b }; - - if b == 0 { - let mut j = i + 1; - while j < n { - unsafe { *dest.add(j) = 0 }; - j += 1; - } - break; - } - i += 1; - } - - dest -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strdup(s: *const u8) -> *mut u8 { - let len = strlen(s); - let memory = malloc((len + 1) as u64); - if memory.is_null() { - return null_mut(); - } - unsafe { memcpy(memory, s, len + 1) }; - memory -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strstr(haystack: *const u8, needle: *const u8) -> *const u8 { - if haystack.is_null() || needle.is_null() { - return null(); - } - - let mut h = haystack; - - unsafe { - if *needle == 0 { - return haystack; - } - - while *h != 0 { - if *h == *needle { - let mut h2 = h; - let mut n2 = needle; - - while *n2 != 0 && *h2 != 0 && *h2 == *n2 { - h2 = h2.add(1); - n2 = n2.add(1); - } - - if *n2 == 0 { - return h; - } - } - - h = h.add(1); - } - } - - null() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strchr(s: *const u8, ch: i32) -> *const u8 { - if s.is_null() { - return null(); - } - - let mut i = 0usize; - - unsafe { - while *s.add(i) != 0 { - if *s.add(i) == ch as u8 { - return s.add(i); - } - - i += 1; - } - } - - null() -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn strrchr(s: *const u8, ch: u8) -> *const u8 { - let mut n = 0; - let mut last: *const u8 = null(); - - if ch == 0 { - while unsafe { *s.add(n) } != 0 { - n += 1; - } - return unsafe { s.add(n + 1) }; - } else { - while unsafe { *s.add(n) } != 0 { - let cur_ch = unsafe { s.add(n) }; - if unsafe { *cur_ch == ch } { - last = cur_ch; - } - n += 1; - } - - last - } -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn toupper(char: i32) -> i32 { - (char as u8).to_ascii_uppercase() as i32 -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn tolower(char: i32) -> i32 { - (char as u8).to_ascii_lowercase() as i32 -} - -#[unsafe(no_mangle)] -extern "C" fn system(cmd: *const u8) -> i32 { - 0 -} -#[unsafe(no_mangle)] -extern "C" fn __ctype_toupper_loc() -> *const u8 { - TOUPPER_TABLE.as_ptr() as *const u8 -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn __isoc23_sscanf() -> ! { - panic!("sscanf not implemented"); -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn sscanf(str: *mut u8, fmt: *const u8, args: ...) -> i32 { - 0 -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn __errno_location() -> *mut core::ffi::c_int { - addr_of_mut!(ERRNO) -} - -#[panic_handler] -fn panic(error: &core::panic::PanicInfo) -> ! { - exit(-1) -} diff --git a/user/libxunil/src/mem.rs b/user/libxunil/src/mem.rs deleted file mode 100644 index 9b4f3f0..0000000 --- a/user/libxunil/src/mem.rs +++ /dev/null @@ -1,258 +0,0 @@ -use core::{ffi::c_int, mem, ptr::null_mut, usize}; - -use crate::{ - heap::{ALLOCATOR, LinkedNode}, - syscall::{BRK, syscall1}, - util::align_up, -}; - -pub fn sbrk(increment: i64) -> isize { - unsafe { syscall1(BRK, increment as isize) as isize } -} - -const MAX_SIZE: u64 = 18446744073709551615; - -const HEADER_MAGIC_ALLOC: u64 = 0xBADC0FFEE0DDF00D; -const HEADER_MAGIC_FREE: u64 = 0xFEE1DEADCAFEBABE; - -#[repr(C, align(16))] -struct Header { - magic: u64, - _pad: u64, - alloc_size: usize, - region_size: usize, -} - -#[unsafe(no_mangle)] -pub extern "C" fn calloc(count: u64, size: u64) -> *mut u8 { - if count != 0 && size > MAX_SIZE / count { - return null_mut(); - } - - let mut total = count * size; - if total == 0 { - total = 1; - } - - let ptr = malloc(total); - if ptr.is_null() { - return null_mut(); - } - - unsafe { memset(ptr, 0, total as usize) }; - ptr -} - -#[unsafe(no_mangle)] -pub extern "C" fn free(ptr: *mut u8) { - if ptr.is_null() { - return; - } - - unsafe { - let header_ptr = (ptr as usize - mem::size_of::
()) as *mut Header; - if (header_ptr as usize) & 0xF != 0 { - core::hint::unreachable_unchecked(); - } - - if (*header_ptr).magic != HEADER_MAGIC_ALLOC { - return; - } - - let region_size = (*header_ptr).region_size; - (*header_ptr).magic = HEADER_MAGIC_FREE; - let mut allocator = ALLOCATOR.lock(); - allocator.add_free_memory_region(header_ptr as usize, region_size); - } -} - -#[unsafe(no_mangle)] -pub extern "C" fn malloc(size: u64) -> *mut u8 { - let req = size as usize; - let req = if req == 0 { 1 } else { req }; - - let hdr = mem::size_of::
(); - let needed_unaligned = match hdr.checked_add(req) { - Some(v) => v, - None => return null_mut(), - }; - let align_req = 16; - let needed = align_up(needed_unaligned, align_req); - - let mut allocator = ALLOCATOR.lock(); - - if let Some(region) = allocator.find_region(needed) { - unsafe { - let header_ptr = region.start as *mut Header; - header_ptr.write(Header { - magic: HEADER_MAGIC_ALLOC, - _pad: 0, - alloc_size: (region.end - region.start).saturating_sub(hdr), - region_size: region.end - region.start, - }); - return (region.start + hdr) as *mut u8; - } - } - - let min_region = mem::size_of::(); - let req_region = core::cmp::max(needed, min_region); - - let align = align_req; - let over = match req_region.checked_add(align) { - Some(v) => v, - None => return null_mut(), - }; - if over > i64::MAX as usize { - return null_mut(); - } - - let raw_start = sbrk(over as i64); - if raw_start == -1 { - return null_mut(); - } - - let raw_start = raw_start as usize; - let aligned_start = align_up(raw_start, align); - let usable = over - (aligned_start - raw_start); - - if usable < min_region { - return null_mut(); - } - - unsafe { - allocator.add_free_memory_region(aligned_start, usable); - } - - drop(allocator); - malloc(size) -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn realloc(ptr: *mut u8, size: usize) -> *mut u8 { - if size == 0 { - free(ptr); - return null_mut(); - } - - if ptr.is_null() { - return malloc(size as u64); - } - - unsafe { - let hdr = mem::size_of::
(); - let header_ptr = (ptr as usize - hdr) as *mut Header; - - if (*header_ptr).magic != HEADER_MAGIC_ALLOC { - return null_mut(); - } - - let old_alloc_size = (*header_ptr).alloc_size; - - if size <= old_alloc_size { - return ptr; - } - - let new_ptr = malloc(size as u64); - if new_ptr.is_null() { - return null_mut(); - } - - core::ptr::copy_nonoverlapping(ptr, new_ptr, old_alloc_size); - free(ptr); - new_ptr - } -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn memset(dest: *mut u8, c: c_int, n: usize) -> *mut u8 { - if n == 0 { - return dest; - } - if dest.is_null() { - return null_mut(); - } - - let byte = c as u8; - let mut i = 0usize; - while i < n { - unsafe { core::ptr::write_volatile(dest.add(i), byte) }; - i += 1; - } - - dest -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { - if n == 0 { - return dest; - } - if dest.is_null() || src.is_null() { - return null_mut(); - } - - let mut i = 0usize; - while i < n { - let v = unsafe { core::ptr::read_volatile(src.add(i)) }; - unsafe { core::ptr::write_volatile(dest.add(i), v) }; - i += 1; - } - - dest -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { - if n == 0 { - return dest; - } - if dest.is_null() || src.is_null() { - return null_mut(); - } - - let dest_addr = dest as usize; - let src_addr = src as usize; - - if dest_addr == src_addr { - return dest; - } - - if dest_addr < src_addr || dest_addr >= src_addr.saturating_add(n) { - let mut i = 0usize; - while i < n { - let v = unsafe { core::ptr::read_volatile(src.add(i)) }; - unsafe { core::ptr::write_volatile(dest.add(i), v) }; - i += 1; - } - } else { - let mut i = n; - while i != 0 { - i -= 1; - let v = unsafe { core::ptr::read_volatile(src.add(i)) }; - unsafe { core::ptr::write_volatile(dest.add(i), v) }; - } - } - - dest -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn memcmp(a: *const u8, b: *const u8, n: usize) -> i32 { - if n == 0 { - return 0; - } - if a.is_null() || b.is_null() { - return 0; - } - - let mut i = 0usize; - while i < n { - let av = unsafe { core::ptr::read_volatile(a.add(i)) }; - let bv = unsafe { core::ptr::read_volatile(b.add(i)) }; - if av != bv { - return av as i32 - bv as i32; - } - i += 1; - } - 0 -} diff --git a/user/libxunil/src/syscall.rs b/user/libxunil/src/syscall.rs deleted file mode 100644 index 8391b14..0000000 --- a/user/libxunil/src/syscall.rs +++ /dev/null @@ -1,77 +0,0 @@ -pub const READ: usize = 0; -pub const WRITE: usize = 1; -pub const OPEN: usize = 2; -pub const CLOSE: usize = 3; -pub const STAT: usize = 4; -pub const LSEEK: usize = 8; -pub const MMAP: usize = 9; -pub const MUNMAP: usize = 9; -pub const BRK: usize = 12; -pub const GETPID: usize = 39; -pub const FORK: usize = 57; -pub const EXECVE: usize = 59; -pub const EXIT: usize = 60; -pub const WAIT4: usize = 61; -pub const KILL: usize = 62; -pub const CHDIR: usize = 80; -pub const MKDIR: usize = 83; -pub const UNLINK: usize = 87; -pub const GETDENTS64: usize = 217; -pub const CLOCK_GETTIME: usize = 228; -pub const EXIT_GROUP: usize = 231; -pub const SLEEP: usize = 909090; // zzz haha -pub const DRAW_PIXEL: usize = 5555; -pub const DRAW_BUFFER: usize = 7777; -pub const FRAMEBUFFER_SWAP: usize = 6666; - -#[inline(always)] -pub unsafe fn syscall0(num: usize) -> isize { - let ret: isize; - unsafe { - core::arch::asm!( - "int 0x80", - in("rax") num, - lateout("rax") ret, - clobber_abi("sysv64"), - options(nostack) - ); - } - - ret -} - -#[inline(always)] -pub unsafe fn syscall1(num: usize, arg0: isize) -> isize { - let ret: isize; - unsafe { - core::arch::asm!( - "int 0x80", - in("rax") num, - in("rdi") arg0, - lateout("rax") ret, - clobber_abi("sysv64"), - options(nostack) - ); - } - - ret -} - -#[inline(always)] -pub unsafe fn syscall3(num: usize, arg0: isize, arg1: isize, arg2: isize) -> isize { - let ret: isize; - unsafe { - core::arch::asm!( - "int 0x80", - in("rax") num, - in("rdi") arg0, - in("rsi") arg1, - in("rdx") arg2, - lateout("rax") ret, - clobber_abi("sysv64"), - options(nostack) - ); - } - - ret -} diff --git a/user/libxunil/src/time.rs b/user/libxunil/src/time.rs deleted file mode 100644 index 48d36c4..0000000 --- a/user/libxunil/src/time.rs +++ /dev/null @@ -1,38 +0,0 @@ -use crate::syscall::{CLOCK_GETTIME, SLEEP, syscall0, syscall1}; - -#[repr(C)] -pub struct Timeval { - pub tv_sec: i64, - pub tv_usec: i64, -} - -#[repr(C)] -pub struct Timezone { - pub tz_minuteswest: i32, - pub tz_dsttime: i32, -} - -pub const TICKS_PER_SECOND: u64 = 1000; - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn sleep_ms(ms: i32) -> i32 { - unsafe { syscall1(SLEEP, ms as isize) }; - 0 -} - -#[unsafe(no_mangle)] -pub unsafe extern "C" fn gettimeofday(tv: *mut Timeval, _tz: *mut Timezone) -> i32 { - unsafe { - if !tv.is_null() { - let ticks = syscall0(CLOCK_GETTIME) as u64; - - let seconds = ticks / TICKS_PER_SECOND; - let microseconds = (ticks % TICKS_PER_SECOND) * (1_000_000 / TICKS_PER_SECOND); - - (*tv).tv_sec = seconds as i64; - (*tv).tv_usec = microseconds as i64; - } - } - - 0 -} diff --git a/user/libxunil/src/util.rs b/user/libxunil/src/util.rs deleted file mode 100644 index dc50b4d..0000000 --- a/user/libxunil/src/util.rs +++ /dev/null @@ -1,20 +0,0 @@ -#[inline] -pub const fn align_down(addr: usize, align: usize) -> usize { - assert!(align.is_power_of_two(), "`align` must be a power of two"); - addr & !(align - 1) -} - -#[inline] -pub const fn align_up(addr: usize, align: usize) -> usize { - assert!(align.is_power_of_two(), "`align` must be a power of two"); - let align_mask = align - 1; - if addr & align_mask == 0 { - addr - } else { - if let Some(aligned) = (addr | align_mask).checked_add(1) { - aligned - } else { - panic!("attempt to add with overflow") - } - } -} diff --git a/user/libxunil/to_implement.txt b/user/libxunil/to_implement.txt deleted file mode 100644 index 8e8d306..0000000 --- a/user/libxunil/to_implement.txt +++ /dev/null @@ -1,45 +0,0 @@ -abs -atof -atoi -calloc -__ctype_toupper_loc -__errno_location -exit -fclose -fflush -fopen -fprintf -fread -free -fseek -ftell -fwrite -__isoc23_sscanf -malloc -memcpy -memset -mkdir -printf -putchar -puts -realloc -remove -rename -snprintf -__stack_chk_fail -stderr -stdout -strcasecmp -strchr -strcmp -strdup -strlen -strncasecmp -strncmp -strncpy -strrchr -strstr -system -toupper -vfprintf // this -vsnprintf // also this