mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-30 08:17:58 +00:00
Refactor stack handling in thread.cpp
This commit is contained in:
parent
afd9227f31
commit
3cf4fda68a
@ -184,71 +184,71 @@ namespace Tasking
|
|||||||
const char **envp,
|
const char **envp,
|
||||||
const std::vector<AuxiliaryVector> &auxv)
|
const std::vector<AuxiliaryVector> &auxv)
|
||||||
{
|
{
|
||||||
size_t ArgvSize = 0;
|
size_t argvLen = 0;
|
||||||
if (argv)
|
if (argv)
|
||||||
while (argv[ArgvSize] != nullptr)
|
while (argv[argvLen] != nullptr)
|
||||||
ArgvSize++;
|
argvLen++;
|
||||||
|
|
||||||
size_t EnvpSize = 0;
|
size_t envpLen = 0;
|
||||||
if (envp)
|
if (envp)
|
||||||
while (envp[EnvpSize] != nullptr)
|
while (envp[envpLen] != nullptr)
|
||||||
EnvpSize++;
|
envpLen++;
|
||||||
|
|
||||||
debug("ArgvSize: %d", ArgvSize);
|
debug("argvLen: %d", argvLen);
|
||||||
debug("EnvpSize: %d", EnvpSize);
|
debug("envpLen: %d", envpLen);
|
||||||
|
|
||||||
/* https://articles.manugarg.com/aboutelfauxiliaryvectors.html */
|
/* https://articles.manugarg.com/aboutelfauxiliaryvectors.html */
|
||||||
/* https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf#figure.3.9 */
|
/* https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf#figure.3.9 */
|
||||||
/* rsp is the top of the stack */
|
/* rsp is the top of the stack */
|
||||||
char *Stack = (char *)this->Stack->GetStackPhysicalTop();
|
char *pStack = (char *)this->Stack->GetStackPhysicalTop();
|
||||||
/* Temporary stack pointer for strings */
|
/* Temporary stack pointer for strings */
|
||||||
char *StackStrings = (char *)Stack;
|
char *stackStr = (char *)pStack;
|
||||||
char *StackStringsVirtual = (char *)this->Stack->GetStackTop();
|
char *stackStrVirtual = (char *)this->Stack->GetStackTop();
|
||||||
|
|
||||||
/* Store string pointers for later */
|
/* Store string pointers for later */
|
||||||
uintptr_t *ArgvStrings = nullptr;
|
uintptr_t *argvStrings = nullptr;
|
||||||
uintptr_t *EnvpStrings = nullptr;
|
uintptr_t *envpStrings = nullptr;
|
||||||
if (ArgvSize > 0)
|
if (argvLen > 0)
|
||||||
ArgvStrings = new uintptr_t[ArgvSize];
|
argvStrings = new uintptr_t[argvLen];
|
||||||
if (EnvpSize > 0)
|
if (envpLen > 0)
|
||||||
EnvpStrings = new uintptr_t[EnvpSize];
|
envpStrings = new uintptr_t[envpLen];
|
||||||
|
|
||||||
for (size_t i = 0; i < ArgvSize; i++)
|
for (size_t i = 0; i < argvLen; i++)
|
||||||
{
|
{
|
||||||
/* Subtract the length of the string and the null terminator */
|
/* Subtract the length of the string and the null terminator */
|
||||||
StackStrings -= strlen(argv[i]) + 1;
|
stackStr -= strlen(argv[i]) + 1;
|
||||||
StackStringsVirtual -= strlen(argv[i]) + 1;
|
stackStrVirtual -= strlen(argv[i]) + 1;
|
||||||
/* Store the pointer to the string */
|
/* Store the pointer to the string */
|
||||||
ArgvStrings[i] = (uintptr_t)StackStringsVirtual;
|
argvStrings[i] = (uintptr_t)stackStrVirtual;
|
||||||
/* Copy the string to the stack */
|
/* Copy the string to the stack */
|
||||||
strcpy(StackStrings, argv[i]);
|
strcpy(stackStr, argv[i]);
|
||||||
debug("argv[%d]: %s", i, argv[i]);
|
debug("argv[%d]: %s", i, argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < EnvpSize; i++)
|
for (size_t i = 0; i < envpLen; i++)
|
||||||
{
|
{
|
||||||
/* Subtract the length of the string and the null terminator */
|
/* Subtract the length of the string and the null terminator */
|
||||||
StackStrings -= strlen(envp[i]) + 1;
|
stackStr -= strlen(envp[i]) + 1;
|
||||||
StackStringsVirtual -= strlen(envp[i]) + 1;
|
stackStrVirtual -= strlen(envp[i]) + 1;
|
||||||
/* Store the pointer to the string */
|
/* Store the pointer to the string */
|
||||||
EnvpStrings[i] = (uintptr_t)StackStringsVirtual;
|
envpStrings[i] = (uintptr_t)stackStrVirtual;
|
||||||
/* Copy the string to the stack */
|
/* Copy the string to the stack */
|
||||||
strcpy(StackStrings, envp[i]);
|
strcpy(stackStr, envp[i]);
|
||||||
debug("envp[%d]: %s", i, envp[i]);
|
debug("envp[%d]: %s", i, envp[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Align the stack to 16 bytes */
|
/* Align the stack to 16 bytes */
|
||||||
StackStrings -= (uintptr_t)StackStrings & 0xF;
|
stackStr -= (uintptr_t)stackStr & 0xF;
|
||||||
/* Set "Stack" to the new stack pointer */
|
/* Set "pStack" to the new stack pointer */
|
||||||
Stack = (char *)StackStrings;
|
pStack = (char *)stackStr;
|
||||||
/* If argv and envp sizes are odd then we need to align the stack */
|
/* If argv and envp sizes are odd then we need to align the stack */
|
||||||
Stack -= (ArgvSize + EnvpSize) % 2;
|
pStack -= (argvLen + envpLen) % 2;
|
||||||
debug("odd align: %#lx | %#lx -> %#lx",
|
debug("odd align: %#lx | %#lx -> %#lx",
|
||||||
(ArgvSize + EnvpSize) % 2,
|
(argvLen + envpLen) % 2,
|
||||||
StackStrings, Stack);
|
stackStr, pStack);
|
||||||
|
|
||||||
/* We need 8 bit pointers for the stack from here */
|
/* We need 8 bit pointers for the stack from here */
|
||||||
uintptr_t *Stack64 = (uintptr_t *)Stack;
|
uintptr_t *Stack64 = (uintptr_t *)pStack;
|
||||||
assert(Stack64 != nullptr);
|
assert(Stack64 != nullptr);
|
||||||
|
|
||||||
/* Store the null terminator */
|
/* Store the null terminator */
|
||||||
@ -273,45 +273,47 @@ namespace Tasking
|
|||||||
/* Store the null terminator */
|
/* Store the null terminator */
|
||||||
StackPush(Stack64, uintptr_t, AT_NULL);
|
StackPush(Stack64, uintptr_t, AT_NULL);
|
||||||
|
|
||||||
/* Store EnvpStrings[] to the stack */
|
/* Store envpStrings[] to the stack */
|
||||||
Stack64 -= EnvpSize; /* (1 Stack64 = 8 bits; Stack64 = 8 * EnvpSize) */
|
Stack64 -= envpLen; /* (1 Stack64 = 8 bits; Stack64 = 8 * envpLen) */
|
||||||
for (size_t i = 0; i < EnvpSize; i++)
|
for (size_t i = 0; i < envpLen; i++)
|
||||||
{
|
{
|
||||||
*(Stack64 + i) = (uintptr_t)EnvpStrings[i];
|
*(Stack64 + i) = (uintptr_t)envpStrings[i];
|
||||||
debug("EnvpStrings[%d]: %#lx",
|
debug("envpStrings[%d]: %#lx",
|
||||||
i, EnvpStrings[i]);
|
i, envpStrings[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the null terminator */
|
/* Store the null terminator */
|
||||||
StackPush(Stack64, uintptr_t, AT_NULL);
|
StackPush(Stack64, uintptr_t, AT_NULL);
|
||||||
|
|
||||||
/* Store ArgvStrings[] to the stack */
|
/* Store argvStrings[] to the stack */
|
||||||
Stack64 -= ArgvSize; /* (1 Stack64 = 8 bits; Stack64 = 8 * ArgvSize) */
|
Stack64 -= argvLen; /* (1 Stack64 = 8 bits; Stack64 = 8 * argvLen) */
|
||||||
for (size_t i = 0; i < ArgvSize; i++)
|
for (size_t i = 0; i < argvLen; i++)
|
||||||
{
|
{
|
||||||
*(Stack64 + i) = (uintptr_t)ArgvStrings[i];
|
*(Stack64 + i) = (uintptr_t)argvStrings[i];
|
||||||
debug("ArgvStrings[%d]: %#lx",
|
debug("argvStrings[%d]: %#lx",
|
||||||
i, ArgvStrings[i]);
|
i, argvStrings[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store the argc */
|
/* Store the argc */
|
||||||
StackPush(Stack64, uintptr_t, ArgvSize);
|
StackPush(Stack64, uintptr_t, argvLen);
|
||||||
|
|
||||||
/* Set "Stack" to the new stack pointer */
|
/* Set "pStack" to the new stack pointer */
|
||||||
Stack = (char *)Stack64;
|
pStack = (char *)Stack64;
|
||||||
|
|
||||||
|
/* Ensure StackPointerReg is aligned to the closest lower 16 bytes boundary */
|
||||||
|
uintptr_t lower16Align = (uintptr_t)pStack;
|
||||||
|
lower16Align &= ~0xF;
|
||||||
|
pStack = (char *)lower16Align;
|
||||||
|
|
||||||
/* We need the virtual address but because we are in the kernel we can't use the process page table.
|
/* We need the virtual address but because we are in the kernel we can't use the process page table.
|
||||||
So we modify the physical address and store how much we need to subtract to get the virtual address for RSP. */
|
So we modify the physical address and store how much we need to subtract to get the virtual address for RSP. */
|
||||||
uintptr_t SubtractStack = (uintptr_t)this->Stack->GetStackPhysicalTop() - (uintptr_t)Stack;
|
uintptr_t SubtractStack = (uintptr_t)this->Stack->GetStackPhysicalTop() - (uintptr_t)pStack;
|
||||||
debug("SubtractStack: %#lx", SubtractStack);
|
debug("SubtractStack: %#lx", SubtractStack);
|
||||||
|
|
||||||
/* Set the stack pointer to the new stack */
|
/* Set the stack pointer to the new stack */
|
||||||
uintptr_t StackPointerReg = ((uintptr_t)this->Stack->GetStackTop() - SubtractStack);
|
uintptr_t StackPointerReg = ((uintptr_t)this->Stack->GetStackTop() - SubtractStack);
|
||||||
// assert(!(StackPointerReg & 0xF));
|
// assert(!(StackPointerReg & 0xF));
|
||||||
|
|
||||||
/* Ensure StackPointerReg is aligned to the closest lower 16 bytes boundary */
|
|
||||||
StackPointerReg &= ~0xF;
|
|
||||||
|
|
||||||
#if defined(a64)
|
#if defined(a64)
|
||||||
this->Registers.rsp = StackPointerReg;
|
this->Registers.rsp = StackPointerReg;
|
||||||
#elif defined(a32)
|
#elif defined(a32)
|
||||||
@ -320,10 +322,10 @@ namespace Tasking
|
|||||||
this->Registers.sp = StackPointerReg;
|
this->Registers.sp = StackPointerReg;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ArgvSize > 0)
|
if (argvLen > 0)
|
||||||
delete[] ArgvStrings;
|
delete[] argvStrings;
|
||||||
if (EnvpSize > 0)
|
if (envpLen > 0)
|
||||||
delete[] EnvpStrings;
|
delete[] envpStrings;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DumpData("Stack Data",
|
DumpData("Stack Data",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user