mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 22:48:11 +00:00
UserspaceEmulator: Pass arguments through to emulated process
Ultimately we'll want to support passing some options to the emulator as well, but for now just pass all arguments (except argv[0] of course) through to the emulated process. This is still not perfect, but slightly better than what we had before.
This commit is contained in:
parent
3d42b85969
commit
27c1690504
3 changed files with 28 additions and 18 deletions
|
@ -44,33 +44,37 @@ namespace UserspaceEmulator {
|
|||
static constexpr u32 stack_location = 0x10000000;
|
||||
static constexpr size_t stack_size = 64 * KB;
|
||||
|
||||
Emulator::Emulator(const String& executable_path, NonnullRefPtr<ELF::Loader> elf)
|
||||
Emulator::Emulator(const Vector<String>& arguments, NonnullRefPtr<ELF::Loader> elf)
|
||||
: m_elf(move(elf))
|
||||
, m_cpu(*this)
|
||||
, m_executable_path(executable_path)
|
||||
{
|
||||
setup_stack();
|
||||
setup_stack(arguments);
|
||||
}
|
||||
|
||||
void Emulator::setup_stack()
|
||||
void Emulator::setup_stack(const Vector<String>& arguments)
|
||||
{
|
||||
auto stack_region = make<SimpleRegion>(stack_location, stack_size);
|
||||
m_mmu.add_region(move(stack_region));
|
||||
m_cpu.set_esp(stack_location + stack_size);
|
||||
|
||||
m_cpu.push_string(LexicalPath(m_executable_path).basename());
|
||||
u32 argv0 = m_cpu.esp();
|
||||
Vector<u32> argv_entries;
|
||||
|
||||
for (auto& argument : arguments) {
|
||||
m_cpu.push_string(argument.characters());
|
||||
argv_entries.append(m_cpu.esp());
|
||||
}
|
||||
|
||||
m_cpu.push32(0); // char** envp = { nullptr }
|
||||
u32 envp = m_cpu.esp();
|
||||
|
||||
m_cpu.push32(0); // char** argv = { argv0, nullptr }
|
||||
m_cpu.push32(argv0);
|
||||
m_cpu.push32(0); // char** argv = { argv_entries..., nullptr }
|
||||
for (ssize_t i = argv_entries.size() - 1; i >= 0; --i)
|
||||
m_cpu.push32(argv_entries[i]);
|
||||
u32 argv = m_cpu.esp();
|
||||
|
||||
m_cpu.push32(0); // (alignment)
|
||||
|
||||
u32 argc = 1;
|
||||
u32 argc = argv_entries.size();
|
||||
m_cpu.push32(envp);
|
||||
m_cpu.push32(argv);
|
||||
m_cpu.push32(argc);
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace UserspaceEmulator {
|
|||
|
||||
class Emulator {
|
||||
public:
|
||||
Emulator(const String& executable_path, NonnullRefPtr<ELF::Loader>);
|
||||
Emulator(const Vector<String>& arguments, NonnullRefPtr<ELF::Loader>);
|
||||
|
||||
bool load_elf();
|
||||
void dump_backtrace();
|
||||
|
@ -53,7 +53,7 @@ private:
|
|||
SoftMMU m_mmu;
|
||||
SoftCPU m_cpu;
|
||||
|
||||
void setup_stack();
|
||||
void setup_stack(const Vector<String>& arguments);
|
||||
|
||||
u32 virt$mmap(u32);
|
||||
u32 virt$gettid();
|
||||
|
@ -77,8 +77,6 @@ private:
|
|||
|
||||
bool m_shutdown { false };
|
||||
int m_exit_status { 0 };
|
||||
|
||||
String m_executable_path;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -30,14 +30,17 @@
|
|||
#include <AK/MappedFile.h>
|
||||
#include <LibCore/ArgsParser.h>
|
||||
#include <LibELF/Loader.h>
|
||||
#include <getopt.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
const char* executable_path = nullptr;
|
||||
if (argc == 1) {
|
||||
out() << "usage: UserspaceEmulator <command>";
|
||||
return 0;
|
||||
}
|
||||
|
||||
Core::ArgsParser args_parser;
|
||||
args_parser.add_positional_argument(executable_path, "Executable path", "executable");
|
||||
args_parser.parse(argc, argv);
|
||||
// FIXME: Allow specifying any command in $PATH instead of requiring a full executable path.
|
||||
const char* executable_path = argv[1];
|
||||
|
||||
MappedFile mapped_file(executable_path);
|
||||
if (!mapped_file.is_valid()) {
|
||||
|
@ -47,7 +50,12 @@ int main(int argc, char** argv)
|
|||
|
||||
auto elf = ELF::Loader::create((const u8*)mapped_file.data(), mapped_file.size());
|
||||
|
||||
UserspaceEmulator::Emulator emulator(executable_path, move(elf));
|
||||
Vector<String> arguments;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
arguments.append(argv[i]);
|
||||
}
|
||||
|
||||
UserspaceEmulator::Emulator emulator(arguments, move(elf));
|
||||
if (!emulator.load_elf())
|
||||
return 1;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue