mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-09 15:46:17 +00:00
Display emulation status
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -155,3 +155,7 @@ page/public/analyzer.wasm
|
||||
page/public/debugger.js
|
||||
page/public/debugger.wasm
|
||||
page/public/root.zip
|
||||
page/public/32/analyzer.js
|
||||
page/public/32/analyzer.wasm
|
||||
page/public/64/analyzer.js
|
||||
page/public/64/analyzer.wasm
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { CircleFill } from "react-bootstrap-icons";
|
||||
import { EmulationState as State } from "@/emulator";
|
||||
import { EmulationStatus, EmulationState as State } from "@/emulator";
|
||||
|
||||
function getStateName(state: State) {
|
||||
switch (state) {
|
||||
|
||||
@@ -13,6 +13,18 @@ export enum EmulationState {
|
||||
Failed,
|
||||
}
|
||||
|
||||
export interface EmulationStatus {
|
||||
executedInstructions: BigInt;
|
||||
activeThreads: number;
|
||||
}
|
||||
|
||||
function createDefaultEmulationStatus(): EmulationStatus {
|
||||
return {
|
||||
executedInstructions: BigInt(0),
|
||||
activeThreads: 0,
|
||||
};
|
||||
}
|
||||
|
||||
export function isFinalState(state: EmulationState) {
|
||||
switch (state) {
|
||||
case EmulationState.Stopped:
|
||||
@@ -55,10 +67,12 @@ function decodeEvent(data: string) {
|
||||
}
|
||||
|
||||
type StateChangeHandler = (state: EmulationState) => void;
|
||||
type StatusUpdateHandler = (status: EmulationStatus) => void;
|
||||
|
||||
export class Emulator {
|
||||
logHandler: LogHandler;
|
||||
stateChangeHandler: StateChangeHandler;
|
||||
stautsUpdateHandler: StatusUpdateHandler;
|
||||
terminatePromise: Promise<number | null>;
|
||||
terminateResolve: (value: number | null) => void;
|
||||
terminateReject: (reason?: any) => void;
|
||||
@@ -66,9 +80,14 @@ export class Emulator {
|
||||
state: EmulationState = EmulationState.Stopped;
|
||||
exit_status: number | null = null;
|
||||
|
||||
constructor(logHandler: LogHandler, stateChangeHandler: StateChangeHandler) {
|
||||
constructor(
|
||||
logHandler: LogHandler,
|
||||
stateChangeHandler: StateChangeHandler,
|
||||
stautsUpdateHandler: StatusUpdateHandler,
|
||||
) {
|
||||
this.logHandler = logHandler;
|
||||
this.stateChangeHandler = stateChangeHandler;
|
||||
this.stautsUpdateHandler = stautsUpdateHandler;
|
||||
this.terminateResolve = () => {};
|
||||
this.terminateReject = () => {};
|
||||
this.terminatePromise = new Promise((resolve, reject) => {
|
||||
@@ -84,11 +103,13 @@ export class Emulator {
|
||||
);
|
||||
|
||||
this.worker.onerror = this._onError.bind(this);
|
||||
this.worker.onmessage = this._onMessage.bind(this);
|
||||
this.worker.onmessage = (e) => queueMicrotask(() => this._onMessage(e));
|
||||
}
|
||||
|
||||
async start(settings: Settings, file: string) {
|
||||
this._setState(EmulationState.Running);
|
||||
this.stautsUpdateHandler(createDefaultEmulationStatus());
|
||||
|
||||
this.worker.postMessage({
|
||||
message: "run",
|
||||
data: {
|
||||
@@ -197,6 +218,11 @@ export class Emulator {
|
||||
event.event as fbDebugger.ApplicationExitT,
|
||||
);
|
||||
break;
|
||||
case fbDebugger.Event.EmulationStatus:
|
||||
this._handle_emulation_status(
|
||||
event.event as fbDebugger.EmulationStatusT,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,6 +235,13 @@ export class Emulator {
|
||||
this.exit_status = info.exitStatus;
|
||||
}
|
||||
|
||||
_handle_emulation_status(info: fbDebugger.EmulationStatusT) {
|
||||
this.stautsUpdateHandler({
|
||||
activeThreads: info.activeThreads,
|
||||
executedInstructions: info.executedInstructions,
|
||||
});
|
||||
}
|
||||
|
||||
_handle_state_response(response: fbDebugger.GetStateResponseT) {
|
||||
switch (response.state) {
|
||||
case fbDebugger.State.None:
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
export { ApplicationExit, ApplicationExitT } from './debugger/application-exit.js';
|
||||
export { DebugEvent, DebugEventT } from './debugger/debug-event.js';
|
||||
export { EmulationStatus, EmulationStatusT } from './debugger/emulation-status.js';
|
||||
export { Event } from './debugger/event.js';
|
||||
export { GetStateRequest, GetStateRequestT } from './debugger/get-state-request.js';
|
||||
export { GetStateResponse, GetStateResponseT } from './debugger/get-state-response.js';
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { ApplicationExit, ApplicationExitT } from '../debugger/application-exit.js';
|
||||
import { EmulationStatus, EmulationStatusT } from '../debugger/emulation-status.js';
|
||||
import { Event, unionToEvent, unionListToEvent } from '../debugger/event.js';
|
||||
import { GetStateRequest, GetStateRequestT } from '../debugger/get-state-request.js';
|
||||
import { GetStateResponse, GetStateResponseT } from '../debugger/get-state-response.js';
|
||||
@@ -105,7 +106,7 @@ unpackTo(_o: DebugEventT): void {
|
||||
export class DebugEventT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public eventType: Event = Event.NONE,
|
||||
public event: ApplicationExitT|GetStateRequestT|GetStateResponseT|PauseRequestT|ReadMemoryRequestT|ReadMemoryResponseT|ReadRegisterRequestT|ReadRegisterResponseT|RunRequestT|WriteMemoryRequestT|WriteMemoryResponseT|WriteRegisterRequestT|WriteRegisterResponseT|null = null
|
||||
public event: ApplicationExitT|EmulationStatusT|GetStateRequestT|GetStateResponseT|PauseRequestT|ReadMemoryRequestT|ReadMemoryResponseT|ReadRegisterRequestT|ReadRegisterResponseT|RunRequestT|WriteMemoryRequestT|WriteMemoryResponseT|WriteRegisterRequestT|WriteRegisterResponseT|null = null
|
||||
){}
|
||||
|
||||
|
||||
|
||||
110
page/src/fb/debugger/emulation-status.ts
Normal file
110
page/src/fb/debugger/emulation-status.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class EmulationStatus implements flatbuffers.IUnpackableObject<EmulationStatusT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):EmulationStatus {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsEmulationStatus(bb:flatbuffers.ByteBuffer, obj?:EmulationStatus):EmulationStatus {
|
||||
return (obj || new EmulationStatus()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsEmulationStatus(bb:flatbuffers.ByteBuffer, obj?:EmulationStatus):EmulationStatus {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new EmulationStatus()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
executedInstructions():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
mutate_executed_instructions(value:bigint):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint64(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
activeThreads():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.readUint32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
mutate_active_threads(value:number):boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.bb!.writeUint32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
static startEmulationStatus(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addExecutedInstructions(builder:flatbuffers.Builder, executedInstructions:bigint) {
|
||||
builder.addFieldInt64(0, executedInstructions, BigInt('0'));
|
||||
}
|
||||
|
||||
static addActiveThreads(builder:flatbuffers.Builder, activeThreads:number) {
|
||||
builder.addFieldInt32(1, activeThreads, 0);
|
||||
}
|
||||
|
||||
static endEmulationStatus(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createEmulationStatus(builder:flatbuffers.Builder, executedInstructions:bigint, activeThreads:number):flatbuffers.Offset {
|
||||
EmulationStatus.startEmulationStatus(builder);
|
||||
EmulationStatus.addExecutedInstructions(builder, executedInstructions);
|
||||
EmulationStatus.addActiveThreads(builder, activeThreads);
|
||||
return EmulationStatus.endEmulationStatus(builder);
|
||||
}
|
||||
|
||||
unpack(): EmulationStatusT {
|
||||
return new EmulationStatusT(
|
||||
this.executedInstructions(),
|
||||
this.activeThreads()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: EmulationStatusT): void {
|
||||
_o.executedInstructions = this.executedInstructions();
|
||||
_o.activeThreads = this.activeThreads();
|
||||
}
|
||||
}
|
||||
|
||||
export class EmulationStatusT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public executedInstructions: bigint = BigInt('0'),
|
||||
public activeThreads: number = 0
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return EmulationStatus.createEmulationStatus(builder,
|
||||
this.executedInstructions,
|
||||
this.activeThreads
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import { ApplicationExit, ApplicationExitT } from '../debugger/application-exit.js';
|
||||
import { EmulationStatus, EmulationStatusT } from '../debugger/emulation-status.js';
|
||||
import { GetStateRequest, GetStateRequestT } from '../debugger/get-state-request.js';
|
||||
import { GetStateResponse, GetStateResponseT } from '../debugger/get-state-response.js';
|
||||
import { PauseRequest, PauseRequestT } from '../debugger/pause-request.js';
|
||||
@@ -31,13 +32,14 @@ export enum Event {
|
||||
WriteRegisterResponse = 10,
|
||||
ReadRegisterRequest = 11,
|
||||
ReadRegisterResponse = 12,
|
||||
ApplicationExit = 13
|
||||
ApplicationExit = 13,
|
||||
EmulationStatus = 14
|
||||
}
|
||||
|
||||
export function unionToEvent(
|
||||
type: Event,
|
||||
accessor: (obj:ApplicationExit|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse) => ApplicationExit|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null
|
||||
): ApplicationExit|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null {
|
||||
accessor: (obj:ApplicationExit|EmulationStatus|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse) => ApplicationExit|EmulationStatus|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null
|
||||
): ApplicationExit|EmulationStatus|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null {
|
||||
switch(Event[type]) {
|
||||
case 'NONE': return null;
|
||||
case 'PauseRequest': return accessor(new PauseRequest())! as PauseRequest;
|
||||
@@ -53,15 +55,16 @@ export function unionToEvent(
|
||||
case 'ReadRegisterRequest': return accessor(new ReadRegisterRequest())! as ReadRegisterRequest;
|
||||
case 'ReadRegisterResponse': return accessor(new ReadRegisterResponse())! as ReadRegisterResponse;
|
||||
case 'ApplicationExit': return accessor(new ApplicationExit())! as ApplicationExit;
|
||||
case 'EmulationStatus': return accessor(new EmulationStatus())! as EmulationStatus;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function unionListToEvent(
|
||||
type: Event,
|
||||
accessor: (index: number, obj:ApplicationExit|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse) => ApplicationExit|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null,
|
||||
accessor: (index: number, obj:ApplicationExit|EmulationStatus|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse) => ApplicationExit|EmulationStatus|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null,
|
||||
index: number
|
||||
): ApplicationExit|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null {
|
||||
): ApplicationExit|EmulationStatus|GetStateRequest|GetStateResponse|PauseRequest|ReadMemoryRequest|ReadMemoryResponse|ReadRegisterRequest|ReadRegisterResponse|RunRequest|WriteMemoryRequest|WriteMemoryResponse|WriteRegisterRequest|WriteRegisterResponse|null {
|
||||
switch(Event[type]) {
|
||||
case 'NONE': return null;
|
||||
case 'PauseRequest': return accessor(index, new PauseRequest())! as PauseRequest;
|
||||
@@ -77,6 +80,7 @@ export function unionListToEvent(
|
||||
case 'ReadRegisterRequest': return accessor(index, new ReadRegisterRequest())! as ReadRegisterRequest;
|
||||
case 'ReadRegisterResponse': return accessor(index, new ReadRegisterResponse())! as ReadRegisterResponse;
|
||||
case 'ApplicationExit': return accessor(index, new ApplicationExit())! as ApplicationExit;
|
||||
case 'EmulationStatus': return accessor(index, new EmulationStatus())! as EmulationStatus;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import {
|
||||
GearFill,
|
||||
PauseFill,
|
||||
HouseFill,
|
||||
BarChartSteps,
|
||||
CpuFill,
|
||||
} from "react-bootstrap-icons";
|
||||
import { StatusIndicator } from "@/components/status-indicator";
|
||||
import { Header } from "./Header";
|
||||
@@ -38,6 +40,7 @@ import {
|
||||
DrawerTitle,
|
||||
} from "@/components/ui/drawer";
|
||||
import { FilesystemExplorer } from "./filesystem-explorer";
|
||||
import { EmulationStatus } from "./emulator";
|
||||
|
||||
interface PlaygroundProps {}
|
||||
interface PlaygroundState {
|
||||
@@ -45,6 +48,7 @@ interface PlaygroundState {
|
||||
filesystemPromise: Promise<Filesystem> | null;
|
||||
filesystem: Filesystem | null;
|
||||
emulator: Emulator | null;
|
||||
emulationStatus: EmulationStatus | null;
|
||||
application: string | undefined;
|
||||
drawerOpen: boolean;
|
||||
allowWasm64: boolean;
|
||||
@@ -94,6 +98,10 @@ export class Playground extends React.Component<
|
||||
filesystemPromise: null,
|
||||
filesystem: null,
|
||||
emulator: null,
|
||||
emulationStatus: {
|
||||
activeThreads: 5,
|
||||
executedInstructions: BigInt(1233252643),
|
||||
},
|
||||
drawerOpen: false,
|
||||
application: undefined,
|
||||
allowWasm64: false,
|
||||
@@ -124,6 +132,10 @@ export class Playground extends React.Component<
|
||||
location.reload();
|
||||
}
|
||||
|
||||
_onEmulatorStatusChanged(s: EmulationStatus) {
|
||||
this.setState({ emulationStatus: s });
|
||||
}
|
||||
|
||||
_onEmulatorStateChanged(s: EmulationState, persistFs: boolean) {
|
||||
if (isFinalState(s) && persistFs) {
|
||||
this.setState({ filesystemPromise: null, filesystem: null });
|
||||
@@ -208,6 +220,7 @@ export class Playground extends React.Component<
|
||||
const new_emulator = new Emulator(
|
||||
(l) => this.logLines(l),
|
||||
(s) => this._onEmulatorStateChanged(s, persistFs),
|
||||
(s) => this._onEmulatorStatusChanged(s),
|
||||
);
|
||||
//new_emulator.onTerminate().then(() => this.setState({ emulator: null }));
|
||||
|
||||
@@ -320,7 +333,9 @@ export class Playground extends React.Component<
|
||||
</Drawer>
|
||||
)}
|
||||
|
||||
<div className="text-right flex-1">
|
||||
<div className="flex-1"></div>
|
||||
|
||||
<div className="text-right items-center">
|
||||
<StatusIndicator
|
||||
application={this.state.application}
|
||||
state={
|
||||
@@ -331,8 +346,23 @@ export class Playground extends React.Component<
|
||||
/>
|
||||
</div>
|
||||
</header>
|
||||
<div className="flex flex-1 flex-col pl-1 overflow-auto">
|
||||
<Output ref={this.output} />
|
||||
<div className="flex flex-1">
|
||||
<div className="items-center absolute z-100 right-0 rounded-bl-lg min-w-[140px] p-2 bg-[var(--background)] pointer-events-none font-medium text-right text-xs whitespace-nowrap leading-6">
|
||||
{!this.state.emulationStatus ? (
|
||||
<></>
|
||||
) : (
|
||||
<>
|
||||
{this.state.emulationStatus.activeThreads}
|
||||
<BarChartSteps className="inline ml-3" />
|
||||
<br />
|
||||
{this.state.emulationStatus.executedInstructions.toLocaleString()}
|
||||
<CpuFill className="inline ml-3" />
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-1 flex-col pl-1 overflow-auto">
|
||||
<Output ref={this.output} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -141,7 +141,7 @@ namespace
|
||||
std::optional<NTSTATUS> exit_status{};
|
||||
#ifdef OS_EMSCRIPTEN
|
||||
const auto _1 = utils::finally([&] {
|
||||
debugger::handle_exit(exit_status); //
|
||||
debugger::handle_exit(win_emu, exit_status); //
|
||||
});
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "event_handler.hpp"
|
||||
#include "message_transmitter.hpp"
|
||||
#include "windows_emulator.hpp"
|
||||
|
||||
#include <base64.hpp>
|
||||
|
||||
@@ -218,6 +219,8 @@ namespace debugger
|
||||
|
||||
void handle_events(event_context& c)
|
||||
{
|
||||
update_emulation_status(c.win_emu);
|
||||
|
||||
while (true)
|
||||
{
|
||||
handle_events_once(c);
|
||||
@@ -231,8 +234,18 @@ namespace debugger
|
||||
}
|
||||
}
|
||||
|
||||
void handle_exit(std::optional<NTSTATUS> exit_status)
|
||||
void update_emulation_status(const windows_emulator& win_emu)
|
||||
{
|
||||
Debugger::EmulationStatusT status{};
|
||||
status.executed_instructions = win_emu.get_executed_instructions();
|
||||
status.active_threads = static_cast<uint32_t>(win_emu.process.threads.size());
|
||||
send_event(status);
|
||||
}
|
||||
|
||||
void handle_exit(const windows_emulator& win_emu, std::optional<NTSTATUS> exit_status)
|
||||
{
|
||||
update_emulation_status(win_emu);
|
||||
|
||||
Debugger::ApplicationExitT response{};
|
||||
response.exit_status = exit_status;
|
||||
send_event(response);
|
||||
|
||||
@@ -18,5 +18,6 @@ namespace debugger
|
||||
};
|
||||
|
||||
void handle_events(event_context& c);
|
||||
void handle_exit(std::optional<NTSTATUS> exit_status);
|
||||
void handle_exit(const windows_emulator& win_emu, std::optional<NTSTATUS> exit_status);
|
||||
void update_emulation_status(const windows_emulator& win_emu);
|
||||
}
|
||||
|
||||
@@ -63,6 +63,11 @@ table ApplicationExit {
|
||||
exit_status: uint32 = null;
|
||||
}
|
||||
|
||||
table EmulationStatus {
|
||||
executed_instructions: uint64;
|
||||
active_threads: uint32;
|
||||
}
|
||||
|
||||
union Event {
|
||||
PauseRequest,
|
||||
RunRequest,
|
||||
@@ -77,6 +82,7 @@ union Event {
|
||||
ReadRegisterRequest,
|
||||
ReadRegisterResponse,
|
||||
ApplicationExit,
|
||||
EmulationStatus,
|
||||
}
|
||||
|
||||
table DebugEvent {
|
||||
|
||||
@@ -67,6 +67,10 @@ struct ApplicationExit;
|
||||
struct ApplicationExitBuilder;
|
||||
struct ApplicationExitT;
|
||||
|
||||
struct EmulationStatus;
|
||||
struct EmulationStatusBuilder;
|
||||
struct EmulationStatusT;
|
||||
|
||||
struct DebugEvent;
|
||||
struct DebugEventBuilder;
|
||||
struct DebugEventT;
|
||||
@@ -119,11 +123,12 @@ enum Event : uint8_t {
|
||||
Event_ReadRegisterRequest = 11,
|
||||
Event_ReadRegisterResponse = 12,
|
||||
Event_ApplicationExit = 13,
|
||||
Event_EmulationStatus = 14,
|
||||
Event_MIN = Event_NONE,
|
||||
Event_MAX = Event_ApplicationExit
|
||||
Event_MAX = Event_EmulationStatus
|
||||
};
|
||||
|
||||
inline const Event (&EnumValuesEvent())[14] {
|
||||
inline const Event (&EnumValuesEvent())[15] {
|
||||
static const Event values[] = {
|
||||
Event_NONE,
|
||||
Event_PauseRequest,
|
||||
@@ -138,13 +143,14 @@ inline const Event (&EnumValuesEvent())[14] {
|
||||
Event_WriteRegisterResponse,
|
||||
Event_ReadRegisterRequest,
|
||||
Event_ReadRegisterResponse,
|
||||
Event_ApplicationExit
|
||||
Event_ApplicationExit,
|
||||
Event_EmulationStatus
|
||||
};
|
||||
return values;
|
||||
}
|
||||
|
||||
inline const char * const *EnumNamesEvent() {
|
||||
static const char * const names[15] = {
|
||||
static const char * const names[16] = {
|
||||
"NONE",
|
||||
"PauseRequest",
|
||||
"RunRequest",
|
||||
@@ -159,13 +165,14 @@ inline const char * const *EnumNamesEvent() {
|
||||
"ReadRegisterRequest",
|
||||
"ReadRegisterResponse",
|
||||
"ApplicationExit",
|
||||
"EmulationStatus",
|
||||
nullptr
|
||||
};
|
||||
return names;
|
||||
}
|
||||
|
||||
inline const char *EnumNameEvent(Event e) {
|
||||
if (::flatbuffers::IsOutRange(e, Event_NONE, Event_ApplicationExit)) return "";
|
||||
if (::flatbuffers::IsOutRange(e, Event_NONE, Event_EmulationStatus)) return "";
|
||||
const size_t index = static_cast<size_t>(e);
|
||||
return EnumNamesEvent()[index];
|
||||
}
|
||||
@@ -226,6 +233,10 @@ template<> struct EventTraits<Debugger::ApplicationExit> {
|
||||
static const Event enum_value = Event_ApplicationExit;
|
||||
};
|
||||
|
||||
template<> struct EventTraits<Debugger::EmulationStatus> {
|
||||
static const Event enum_value = Event_EmulationStatus;
|
||||
};
|
||||
|
||||
template<typename T> struct EventUnionTraits {
|
||||
static const Event enum_value = Event_NONE;
|
||||
};
|
||||
@@ -282,6 +293,10 @@ template<> struct EventUnionTraits<Debugger::ApplicationExitT> {
|
||||
static const Event enum_value = Event_ApplicationExit;
|
||||
};
|
||||
|
||||
template<> struct EventUnionTraits<Debugger::EmulationStatusT> {
|
||||
static const Event enum_value = Event_EmulationStatus;
|
||||
};
|
||||
|
||||
struct EventUnion {
|
||||
Event type;
|
||||
void *value;
|
||||
@@ -416,6 +431,14 @@ struct EventUnion {
|
||||
return type == Event_ApplicationExit ?
|
||||
reinterpret_cast<const Debugger::ApplicationExitT *>(value) : nullptr;
|
||||
}
|
||||
Debugger::EmulationStatusT *AsEmulationStatus() {
|
||||
return type == Event_EmulationStatus ?
|
||||
reinterpret_cast<Debugger::EmulationStatusT *>(value) : nullptr;
|
||||
}
|
||||
const Debugger::EmulationStatusT *AsEmulationStatus() const {
|
||||
return type == Event_EmulationStatus ?
|
||||
reinterpret_cast<const Debugger::EmulationStatusT *>(value) : nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
bool VerifyEvent(::flatbuffers::Verifier &verifier, const void *obj, Event type);
|
||||
@@ -1278,6 +1301,75 @@ inline ::flatbuffers::Offset<ApplicationExit> CreateApplicationExit(
|
||||
|
||||
::flatbuffers::Offset<ApplicationExit> CreateApplicationExit(::flatbuffers::FlatBufferBuilder &_fbb, const ApplicationExitT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
|
||||
struct EmulationStatusT : public ::flatbuffers::NativeTable {
|
||||
typedef EmulationStatus TableType;
|
||||
uint64_t executed_instructions = 0;
|
||||
uint32_t active_threads = 0;
|
||||
};
|
||||
|
||||
struct EmulationStatus FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
typedef EmulationStatusT NativeTableType;
|
||||
typedef EmulationStatusBuilder Builder;
|
||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||
VT_EXECUTED_INSTRUCTIONS = 4,
|
||||
VT_ACTIVE_THREADS = 6
|
||||
};
|
||||
uint64_t executed_instructions() const {
|
||||
return GetField<uint64_t>(VT_EXECUTED_INSTRUCTIONS, 0);
|
||||
}
|
||||
bool mutate_executed_instructions(uint64_t _executed_instructions = 0) {
|
||||
return SetField<uint64_t>(VT_EXECUTED_INSTRUCTIONS, _executed_instructions, 0);
|
||||
}
|
||||
uint32_t active_threads() const {
|
||||
return GetField<uint32_t>(VT_ACTIVE_THREADS, 0);
|
||||
}
|
||||
bool mutate_active_threads(uint32_t _active_threads = 0) {
|
||||
return SetField<uint32_t>(VT_ACTIVE_THREADS, _active_threads, 0);
|
||||
}
|
||||
bool Verify(::flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<uint64_t>(verifier, VT_EXECUTED_INSTRUCTIONS, 8) &&
|
||||
VerifyField<uint32_t>(verifier, VT_ACTIVE_THREADS, 4) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
EmulationStatusT *UnPack(const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
|
||||
void UnPackTo(EmulationStatusT *_o, const ::flatbuffers::resolver_function_t *_resolver = nullptr) const;
|
||||
static ::flatbuffers::Offset<EmulationStatus> Pack(::flatbuffers::FlatBufferBuilder &_fbb, const EmulationStatusT* _o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
};
|
||||
|
||||
struct EmulationStatusBuilder {
|
||||
typedef EmulationStatus Table;
|
||||
::flatbuffers::FlatBufferBuilder &fbb_;
|
||||
::flatbuffers::uoffset_t start_;
|
||||
void add_executed_instructions(uint64_t executed_instructions) {
|
||||
fbb_.AddElement<uint64_t>(EmulationStatus::VT_EXECUTED_INSTRUCTIONS, executed_instructions, 0);
|
||||
}
|
||||
void add_active_threads(uint32_t active_threads) {
|
||||
fbb_.AddElement<uint32_t>(EmulationStatus::VT_ACTIVE_THREADS, active_threads, 0);
|
||||
}
|
||||
explicit EmulationStatusBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
::flatbuffers::Offset<EmulationStatus> Finish() {
|
||||
const auto end = fbb_.EndTable(start_);
|
||||
auto o = ::flatbuffers::Offset<EmulationStatus>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline ::flatbuffers::Offset<EmulationStatus> CreateEmulationStatus(
|
||||
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||
uint64_t executed_instructions = 0,
|
||||
uint32_t active_threads = 0) {
|
||||
EmulationStatusBuilder builder_(_fbb);
|
||||
builder_.add_executed_instructions(executed_instructions);
|
||||
builder_.add_active_threads(active_threads);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
::flatbuffers::Offset<EmulationStatus> CreateEmulationStatus(::flatbuffers::FlatBufferBuilder &_fbb, const EmulationStatusT *_o, const ::flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
|
||||
struct DebugEventT : public ::flatbuffers::NativeTable {
|
||||
typedef DebugEvent TableType;
|
||||
Debugger::EventUnion event{};
|
||||
@@ -1336,6 +1428,9 @@ struct DebugEvent FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
const Debugger::ApplicationExit *event_as_ApplicationExit() const {
|
||||
return event_type() == Debugger::Event_ApplicationExit ? static_cast<const Debugger::ApplicationExit *>(event()) : nullptr;
|
||||
}
|
||||
const Debugger::EmulationStatus *event_as_EmulationStatus() const {
|
||||
return event_type() == Debugger::Event_EmulationStatus ? static_cast<const Debugger::EmulationStatus *>(event()) : nullptr;
|
||||
}
|
||||
void *mutable_event() {
|
||||
return GetPointer<void *>(VT_EVENT);
|
||||
}
|
||||
@@ -1403,6 +1498,10 @@ template<> inline const Debugger::ApplicationExit *DebugEvent::event_as<Debugger
|
||||
return event_as_ApplicationExit();
|
||||
}
|
||||
|
||||
template<> inline const Debugger::EmulationStatus *DebugEvent::event_as<Debugger::EmulationStatus>() const {
|
||||
return event_as_EmulationStatus();
|
||||
}
|
||||
|
||||
struct DebugEventBuilder {
|
||||
typedef DebugEvent Table;
|
||||
::flatbuffers::FlatBufferBuilder &fbb_;
|
||||
@@ -1795,6 +1894,35 @@ inline ::flatbuffers::Offset<ApplicationExit> CreateApplicationExit(::flatbuffer
|
||||
_exit_status);
|
||||
}
|
||||
|
||||
inline EmulationStatusT *EmulationStatus::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
|
||||
auto _o = std::unique_ptr<EmulationStatusT>(new EmulationStatusT());
|
||||
UnPackTo(_o.get(), _resolver);
|
||||
return _o.release();
|
||||
}
|
||||
|
||||
inline void EmulationStatus::UnPackTo(EmulationStatusT *_o, const ::flatbuffers::resolver_function_t *_resolver) const {
|
||||
(void)_o;
|
||||
(void)_resolver;
|
||||
{ auto _e = executed_instructions(); _o->executed_instructions = _e; }
|
||||
{ auto _e = active_threads(); _o->active_threads = _e; }
|
||||
}
|
||||
|
||||
inline ::flatbuffers::Offset<EmulationStatus> EmulationStatus::Pack(::flatbuffers::FlatBufferBuilder &_fbb, const EmulationStatusT* _o, const ::flatbuffers::rehasher_function_t *_rehasher) {
|
||||
return CreateEmulationStatus(_fbb, _o, _rehasher);
|
||||
}
|
||||
|
||||
inline ::flatbuffers::Offset<EmulationStatus> CreateEmulationStatus(::flatbuffers::FlatBufferBuilder &_fbb, const EmulationStatusT *_o, const ::flatbuffers::rehasher_function_t *_rehasher) {
|
||||
(void)_rehasher;
|
||||
(void)_o;
|
||||
struct _VectorArgs { ::flatbuffers::FlatBufferBuilder *__fbb; const EmulationStatusT* __o; const ::flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
|
||||
auto _executed_instructions = _o->executed_instructions;
|
||||
auto _active_threads = _o->active_threads;
|
||||
return Debugger::CreateEmulationStatus(
|
||||
_fbb,
|
||||
_executed_instructions,
|
||||
_active_threads);
|
||||
}
|
||||
|
||||
inline DebugEventT *DebugEvent::UnPack(const ::flatbuffers::resolver_function_t *_resolver) const {
|
||||
auto _o = std::unique_ptr<DebugEventT>(new DebugEventT());
|
||||
UnPackTo(_o.get(), _resolver);
|
||||
@@ -1881,6 +2009,10 @@ inline bool VerifyEvent(::flatbuffers::Verifier &verifier, const void *obj, Even
|
||||
auto ptr = reinterpret_cast<const Debugger::ApplicationExit *>(obj);
|
||||
return verifier.VerifyTable(ptr);
|
||||
}
|
||||
case Event_EmulationStatus: {
|
||||
auto ptr = reinterpret_cast<const Debugger::EmulationStatus *>(obj);
|
||||
return verifier.VerifyTable(ptr);
|
||||
}
|
||||
default: return true;
|
||||
}
|
||||
}
|
||||
@@ -1952,6 +2084,10 @@ inline void *EventUnion::UnPack(const void *obj, Event type, const ::flatbuffers
|
||||
auto ptr = reinterpret_cast<const Debugger::ApplicationExit *>(obj);
|
||||
return ptr->UnPack(resolver);
|
||||
}
|
||||
case Event_EmulationStatus: {
|
||||
auto ptr = reinterpret_cast<const Debugger::EmulationStatus *>(obj);
|
||||
return ptr->UnPack(resolver);
|
||||
}
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -2011,6 +2147,10 @@ inline ::flatbuffers::Offset<void> EventUnion::Pack(::flatbuffers::FlatBufferBui
|
||||
auto ptr = reinterpret_cast<const Debugger::ApplicationExitT *>(value);
|
||||
return CreateApplicationExit(_fbb, ptr, _rehasher).Union();
|
||||
}
|
||||
case Event_EmulationStatus: {
|
||||
auto ptr = reinterpret_cast<const Debugger::EmulationStatusT *>(value);
|
||||
return CreateEmulationStatus(_fbb, ptr, _rehasher).Union();
|
||||
}
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
@@ -2069,6 +2209,10 @@ inline EventUnion::EventUnion(const EventUnion &u) : type(u.type), value(nullptr
|
||||
value = new Debugger::ApplicationExitT(*reinterpret_cast<Debugger::ApplicationExitT *>(u.value));
|
||||
break;
|
||||
}
|
||||
case Event_EmulationStatus: {
|
||||
value = new Debugger::EmulationStatusT(*reinterpret_cast<Debugger::EmulationStatusT *>(u.value));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2141,6 +2285,11 @@ inline void EventUnion::Reset() {
|
||||
delete ptr;
|
||||
break;
|
||||
}
|
||||
case Event_EmulationStatus: {
|
||||
auto ptr = reinterpret_cast<Debugger::EmulationStatusT *>(value);
|
||||
delete ptr;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
value = nullptr;
|
||||
|
||||
Reference in New Issue
Block a user