Skip to content

Commit

Permalink
GdbServer: Support 32-bit context definitions
Browse files Browse the repository at this point in the history
Requires restructuring a couple of things, but nothing too crazy here.
  • Loading branch information
Sonicadvance1 committed Dec 12, 2024
1 parent d85153d commit 33c7efa
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 17 deletions.
8 changes: 6 additions & 2 deletions Source/Tools/LinuxEmulation/GdbServer/Info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,17 @@ fextl::string BuildOSXML() {
return xml.str();
}

fextl::string BuildTargetXML() {
fextl::string BuildTargetXML(bool Is64Bit) {
fextl::ostringstream xml;

xml << "<?xml version='1.0'?>\n";
xml << "<!DOCTYPE target SYSTEM 'gdb-target.dtd'>\n";
xml << "<target>\n";
xml << "<architecture>i386:x86-64</architecture>\n";
if (Is64Bit) {
xml << "<architecture>i386:x86-64</architecture>\n";
} else {
xml << "<architecture>i386</architecture>\n";
}
xml << "<osabi>GNU/Linux</osabi>\n";
xml << "<feature name='org.gnu.gdb.i386.core'>\n";

Expand Down
2 changes: 1 addition & 1 deletion Source/Tools/LinuxEmulation/GdbServer/Info.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ fextl::string BuildOSXML();
/**
* @brief Returns the GDB specific construct of target describing XML.
*/
fextl::string BuildTargetXML();
fextl::string BuildTargetXML(bool Is64Bit);
} // namespace FEX::GDB::Info
70 changes: 57 additions & 13 deletions Source/Tools/LinuxEmulation/LinuxSyscalls/GdbServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,19 +109,20 @@ GdbServer::GdbServer(FEXCore::Context::Context* ctx, FEX::HLE::SignalDelegator*
}

auto ThreadObject = FEX::HLE::ThreadManager::GetStateObjectFromFEXCoreThread(Thread);
ThreadObject->GdbInfo.Signal = Signal;
ThreadObject->GdbInfo = {};
ThreadObject->GdbInfo->Signal = Signal;

ThreadObject->GdbInfo.SignalPC = ArchHelpers::Context::GetPc(ucontext);
uint32_t IgnoreMask = Thread->CurrentFrame->InSyscallInfo & 0xFFFF;
this->SignalDelegation->SpillSRA(Thread, ucontext, IgnoreMask);
ThreadObject->GdbInfo->SignalPC = ArchHelpers::Context::GetPc(ucontext);
this->SignalDelegation->SpillSRA(Thread, ucontext, Thread->CurrentFrame->InSyscallInfo);

memcpy(ThreadObject->GdbInfo.GPRs, ArchHelpers::Context::GetArmGPRs(ucontext), sizeof(uint64_t) * 32);
ThreadObject->GdbInfo.PState = ArchHelpers::Context::GetArmPState(ucontext);
memcpy(ThreadObject->GdbInfo->GPRs, ArchHelpers::Context::GetArmGPRs(ucontext), sizeof(ThreadObject->GdbInfo->GPRs));
ThreadObject->GdbInfo->PState = ArchHelpers::Context::GetArmPState(ucontext);

// Let GDB know that we have a signal
this->Break(Thread, Signal);

WaitForThreadWakeup();
ThreadObject->GdbInfo.reset();

return true;
},
Expand Down Expand Up @@ -156,6 +157,10 @@ static fextl::string hexstring(fextl::istringstream& ss, int delm) {
return ret;
}

static std::string appendHex(const unsigned char* data, size_t length) {
return fmt::format("{:#02x}", fmt::join(data, data + length, ""));
}

static fextl::string encodeHex(const unsigned char* data, size_t length) {
fextl::ostringstream ss;

Expand Down Expand Up @@ -282,7 +287,6 @@ const FEX::HLE::ThreadStateObject* GdbServer::FindThreadByTID(uint32_t TID) {
return Threads->at(0);
}


GdbServer::GDBContextDefinition GdbServer::GenerateContextDefinition(const FEX::HLE::ThreadStateObject* ThreadObject) {
GDBContextDefinition GDB {};
FEXCore::Core::CPUState state {};
Expand All @@ -292,9 +296,16 @@ GdbServer::GDBContextDefinition GdbServer::GenerateContextDefinition(const FEX::

// Encode the GDB context definition
memcpy(&GDB.gregs[0], &state.gregs[0], sizeof(GDB.gregs));
memcpy(&GDB.rip, &state.rip, sizeof(GDB.rip));
if (ThreadObject->GdbInfo.has_value()) {
GDB.rip = CTX->RestoreRIPFromHostPC(ThreadObject->Thread, ThreadObject->GdbInfo->SignalPC);

GDB.eflags = CTX->ReconstructCompactedEFLAGS(ThreadObject->Thread, false, nullptr, 0);
const bool WasInJIT = CTX->IsAddressInCodeBuffer(ThreadObject->Thread, ThreadObject->GdbInfo->SignalPC);
GDB.eflags = CTX->ReconstructCompactedEFLAGS(ThreadObject->Thread, WasInJIT, const_cast<uint64_t*>(ThreadObject->GdbInfo->GPRs),
ThreadObject->GdbInfo->PState);
} else {
GDB.rip = ThreadObject->Thread->CurrentFrame->State.rip;
GDB.eflags = CTX->ReconstructCompactedEFLAGS(ThreadObject->Thread, false, nullptr, 0);
}

for (size_t i = 0; i < FEXCore::Core::CPUState::NUM_MMS; ++i) {
memcpy(&GDB.mm[i], &state.mm[i], sizeof(GDB.mm[i]));
Expand All @@ -313,8 +324,8 @@ GdbServer::GDBContextDefinition GdbServer::GenerateContextDefinition(const FEX::

CTX->ReconstructXMMRegisters(ThreadObject->Thread, XMM_Low, YMM_High);
for (size_t i = 0; i < FEXCore::Core::CPUState::NUM_XMMS; ++i) {
memcpy(&GDB.xmm[0], &XMM_Low[i], sizeof(__uint128_t));
memcpy(&GDB.xmm[2], &YMM_High[i], sizeof(__uint128_t));
memcpy(&GDB.xmm[i][0], &XMM_Low[i], sizeof(__uint128_t));
memcpy(&GDB.xmm[i][2], &YMM_High[i], sizeof(__uint128_t));
}

return GDB;
Expand Down Expand Up @@ -417,7 +428,7 @@ GdbServer::HandledPacketType GdbServer::XferCommandExecFile(const fextl::string&

GdbServer::HandledPacketType GdbServer::XferCommandFeatures(const fextl::string& annex, int offset, int length) {
if (annex == "target.xml") {
return {EncodeXferString(GDB::Info::BuildTargetXML(), offset, length), HandledPacketType::TYPE_ACK};
return {EncodeXferString(GDB::Info::BuildTargetXML(Is64BitMode()), offset, length), HandledPacketType::TYPE_ACK};
}

return {"E00", HandledPacketType::TYPE_ACK};
Expand Down Expand Up @@ -650,8 +661,41 @@ GdbServer::HandledPacketType GdbServer::CommandReadRegisters(const fextl::string
// Pause up front
SyscallHandler->TM.Pause();
const FEX::HLE::ThreadStateObject* CurrentThread = FindThreadByTID(CurrentDebuggingThread);
const size_t NumGPR = Is64BitMode() ? FEXCore::Core::CPUState::NUM_GPRS : FEXCore::Core::CPUState::NUM_GPRS / 2;
const size_t GPRSize = Is64BitMode() ? sizeof(uint64_t) : sizeof(uint32_t);
const size_t NumXMM = Is64BitMode() ? FEXCore::Core::CPUState::NUM_XMMS : FEXCore::Core::CPUState::NUM_XMMS / 2;
const size_t XMMSize = Is64BitMode() ? sizeof(__uint128_t) * 2 : sizeof(__uint128_t);
fextl::string str;
auto GDB = GenerateContextDefinition(CurrentThread);
return {encodeHex((unsigned char*)&GDB, sizeof(GDBContextDefinition)), HandledPacketType::TYPE_ACK};
for (size_t i = 0; i < NumGPR; ++i) {
str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.gregs[i]), GPRSize);
}
str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.rip), GPRSize);
str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.eflags), sizeof(uint32_t));

str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.cs), sizeof(uint32_t));
str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.ss), sizeof(uint32_t));
str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.ds), sizeof(uint32_t));
str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.es), sizeof(uint32_t));
str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.fs), sizeof(uint32_t));
str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.gs), sizeof(uint32_t));
for (auto& mm : GDB.mm) {
str += appendHex(reinterpret_cast<const unsigned char*>(&mm), sizeof(X80Float));
}

str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.fctrl), sizeof(uint32_t));
str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.fstat), sizeof(uint32_t));
for (auto& dummy : GDB.dummies) {
str += appendHex(reinterpret_cast<const unsigned char*>(&dummy), sizeof(uint32_t));
}

for (size_t i = 0; i < NumXMM; ++i) {
str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.xmm[i]), XMMSize);
}

str += appendHex(reinterpret_cast<const unsigned char*>(&GDB.mxcsr), sizeof(uint32_t));

return {str, HandledPacketType::TYPE_ACK};
}

GdbServer::HandledPacketType GdbServer::CommandThreadOp(const fextl::string& packet) {
Expand Down
3 changes: 2 additions & 1 deletion Source/Tools/LinuxEmulation/LinuxSyscalls/ThreadManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ struct ThreadStateObject : public FEXCore::Allocator::FEXAllocOperators {
uint64_t SignalPC {};
uint64_t GPRs[32];
uint64_t PState {};
} GdbInfo;
};
std::optional<GdbInfoStruct> GdbInfo;

int StatusCode {};
};
Expand Down

0 comments on commit 33c7efa

Please sign in to comment.