mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-29 16:21:29 +00:00
UserspaceEmulator: Implement the execve() syscall :^)
This virtual syscall works by exec'ing the UserspaceEmulator itself, with the emulated program's provided arguments as the arguments to the new UserspaceEmulator instance. This means that we "follow" exec'ed programs and emulate them as well. In the future we might want to make this an opt-in (or opt-out, idk) behavior, but for now it's what we do. This is really quite cool, I think! :^)
This commit is contained in:
parent
b9a0ba9624
commit
0b287c18b9
Notes:
sideshowbarker
2024-07-19 04:33:39 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/0b287c18b93
|
@ -242,6 +242,8 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
|
|||
dbgprintf("Syscall: %s (%x)\n", Syscall::to_string((Syscall::Function)function), function);
|
||||
#endif
|
||||
switch (function) {
|
||||
case SC_execve:
|
||||
return virt$execve(arg1);
|
||||
case SC_ioctl:
|
||||
return virt$ioctl(arg1, arg2, arg3);
|
||||
case SC_get_dir_entries:
|
||||
|
@ -872,4 +874,46 @@ int Emulator::virt$fork()
|
|||
return fork();
|
||||
}
|
||||
|
||||
int Emulator::virt$execve(FlatPtr params_addr)
|
||||
{
|
||||
Syscall::SC_execve_params params;
|
||||
mmu().copy_from_vm(¶ms, params_addr, sizeof(params));
|
||||
|
||||
auto path = String::copy(mmu().copy_buffer_from_vm((FlatPtr)params.path.characters, params.path.length));
|
||||
Vector<String> arguments;
|
||||
Vector<String> environment;
|
||||
|
||||
auto copy_string_list = [this](auto& output_vector, auto& string_list) {
|
||||
for (size_t i = 0; i < string_list.length; ++i) {
|
||||
Syscall::StringArgument string;
|
||||
mmu().copy_from_vm(&string, (FlatPtr)&string_list.strings[i], sizeof(string));
|
||||
output_vector.append(String::copy(mmu().copy_buffer_from_vm((FlatPtr)string.characters, string.length)));
|
||||
}
|
||||
};
|
||||
|
||||
copy_string_list(arguments, params.arguments);
|
||||
copy_string_list(environment, params.environment);
|
||||
|
||||
dbgprintf("\n");
|
||||
dbgprintf("==%d== \033[33;1mSyscall:\033[0m execve\n", getpid());
|
||||
for (auto& argument : arguments)
|
||||
dbgprintf("==%d== - %s\n", getpid(), argument.characters());
|
||||
|
||||
Vector<char*> argv;
|
||||
Vector<char*> envp;
|
||||
|
||||
argv.append(const_cast<char*>("/bin/UserspaceEmulator"));
|
||||
|
||||
auto create_string_vector = [](auto& output_vector, auto& input_vector) {
|
||||
for (auto& string : input_vector)
|
||||
output_vector.append(const_cast<char*>(string.characters()));
|
||||
output_vector.append(nullptr);
|
||||
};
|
||||
|
||||
create_string_vector(argv, arguments);
|
||||
create_string_vector(envp, environment);
|
||||
|
||||
return execve(argv[0], (char* const*)argv.data(), (char* const*)envp.data());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,6 +71,7 @@ private:
|
|||
void setup_stack(const Vector<String>& arguments, const Vector<String>& environment);
|
||||
|
||||
int virt$fork();
|
||||
int virt$execve(FlatPtr);
|
||||
int virt$get_dir_entries(int fd, FlatPtr buffer, ssize_t);
|
||||
int virt$ioctl(int fd, unsigned, FlatPtr);
|
||||
int virt$usleep(useconds_t);
|
||||
|
|
Loading…
Reference in a new issue