This commit is contained in:
Jarek Syrylak
2018-07-12 19:18:04 +01:00
9 changed files with 46 additions and 103 deletions

View File

@@ -1,4 +1,4 @@
# Copyright 2016 Citra Emulator Project
# Copyright 2018 Yuzu Emulator Project
# Licensed under GPLv2 or any later version
# Refer to the license.txt file included.
@@ -22,7 +22,7 @@ function(windows_copy_files TARGET SOURCE_DIR DEST_DIR)
# cmake adds an extra check for command success which doesn't work too well with robocopy
# so trick it into thinking the command was successful with the || cmd /c "exit /b 0"
add_custom_command(TARGET ${TARGET} POST_BUILD
COMMAND if not exist ${DEST_DIR} mkdir ${DEST_DIR} 2> nul
COMMAND ${CMAKE_COMMAND} -E make_directory ${DEST_DIR}
COMMAND robocopy ${SOURCE_DIR} ${DEST_DIR} ${ARGN} /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0"
)
endfunction()
endfunction()

View File

@@ -11,6 +11,7 @@ namespace FileSys {
namespace ErrCodes {
enum {
NotFound = 1,
SaveDataNotFound = 1002,
};
}

View File

@@ -133,39 +133,6 @@ static const char* target_xml =
<reg name="cpsr" bitsize="32" type="cpsr_flags"/>
</feature>
<feature name="org.gnu.gdb.aarch64.fpu">
<reg name="d0" bitsize="64" type="ieee_double"/>
<reg name="d1" bitsize="64" type="ieee_double"/>
<reg name="d2" bitsize="64" type="ieee_double"/>
<reg name="d3" bitsize="64" type="ieee_double"/>
<reg name="d4" bitsize="64" type="ieee_double"/>
<reg name="d5" bitsize="64" type="ieee_double"/>
<reg name="d6" bitsize="64" type="ieee_double"/>
<reg name="d7" bitsize="64" type="ieee_double"/>
<reg name="d8" bitsize="64" type="ieee_double"/>
<reg name="d9" bitsize="64" type="ieee_double"/>
<reg name="d10" bitsize="64" type="ieee_double"/>
<reg name="d11" bitsize="64" type="ieee_double"/>
<reg name="d12" bitsize="64" type="ieee_double"/>
<reg name="d13" bitsize="64" type="ieee_double"/>
<reg name="d14" bitsize="64" type="ieee_double"/>
<reg name="d15" bitsize="64" type="ieee_double"/>
<reg name="d16" bitsize="64" type="ieee_double"/>
<reg name="d17" bitsize="64" type="ieee_double"/>
<reg name="d18" bitsize="64" type="ieee_double"/>
<reg name="d19" bitsize="64" type="ieee_double"/>
<reg name="d20" bitsize="64" type="ieee_double"/>
<reg name="d21" bitsize="64" type="ieee_double"/>
<reg name="d22" bitsize="64" type="ieee_double"/>
<reg name="d23" bitsize="64" type="ieee_double"/>
<reg name="d24" bitsize="64" type="ieee_double"/>
<reg name="d25" bitsize="64" type="ieee_double"/>
<reg name="d26" bitsize="64" type="ieee_double"/>
<reg name="d27" bitsize="64" type="ieee_double"/>
<reg name="d28" bitsize="64" type="ieee_double"/>
<reg name="d29" bitsize="64" type="ieee_double"/>
<reg name="d30" bitsize="64" type="ieee_double"/>
<reg name="d31" bitsize="64" type="ieee_double"/>
<reg name="fpscr" bitsize="32" type="int" group="float"/>
</feature>
</target>
)";
@@ -181,7 +148,7 @@ static u32 latest_signal = 0;
static bool memory_break = false;
static Kernel::Thread* current_thread = nullptr;
static unsigned current_core = 0;
static u32 current_core = 0;
// Binding to a port within the reserved ports range (0-1023) requires root permissions,
// so default to a port outside of that range.
@@ -210,25 +177,30 @@ static std::map<u64, Breakpoint> breakpoints_read;
static std::map<u64, Breakpoint> breakpoints_write;
struct Module {
char name[128];
std::string name;
PAddr beg;
PAddr end;
};
static std::vector<Module> modules;
void RegisterModule(const char* name, PAddr beg, PAddr end) {
void RegisterModule(std::string name, PAddr beg, PAddr end, bool add_elf_ext) {
Module module;
strncpy(module.name, name, sizeof(module.name));
if (add_elf_ext) {
Common::SplitPath(name, nullptr, &module.name, nullptr);
module.name += ".elf";
} else {
module.name = std::move(name);
}
module.beg = beg;
module.end = end;
modules.push_back(module);
modules.push_back(std::move(module));
}
static Kernel::Thread* FindThreadById(int id) {
for (unsigned core = 0; core < Core::NUM_CPU_CORES; core++) {
auto threads = Core::System::GetInstance().Scheduler(core)->GetThreadList();
for (auto thread : threads) {
for (u32 core = 0; core < Core::NUM_CPU_CORES; core++) {
const auto& threads = Core::System::GetInstance().Scheduler(core)->GetThreadList();
for (auto& thread : threads) {
if (thread->GetThreadId() == id) {
current_core = core;
return thread.get();
@@ -393,21 +365,6 @@ static void LongToGdbHex(u8* dest, u64 v) {
}
}
/**
* Convert a u128 into a gdb-formatted hex string.
*
* @param dest Pointer to buffer to store output hex string characters.
* @param v Value to convert.
*/
// static void LongLongToGdbHex(u8* dest, u128 v)
//{
// for(int i = 0; i < 32; i += 2)
// {
// dest[i + 1] = NibbleToHex(static_cast<u8>(v >> (4 * i)));
// dest[i] = NibbleToHex(static_cast<u8>(v >> (4 * (i + 1))));
// }
//}
/**
* Convert a gdb-formatted hex string into a u32.
*
@@ -440,24 +397,6 @@ static u64 GdbHexToLong(const u8* src) {
return output;
}
/**
* Convert a gdb-formatted hex string into a u128.
*
* @param src Pointer to hex string.
*/
// static u128 GdbHexToLong(const u8* src)
//{
// u128 output = 0;
//
// for(int i = 0; i < 32; i += 2)
// {
// output = (output << 4) | HexCharToValue(src[15 - i - 1]);
// output = (output << 4) | HexCharToValue(src[15 - i]);
// }
//
// return output;
//}
/// Read a byte from the gdb client.
static u8 ReadByte() {
u8 c;
@@ -634,14 +573,13 @@ static void HandleQuery() {
strlen("Xfer:features:read:target.xml:")) == 0) {
SendReply(target_xml);
} else if (strncmp(query, "Offsets", strlen("Offsets")) == 0) {
std::string buffer;
buffer = fmt::format("TextSeg={:0x}", Memory::PROCESS_IMAGE_VADDR);
std::string buffer = fmt::format("TextSeg={:0x}", Memory::PROCESS_IMAGE_VADDR);
SendReply(buffer.c_str());
} else if (strncmp(query, "fThreadInfo", strlen("fThreadInfo")) == 0) {
std::string val = "m";
for (int core = 0; core < Core::NUM_CPU_CORES; core++) {
auto threads = Core::System::GetInstance().Scheduler(core)->GetThreadList();
for (auto thread : threads) {
for (u32 core = 0; core < Core::NUM_CPU_CORES; core++) {
const auto& threads = Core::System::GetInstance().Scheduler(core)->GetThreadList();
for (const auto& thread : threads) {
val += fmt::format("{:x}", thread->GetThreadId());
val += ",";
}
@@ -654,9 +592,9 @@ static void HandleQuery() {
std::string buffer;
buffer += "l<?xml version=\"1.0\"?>";
buffer += "<threads>";
for (int core = 0; core < Core::NUM_CPU_CORES; core++) {
auto threads = Core::System::GetInstance().Scheduler(core)->GetThreadList();
for (auto thread : threads) {
for (u32 core = 0; core < Core::NUM_CPU_CORES; core++) {
const auto& threads = Core::System::GetInstance().Scheduler(core)->GetThreadList();
for (const auto& thread : threads) {
buffer +=
fmt::format(R"*(<thread id="{:x}" core="{:d}" name="Thread {:x}"></thread>)*",
thread->GetThreadId(), core, thread->GetThreadId());
@@ -668,7 +606,7 @@ static void HandleQuery() {
std::string buffer;
buffer += "l<?xml version=\"1.0\"?>";
buffer += "<library-list>";
for (auto module : modules) {
for (const auto& module : modules) {
buffer +=
fmt::format(R"*("<library name = "{}"><segment address = "0x{:x}"/></library>)*",
module.name, module.beg);
@@ -856,7 +794,7 @@ static void ReadRegisters() {
LongToGdbHex(bufptr + reg * 16, RegRead(reg, current_thread));
}
bufptr += (32 * 16);
bufptr += 32 * 16;
LongToGdbHex(bufptr, RegRead(PC_REGISTER, current_thread));
@@ -870,7 +808,7 @@ static void ReadRegisters() {
LongToGdbHex(bufptr + reg * 16, RegRead(reg, current_thread));
}
bufptr += (32 * 32);
bufptr += 32 * 32;
LongToGdbHex(bufptr, RegRead(998, current_thread));
@@ -956,7 +894,7 @@ static void ReadMemory() {
SendReply("E01");
}
if ((addr < Memory::PROCESS_IMAGE_VADDR) || (addr >= Memory::MAP_REGION_VADDR_END)) {
if (addr < Memory::PROCESS_IMAGE_VADDR || addr >= Memory::MAP_REGION_VADDR_END) {
return SendReply("E00");
}
@@ -1349,7 +1287,7 @@ void SetCpuStepFlag(bool is_step) {
void SendTrap(Kernel::Thread* thread, int trap) {
if (send_trap) {
if (!halt_loop || (current_thread == thread)) {
if (!halt_loop || current_thread == thread) {
current_thread = thread;
SendSignal(thread, trap);
}

View File

@@ -6,6 +6,7 @@
#pragma once
#include <string>
#include "common/common_types.h"
#include "core/hle/kernel/thread.h"
@@ -52,7 +53,7 @@ bool IsServerEnabled();
bool IsConnected();
/// Register module.
void RegisterModule(const char* name, PAddr beg, PAddr end);
void RegisterModule(std::string name, PAddr beg, PAddr end, bool add_elf_ext = true);
/**
* Signal to the gdbstub server that it should halt CPU execution.

View File

@@ -7,6 +7,7 @@
#include "common/string_util.h"
#include "core/core.h"
#include "core/file_sys/directory.h"
#include "core/file_sys/errors.h"
#include "core/file_sys/filesystem.h"
#include "core/file_sys/storage.h"
#include "core/hle/ipc_helpers.h"
@@ -531,12 +532,20 @@ void FSP_SRV::CreateSaveData(Kernel::HLERequestContext& ctx) {
void FSP_SRV::MountSaveData(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_FS, "(STUBBED) called");
// TODO(Subv): Read the input parameters and mount the requested savedata instead of always
// mounting the current process' savedata.
FileSys::Path unused;
auto filesystem = OpenFileSystem(Type::SaveData, unused).Unwrap();
auto filesystem = OpenFileSystem(Type::SaveData, unused);
if (filesystem.Failed()) {
IPC::ResponseBuilder rb{ctx, 2, 0, 0};
rb.Push(ResultCode(ErrorModule::FS, FileSys::ErrCodes::SaveDataNotFound));
return;
}
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IFileSystem>(std::move(filesystem));
rb.PushIpcInterface<IFileSystem>(std::move(filesystem.Unwrap()));
}
void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {

View File

@@ -135,7 +135,7 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
if (next_load_addr) {
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
// Register module with GDBStub
GDBStub::RegisterModule(module, load_addr, next_load_addr - 1);
GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
} else {
next_load_addr = load_addr;
}

View File

@@ -262,7 +262,7 @@ ResultStatus AppLoader_NCA::Load(Kernel::SharedPtr<Kernel::Process>& process) {
if (next_load_addr) {
LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr);
// Register module with GDBStub
GDBStub::RegisterModule(module, load_addr, next_load_addr - 1);
GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false);
} else {
next_load_addr = load_addr;
}

View File

@@ -7,7 +7,6 @@
#include "common/common_funcs.h"
#include "common/file_util.h"
#include "common/logging/log.h"
#include "common/string_util.h"
#include "common/swap.h"
#include "core/core.h"
#include "core/gdbstub/gdbstub.h"
@@ -118,9 +117,7 @@ bool AppLoader_NRO::LoadNro(const std::string& path, VAddr load_base) {
Core::CurrentProcess()->LoadModule(codeset, load_base);
// Register module with GDBStub
std::string filename;
Common::SplitPath(codeset->name, nullptr, &filename, nullptr);
GDBStub::RegisterModule((filename + ".elf").c_str(), load_base, load_base);
GDBStub::RegisterModule(codeset->name, load_base, load_base);
return true;
}

View File

@@ -8,7 +8,6 @@
#include "common/common_funcs.h"
#include "common/file_util.h"
#include "common/logging/log.h"
#include "common/string_util.h"
#include "common/swap.h"
#include "core/core.h"
#include "core/gdbstub/gdbstub.h"
@@ -150,9 +149,7 @@ VAddr AppLoader_NSO::LoadModule(const std::string& name, const std::vector<u8>&
Core::CurrentProcess()->LoadModule(codeset, load_base);
// Register module with GDBStub
std::string filename;
Common::SplitPath(codeset->name, nullptr, &filename, nullptr);
GDBStub::RegisterModule((filename + ".elf").c_str(), load_base, load_base);
GDBStub::RegisterModule(codeset->name, load_base, load_base);
return load_base + image_size;
}