Partial thread data plumbing.
This commit is contained in:
parent
aae45515ae
commit
b750370759
|
@ -312,6 +312,7 @@ namespace Xenia.Debug {
|
||||||
private async Task CompleteRunStateTransition(RunState newRunState) {
|
private async Task CompleteRunStateTransition(RunState newRunState) {
|
||||||
await Task.WhenAll(new Task[] {
|
await Task.WhenAll(new Task[] {
|
||||||
ModuleList.Invalidate(),
|
ModuleList.Invalidate(),
|
||||||
|
ThreadList.Invalidate(),
|
||||||
});
|
});
|
||||||
|
|
||||||
CurrentContext.SetRunState(newRunState);
|
CurrentContext.SetRunState(newRunState);
|
||||||
|
|
|
@ -10,8 +10,21 @@ public sealed class ListThreadsResponse : Table {
|
||||||
public static ListThreadsResponse GetRootAsListThreadsResponse(ByteBuffer _bb, ListThreadsResponse obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
public static ListThreadsResponse GetRootAsListThreadsResponse(ByteBuffer _bb, ListThreadsResponse obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||||
public ListThreadsResponse __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
public ListThreadsResponse __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||||
|
|
||||||
|
public Thread GetThread(int j) { return GetThread(new Thread(), j); }
|
||||||
|
public Thread GetThread(Thread obj, int j) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
|
||||||
|
public int ThreadLength { get { int o = __offset(4); return o != 0 ? __vector_len(o) : 0; } }
|
||||||
|
|
||||||
public static void StartListThreadsResponse(FlatBufferBuilder builder) { builder.StartObject(0); }
|
public static int CreateListThreadsResponse(FlatBufferBuilder builder,
|
||||||
|
int thread = 0) {
|
||||||
|
builder.StartObject(1);
|
||||||
|
ListThreadsResponse.AddThread(builder, thread);
|
||||||
|
return ListThreadsResponse.EndListThreadsResponse(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void StartListThreadsResponse(FlatBufferBuilder builder) { builder.StartObject(1); }
|
||||||
|
public static void AddThread(FlatBufferBuilder builder, int threadOffset) { builder.AddOffset(0, threadOffset, 0); }
|
||||||
|
public static int CreateThreadVector(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i]); return builder.EndVector(); }
|
||||||
|
public static void StartThreadVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
|
||||||
public static int EndListThreadsResponse(FlatBufferBuilder builder) {
|
public static int EndListThreadsResponse(FlatBufferBuilder builder) {
|
||||||
int o = builder.EndObject();
|
int o = builder.EndObject();
|
||||||
return o;
|
return o;
|
||||||
|
|
|
@ -15,10 +15,11 @@ public enum RequestData : byte
|
||||||
GetModuleRequest = 7,
|
GetModuleRequest = 7,
|
||||||
ListFunctionsRequest = 8,
|
ListFunctionsRequest = 8,
|
||||||
GetFunctionRequest = 9,
|
GetFunctionRequest = 9,
|
||||||
StopRequest = 10,
|
ListThreadsRequest = 10,
|
||||||
BreakRequest = 11,
|
StopRequest = 11,
|
||||||
ContinueRequest = 12,
|
BreakRequest = 12,
|
||||||
StepRequest = 13,
|
ContinueRequest = 13,
|
||||||
|
StepRequest = 14,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,12 +15,13 @@ public enum ResponseData : byte
|
||||||
GetModuleResponse = 7,
|
GetModuleResponse = 7,
|
||||||
ListFunctionsResponse = 8,
|
ListFunctionsResponse = 8,
|
||||||
GetFunctionResponse = 9,
|
GetFunctionResponse = 9,
|
||||||
StopResponse = 10,
|
ListThreadsResponse = 10,
|
||||||
BreakResponse = 11,
|
StopResponse = 11,
|
||||||
ContinueResponse = 12,
|
BreakResponse = 12,
|
||||||
StepResponse = 13,
|
ContinueResponse = 13,
|
||||||
BreakpointEvent = 14,
|
StepResponse = 14,
|
||||||
AccessViolationEvent = 15,
|
BreakpointEvent = 15,
|
||||||
|
AccessViolationEvent = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,36 @@ public sealed class Thread : Table {
|
||||||
public XObject Object { get { return GetObject(new XObject()); } }
|
public XObject Object { get { return GetObject(new XObject()); } }
|
||||||
public XObject GetObject(XObject obj) { int o = __offset(4); return o != 0 ? obj.__init(o + bb_pos, bb) : null; }
|
public XObject GetObject(XObject obj) { int o = __offset(4); return o != 0 ? obj.__init(o + bb_pos, bb) : null; }
|
||||||
public ThreadType Type { get { int o = __offset(6); return o != 0 ? (ThreadType)bb.GetSbyte(o + bb_pos) : (ThreadType)0; } }
|
public ThreadType Type { get { int o = __offset(6); return o != 0 ? (ThreadType)bb.GetSbyte(o + bb_pos) : (ThreadType)0; } }
|
||||||
|
public uint StackSize { get { int o = __offset(8); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||||
|
public uint XapiThreadStartup { get { int o = __offset(10); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||||
|
public uint StartAddress { get { int o = __offset(12); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||||
|
public uint StartContext { get { int o = __offset(14); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||||
|
public uint CreationFlags { get { int o = __offset(16); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||||
|
public uint TlsAddress { get { int o = __offset(18); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||||
|
public uint PcrAddress { get { int o = __offset(20); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||||
|
public uint ThreadStateAddress { get { int o = __offset(22); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||||
|
public uint ThreadId { get { int o = __offset(24); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||||
|
public string Name { get { int o = __offset(26); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||||
|
public uint Priority { get { int o = __offset(28); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||||
|
public uint Affinity { get { int o = __offset(30); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||||
|
public uint State { get { int o = __offset(32); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||||
|
|
||||||
public static void StartThread(FlatBufferBuilder builder) { builder.StartObject(2); }
|
public static void StartThread(FlatBufferBuilder builder) { builder.StartObject(15); }
|
||||||
public static void AddObject(FlatBufferBuilder builder, int objectOffset) { builder.AddStruct(0, objectOffset, 0); }
|
public static void AddObject(FlatBufferBuilder builder, int objectOffset) { builder.AddStruct(0, objectOffset, 0); }
|
||||||
public static void AddType(FlatBufferBuilder builder, ThreadType type) { builder.AddSbyte(1, (sbyte)(type), 0); }
|
public static void AddType(FlatBufferBuilder builder, ThreadType type) { builder.AddSbyte(1, (sbyte)(type), 0); }
|
||||||
|
public static void AddStackSize(FlatBufferBuilder builder, uint stackSize) { builder.AddUint(2, stackSize, 0); }
|
||||||
|
public static void AddXapiThreadStartup(FlatBufferBuilder builder, uint xapiThreadStartup) { builder.AddUint(3, xapiThreadStartup, 0); }
|
||||||
|
public static void AddStartAddress(FlatBufferBuilder builder, uint startAddress) { builder.AddUint(4, startAddress, 0); }
|
||||||
|
public static void AddStartContext(FlatBufferBuilder builder, uint startContext) { builder.AddUint(5, startContext, 0); }
|
||||||
|
public static void AddCreationFlags(FlatBufferBuilder builder, uint creationFlags) { builder.AddUint(6, creationFlags, 0); }
|
||||||
|
public static void AddTlsAddress(FlatBufferBuilder builder, uint tlsAddress) { builder.AddUint(7, tlsAddress, 0); }
|
||||||
|
public static void AddPcrAddress(FlatBufferBuilder builder, uint pcrAddress) { builder.AddUint(8, pcrAddress, 0); }
|
||||||
|
public static void AddThreadStateAddress(FlatBufferBuilder builder, uint threadStateAddress) { builder.AddUint(9, threadStateAddress, 0); }
|
||||||
|
public static void AddThreadId(FlatBufferBuilder builder, uint threadId) { builder.AddUint(10, threadId, 0); }
|
||||||
|
public static void AddName(FlatBufferBuilder builder, int nameOffset) { builder.AddOffset(11, nameOffset, 0); }
|
||||||
|
public static void AddPriority(FlatBufferBuilder builder, uint priority) { builder.AddUint(12, priority, 0); }
|
||||||
|
public static void AddAffinity(FlatBufferBuilder builder, uint affinity) { builder.AddUint(13, affinity, 0); }
|
||||||
|
public static void AddState(FlatBufferBuilder builder, uint state) { builder.AddUint(14, state, 0); }
|
||||||
public static int EndThread(FlatBufferBuilder builder) {
|
public static int EndThread(FlatBufferBuilder builder) {
|
||||||
int o = builder.EndObject();
|
int o = builder.EndObject();
|
||||||
return o;
|
return o;
|
||||||
|
|
|
@ -13,6 +13,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using xe.debug.proto;
|
||||||
using Xenia.Debug.Utilities;
|
using Xenia.Debug.Utilities;
|
||||||
|
|
||||||
namespace Xenia.Debug {
|
namespace Xenia.Debug {
|
||||||
|
@ -25,6 +26,23 @@ namespace Xenia.Debug {
|
||||||
this.debugger = debugger;
|
this.debugger = debugger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task Invalidate() {
|
||||||
|
var fbb = debugger.BeginRequest();
|
||||||
|
ListThreadsRequest.StartListThreadsRequest(fbb);
|
||||||
|
int requestDataOffset = ListThreadsRequest.EndListThreadsRequest(fbb);
|
||||||
|
var response = await debugger.CommitRequest(
|
||||||
|
fbb, RequestData.ListThreadsRequest, requestDataOffset);
|
||||||
|
ListThreadsResponse responseData = new ListThreadsResponse();
|
||||||
|
response.GetResponseData(responseData);
|
||||||
|
|
||||||
|
for (int i = 0; i < responseData.ThreadLength; ++i) {
|
||||||
|
var threadData = responseData.GetThread(i);
|
||||||
|
// threadData.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
OnChanged();
|
||||||
|
}
|
||||||
|
|
||||||
public int Count {
|
public int Count {
|
||||||
get {
|
get {
|
||||||
return threads.Count;
|
return threads.Count;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "xenia/debug/proto/control_generated.h"
|
#include "xenia/debug/proto/control_generated.h"
|
||||||
#include "xenia/debug/proto/messages_generated.h"
|
#include "xenia/debug/proto/messages_generated.h"
|
||||||
#include "xenia/debug/proto/modules_generated.h"
|
#include "xenia/debug/proto/modules_generated.h"
|
||||||
|
#include "xenia/debug/proto/threads_generated.h"
|
||||||
|
|
||||||
DEFINE_string(debug_session_path, "", "Debug output path.");
|
DEFINE_string(debug_session_path, "", "Debug output path.");
|
||||||
DEFINE_int32(debug_port, 19000, "Port the debugger listens on.");
|
DEFINE_int32(debug_port, 19000, "Port the debugger listens on.");
|
||||||
|
@ -400,6 +401,38 @@ void Debugger::OnMessage(std::vector<uint8_t> buffer) {
|
||||||
response_data_offset = response_data.Finish().Union();
|
response_data_offset = response_data.Finish().Union();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case proto::RequestData_ListThreadsRequest: {
|
||||||
|
response_data_type = proto::ResponseData_ListThreadsResponse;
|
||||||
|
auto threads =
|
||||||
|
emulator()->kernel_state()->object_table()->GetObjectsByType<XThread>(
|
||||||
|
XObject::kTypeThread);
|
||||||
|
std::vector<flatbuffers::Offset<proto::Thread>> thread_list;
|
||||||
|
for (size_t i = 0; i < threads.size(); ++i) {
|
||||||
|
auto& thread = threads[i];
|
||||||
|
auto thread_name_string = fbb.CreateString(thread->name());
|
||||||
|
auto thread_builder = proto::ThreadBuilder(fbb);
|
||||||
|
// thread_builder.add_type();
|
||||||
|
// thread_builder.add_stack_size();
|
||||||
|
// thread_builder.add_xapi_thread_startup();
|
||||||
|
// thread_builder.add_start_address();
|
||||||
|
// thread_builder.add_start_context();
|
||||||
|
// thread_builder.add_creation_flags();
|
||||||
|
thread_builder.add_tls_address(thread->tls_ptr());
|
||||||
|
thread_builder.add_pcr_address(thread->pcr_ptr());
|
||||||
|
thread_builder.add_thread_state_address(thread->thread_state_ptr());
|
||||||
|
thread_builder.add_thread_id(thread->thread_id());
|
||||||
|
thread_builder.add_name(thread_name_string);
|
||||||
|
thread_builder.add_priority(thread->priority());
|
||||||
|
thread_builder.add_affinity(thread->affinity());
|
||||||
|
// thread_builder.add_state(thread->);
|
||||||
|
thread_list.push_back(thread_builder.Finish());
|
||||||
|
}
|
||||||
|
auto threads_offset = fbb.CreateVector(thread_list);
|
||||||
|
auto response_data = proto::ListThreadsResponseBuilder(fbb);
|
||||||
|
response_data.add_thread(threads_offset);
|
||||||
|
response_data_offset = response_data.Finish().Union();
|
||||||
|
} break;
|
||||||
|
|
||||||
case proto::RequestData_StopRequest: {
|
case proto::RequestData_StopRequest: {
|
||||||
response_data_type = proto::ResponseData_StopResponse;
|
response_data_type = proto::ResponseData_StopResponse;
|
||||||
auto response_data = proto::StopResponseBuilder(fbb);
|
auto response_data = proto::StopResponseBuilder(fbb);
|
||||||
|
|
|
@ -31,6 +31,8 @@ union RequestData {
|
||||||
ListFunctionsRequest,
|
ListFunctionsRequest,
|
||||||
GetFunctionRequest,
|
GetFunctionRequest,
|
||||||
|
|
||||||
|
ListThreadsRequest,
|
||||||
|
|
||||||
StopRequest,
|
StopRequest,
|
||||||
BreakRequest,
|
BreakRequest,
|
||||||
ContinueRequest,
|
ContinueRequest,
|
||||||
|
@ -55,6 +57,8 @@ union ResponseData {
|
||||||
ListFunctionsResponse,
|
ListFunctionsResponse,
|
||||||
GetFunctionResponse,
|
GetFunctionResponse,
|
||||||
|
|
||||||
|
ListThreadsResponse,
|
||||||
|
|
||||||
StopResponse,
|
StopResponse,
|
||||||
BreakResponse,
|
BreakResponse,
|
||||||
ContinueResponse,
|
ContinueResponse,
|
||||||
|
|
|
@ -91,14 +91,23 @@ enum RequestData {
|
||||||
RequestData_GetModuleRequest = 7,
|
RequestData_GetModuleRequest = 7,
|
||||||
RequestData_ListFunctionsRequest = 8,
|
RequestData_ListFunctionsRequest = 8,
|
||||||
RequestData_GetFunctionRequest = 9,
|
RequestData_GetFunctionRequest = 9,
|
||||||
RequestData_StopRequest = 10,
|
RequestData_ListThreadsRequest = 10,
|
||||||
RequestData_BreakRequest = 11,
|
RequestData_StopRequest = 11,
|
||||||
RequestData_ContinueRequest = 12,
|
RequestData_BreakRequest = 12,
|
||||||
RequestData_StepRequest = 13
|
RequestData_ContinueRequest = 13,
|
||||||
|
RequestData_StepRequest = 14
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const char **EnumNamesRequestData() {
|
inline const char **EnumNamesRequestData() {
|
||||||
static const char *names[] = { "NONE", "AttachRequest", "ListBreakpointsRequest", "AddBreakpointsRequest", "UpdateBreakpointsRequest", "RemoveBreakpointsRequest", "ListModulesRequest", "GetModuleRequest", "ListFunctionsRequest", "GetFunctionRequest", "StopRequest", "BreakRequest", "ContinueRequest", "StepRequest", nullptr };
|
static const char *names[] = {
|
||||||
|
"NONE", "AttachRequest",
|
||||||
|
"ListBreakpointsRequest", "AddBreakpointsRequest",
|
||||||
|
"UpdateBreakpointsRequest", "RemoveBreakpointsRequest",
|
||||||
|
"ListModulesRequest", "GetModuleRequest",
|
||||||
|
"ListFunctionsRequest", "GetFunctionRequest",
|
||||||
|
"ListThreadsRequest", "StopRequest",
|
||||||
|
"BreakRequest", "ContinueRequest",
|
||||||
|
"StepRequest", nullptr};
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,16 +126,26 @@ enum ResponseData {
|
||||||
ResponseData_GetModuleResponse = 7,
|
ResponseData_GetModuleResponse = 7,
|
||||||
ResponseData_ListFunctionsResponse = 8,
|
ResponseData_ListFunctionsResponse = 8,
|
||||||
ResponseData_GetFunctionResponse = 9,
|
ResponseData_GetFunctionResponse = 9,
|
||||||
ResponseData_StopResponse = 10,
|
ResponseData_ListThreadsResponse = 10,
|
||||||
ResponseData_BreakResponse = 11,
|
ResponseData_StopResponse = 11,
|
||||||
ResponseData_ContinueResponse = 12,
|
ResponseData_BreakResponse = 12,
|
||||||
ResponseData_StepResponse = 13,
|
ResponseData_ContinueResponse = 13,
|
||||||
ResponseData_BreakpointEvent = 14,
|
ResponseData_StepResponse = 14,
|
||||||
ResponseData_AccessViolationEvent = 15
|
ResponseData_BreakpointEvent = 15,
|
||||||
|
ResponseData_AccessViolationEvent = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const char **EnumNamesResponseData() {
|
inline const char **EnumNamesResponseData() {
|
||||||
static const char *names[] = { "NONE", "AttachResponse", "ListBreakpointsResponse", "AddBreakpointsResponse", "UpdateBreakpointsResponse", "RemoveBreakpointsResponse", "ListModulesResponse", "GetModuleResponse", "ListFunctionsResponse", "GetFunctionResponse", "StopResponse", "BreakResponse", "ContinueResponse", "StepResponse", "BreakpointEvent", "AccessViolationEvent", nullptr };
|
static const char *names[] = {
|
||||||
|
"NONE", "AttachResponse",
|
||||||
|
"ListBreakpointsResponse", "AddBreakpointsResponse",
|
||||||
|
"UpdateBreakpointsResponse", "RemoveBreakpointsResponse",
|
||||||
|
"ListModulesResponse", "GetModuleResponse",
|
||||||
|
"ListFunctionsResponse", "GetFunctionResponse",
|
||||||
|
"ListThreadsResponse", "StopResponse",
|
||||||
|
"BreakResponse", "ContinueResponse",
|
||||||
|
"StepResponse", "BreakpointEvent",
|
||||||
|
"AccessViolationEvent", nullptr};
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,6 +323,10 @@ inline bool VerifyRequestData(flatbuffers::Verifier &verifier, const void *union
|
||||||
case RequestData_GetModuleRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::GetModuleRequest *>(union_obj));
|
case RequestData_GetModuleRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::GetModuleRequest *>(union_obj));
|
||||||
case RequestData_ListFunctionsRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::ListFunctionsRequest *>(union_obj));
|
case RequestData_ListFunctionsRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::ListFunctionsRequest *>(union_obj));
|
||||||
case RequestData_GetFunctionRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::GetFunctionRequest *>(union_obj));
|
case RequestData_GetFunctionRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::GetFunctionRequest *>(union_obj));
|
||||||
|
case RequestData_ListThreadsRequest:
|
||||||
|
return verifier.VerifyTable(
|
||||||
|
reinterpret_cast<const xe::debug::proto::ListThreadsRequest *>(
|
||||||
|
union_obj));
|
||||||
case RequestData_StopRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::StopRequest *>(union_obj));
|
case RequestData_StopRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::StopRequest *>(union_obj));
|
||||||
case RequestData_BreakRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::BreakRequest *>(union_obj));
|
case RequestData_BreakRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::BreakRequest *>(union_obj));
|
||||||
case RequestData_ContinueRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::ContinueRequest *>(union_obj));
|
case RequestData_ContinueRequest: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::ContinueRequest *>(union_obj));
|
||||||
|
@ -324,6 +347,10 @@ inline bool VerifyResponseData(flatbuffers::Verifier &verifier, const void *unio
|
||||||
case ResponseData_GetModuleResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::GetModuleResponse *>(union_obj));
|
case ResponseData_GetModuleResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::GetModuleResponse *>(union_obj));
|
||||||
case ResponseData_ListFunctionsResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::ListFunctionsResponse *>(union_obj));
|
case ResponseData_ListFunctionsResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::ListFunctionsResponse *>(union_obj));
|
||||||
case ResponseData_GetFunctionResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::GetFunctionResponse *>(union_obj));
|
case ResponseData_GetFunctionResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::GetFunctionResponse *>(union_obj));
|
||||||
|
case ResponseData_ListThreadsResponse:
|
||||||
|
return verifier.VerifyTable(
|
||||||
|
reinterpret_cast<const xe::debug::proto::ListThreadsResponse *>(
|
||||||
|
union_obj));
|
||||||
case ResponseData_StopResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::StopResponse *>(union_obj));
|
case ResponseData_StopResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::StopResponse *>(union_obj));
|
||||||
case ResponseData_BreakResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::BreakResponse *>(union_obj));
|
case ResponseData_BreakResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::BreakResponse *>(union_obj));
|
||||||
case ResponseData_ContinueResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::ContinueResponse *>(union_obj));
|
case ResponseData_ContinueResponse: return verifier.VerifyTable(reinterpret_cast<const xe::debug::proto::ContinueResponse *>(union_obj));
|
||||||
|
|
|
@ -13,9 +13,26 @@ table Thread {
|
||||||
|
|
||||||
// module_id:uint;
|
// module_id:uint;
|
||||||
// creation callstack
|
// creation callstack
|
||||||
|
|
||||||
|
stack_size:uint;
|
||||||
|
xapi_thread_startup:uint;
|
||||||
|
start_address:uint;
|
||||||
|
start_context:uint;
|
||||||
|
creation_flags:uint;
|
||||||
|
|
||||||
|
tls_address:uint;
|
||||||
|
pcr_address:uint;
|
||||||
|
thread_state_address:uint;
|
||||||
|
thread_id:uint;
|
||||||
|
name:string;
|
||||||
|
|
||||||
|
priority:uint;
|
||||||
|
affinity:uint;
|
||||||
|
state:uint;
|
||||||
}
|
}
|
||||||
|
|
||||||
table ListThreadsRequest {
|
table ListThreadsRequest {
|
||||||
}
|
}
|
||||||
table ListThreadsResponse {
|
table ListThreadsResponse {
|
||||||
|
thread:[Thread];
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,10 +36,39 @@ inline const char *EnumNameThreadType(ThreadType e) { return EnumNamesThreadType
|
||||||
struct Thread FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
struct Thread FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
const xe::debug::proto::XObject *object() const { return GetStruct<const xe::debug::proto::XObject *>(4); }
|
const xe::debug::proto::XObject *object() const { return GetStruct<const xe::debug::proto::XObject *>(4); }
|
||||||
ThreadType type() const { return static_cast<ThreadType>(GetField<int8_t>(6, 0)); }
|
ThreadType type() const { return static_cast<ThreadType>(GetField<int8_t>(6, 0)); }
|
||||||
|
uint32_t stack_size() const { return GetField<uint32_t>(8, 0); }
|
||||||
|
uint32_t xapi_thread_startup() const { return GetField<uint32_t>(10, 0); }
|
||||||
|
uint32_t start_address() const { return GetField<uint32_t>(12, 0); }
|
||||||
|
uint32_t start_context() const { return GetField<uint32_t>(14, 0); }
|
||||||
|
uint32_t creation_flags() const { return GetField<uint32_t>(16, 0); }
|
||||||
|
uint32_t tls_address() const { return GetField<uint32_t>(18, 0); }
|
||||||
|
uint32_t pcr_address() const { return GetField<uint32_t>(20, 0); }
|
||||||
|
uint32_t thread_state_address() const { return GetField<uint32_t>(22, 0); }
|
||||||
|
uint32_t thread_id() const { return GetField<uint32_t>(24, 0); }
|
||||||
|
const flatbuffers::String *name() const {
|
||||||
|
return GetPointer<const flatbuffers::String *>(26);
|
||||||
|
}
|
||||||
|
uint32_t priority() const { return GetField<uint32_t>(28, 0); }
|
||||||
|
uint32_t affinity() const { return GetField<uint32_t>(30, 0); }
|
||||||
|
uint32_t state() const { return GetField<uint32_t>(32, 0); }
|
||||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||||
return VerifyTableStart(verifier) &&
|
return VerifyTableStart(verifier) &&
|
||||||
VerifyField<xe::debug::proto::XObject>(verifier, 4 /* object */) &&
|
VerifyField<xe::debug::proto::XObject>(verifier, 4 /* object */) &&
|
||||||
VerifyField<int8_t>(verifier, 6 /* type */) &&
|
VerifyField<int8_t>(verifier, 6 /* type */) &&
|
||||||
|
VerifyField<uint32_t>(verifier, 8 /* stack_size */) &&
|
||||||
|
VerifyField<uint32_t>(verifier, 10 /* xapi_thread_startup */) &&
|
||||||
|
VerifyField<uint32_t>(verifier, 12 /* start_address */) &&
|
||||||
|
VerifyField<uint32_t>(verifier, 14 /* start_context */) &&
|
||||||
|
VerifyField<uint32_t>(verifier, 16 /* creation_flags */) &&
|
||||||
|
VerifyField<uint32_t>(verifier, 18 /* tls_address */) &&
|
||||||
|
VerifyField<uint32_t>(verifier, 20 /* pcr_address */) &&
|
||||||
|
VerifyField<uint32_t>(verifier, 22 /* thread_state_address */) &&
|
||||||
|
VerifyField<uint32_t>(verifier, 24 /* thread_id */) &&
|
||||||
|
VerifyField<flatbuffers::uoffset_t>(verifier, 26 /* name */) &&
|
||||||
|
verifier.Verify(name()) &&
|
||||||
|
VerifyField<uint32_t>(verifier, 28 /* priority */) &&
|
||||||
|
VerifyField<uint32_t>(verifier, 30 /* affinity */) &&
|
||||||
|
VerifyField<uint32_t>(verifier, 32 /* state */) &&
|
||||||
verifier.EndTable();
|
verifier.EndTable();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -49,18 +78,75 @@ struct ThreadBuilder {
|
||||||
flatbuffers::uoffset_t start_;
|
flatbuffers::uoffset_t start_;
|
||||||
void add_object(const xe::debug::proto::XObject *object) { fbb_.AddStruct(4, object); }
|
void add_object(const xe::debug::proto::XObject *object) { fbb_.AddStruct(4, object); }
|
||||||
void add_type(ThreadType type) { fbb_.AddElement<int8_t>(6, static_cast<int8_t>(type), 0); }
|
void add_type(ThreadType type) { fbb_.AddElement<int8_t>(6, static_cast<int8_t>(type), 0); }
|
||||||
|
void add_stack_size(uint32_t stack_size) {
|
||||||
|
fbb_.AddElement<uint32_t>(8, stack_size, 0);
|
||||||
|
}
|
||||||
|
void add_xapi_thread_startup(uint32_t xapi_thread_startup) {
|
||||||
|
fbb_.AddElement<uint32_t>(10, xapi_thread_startup, 0);
|
||||||
|
}
|
||||||
|
void add_start_address(uint32_t start_address) {
|
||||||
|
fbb_.AddElement<uint32_t>(12, start_address, 0);
|
||||||
|
}
|
||||||
|
void add_start_context(uint32_t start_context) {
|
||||||
|
fbb_.AddElement<uint32_t>(14, start_context, 0);
|
||||||
|
}
|
||||||
|
void add_creation_flags(uint32_t creation_flags) {
|
||||||
|
fbb_.AddElement<uint32_t>(16, creation_flags, 0);
|
||||||
|
}
|
||||||
|
void add_tls_address(uint32_t tls_address) {
|
||||||
|
fbb_.AddElement<uint32_t>(18, tls_address, 0);
|
||||||
|
}
|
||||||
|
void add_pcr_address(uint32_t pcr_address) {
|
||||||
|
fbb_.AddElement<uint32_t>(20, pcr_address, 0);
|
||||||
|
}
|
||||||
|
void add_thread_state_address(uint32_t thread_state_address) {
|
||||||
|
fbb_.AddElement<uint32_t>(22, thread_state_address, 0);
|
||||||
|
}
|
||||||
|
void add_thread_id(uint32_t thread_id) {
|
||||||
|
fbb_.AddElement<uint32_t>(24, thread_id, 0);
|
||||||
|
}
|
||||||
|
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
||||||
|
fbb_.AddOffset(26, name);
|
||||||
|
}
|
||||||
|
void add_priority(uint32_t priority) {
|
||||||
|
fbb_.AddElement<uint32_t>(28, priority, 0);
|
||||||
|
}
|
||||||
|
void add_affinity(uint32_t affinity) {
|
||||||
|
fbb_.AddElement<uint32_t>(30, affinity, 0);
|
||||||
|
}
|
||||||
|
void add_state(uint32_t state) { fbb_.AddElement<uint32_t>(32, state, 0); }
|
||||||
ThreadBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
ThreadBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||||
ThreadBuilder &operator=(const ThreadBuilder &);
|
ThreadBuilder &operator=(const ThreadBuilder &);
|
||||||
flatbuffers::Offset<Thread> Finish() {
|
flatbuffers::Offset<Thread> Finish() {
|
||||||
auto o = flatbuffers::Offset<Thread>(fbb_.EndTable(start_, 2));
|
auto o = flatbuffers::Offset<Thread>(fbb_.EndTable(start_, 15));
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline flatbuffers::Offset<Thread> CreateThread(flatbuffers::FlatBufferBuilder &_fbb,
|
inline flatbuffers::Offset<Thread> CreateThread(
|
||||||
const xe::debug::proto::XObject *object = 0,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
ThreadType type = ThreadType_Kernel) {
|
const xe::debug::proto::XObject *object = 0,
|
||||||
|
ThreadType type = ThreadType_Kernel, uint32_t stack_size = 0,
|
||||||
|
uint32_t xapi_thread_startup = 0, uint32_t start_address = 0,
|
||||||
|
uint32_t start_context = 0, uint32_t creation_flags = 0,
|
||||||
|
uint32_t tls_address = 0, uint32_t pcr_address = 0,
|
||||||
|
uint32_t thread_state_address = 0, uint32_t thread_id = 0,
|
||||||
|
flatbuffers::Offset<flatbuffers::String> name = 0, uint32_t priority = 0,
|
||||||
|
uint32_t affinity = 0, uint32_t state = 0) {
|
||||||
ThreadBuilder builder_(_fbb);
|
ThreadBuilder builder_(_fbb);
|
||||||
|
builder_.add_state(state);
|
||||||
|
builder_.add_affinity(affinity);
|
||||||
|
builder_.add_priority(priority);
|
||||||
|
builder_.add_name(name);
|
||||||
|
builder_.add_thread_id(thread_id);
|
||||||
|
builder_.add_thread_state_address(thread_state_address);
|
||||||
|
builder_.add_pcr_address(pcr_address);
|
||||||
|
builder_.add_tls_address(tls_address);
|
||||||
|
builder_.add_creation_flags(creation_flags);
|
||||||
|
builder_.add_start_context(start_context);
|
||||||
|
builder_.add_start_address(start_address);
|
||||||
|
builder_.add_xapi_thread_startup(xapi_thread_startup);
|
||||||
|
builder_.add_stack_size(stack_size);
|
||||||
builder_.add_object(object);
|
builder_.add_object(object);
|
||||||
builder_.add_type(type);
|
builder_.add_type(type);
|
||||||
return builder_.Finish();
|
return builder_.Finish();
|
||||||
|
@ -90,25 +176,39 @@ inline flatbuffers::Offset<ListThreadsRequest> CreateListThreadsRequest(flatbuff
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ListThreadsResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
struct ListThreadsResponse FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
|
const flatbuffers::Vector<flatbuffers::Offset<Thread>> *thread() const {
|
||||||
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Thread>> *>(
|
||||||
|
4);
|
||||||
|
}
|
||||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||||
return VerifyTableStart(verifier) &&
|
return VerifyTableStart(verifier) &&
|
||||||
verifier.EndTable();
|
VerifyField<flatbuffers::uoffset_t>(verifier, 4 /* thread */) &&
|
||||||
|
verifier.Verify(thread()) &&
|
||||||
|
verifier.VerifyVectorOfTables(thread()) && verifier.EndTable();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ListThreadsResponseBuilder {
|
struct ListThreadsResponseBuilder {
|
||||||
flatbuffers::FlatBufferBuilder &fbb_;
|
flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
flatbuffers::uoffset_t start_;
|
flatbuffers::uoffset_t start_;
|
||||||
|
void add_thread(flatbuffers::Offset<
|
||||||
|
flatbuffers::Vector<flatbuffers::Offset<Thread>>> thread) {
|
||||||
|
fbb_.AddOffset(4, thread);
|
||||||
|
}
|
||||||
ListThreadsResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
ListThreadsResponseBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||||
ListThreadsResponseBuilder &operator=(const ListThreadsResponseBuilder &);
|
ListThreadsResponseBuilder &operator=(const ListThreadsResponseBuilder &);
|
||||||
flatbuffers::Offset<ListThreadsResponse> Finish() {
|
flatbuffers::Offset<ListThreadsResponse> Finish() {
|
||||||
auto o = flatbuffers::Offset<ListThreadsResponse>(fbb_.EndTable(start_, 0));
|
auto o = flatbuffers::Offset<ListThreadsResponse>(fbb_.EndTable(start_, 1));
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline flatbuffers::Offset<ListThreadsResponse> CreateListThreadsResponse(flatbuffers::FlatBufferBuilder &_fbb) {
|
inline flatbuffers::Offset<ListThreadsResponse> CreateListThreadsResponse(
|
||||||
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Thread>>>
|
||||||
|
thread = 0) {
|
||||||
ListThreadsResponseBuilder builder_(_fbb);
|
ListThreadsResponseBuilder builder_(_fbb);
|
||||||
|
builder_.add_thread(thread);
|
||||||
return builder_.Finish();
|
return builder_.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,8 @@ XThread::XThread(KernelState* kernel_state, uint32_t stack_size,
|
||||||
pcr_address_(0),
|
pcr_address_(0),
|
||||||
thread_state_address_(0),
|
thread_state_address_(0),
|
||||||
thread_state_(0),
|
thread_state_(0),
|
||||||
|
priority_(0),
|
||||||
|
affinity_(0),
|
||||||
irql_(0) {
|
irql_(0) {
|
||||||
creation_params_.stack_size = stack_size;
|
creation_params_.stack_size = stack_size;
|
||||||
creation_params_.xapi_thread_startup = xapi_thread_startup;
|
creation_params_.xapi_thread_startup = xapi_thread_startup;
|
||||||
|
@ -613,6 +615,7 @@ void XThread::RundownAPCs() {
|
||||||
int32_t XThread::QueryPriority() { return GetThreadPriority(thread_handle_); }
|
int32_t XThread::QueryPriority() { return GetThreadPriority(thread_handle_); }
|
||||||
|
|
||||||
void XThread::SetPriority(int32_t increment) {
|
void XThread::SetPriority(int32_t increment) {
|
||||||
|
priority_ = increment;
|
||||||
int target_priority = 0;
|
int target_priority = 0;
|
||||||
if (increment > 0x22) {
|
if (increment > 0x22) {
|
||||||
target_priority = THREAD_PRIORITY_HIGHEST;
|
target_priority = THREAD_PRIORITY_HIGHEST;
|
||||||
|
@ -647,11 +650,17 @@ void XThread::SetAffinity(uint32_t affinity) {
|
||||||
XELOGW("Too few processors - scheduling will be wonky");
|
XELOGW("Too few processors - scheduling will be wonky");
|
||||||
}
|
}
|
||||||
SetActiveCpu(GetFakeCpuNumber(affinity));
|
SetActiveCpu(GetFakeCpuNumber(affinity));
|
||||||
|
affinity_ = affinity;
|
||||||
if (!FLAGS_ignore_thread_affinities) {
|
if (!FLAGS_ignore_thread_affinities) {
|
||||||
SetThreadAffinityMask(reinterpret_cast<HANDLE>(thread_handle_), affinity);
|
SetThreadAffinityMask(reinterpret_cast<HANDLE>(thread_handle_), affinity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t XThread::active_cpu() const {
|
||||||
|
uint8_t* pcr = memory()->TranslateVirtual(pcr_address_);
|
||||||
|
return xe::load_and_swap<uint8_t>(pcr + 0x10C);
|
||||||
|
}
|
||||||
|
|
||||||
void XThread::SetActiveCpu(uint32_t cpu_index) {
|
void XThread::SetActiveCpu(uint32_t cpu_index) {
|
||||||
uint8_t* pcr = memory()->TranslateVirtual(pcr_address_);
|
uint8_t* pcr = memory()->TranslateVirtual(pcr_address_);
|
||||||
xe::store_and_swap<uint8_t>(pcr + 0x10C, cpu_index);
|
xe::store_and_swap<uint8_t>(pcr + 0x10C, cpu_index);
|
||||||
|
|
|
@ -85,6 +85,7 @@ class XThread : public XObject {
|
||||||
static uint32_t GetCurrentThreadHandle();
|
static uint32_t GetCurrentThreadHandle();
|
||||||
static uint32_t GetCurrentThreadId(const uint8_t* pcr);
|
static uint32_t GetCurrentThreadId(const uint8_t* pcr);
|
||||||
|
|
||||||
|
uint32_t tls_ptr() const { return tls_address_; }
|
||||||
uint32_t pcr_ptr() const { return pcr_address_; }
|
uint32_t pcr_ptr() const { return pcr_address_; }
|
||||||
uint32_t thread_state_ptr() const { return thread_state_address_; }
|
uint32_t thread_state_ptr() const { return thread_state_address_; }
|
||||||
|
|
||||||
|
@ -112,9 +113,12 @@ class XThread : public XObject {
|
||||||
void EnqueueApc(uint32_t normal_routine, uint32_t normal_context,
|
void EnqueueApc(uint32_t normal_routine, uint32_t normal_context,
|
||||||
uint32_t arg1, uint32_t arg2);
|
uint32_t arg1, uint32_t arg2);
|
||||||
|
|
||||||
|
int32_t priority() const { return priority_; }
|
||||||
int32_t QueryPriority();
|
int32_t QueryPriority();
|
||||||
void SetPriority(int32_t increment);
|
void SetPriority(int32_t increment);
|
||||||
|
uint32_t affinity() const { return affinity_; }
|
||||||
void SetAffinity(uint32_t affinity);
|
void SetAffinity(uint32_t affinity);
|
||||||
|
uint32_t active_cpu() const;
|
||||||
void SetActiveCpu(uint32_t cpu_index);
|
void SetActiveCpu(uint32_t cpu_index);
|
||||||
|
|
||||||
X_STATUS Resume(uint32_t* out_suspend_count = nullptr);
|
X_STATUS Resume(uint32_t* out_suspend_count = nullptr);
|
||||||
|
@ -151,6 +155,9 @@ class XThread : public XObject {
|
||||||
|
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
|
||||||
|
int32_t priority_;
|
||||||
|
uint32_t affinity_;
|
||||||
|
|
||||||
std::atomic<uint32_t> irql_;
|
std::atomic<uint32_t> irql_;
|
||||||
xe::mutex apc_lock_;
|
xe::mutex apc_lock_;
|
||||||
NativeList* apc_list_;
|
NativeList* apc_list_;
|
||||||
|
|
Loading…
Reference in New Issue