execve(2) now pushes envp to the new stack and sets up registers.
This fully implements environmental variables over exec.
This commit is contained in:
parent
60b9a84a51
commit
6f36ecf0b3
|
@ -29,6 +29,8 @@
|
||||||
.type _start, @function
|
.type _start, @function
|
||||||
_start:
|
_start:
|
||||||
|
|
||||||
|
movq %rcx, environ # envp
|
||||||
|
|
||||||
pushq %rsi
|
pushq %rsi
|
||||||
pushq %rdi
|
pushq %rdi
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
.type _start, @function
|
.type _start, @function
|
||||||
_start:
|
_start:
|
||||||
|
|
||||||
|
movl %ecx, environ # envp
|
||||||
|
|
||||||
# Arguments for main
|
# Arguments for main
|
||||||
push %ebx # argv
|
push %ebx # argv
|
||||||
push %eax # argc
|
push %eax # argc
|
||||||
|
|
|
@ -259,7 +259,10 @@ namespace Sortix
|
||||||
ResetAddressSpace();
|
ResetAddressSpace();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Process::Execute(const char* programname, const byte* program, size_t programsize, int argc, const char* const* argv, CPU::InterruptRegisters* regs)
|
int Process::Execute(const char* programname, const byte* program,
|
||||||
|
size_t programsize, int argc, const char* const* argv,
|
||||||
|
int envc, const char* const* envp,
|
||||||
|
CPU::InterruptRegisters* regs)
|
||||||
{
|
{
|
||||||
ASSERT(CurrentProcess() == this);
|
ASSERT(CurrentProcess() == this);
|
||||||
|
|
||||||
|
@ -269,10 +272,11 @@ namespace Sortix
|
||||||
// TODO: This may be an ugly hack!
|
// TODO: This may be an ugly hack!
|
||||||
// TODO: Move this to x86/process.cpp.
|
// TODO: Move this to x86/process.cpp.
|
||||||
|
|
||||||
|
addr_t stackpos = CurrentThread()->stackpos + CurrentThread()->stacksize;
|
||||||
|
|
||||||
// Alright, move argv onto the new stack! First figure out exactly how
|
// Alright, move argv onto the new stack! First figure out exactly how
|
||||||
// big argv actually is.
|
// big argv actually is.
|
||||||
addr_t stackpos = CurrentThread()->stackpos + CurrentThread()->stacksize;
|
addr_t argvpos = stackpos - sizeof(char*) * (argc+1);
|
||||||
addr_t argvpos = stackpos - sizeof(char*) * argc;
|
|
||||||
char** stackargv = (char**) argvpos;
|
char** stackargv = (char**) argvpos;
|
||||||
|
|
||||||
size_t argvsize = 0;
|
size_t argvsize = 0;
|
||||||
|
@ -285,9 +289,31 @@ namespace Sortix
|
||||||
Maxsi::Memory::Copy(dest, argv[i], len);
|
Maxsi::Memory::Copy(dest, argv[i], len);
|
||||||
}
|
}
|
||||||
|
|
||||||
stackpos = argvpos - argvsize;
|
stackargv[argc] = NULL;
|
||||||
|
|
||||||
ExecuteCPU(argc, stackargv, stackpos, entry, regs);
|
if ( argvsize % 16UL ) { argvsize += 16 - (argvsize % 16UL); }
|
||||||
|
|
||||||
|
// And then move envp onto the stack.
|
||||||
|
addr_t envppos = argvpos - argvsize - sizeof(char*) * (envc+1);
|
||||||
|
char** stackenvp = (char**) envppos;
|
||||||
|
|
||||||
|
size_t envpsize = 0;
|
||||||
|
for ( int i = 0; i < envc; i++ )
|
||||||
|
{
|
||||||
|
size_t len = String::Length(envp[i]) + 1;
|
||||||
|
envpsize += len;
|
||||||
|
char* dest = ((char*) envppos) - envpsize;
|
||||||
|
stackenvp[i] = dest;
|
||||||
|
Maxsi::Memory::Copy(dest, envp[i], len);
|
||||||
|
}
|
||||||
|
|
||||||
|
stackenvp[envc] = NULL;
|
||||||
|
|
||||||
|
if ( envpsize % 16UL ) { envpsize += 16 - (envpsize % 16UL); }
|
||||||
|
|
||||||
|
stackpos = envppos - envpsize;
|
||||||
|
|
||||||
|
ExecuteCPU(argc, stackargv, envc, stackenvp, stackpos, entry, regs);
|
||||||
|
|
||||||
descriptors.OnExecute();
|
descriptors.OnExecute();
|
||||||
|
|
||||||
|
@ -303,7 +329,9 @@ namespace Sortix
|
||||||
size_t count;
|
size_t count;
|
||||||
size_t sofar;
|
size_t sofar;
|
||||||
int argc;
|
int argc;
|
||||||
|
int envc;
|
||||||
char** argv;
|
char** argv;
|
||||||
|
char** envp;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SysExecVEState()
|
SysExecVEState()
|
||||||
|
@ -315,6 +343,8 @@ namespace Sortix
|
||||||
sofar = 0;
|
sofar = 0;
|
||||||
argc = 0;
|
argc = 0;
|
||||||
argv = NULL;
|
argv = NULL;
|
||||||
|
envc = 0;
|
||||||
|
envp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
~SysExecVEState()
|
~SysExecVEState()
|
||||||
|
@ -324,6 +354,8 @@ namespace Sortix
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
for ( int i = 0; i < argc; i++ ) { delete[] argv[i]; }
|
for ( int i = 0; i < argc; i++ ) { delete[] argv[i]; }
|
||||||
delete[] argv;
|
delete[] argv;
|
||||||
|
for ( int i = 0; i < envc; i++ ) { delete[] envp[i]; }
|
||||||
|
delete[] envp;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -350,7 +382,10 @@ namespace Sortix
|
||||||
{
|
{
|
||||||
CPU::InterruptRegisters* regs = Syscall::InterruptRegs();
|
CPU::InterruptRegisters* regs = Syscall::InterruptRegs();
|
||||||
Process* process = CurrentProcess();
|
Process* process = CurrentProcess();
|
||||||
int result = process->Execute(state->filename, state->buffer, state->count, state->argc, state->argv, regs);
|
int result = process->Execute(state->filename, state->buffer,
|
||||||
|
state->count, state->argc,
|
||||||
|
state->argv, state->envc,
|
||||||
|
state->envp, regs);
|
||||||
if ( result == 0 ) { Syscall::AsIs(); }
|
if ( result == 0 ) { Syscall::AsIs(); }
|
||||||
delete state;
|
delete state;
|
||||||
return result;
|
return result;
|
||||||
|
@ -391,7 +426,7 @@ namespace Sortix
|
||||||
return (DevBuffer*) dev;
|
return (DevBuffer*) dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SysExecVE(const char* filename, char* const argv[], char* const /*envp*/[])
|
int SysExecVE(const char* filename, char* const argv[], char* const envp[])
|
||||||
{
|
{
|
||||||
// TODO: Validate that all the pointer-y parameters are SAFE!
|
// TODO: Validate that all the pointer-y parameters are SAFE!
|
||||||
|
|
||||||
|
@ -404,12 +439,13 @@ namespace Sortix
|
||||||
state->filename = String::Clone(filename);
|
state->filename = String::Clone(filename);
|
||||||
if ( !state->filename ) { delete state; return -1; }
|
if ( !state->filename ) { delete state; return -1; }
|
||||||
|
|
||||||
int argc; for ( argc = 0; argv[argc]; argc++ );
|
int argc; for ( argc = 0; argv && argv[argc]; argc++ );
|
||||||
|
int envc; for ( envc = 0; envp && envp[envc]; envc++ );
|
||||||
|
|
||||||
state->argc = argc;
|
state->argv = new char*[argc+1];
|
||||||
state->argv = new char*[state->argc];
|
|
||||||
Maxsi::Memory::Set(state->argv, 0, sizeof(char*) * state->argc);
|
|
||||||
if ( !state->argv ) { delete state; return -1; }
|
if ( !state->argv ) { delete state; return -1; }
|
||||||
|
state->argc = argc;
|
||||||
|
Maxsi::Memory::Set(state->argv, 0, sizeof(char*) * (state->argc+1));
|
||||||
|
|
||||||
for ( int i = 0; i < state->argc; i++ )
|
for ( int i = 0; i < state->argc; i++ )
|
||||||
{
|
{
|
||||||
|
@ -417,6 +453,17 @@ namespace Sortix
|
||||||
if ( !state->argv[i] ) { delete state; return -1; }
|
if ( !state->argv[i] ) { delete state; return -1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state->envp = new char*[envc+1];
|
||||||
|
if ( !state->envp ) { delete state; return -1; }
|
||||||
|
state->envc = envc;
|
||||||
|
Maxsi::Memory::Set(state->envp, 0, sizeof(char*) * (state->envc+1));
|
||||||
|
|
||||||
|
for ( int i = 0; i < state->envc; i++ )
|
||||||
|
{
|
||||||
|
state->envp[i] = String::Clone(envp[i]);
|
||||||
|
if ( !state->envp[i] ) { delete state; return -1; }
|
||||||
|
}
|
||||||
|
|
||||||
Process* process = CurrentProcess();
|
Process* process = CurrentProcess();
|
||||||
state->dev = OpenProgramImage(state->filename, process->workingdir, "/bin");
|
state->dev = OpenProgramImage(state->filename, process->workingdir, "/bin");
|
||||||
if ( !state->dev ) { delete state; return -1; }
|
if ( !state->dev ) { delete state; return -1; }
|
||||||
|
|
|
@ -96,7 +96,10 @@ namespace Sortix
|
||||||
bool sigint;
|
bool sigint;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int Execute(const char* programname, const byte* program, size_t programsize, int argc, const char* const* argv, CPU::InterruptRegisters* regs);
|
int Execute(const char* programname, const byte* program,
|
||||||
|
size_t programsize, int argc, const char* const* argv,
|
||||||
|
int envc, const char* const* envp,
|
||||||
|
CPU::InterruptRegisters* regs);
|
||||||
void ResetAddressSpace();
|
void ResetAddressSpace();
|
||||||
void Exit(int status);
|
void Exit(int status);
|
||||||
|
|
||||||
|
@ -108,7 +111,9 @@ namespace Sortix
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Thread* ForkThreads(Process* processclone);
|
Thread* ForkThreads(Process* processclone);
|
||||||
void ExecuteCPU(int argc, char** argv, addr_t stackpos, addr_t entry, CPU::InterruptRegisters* regs);
|
void ExecuteCPU(int argc, char** argv, int envc, char** envp,
|
||||||
|
addr_t stackpos, addr_t entry,
|
||||||
|
CPU::InterruptRegisters* regs);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void ResetForExecute();
|
void ResetForExecute();
|
||||||
|
|
|
@ -27,10 +27,14 @@
|
||||||
|
|
||||||
namespace Sortix
|
namespace Sortix
|
||||||
{
|
{
|
||||||
void Process::ExecuteCPU(int argc, char** argv, addr_t stackpos, addr_t entry, CPU::InterruptRegisters* regs)
|
void Process::ExecuteCPU(int argc, char** argv, int envc, char** envp,
|
||||||
|
addr_t stackpos, addr_t entry,
|
||||||
|
CPU::InterruptRegisters* regs)
|
||||||
{
|
{
|
||||||
regs->rdi = argc;
|
regs->rdi = argc;
|
||||||
regs->rsi = (size_t) argv;
|
regs->rsi = (size_t) argv;
|
||||||
|
regs->rdx = envc;
|
||||||
|
regs->rcx = (size_t) envp;
|
||||||
regs->rip = entry;
|
regs->rip = entry;
|
||||||
regs->userrsp = stackpos & ~(15UL);
|
regs->userrsp = stackpos & ~(15UL);
|
||||||
regs->rbp = stackpos;
|
regs->rbp = stackpos;
|
||||||
|
|
|
@ -27,10 +27,15 @@
|
||||||
|
|
||||||
namespace Sortix
|
namespace Sortix
|
||||||
{
|
{
|
||||||
void Process::ExecuteCPU(int argc, char** argv, addr_t stackpos, addr_t entry, CPU::InterruptRegisters* regs)
|
|
||||||
|
void Process::ExecuteCPU(int argc, char** argv, int envc, char** envp,
|
||||||
|
addr_t stackpos, addr_t entry,
|
||||||
|
CPU::InterruptRegisters* regs)
|
||||||
{
|
{
|
||||||
regs->eax = argc;
|
regs->eax = argc;
|
||||||
regs->ebx = (size_t) argv;
|
regs->ebx = (size_t) argv;
|
||||||
|
regs->edx = envc;
|
||||||
|
regs->ecx = (size_t) envp;
|
||||||
regs->eip = entry;
|
regs->eip = entry;
|
||||||
regs->useresp = stackpos;
|
regs->useresp = stackpos;
|
||||||
regs->ebp = stackpos;
|
regs->ebp = stackpos;
|
||||||
|
|
Loading…
Reference in New Issue