
For now this only allows us to single-step through execution and inspect part of the execution environment for debugging This also allows to run to function return and sending signals to the VM This changes the behavior of SIGINT for UE to pause execution and then terminate if already paused A way of setting a watchpoint for a function would be a good addition in the future, the scaffold for this is already present, we only need to figure out a way to find the address of a function On a side note I have changed all occurences of west-const to east const
71 lines
2.1 KiB
C++
71 lines
2.1 KiB
C++
/*
|
|
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include "Emulator.h"
|
|
#include <AK/Format.h>
|
|
#include <AK/LexicalPath.h>
|
|
#include <AK/StringBuilder.h>
|
|
#include <LibCore/ArgsParser.h>
|
|
#include <LibCore/DirIterator.h>
|
|
#include <LibCore/File.h>
|
|
#include <pthread.h>
|
|
#include <serenity.h>
|
|
#include <string.h>
|
|
|
|
bool g_report_to_debug = false;
|
|
|
|
int main(int argc, char** argv, char** env)
|
|
{
|
|
Vector<String> arguments;
|
|
bool pause_on_startup { false };
|
|
|
|
Core::ArgsParser parser;
|
|
parser.set_stop_on_first_non_option(true);
|
|
parser.add_option(g_report_to_debug, "Write reports to the debug log", "report-to-debug", 0);
|
|
parser.add_option(pause_on_startup, "Pause on startup", "pause", 'p');
|
|
|
|
parser.add_positional_argument(arguments, "Command to emulate", "command");
|
|
|
|
parser.parse(argc, argv);
|
|
|
|
String executable_path;
|
|
if (arguments[0].contains("/"sv))
|
|
executable_path = Core::File::real_path_for(arguments[0]);
|
|
else
|
|
executable_path = Core::find_executable_in_path(arguments[0]);
|
|
if (executable_path.is_empty()) {
|
|
reportln("Cannot find executable for '{}'.", arguments[0]);
|
|
return 1;
|
|
}
|
|
|
|
Vector<String> environment;
|
|
for (int i = 0; env[i]; ++i) {
|
|
environment.append(env[i]);
|
|
}
|
|
|
|
// FIXME: It might be nice to tear down the emulator properly.
|
|
auto& emulator = *new UserspaceEmulator::Emulator(executable_path, arguments, environment);
|
|
if (!emulator.load_elf())
|
|
return 1;
|
|
|
|
StringBuilder builder;
|
|
builder.append("(UE) ");
|
|
builder.append(LexicalPath(arguments[0]).basename());
|
|
if (set_process_name(builder.string_view().characters_without_null_termination(), builder.string_view().length()) < 0) {
|
|
perror("set_process_name");
|
|
return 1;
|
|
}
|
|
int rc = pthread_setname_np(pthread_self(), builder.to_string().characters());
|
|
if (rc != 0) {
|
|
reportln("pthread_setname_np: {}", strerror(rc));
|
|
return 1;
|
|
}
|
|
|
|
if (pause_on_startup)
|
|
emulator.pause();
|
|
|
|
return emulator.exec();
|
|
}
|