#include "utils.h"
#include <stddef.h>
+#include <stdint.h>
static inline void cpuid(uint32_t leaf, uint32_t* eax, uint32_t* ebx,
uint32_t* ecx, uint32_t* edx) {
cpuid(0, &eax, &ebx, &ecx, &edx);
out->max_leaf = eax;
- /* Vendor: EBX-EDX-ECX */
- *(uint32_t*)&out->vendor[0] = ebx;
- *(uint32_t*)&out->vendor[4] = edx;
- *(uint32_t*)&out->vendor[8] = ecx;
+ /* Vendor: EBX-EDX-ECX (use memcpy to avoid strict-aliasing UB) */
+ memcpy(&out->vendor[0], &ebx, 4);
+ memcpy(&out->vendor[4], &edx, 4);
+ memcpy(&out->vendor[8], &ecx, 4);
out->vendor[12] = '\0';
if (out->max_leaf < 1) return;
uart_print("\n");
uart_print("[CPUID] APIC ID: ");
- char tmp[4];
+ char tmp[12];
itoa(f->initial_apic_id, tmp, 10);
uart_print(tmp);
uart_print(", Logical CPUs: ");
* User stack: [return_eip, saved_edx(arg3), saved_ecx(arg2)]
*/
+ /* Ensure direction flag is clear — userspace may have set DF=1 */
+ cld
+
/* Build iret-style frame: ss, useresp, eflags, cs, eip */
push $0x23 /* ss = user data segment (GDT entry 4 | RPL 3) */
push %ecx /* useresp = user ESP */
int vsnprintf(char* buf, size_t size, const char* fmt, va_list ap) {
size_t pos = 0;
-#define PUTC(c) do { if (pos < size - 1) buf[pos] = (c); pos++; } while(0)
+#define PUTC(c) do { if (pos + 1 < size) buf[pos] = (c); pos++; } while(0)
if (size == 0) {
- /* Just count characters */
- while (*fmt) { pos++; fmt++; }
- return (int)pos;
+ /* Cannot write anything; return 0 */
+ return 0;
}
while (*fmt) {
void* new_end = (void*)((char*)heap_end + size);
void* result = brk(new_end);
- if ((unsigned int)result < (unsigned int)new_end) {
+ if ((uintptr_t)result < (uintptr_t)new_end) {
return (void*)0; /* OOM */
}
void _exit(int status) {
_syscall1(SYS_EXIT, status);
- for (;;) __asm__ volatile("hlt");
+ /* If exit syscall somehow returns, loop forever.
+ * Cannot use hlt — it's privileged and causes #GP in ring 3. */
+ for (;;) __asm__ volatile("nop");
}