/* ------------------------------------------- Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. ------------------------------------------- */ #include #include #include #include using namespace LibSystem; IMPORT_C Char* StrFmt(const Char* fmt, ...) { if (!fmt || *fmt == 0) return const_cast("(null)"); return const_cast(""); } // memmove-style copy IMPORT_C VoidPtr MmCopyMemory(_Input VoidPtr dest, _Input VoidPtr src, _Input SizeT len) { // handles overlap, prefers 64-bit word copies when aligned if (!len || !dest || !src) return nullptr; auto s = static_cast(src); auto d = static_cast(dest); if (d == s) return dest; // decide direction if (d > s && d < s + len) { const UInt8* rs = s + len; UInt8* rd = d + len; // try 64-bit aligned backward copy if (len >= sizeof(UInt64) && (reinterpret_cast(rs) % sizeof(UInt64) == 0) && (reinterpret_cast(rd) % sizeof(UInt64) == 0)) { auto rsw = reinterpret_cast(rs); auto rdw = reinterpret_cast(rd); SizeT words = len / sizeof(UInt64); for (SizeT i = 0; i < words; ++i) { rdw[-1 - static_cast(i)] = rsw[-1 - static_cast(i)]; } SizeT rem = len % sizeof(UInt64); for (SizeT i = 0; i < rem; ++i) { rd[-1 - i] = rs[-1 - i]; } } else { // byte-wise backward for (SizeT i = 0; i < len; ++i) { rd[-1 - i] = rs[-1 - i]; } } } else { // try 64-bit aligned forward copy if (len >= sizeof(UInt64) && (reinterpret_cast(s) % sizeof(UInt64) == 0) && (reinterpret_cast(d) % sizeof(UInt64) == 0)) { auto sw = reinterpret_cast(s); auto dw = reinterpret_cast(d); SizeT words = len / sizeof(UInt64); for (SizeT i = 0; i < words; ++i) { dw[i] = sw[i]; } SizeT rem = len % sizeof(UInt64); const SizeT offset = words * sizeof(UInt64); for (SizeT i = 0; i < rem; ++i) { d[offset + i] = s[offset + i]; } } else { for (SizeT i = 0; i < len; ++i) { d[i] = s[i]; } } } return dest; } IMPORT_C SInt64 MmStrLen(const Char* in) { // strlen via pointer walk if (!in) return -kErrorInvalidData; const Char* p = in; while (*p) ++p; return static_cast(p - in); } IMPORT_C VoidPtr MmFillMemory(_Input VoidPtr dest, _Input SizeT len, _Input UInt8 value) { if (!len || !dest) return nullptr; auto d = static_cast(dest); if (len >= sizeof(UInt64) && (reinterpret_cast(d) % sizeof(UInt64)) == 0) { UInt64 pattern = static_cast(value); pattern |= (pattern << 8); pattern |= (pattern << 16); pattern |= (pattern << 32); auto dw = reinterpret_cast(d); SizeT words = len / sizeof(UInt64); for (SizeT i = 0; i < words; ++i) { dw[i] = pattern; } SizeT rem = len % sizeof(UInt64); const SizeT offset = words * sizeof(UInt64); for (SizeT i = 0; i < rem; ++i) { d[offset + i] = value; } } else { for (SizeT i = 0; i < len; ++i) d[i] = value; } return dest; } IMPORT_C Ref IoOpenFile(_Input const Char* path, _Input const Char* drv_letter) { return static_cast(libsys_syscall_arg_3( SYSCALL_HASH("IoOpenFile"), Verify::sys_safe_cast(path), Verify::sys_safe_cast(drv_letter))); } IMPORT_C Void IoCloseFile(_Input Ref desc) { libsys_syscall_arg_2(SYSCALL_HASH("IoCloseFile"), static_cast(desc)); } IMPORT_C UInt64 IoSeekFile(_Input Ref desc, _Input UInt64 off) { auto ret_ptr = libsys_syscall_arg_3(SYSCALL_HASH("IoSeekFile"), static_cast(desc), reinterpret_cast(&off)); if (!ret_ptr) return ~0UL; auto ret = static_cast(ret_ptr); UInt64 result = *ret; MUST_PASS(result != ~0UL); return result; } IMPORT_C UInt64 IoTellFile(_Input Ref desc) { auto ret_ptr = libsys_syscall_arg_2(SYSCALL_HASH("IoTellFile"), static_cast(desc)); if (!ret_ptr) return ~0UL; auto ret = static_cast(ret_ptr); return *ret; } IMPORT_C SInt32 PrintOut(_Input IORef desc, const Char* fmt, ...) { va_list args; va_start(args, fmt); auto buf = StrFmt(fmt, args); va_end(args); // if truncated, `needed` >= kBufferSz; we still send truncated buffer auto ret_ptr = libsys_syscall_arg_3(SYSCALL_HASH("PrintOut"), static_cast(desc), Verify::sys_safe_cast(buf)); if (!ret_ptr) return -kErrorInvalidData; auto ret = static_cast(ret_ptr); return *ret; }