yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
emulator_service_impl.cc
Go to the documentation of this file.
2
3#include <chrono>
4#include <filesystem>
5#include <fstream>
6#include <thread>
7#include <vector>
8
9#include "absl/strings/str_format.h"
13#include "rom/rom.h"
14
15namespace yaze::net {
16
17namespace {
18grpc::Status ToGrpcStatus(const absl::Status& status) {
19 if (status.ok()) return grpc::Status::OK;
20
21 grpc::StatusCode code = grpc::StatusCode::UNKNOWN;
22 switch (status.code()) {
23 case absl::StatusCode::kOk: code = grpc::StatusCode::OK; break;
24 case absl::StatusCode::kCancelled: code = grpc::StatusCode::CANCELLED; break;
25 case absl::StatusCode::kUnknown: code = grpc::StatusCode::UNKNOWN; break;
26 case absl::StatusCode::kInvalidArgument: code = grpc::StatusCode::INVALID_ARGUMENT; break;
27 case absl::StatusCode::kDeadlineExceeded: code = grpc::StatusCode::DEADLINE_EXCEEDED; break;
28 case absl::StatusCode::kNotFound: code = grpc::StatusCode::NOT_FOUND; break;
29 case absl::StatusCode::kAlreadyExists: code = grpc::StatusCode::ALREADY_EXISTS; break;
30 case absl::StatusCode::kPermissionDenied: code = grpc::StatusCode::PERMISSION_DENIED; break;
31 case absl::StatusCode::kUnauthenticated: code = grpc::StatusCode::UNAUTHENTICATED; break;
32 case absl::StatusCode::kResourceExhausted: code = grpc::StatusCode::RESOURCE_EXHAUSTED; break;
33 case absl::StatusCode::kFailedPrecondition: code = grpc::StatusCode::FAILED_PRECONDITION; break;
34 case absl::StatusCode::kAborted: code = grpc::StatusCode::ABORTED; break;
35 case absl::StatusCode::kOutOfRange: code = grpc::StatusCode::OUT_OF_RANGE; break;
36 case absl::StatusCode::kUnimplemented: code = grpc::StatusCode::UNIMPLEMENTED; break;
37 case absl::StatusCode::kInternal: code = grpc::StatusCode::INTERNAL; break;
38 case absl::StatusCode::kUnavailable: code = grpc::StatusCode::UNAVAILABLE; break;
39 case absl::StatusCode::kDataLoss: code = grpc::StatusCode::DATA_LOSS; break;
40 default: code = grpc::StatusCode::UNKNOWN; break;
41 }
42 return grpc::Status(code, std::string(status.message()));
43}
44} // namespace
45
47 RomGetter rom_getter,
48 RomLoader rom_loader)
49 : emulator_(emulator), rom_getter_(rom_getter), rom_loader_(rom_loader) {}
50
51// --- ROM Loading ---
52
53grpc::Status EmulatorServiceImpl::LoadRom(grpc::ServerContext* context,
54 const agent::LoadRomRequest* request,
55 agent::LoadRomResponse* response) {
56 if (!emulator_) {
57 response->set_success(false);
58 response->set_message("Emulator middleware not initialized");
59 return grpc::Status::OK;
60 }
61 auto status = emulator_->LoadRom(request->filepath());
62 if (status.ok()) {
63 response->set_success(true);
64 response->set_message("ROM loaded successfully");
65 if (rom_getter_) {
66 Rom* rom = rom_getter_();
67 if (rom && rom->is_loaded()) {
68 response->set_rom_title(rom->title());
69 response->set_rom_size(rom->size());
70 }
71 }
72 } else {
73 response->set_success(false);
74 response->set_message("Failed to load ROM: " +
75 std::string(status.message()));
76 }
77 return grpc::Status::OK;
78}
79
81 grpc::ServerContext* context, const agent::Empty* request,
82 agent::LoadedRomPathResponse* response) {
83 if (emulator_) {
84 std::string path = emulator_->GetLoadedRomPath();
85 if (!path.empty()) {
86 response->set_has_rom(true);
87 response->set_filepath(path);
88 response->set_title(std::filesystem::path(path).stem().string());
89 return grpc::Status::OK;
90 }
91 }
92
93 response->set_has_rom(false);
94 return grpc::Status::OK;
95}
96
97// --- Core Lifecycle & Control ---
98
100 grpc::ServerContext* context, const agent::ControlRequest* request,
101 agent::CommandResponse* response) {
102 if (!emulator_ || !emulator_->IsConnected())
103 return grpc::Status(grpc::StatusCode::UNAVAILABLE,
104 "Emulator not connected.");
105
106 std::string action = request->action();
107 if (action == "start" || action == "resume") {
108 emulator_->Resume();
109 response->set_message("Emulator resumed.");
110 } else if (action == "stop" || action == "pause") {
111 emulator_->Pause();
112 response->set_message("Emulator paused.");
113 } else if (action == "reset") {
114 emulator_->Reset();
115 response->set_message("Emulator reset.");
116 } else if (action == "init" || action == "initialize") {
117 response->set_message("Emulator connection active.");
118 } else {
119 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
120 "Unknown action: " + action);
121 }
122
123 response->set_success(true);
124 return grpc::Status::OK;
125}
126
128 grpc::ServerContext* context, const agent::StepControlRequest* request,
129 agent::StepResponse* response) {
130 if (!emulator_ || !emulator_->IsConnected()) {
131 return grpc::Status(grpc::StatusCode::UNAVAILABLE,
132 "Emulator not connected.");
133 }
134
135 std::string mode = request->mode();
136 absl::Status status;
137 if (mode == "instruction") {
138 status = emulator_->Step(1);
139 response->set_message("Stepped 1 instruction.");
140 } else if (mode == "over") {
141 status = emulator_->StepOver();
142 response->set_message("Step Over executed.");
143 } else if (mode == "out") {
144 status = emulator_->StepOut();
145 response->set_message("Step Out executed.");
146 } else {
147 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
148 "Unknown step mode: " + mode);
149 }
150
151 if (!status.ok()) return ToGrpcStatus(status);
152
153 emu::CpuStateSnapshot cpu_snap;
154 auto cpu_status = emulator_->GetCpuState(&cpu_snap);
155 if (!cpu_status.ok()) return ToGrpcStatus(cpu_status);
156 emu::ToProtoCpuState(cpu_snap, response->mutable_cpu_state());
157 response->set_success(true);
158 return grpc::Status::OK;
159}
160
162 grpc::ServerContext* context, const agent::Empty* request,
163 agent::BreakpointHitResponse* response) {
164 if (!emulator_)
165 return grpc::Status(grpc::StatusCode::UNAVAILABLE,
166 "Emulator not initialized.");
167
169 auto status = emulator_->RunToBreakpoint(&result);
170 if (!status.ok()) return ToGrpcStatus(status);
171 emu::ToProtoBreakpointHitResponse(result, response);
172 return grpc::Status::OK;
173}
174
175// --- Input & State ---
176
178 grpc::ServerContext* context, const agent::ButtonRequest* request,
179 agent::CommandResponse* response) {
180 if (!emulator_)
181 return grpc::Status(grpc::StatusCode::UNAVAILABLE,
182 "Emulator not initialized.");
183
184 std::vector<emu::InputButton> pressed_buttons;
185 pressed_buttons.reserve(request->buttons_size());
186 for (int i = 0; i < request->buttons_size(); i++) {
187 auto btn = emu::FromProtoButton(
188 static_cast<agent::Button>(request->buttons(i)));
190 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
191 absl::StrFormat("Invalid button at index %d: %d", i,
192 request->buttons(i)));
193 }
194 auto press_status = emulator_->PressButton(btn);
195 if (!press_status.ok()) {
196 for (auto it = pressed_buttons.rbegin(); it != pressed_buttons.rend();
197 ++it) {
198 (void)emulator_->ReleaseButton(*it);
199 }
200 return ToGrpcStatus(press_status);
201 }
202 pressed_buttons.push_back(btn);
203 }
204 std::this_thread::sleep_for(std::chrono::milliseconds(50));
205 for (auto it = pressed_buttons.rbegin(); it != pressed_buttons.rend(); ++it) {
206 auto release_status = emulator_->ReleaseButton(*it);
207 if (!release_status.ok()) return ToGrpcStatus(release_status);
208 }
209 response->set_success(true);
210 return grpc::Status::OK;
211}
212
214 grpc::ServerContext* context, const agent::ButtonRequest* request,
215 agent::CommandResponse* response) {
216 if (!emulator_)
217 return grpc::Status(grpc::StatusCode::UNAVAILABLE,
218 "Emulator not initialized.");
219
220 for (int i = 0; i < request->buttons_size(); i++) {
221 auto btn = emu::FromProtoButton(
222 static_cast<agent::Button>(request->buttons(i)));
224 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
225 absl::StrFormat("Invalid button at index %d: %d", i,
226 request->buttons(i)));
227 }
228 auto status = emulator_->ReleaseButton(btn);
229 if (!status.ok()) return ToGrpcStatus(status);
230 }
231 response->set_success(true);
232 return grpc::Status::OK;
233}
234
236 grpc::ServerContext* context, const agent::ButtonHoldRequest* request,
237 agent::CommandResponse* response) {
238 if (!emulator_)
239 return grpc::Status(grpc::StatusCode::UNAVAILABLE,
240 "Emulator not initialized.");
241
242 std::vector<emu::InputButton> held_buttons;
243 held_buttons.reserve(request->buttons_size());
244 for (int i = 0; i < request->buttons_size(); i++) {
245 auto btn = emu::FromProtoButton(
246 static_cast<agent::Button>(request->buttons(i)));
248 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
249 absl::StrFormat("Invalid button at index %d: %d", i,
250 request->buttons(i)));
251 }
252 auto press_status = emulator_->PressButton(btn);
253 if (!press_status.ok()) {
254 for (auto it = held_buttons.rbegin(); it != held_buttons.rend(); ++it) {
255 (void)emulator_->ReleaseButton(*it);
256 }
257 return ToGrpcStatus(press_status);
258 }
259 held_buttons.push_back(btn);
260 }
261 std::this_thread::sleep_for(
262 std::chrono::milliseconds(request->duration_ms()));
263 for (auto it = held_buttons.rbegin(); it != held_buttons.rend(); ++it) {
264 auto release_status = emulator_->ReleaseButton(*it);
265 if (!release_status.ok()) return ToGrpcStatus(release_status);
266 }
267 response->set_success(true);
268 return grpc::Status::OK;
269}
270
272 grpc::ServerContext* context, const agent::GameStateRequest* request,
273 agent::GameStateResponse* response) {
274 if (!emulator_)
275 return grpc::Status(grpc::StatusCode::UNAVAILABLE,
276 "Emulator not initialized.");
277
278 emu::GameSnapshot snapshot;
279 auto status = emulator_->GetGameState(&snapshot);
280 if (!status.ok()) return ToGrpcStatus(status);
281 emu::ToProtoGameState(snapshot, response);
282
283 // Fill memory reads if requested
284 for (const auto& mem_req : request->memory_reads()) {
285 auto* mem_resp = response->add_memory_responses();
286 mem_resp->set_address(mem_req.address());
287 auto data_or = emulator_->ReadBlock(mem_req.address(), mem_req.size());
288 if (data_or.ok()) {
289 mem_resp->set_data(data_or->data(), data_or->size());
290 }
291 }
292
293#ifdef YAZE_WITH_GRPC
294 if (request->include_screenshot()) {
295 auto screenshot = yaze::test::CaptureHarnessScreenshot();
296 if (screenshot.ok()) {
297 std::ifstream file(screenshot->file_path, std::ios::binary);
298 if (file.good()) {
299 std::string png_data((std::istreambuf_iterator<char>(file)),
300 std::istreambuf_iterator<char>());
301 response->set_screenshot_png(png_data);
302 }
303 }
304 }
305#endif
306 return grpc::Status::OK;
307}
308
310 grpc::ServerContext* context, const agent::MemoryRequest* request,
311 agent::MemoryResponse* response) {
312 if (!emulator_)
313 return grpc::Status(grpc::StatusCode::UNAVAILABLE,
314 "Emulator not initialized.");
315
316 response->set_address(request->address());
317 auto data_or = emulator_->ReadBlock(request->address(), request->size());
318 if (!data_or.ok()) return ToGrpcStatus(data_or.status());
319
320 response->set_data(data_or->data(), data_or->size());
321 return grpc::Status::OK;
322}
323
325 grpc::ServerContext* context, const agent::MemoryWriteRequest* request,
326 agent::CommandResponse* response) {
327 if (!emulator_)
328 return grpc::Status(grpc::StatusCode::UNAVAILABLE,
329 "Emulator not initialized.");
330
331 std::vector<uint8_t> data(request->data().begin(), request->data().end());
332 auto status = emulator_->WriteBlock(request->address(), data);
333 if (!status.ok()) return ToGrpcStatus(status);
334
335 response->set_success(true);
336 return grpc::Status::OK;
337}
338
339// --- Debugging Management ---
340
342 grpc::ServerContext* context,
343 const agent::BreakpointControlRequest* request,
344 agent::BreakpointControlResponse* response) {
345 if (!emulator_)
346 return grpc::Status(grpc::StatusCode::UNAVAILABLE,
347 "Emulator not initialized.");
348
349 std::string action = request->action();
350 if (action == "add") {
351 auto id_or = emulator_->AddBreakpoint(
352 request->address(),
353 emu::FromProtoBreakpointType(request->type()),
354 emu::FromProtoCpuType(request->cpu()),
355 request->condition(), request->description());
356 if (!id_or.ok()) return ToGrpcStatus(id_or.status());
357 response->set_breakpoint_id(*id_or);
358 response->set_message("Breakpoint added.");
359 } else if (action == "remove") {
360 auto status = emulator_->RemoveBreakpoint(request->id());
361 if (!status.ok()) return ToGrpcStatus(status);
362 response->set_message("Breakpoint removed.");
363 } else if (action == "toggle") {
364 auto status =
365 emulator_->ToggleBreakpoint(request->id(), request->enabled());
366 if (!status.ok()) return ToGrpcStatus(status);
367 response->set_message("Breakpoint toggled.");
368 } else if (action == "list") {
369 auto list = emulator_->ListBreakpoints();
370 for (const auto& bp_snap : list) {
371 emu::ToProtoBreakpointInfo(bp_snap, response->add_breakpoints());
372 }
373 } else {
374 return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
375 "Unknown action: " + action);
376 }
377
378 response->set_success(true);
379 return grpc::Status::OK;
380}
381
383 grpc::ServerContext* context,
384 const agent::WatchpointControlRequest* request,
385 agent::WatchpointControlResponse* response) {
386 return grpc::Status(grpc::StatusCode::UNIMPLEMENTED,
387 "WatchpointManager integration pending.");
388}
389
390// --- Analysis & Symbols ---
391
393 grpc::ServerContext* context, const agent::DisassemblyRequest* request,
394 agent::DisassemblyResponse* response) {
395 if (!emulator_)
396 return grpc::Status(grpc::StatusCode::UNAVAILABLE,
397 "Emulator not initialized.");
398
400
401 uint32_t addr = request->start_address();
402 int fetch_size = request->count() * 4;
403 auto data_or = emulator_->ReadBlock(addr, fetch_size);
404 if (!data_or.ok()) return ToGrpcStatus(data_or.status());
405
406 const auto& data = *data_or;
407 auto mem_reader = [&](uint32_t read_addr) -> uint8_t {
408 if (read_addr >= addr && read_addr < addr + data.size()) {
409 return data[read_addr - addr];
410 }
411 return 0;
412 };
413
414 emu::CpuStateSnapshot cpu_snap;
415 auto cpu_status = emulator_->GetCpuState(&cpu_snap);
416 if (!cpu_status.ok()) return ToGrpcStatus(cpu_status);
417 bool m_flag = (cpu_snap.status & 0x20) != 0;
418 bool x_flag = (cpu_snap.status & 0x10) != 0;
419
420 for (uint32_t i = 0; i < request->count(); ++i) {
421 auto inst = dis.Disassemble(addr, mem_reader, m_flag, x_flag);
422 auto* line = response->add_lines();
423 line->set_address(inst.address);
424 line->set_mnemonic(inst.mnemonic);
425 line->set_operand_str(inst.operand_str);
426 addr += inst.size;
427 if (addr >= request->start_address() + fetch_size) break;
428 }
429 return grpc::Status::OK;
430}
431
433 grpc::ServerContext* context, const agent::TraceRequest* request,
434 agent::TraceResponse* response) {
435 return grpc::Status(grpc::StatusCode::UNIMPLEMENTED,
436 "Trace not implemented.");
437}
438
440 grpc::ServerContext* context, const agent::SymbolLookupRequest* request,
441 agent::SymbolLookupResponse* response) {
442 auto sym = symbol_provider_.FindSymbol(request->symbol_name());
443 if (sym) {
444 response->set_found(true);
445 response->set_symbol_name(sym->name);
446 response->set_address(sym->address);
447 }
448 return grpc::Status::OK;
449}
450
452 grpc::ServerContext* context, const agent::AddressRequest* request,
453 agent::SymbolLookupResponse* response) {
454 auto sym = symbol_provider_.GetSymbol(request->address());
455 if (sym) {
456 response->set_found(true);
457 response->set_symbol_name(sym->name);
458 response->set_address(sym->address);
459 }
460 return grpc::Status::OK;
461}
462
464 grpc::ServerContext* context, const agent::SymbolFileRequest* request,
465 agent::CommandResponse* response) {
466 auto status = symbol_provider_.LoadSymbolFile(
467 request->filepath(),
468 static_cast<emu::debug::SymbolFormat>(request->format()));
469 response->set_success(status.ok());
470 response->set_message(std::string(status.message()));
471 return grpc::Status::OK;
472}
473
474// --- Session & Experiments ---
475
477 grpc::ServerContext* context, const agent::Empty* request,
478 agent::DebugStatusResponse* response) {
479 if (!emulator_)
480 return grpc::Status(grpc::StatusCode::UNAVAILABLE,
481 "Emulator not initialized.");
482
483 response->set_is_running(emulator_->IsRunning());
484
485 emu::CpuStateSnapshot cpu_snap;
486 auto cpu_status = emulator_->GetCpuState(&cpu_snap);
487 if (!cpu_status.ok()) return ToGrpcStatus(cpu_status);
488 emu::ToProtoCpuState(cpu_snap, response->mutable_cpu_state());
489
490 response->set_active_breakpoints(emulator_->ListBreakpoints().size());
491 return grpc::Status::OK;
492}
493
495 grpc::ServerContext* context, const agent::TestRunRequest* request,
496 agent::TestRunResponse* response) {
497 return grpc::Status(grpc::StatusCode::UNIMPLEMENTED,
498 "TestRun requires refactoring for IEmulator");
499}
500
501// --- Save State Management ---
502
504 grpc::ServerContext* context, const agent::SaveStateRequest* request,
505 agent::SaveStateResponse* response) {
506 return grpc::Status(grpc::StatusCode::UNIMPLEMENTED,
507 "SaveState not yet ported to IEmulator");
508}
509
511 grpc::ServerContext* context, const agent::LoadStateRequest* request,
512 agent::LoadStateResponse* response) {
513 return grpc::Status(grpc::StatusCode::UNIMPLEMENTED,
514 "LoadState not yet ported to IEmulator");
515}
516
518 grpc::ServerContext* context, const agent::ListStatesRequest* request,
519 agent::ListStatesResponse* response) {
520 return grpc::Status(grpc::StatusCode::UNIMPLEMENTED,
521 "ListStates not yet ported to IEmulator");
522}
523
524} // namespace yaze::net
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:28
auto size() const
Definition rom.h:138
bool is_loaded() const
Definition rom.h:132
auto title() const
Definition rom.h:137
Abstract interface for emulator backends (Internal vs Mesen2)
Definition i_emulator.h:23
virtual bool IsRunning() const =0
virtual absl::StatusOr< std::vector< uint8_t > > ReadBlock(uint32_t addr, size_t len)=0
virtual void Pause()=0
virtual absl::Status StepOver()=0
virtual absl::Status LoadRom(const std::string &path)=0
virtual void Resume()=0
virtual absl::Status GetCpuState(CpuStateSnapshot *out_state)=0
virtual absl::Status RemoveBreakpoint(uint32_t breakpoint_id)=0
virtual absl::Status ToggleBreakpoint(uint32_t breakpoint_id, bool enabled)=0
virtual absl::Status Step(int count)=0
virtual absl::Status ReleaseButton(InputButton button)=0
virtual absl::Status GetGameState(GameSnapshot *out_state)=0
virtual absl::Status StepOut()=0
virtual std::string GetLoadedRomPath() const =0
virtual bool IsConnected() const =0
virtual absl::Status WriteBlock(uint32_t addr, const std::vector< uint8_t > &data)=0
virtual absl::Status PressButton(InputButton button)=0
virtual std::vector< BreakpointSnapshot > ListBreakpoints()=0
virtual absl::StatusOr< uint32_t > AddBreakpoint(uint32_t addr, BreakpointKind type, CpuKind cpu, const std::string &condition, const std::string &description)=0
virtual absl::Status RunToBreakpoint(BreakpointHitResult *response)=0
virtual void Reset()=0
65816 CPU disassembler for debugging and ROM hacking
DisassembledInstruction Disassemble(uint32_t address, MemoryReader read_byte, bool m_flag=true, bool x_flag=true) const
Disassemble a single instruction.
absl::Status LoadSymbolFile(const std::string &path, SymbolFormat format=SymbolFormat::kAuto)
Load symbols from a .sym file (various formats)
std::optional< Symbol > GetSymbol(uint32_t address) const
Get full symbol info for an address.
std::optional< Symbol > FindSymbol(const std::string &name) const
Find symbol by name.
grpc::Status GetSymbolAt(grpc::ServerContext *context, const agent::AddressRequest *request, agent::SymbolLookupResponse *response) override
std::function< bool(const std::string &path)> RomLoader
grpc::Status ControlEmulator(grpc::ServerContext *context, const agent::ControlRequest *request, agent::CommandResponse *response) override
grpc::Status TestRun(grpc::ServerContext *context, const agent::TestRunRequest *request, agent::TestRunResponse *response) override
grpc::Status GetDebugStatus(grpc::ServerContext *context, const agent::Empty *request, agent::DebugStatusResponse *response) override
grpc::Status WriteMemory(grpc::ServerContext *context, const agent::MemoryWriteRequest *request, agent::CommandResponse *response) override
grpc::Status ReleaseButtons(grpc::ServerContext *context, const agent::ButtonRequest *request, agent::CommandResponse *response) override
grpc::Status PressButtons(grpc::ServerContext *context, const agent::ButtonRequest *request, agent::CommandResponse *response) override
grpc::Status GetGameState(grpc::ServerContext *context, const agent::GameStateRequest *request, agent::GameStateResponse *response) override
grpc::Status BreakpointControl(grpc::ServerContext *context, const agent::BreakpointControlRequest *request, agent::BreakpointControlResponse *response) override
grpc::Status GetDisassembly(grpc::ServerContext *context, const agent::DisassemblyRequest *request, agent::DisassemblyResponse *response) override
grpc::Status LoadSymbols(grpc::ServerContext *context, const agent::SymbolFileRequest *request, agent::CommandResponse *response) override
grpc::Status ReadMemory(grpc::ServerContext *context, const agent::MemoryRequest *request, agent::MemoryResponse *response) override
grpc::Status StepEmulator(grpc::ServerContext *context, const agent::StepControlRequest *request, agent::StepResponse *response) override
grpc::Status HoldButtons(grpc::ServerContext *context, const agent::ButtonHoldRequest *request, agent::CommandResponse *response) override
grpc::Status LoadRom(grpc::ServerContext *context, const agent::LoadRomRequest *request, agent::LoadRomResponse *response) override
grpc::Status GetLoadedRomPath(grpc::ServerContext *context, const agent::Empty *request, agent::LoadedRomPathResponse *response) override
grpc::Status LoadState(grpc::ServerContext *context, const agent::LoadStateRequest *request, agent::LoadStateResponse *response) override
grpc::Status SaveState(grpc::ServerContext *context, const agent::SaveStateRequest *request, agent::SaveStateResponse *response) override
grpc::Status ResolveSymbol(grpc::ServerContext *context, const agent::SymbolLookupRequest *request, agent::SymbolLookupResponse *response) override
emu::debug::SymbolProvider symbol_provider_
grpc::Status ListStates(grpc::ServerContext *context, const agent::ListStatesRequest *request, agent::ListStatesResponse *response) override
grpc::Status GetExecutionTrace(grpc::ServerContext *context, const agent::TraceRequest *request, agent::TraceResponse *response) override
grpc::Status RunToBreakpoint(grpc::ServerContext *context, const agent::Empty *request, agent::BreakpointHitResponse *response) override
EmulatorServiceImpl(emu::IEmulator *emulator, RomGetter rom_getter=nullptr, RomLoader rom_loader=nullptr)
grpc::Status WatchpointControl(grpc::ServerContext *context, const agent::WatchpointControlRequest *request, agent::WatchpointControlResponse *response) override
SymbolFormat
Supported symbol file formats.