Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Fix pointer casting tomfoolery preventing boot on release kernel
Browse files Browse the repository at this point in the history
  • Loading branch information
byteduck committed Dec 3, 2023
1 parent 3dd4bed commit ff7fc65
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 88 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,6 @@ toolchain/build
toolchain/sysroot
toolchain/edit

user/
user/
compile_commands.json
.cache/
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.0.0)
PROJECT(duckOS C CXX ASM)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

set(CMAKE_SYSROOT ${CMAKE_BINARY_DIR}/root)
set(CMAKE_STAGING_PREFIX ${CMAKE_BINARY_DIR}/root)
Expand Down Expand Up @@ -87,4 +88,4 @@ ADD_CUSTOM_TARGET(qemu
ADD_CUSTOM_TARGET(tests
COMMAND ${CMAKE_SOURCE_DIR}/scripts/qemu.sh kernel-tests=true
USES_TERMINAL
)
)
10 changes: 9 additions & 1 deletion kernel/kstd/cstring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,15 @@ extern "C" void *memcpy(void *dest, const void *src, size_t count){
}

extern "C" void* memmove(void* dest, const void* src, size_t n) {
return __builtin_memmove(dest, src, n);
if (dest < src)
return memcpy(dest, src, n);

uint8_t* dest8 = (uint8_t*) dest;
const uint8_t* src8 = (const uint8_t*) src;
for (dest8 += n, src8 += n; n--;)
*--dest8 = *--src8;

return dest;
}

void* memcpy_uint32(uint32_t* d, uint32_t* s, size_t n) {
Expand Down
56 changes: 9 additions & 47 deletions kernel/memory/Stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,64 +24,31 @@
class Stack {
public:
Stack(void* stackptr, size_t real_stackptr):
_stackptr(stackptr),
_stackptr8(reinterpret_cast<uint8_t*&>(_stackptr)),
_stackptr16(reinterpret_cast<uint16_t*&>(_stackptr)),
_stackptr32(reinterpret_cast<uint32_t*&>(_stackptr)),
_stackptrsizet(reinterpret_cast<size_t*&>(_stackptr)),
_stackptrint(reinterpret_cast<int*&>(_stackptr)),

This comment has been minimized.

Copy link
@sylv256

sylv256 Jan 4, 2024

this whole commit is hilarious

_stackptr((size_t) stackptr),
_real_stackptr(real_stackptr) {}

Stack(void* stackptr): Stack(stackptr, (size_t) stackptr) {}

Stack(const Stack& other):
_stackptr(other._stackptr),
_stackptr8(reinterpret_cast<uint8_t*&>(_stackptr)),
_stackptr16(reinterpret_cast<uint16_t*&>(_stackptr)),
_stackptr32(reinterpret_cast<uint32_t*&>(_stackptr)),
_stackptrsizet(reinterpret_cast<size_t*&>(_stackptr)),
_stackptrint(reinterpret_cast<int*&>(_stackptr)),
_real_stackptr(other._real_stackptr) {}

inline Stack& operator=(const Stack& other) noexcept {
_stackptr = other._stackptr;
_stackptr8 = reinterpret_cast<uint8_t*&>(_stackptr);
_stackptr16 = reinterpret_cast<uint16_t*&>(_stackptr);
_stackptr32 = reinterpret_cast<uint32_t*&>(_stackptr);
_stackptrsizet = reinterpret_cast<size_t*&>(_stackptr);
_stackptrint = reinterpret_cast<int*&>(_stackptr);
_real_stackptr = other._real_stackptr;
return *this;
}

inline void push8(uint8_t val) {
*--_stackptr8 = val;
_real_stackptr -= sizeof(uint8_t);
}

inline void push16(uint16_t val) {
*--_stackptr16 = val;
_real_stackptr -= sizeof(uint16_t);
}

inline void push32(uint32_t val) {
*--_stackptr32 = val;
_real_stackptr -= sizeof(uint32_t);
}

inline void push_sizet(size_t val) {
*--_stackptrsizet = val;
_real_stackptr -= sizeof(size_t);
}

inline void push_int(int val) {
*--_stackptrint = val;
_real_stackptr -= sizeof(int);
template<typename T>
inline void push(T val) {
_stackptr -= sizeof(val);
_real_stackptr -= sizeof(T);
*((T*) _stackptr) = val;
}

inline void push_string(const char* str) {
size_t len = strlen(str) + 1;
_stackptr8 -= len;
_stackptr -= len;
_real_stackptr -= sizeof(char) * len;
strcpy((char*)_stackptr, str);
}
Expand All @@ -91,16 +58,11 @@ class Stack {
}

inline void* stackptr() const {
return _stackptr;
return (void*) _stackptr;
}

private:
size_t _real_stackptr;
void* _stackptr;
uint8_t*& _stackptr8;
uint16_t*& _stackptr16;
uint32_t*& _stackptr32;
size_t*& _stackptrsizet;
int*& _stackptrint;
size_t _stackptr;
};

16 changes: 8 additions & 8 deletions kernel/tasking/ProcessArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,20 @@ void ProcessArgs::setup_stack(Stack& stack) {
}

//Copy pointers to all args into stack
stack.push32(0);
stack.push<uint32_t>(0);
for(auto i = argv.size(); i > 0; i--)
stack.push32(argp[i - 1]);
stack.push<uint32_t>(argp[i - 1]);
size_t argvp = stack.real_stackptr();

//Copy pointers to all env into stack
stack.push32(0);
stack.push<uint32_t>(0);
for(auto i = env.size(); i > 0; i--)
stack.push32(envp[i - 1]);
stack.push<uint32_t>(envp[i - 1]);
size_t envpp = stack.real_stackptr();

//Push argc, argv, and env on to stack
stack.push_sizet(envpp); //env
stack.push_sizet(argvp); //argv
stack.push_int(argv.size()); //argc
stack.push32(0);
stack.push<size_t>(envpp); //env
stack.push<size_t>(argvp); //argv
stack.push<int>(argv.size()); //argc
stack.push<uint32_t>(0);
}
60 changes: 30 additions & 30 deletions kernel/tasking/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ Thread::Thread(Process* process, tid_t tid, void* (*entry_func)(void* (*)(void*)
}

//Set up the user stack for the thread arguments
user_stack.push_sizet((size_t) arg);
user_stack.push_sizet((size_t) thread_func);
user_stack.push_sizet(0);
user_stack.push<size_t>((size_t) arg);
user_stack.push<size_t>((size_t) thread_func);
user_stack.push<size_t>(0);

//Setup the kernel stack with register states
if(is_kernel_mode())
Expand Down Expand Up @@ -435,8 +435,8 @@ bool Thread::call_signal_handler(int signal) {
_signal_stack_top = _sighandler_kstack_region->end();

//Push signal number and fake return address to the stack
user_stack.push_int(signal);
user_stack.push_sizet(SIGNAL_RETURN_FAKE_ADDR);
user_stack.push<int>(signal);
user_stack.push<size_t>(SIGNAL_RETURN_FAKE_ADDR);

//Setup signal registers
signal_registers.eflags = 0x202;
Expand Down Expand Up @@ -539,35 +539,35 @@ Thread* Thread::next_thread() {

void Thread::setup_kernel_stack(Stack& kernel_stack, size_t user_stack_ptr, Registers& regs) {
//If usermode, push ss and useresp
if(!is_kernel_mode()) {
kernel_stack.push32(0x23);
kernel_stack.push_sizet(user_stack_ptr);
if(__builtin_expect(!is_kernel_mode(), true)) {
kernel_stack.push<uint32_t>(0x23);
kernel_stack.push(user_stack_ptr);
}

//Push EFLAGS, CS, and EIP for iret
kernel_stack.push32(regs.eflags); // eflags
kernel_stack.push32(regs.cs); // cs
kernel_stack.push32(regs.eip); // eip

kernel_stack.push32(regs.eax);
kernel_stack.push32(regs.ebx);
kernel_stack.push32(regs.ecx);
kernel_stack.push32(regs.edx);
kernel_stack.push32(regs.ebp);
kernel_stack.push32(regs.edi);
kernel_stack.push32(regs.esi);
kernel_stack.push32(regs.ds);
kernel_stack.push32(regs.es);
kernel_stack.push32(regs.fs);
kernel_stack.push32(regs.gs);
kernel_stack.push<uint32_t>(regs.eflags); // eflags
kernel_stack.push<uint32_t>(regs.cs); // cs
kernel_stack.push<uint32_t>(regs.eip); // eip

kernel_stack.push<uint32_t>(regs.eax);
kernel_stack.push<uint32_t>(regs.ebx);
kernel_stack.push<uint32_t>(regs.ecx);
kernel_stack.push<uint32_t>(regs.edx);
kernel_stack.push<uint32_t>(regs.ebp);
kernel_stack.push<uint32_t>(regs.edi);
kernel_stack.push<uint32_t>(regs.esi);
kernel_stack.push<uint32_t>(regs.ds);
kernel_stack.push<uint32_t>(regs.es);
kernel_stack.push<uint32_t>(regs.fs);
kernel_stack.push<uint32_t>(regs.gs);

if(_process->pid() != 0 || _tid != 0) {
kernel_stack.push_sizet((size_t) TaskManager::proc_first_preempt);
kernel_stack.push32(0x2u); /* Kernel eflags: We don't want interrupts enabled */
kernel_stack.push32(regs.ebx); /* Kernel ebx */
kernel_stack.push32(regs.esi); /* Kernel esi */
kernel_stack.push32(regs.edi); /* Kernel edi */
kernel_stack.push32(0); //Fake popped EBP
kernel_stack.push<size_t>((size_t) TaskManager::proc_first_preempt);
kernel_stack.push<uint32_t>(0x2u); /* Kernel eflags: We don't want interrupts enabled */
kernel_stack.push<uint32_t>(regs.ebx); /* Kernel ebx */
kernel_stack.push<uint32_t>(regs.esi); /* Kernel esi */
kernel_stack.push<uint32_t>(regs.edi); /* Kernel edi */
kernel_stack.push<uint32_t>(0); //Fake popped EBP
}

regs.esp = (size_t) kernel_stack.stackptr();
Expand Down Expand Up @@ -698,4 +698,4 @@ void Thread::die_from_signal(int signal) {
// If the signal has no handler and is KILL or FATAL, then kill all threads
// Get the current thread as a raw pointer, so that if the current thread is part of this process the reference doesn't stay around
_process->die();
}
}

0 comments on commit ff7fc65

Please sign in to comment.