static void setCallstack(LLDBPlugin* plugin, PDWriter* writer) { lldb::SBThread thread(plugin->process.GetThreadByID(plugin->selectedThreadId)); printf("set callstack\n"); int frameCount = (int)thread.GetNumFrames(); if (frameCount == 0) return; // TODO: Write type of callstack PDWrite_event_begin(writer, PDEventType_SetCallstack); PDWrite_array_begin(writer, "callstack"); for (int i = 0; i < frameCount; ++i) { char fileLine[2048]; char moduleName[2048]; lldb::SBFrame frame = thread.GetFrameAtIndex((uint32_t)i); lldb::SBModule module = frame.GetModule(); lldb::SBCompileUnit compileUnit = frame.GetCompileUnit(); lldb::SBSymbolContext context(frame.GetSymbolContext(0x0000006e)); lldb::SBLineEntry entry(context.GetLineEntry()); uint64_t address = (uint64_t)frame.GetPC(); module.GetFileSpec().GetPath(moduleName, sizeof(moduleName)); PDWrite_array_entry_begin(writer); if (compileUnit.GetNumSupportFiles() > 0) { char filename[2048]; lldb::SBFileSpec fileSpec = compileUnit.GetSupportFileAtIndex(0); fileSpec.GetPath(filename, sizeof(filename)); sprintf(fileLine, "%s:%d", filename, entry.GetLine()); printf("callstack %s:%d\n", fileLine, entry.GetLine()); PDWrite_string(writer, "filename", filename); PDWrite_u32(writer, "line", entry.GetLine()); } PDWrite_string(writer, "module_name", moduleName); PDWrite_u64(writer, "address", address); PDWrite_entry_end(writer); } PDWrite_array_end(writer); PDWrite_event_end(writer); }
static void write_status_registers(PDWriter* writer, const char* name, uint16_t reg) { PDWrite_array_entry_begin(writer); PDWrite_string(writer, "name", name); PDWrite_u8(writer, "read_only", 1); char statusString[128] = { 0 }; sprintf(statusString, "0x$%2x N:%d V:%d -:%d B:%d D:%d I:%d Z:%d C:%d", reg, (reg >> 7) & 1, (reg >> 6) & 1, (reg >> 5) & 1, (reg >> 4) & 1, (reg >> 3) & 1, (reg >> 2) & 1, (reg >> 1) & 1, (reg >> 0) & 1); PDWrite_string(writer, "register_string", statusString); PDWrite_entry_end(writer); }
void test_c64_vice_breakpoint_cond(void**) { CPUState state = { 0 }; Session_action(s_session, PDAction_step); const uint64_t breakAddress = 0x0816; stepToPC(0x080e); // Add a breakpoint at 0x0814 PDWriter* writer = s_session->currentWriter; PDWrite_eventBegin(writer, PDEventType_setBreakpoint); PDWrite_u64(writer, "address", breakAddress); PDWrite_string(writer, "condition", ".y == 0"); PDWrite_eventEnd(writer); PDBinaryWriter_finalize(writer); Session_update(s_session); Session_action(s_session, PDAction_run); waitForBreak(breakAddress, &state, CPUState_maskY); }
static void setExceptionLocation(LLDBPlugin* plugin, PDWriter* writer) { char filename[2048]; memset(filename, 0, sizeof(filename)); // Get the filename & line of the exception/breakpoint // \todo: Right now we assume that we only got the break/exception at the first thread. lldb::SBThread thread(plugin->process.GetThreadByID(plugin->selectedThreadId)); uint32_t frameIndex = getThreadFrame(plugin, plugin->selectedThreadId); lldb::SBFrame frame(thread.GetFrameAtIndex(frameIndex)); lldb::SBCompileUnit compileUnit = frame.GetCompileUnit(); lldb::SBFileSpec filespec(plugin->process.GetTarget().GetExecutable()); if (compileUnit.GetNumSupportFiles() > 0) { lldb::SBFileSpec fileSpec = compileUnit.GetSupportFileAtIndex(0); fileSpec.GetPath(filename, sizeof(filename)); } lldb::SBSymbolContext context(frame.GetSymbolContext(lldb::eSymbolContextEverything)); lldb::SBLineEntry entry(context.GetLineEntry()); uint32_t line = entry.GetLine(); PDWrite_event_begin(writer, PDEventType_SetExceptionLocation); PDWrite_string(writer, "filename", filename); PDWrite_u32(writer, "line", line); PDWrite_event_end(writer); }
static void setThreads(LLDBPlugin* plugin, PDWriter* writer) { uint32_t threadCount = plugin->process.GetNumThreads(); if (threadCount == 0) return; PDWrite_event_begin(writer, PDEventType_SetThreads); PDWrite_array_begin(writer, "threads"); for (uint32_t i = 0; i < threadCount; ++i) { lldb::SBThread thread = plugin->process.GetThreadAtIndex(i); lldb::SBFrame frame = thread.GetFrameAtIndex(0); uint64_t threadId = thread.GetThreadID(); const char* threadName = thread.GetName(); const char* queueName = thread.GetQueueName(); const char* functionName = frame.GetFunctionName(); PDWrite_array_entry_begin(writer); PDWrite_u64(writer, "id", threadId); if (threadName) PDWrite_string(writer, "name", threadName); else if (queueName) PDWrite_string(writer, "name", queueName); else PDWrite_string(writer, "name", "unknown_thread"); if (functionName) PDWrite_string(writer, "function", functionName); else PDWrite_string(writer, "function", "unknown_function"); PDWrite_entry_end(writer); } PDWrite_array_end(writer); PDWrite_event_end(writer); }
static void setDisassembly(PDWriter* writer, int start, int instCount) { char temp[65536]; disassembleToBuffer(temp, &start, &instCount); PDWrite_eventBegin(writer, PDEventType_setDisassembly); PDWrite_u16(writer, "address_start", (uint16_t)start); PDWrite_u16(writer, "instruction_count", (uint16_t)instCount); PDWrite_string(writer, "string_buffer", temp); PDWrite_eventEnd(writer); }
static void setLocals(LLDBPlugin* plugin, PDWriter* writer) { lldb::SBThread thread(plugin->process.GetThreadByID(plugin->selectedThreadId)); lldb::SBFrame frame = thread.GetSelectedFrame(); lldb::SBValueList variables = frame.GetVariables(true, true, true, false); uint32_t count = variables.GetSize(); if (count <= 0) return; PDWrite_event_begin(writer, PDEventType_SetLocals); PDWrite_array_begin(writer, "locals"); for (uint32_t i = 0; i < count; ++i) { lldb::SBValue value = variables.GetValueAtIndex(i); PDWrite_array_entry_begin(writer); PDWrite_u64(writer, "address", value.GetAddress().GetFileAddress()); if (value.GetValue()) PDWrite_string(writer, "value", value.GetValue()); if (value.GetTypeName()) PDWrite_string(writer, "type", value.GetTypeName()); if (value.GetName()) PDWrite_string(writer, "name", value.GetName()); PDWrite_entry_end(writer); } PDWrite_array_end(writer); PDWrite_event_end(writer); }
static void setTty(LLDBPlugin* plugin, PDWriter* writer) { const int bufferSize = 4 * 1024; char buffer[bufferSize]; size_t amountRead = plugin->process.GetSTDOUT(buffer, bufferSize); if (amountRead > 0) { PDWrite_event_begin(writer, PDEventType_SetTty); PDWrite_string(writer, "tty", buffer); PDWrite_event_end(writer); } }
static bool del_breakpoint(PluginData* data, PDReader* reader, PDWriter* writer) { int32_t id; if (PDRead_find_s32(reader, &id, "id", 0) == PDReadStatus_NotFound) { PDWrite_event_begin(writer, PDEventType_ReplyBreakpoint); PDWrite_string(writer, "error", "No ID being sent for breakpoint"); PDWrite_event_end(writer); return false; } log_debug("deleting breakpoint with id %d\n", id); return del_breakpoint_by_id(data, id); }
static void writeRegister(PDWriter* writer, const char* name, uint8_t size, uint16_t reg, uint8_t readOnly) { PDWrite_arrayEntryBegin(writer); PDWrite_string(writer, "name", name); PDWrite_u8(writer, "size", size); if (readOnly) PDWrite_u8(writer, "read_only", 1); if (size == 2) PDWrite_u16(writer, "register", reg); else PDWrite_u8(writer, "register", (uint8_t)reg); PDWrite_arrayEntryEnd(writer); }
static bool delBreakpoint(PluginData* data, PDReader* reader, PDWriter* writer) { int32_t id; if (PDRead_findS32(reader, &id, "id", 0) == PDReadStatus_notFound) { PDWrite_eventBegin(writer, PDEventType_replyBreakpoint); PDWrite_string(writer, "error", "No ID being sent for breakpoint"); PDWrite_eventEnd(writer); return false; } printf("deleting breakpoint with id %d\n", id); return delBreakpointById(data, id); }
bool parse_disassassembly_call(PluginData* plugin, const char* res, int len, PDReader* reader, PDWriter* writer) { memcpy(TEMP_BUFFER, res, len); TEMP_BUFFER[len] = 0; (void)plugin; (void)reader; // parse the buffer char* pch = strtok(TEMP_BUFFER, "\n"); PDWrite_event_begin(writer, PDEventType_SetDisassembly); PDWrite_array_begin(writer, "disassembly"); bool hasAllDisasembly = false; while (pch) { // expected format of each line: // xxx.. .C:080e A9 22 LDA #$22 char* endOfStream = strstr(pch, "(C:"); char* line = strstr(pch, ".C"); if (endOfStream) { hasAllDisasembly = true; break; } if (!line) break; uint16_t address = (uint16_t)strtol(&line[3], 0, 16); PDWrite_array_entry_begin(writer); PDWrite_u16(writer, "address", address); PDWrite_string(writer, "line", parse_disassembly_line(&line[9])); PDWrite_entry_end(writer); pch = strtok(0, "\n"); } PDWrite_array_end(writer); PDWrite_event_end(writer); return hasAllDisasembly; }
static void toggleBreakpointCurrentLine(PDUISCInterface* sourceFuncs, SourceCodeData* data, PDWriter* writer) { (void)data; (void)writer; PDUI_sc_send_command(sourceFuncs, SCN_TOGGLE_BREAKPOINT, 0, 0); uint32_t currentLine = (uint32_t)PDUI_sc_send_command(sourceFuncs, SCN_GETCURRENT_LINE, 0, 0); printf("currentLine %d\n", currentLine); // TODO: Currenty we don't handly if we set breakpoints on a line we can't PDWrite_event_begin(writer, PDEventType_SetBreakpoint); PDWrite_string(writer, "filename", data->filename); PDWrite_u32(writer, "line", currentLine); PDWrite_event_end(writer); }
static void write_register(PDWriter* writer, const char* name, uint8_t size, uint16_t reg, uint8_t read_only) { PDWrite_array_entry_begin(writer); PDWrite_string(writer, "name", name); PDWrite_u8(writer, "size", size); if (read_only) { PDWrite_u8(writer, "read_only", 1); } if (size == 2) { PDWrite_u16(writer, "register", reg); } else { PDWrite_u8(writer, "register", (uint8_t)reg); } PDWrite_entry_end(writer); }
void test_c64_vice_start_executable(void**) { const char* prgFile = "/Users/danielcollin/code/ProDBG/examples/c64_vice/test.prg"; PDWriter* writer = s_session->currentWriter; PDWrite_eventBegin(writer, PDEventType_setExecutable); PDWrite_string(writer, "filename", prgFile); PDWrite_eventEnd(writer); PDBinaryWriter_finalize(writer); Session_update(s_session); // Annoying to da anything about this as VICE doesn't reply back anything // when doing <g $xxx> Time_sleepMs(200); }
static void setSourceFiles(LLDBPlugin* plugin, PDWriter* writer) { if (!plugin->hasValidTarget) return; PDWrite_event_begin(writer, PDEventType_SetSourceFiles); PDWrite_array_begin(writer, "files"); const uint32_t moduleCount = plugin->target.GetNumModules(); for (uint32_t im = 0; im < moduleCount; ++im) { lldb::SBModule module(plugin->target.GetModuleAtIndex(im)); const uint32_t compileUnitCount = module.GetNumCompileUnits(); for (uint32_t ic = 0; ic < compileUnitCount; ++ic) { lldb::SBCompileUnit compileUnit(module.GetCompileUnitAtIndex(ic)); const uint32_t supportFileCount = compileUnit.GetNumSupportFiles(); for (uint32_t is = 0; is < supportFileCount; ++is) { char filename[4096]; lldb::SBFileSpec fileSpec(compileUnit.GetSupportFileAtIndex(is)); filename[0] = 0; fileSpec.GetPath(filename, sizeof(filename)); if (filename[0] == 0) continue; PDWrite_array_entry_begin(writer); PDWrite_string(writer, "file", filename); PDWrite_entry_end(writer); } } } PDWrite_array_end(writer); PDWrite_event_end(writer); }
static int update(void* userData, PDUI* uiFuncs, PDReader* inEvents, PDWriter* outEvents) { ConsoleData* consoleData = (ConsoleData*)userData; uint32_t event = 0; (void)event; // test working build /*while ((event = PDRead_getEvent(inEvents)) != 0) { switch (event) { case PDEventType_setConsole: { //showInUI((ConsoleData*)userData, inEvents, uiFuncs); break; } } }*/ showInUI(consoleData, inEvents, uiFuncs); for (size_t i = 0; i < consoleData->scripts.size(); ++i) { PDWrite_eventBegin(outEvents, PDEventType_executeConsole); PDWrite_string(outEvents, "command", consoleData->scripts[i]); // TODO: Remove me PDWrite_eventEnd(outEvents); //free(consoleData->scripts[i]); } consoleData->scripts.clear(); // Request console data PDWrite_eventBegin(outEvents, PDEventType_getConsole); PDWrite_u8(outEvents, "dummy_remove", 0); // TODO: Remove me PDWrite_eventEnd(outEvents); return 0; }
static void parseDisassembly(PDWriter* writer, const char* data, int length) { memcpy(s_tempBuffer, data, length); s_tempBuffer[length] = 0; // parse the buffer char* pch = strtok(s_tempBuffer, "\n"); PDWrite_eventBegin(writer, PDEventType_setDisassembly); PDWrite_arrayBegin(writer, "disassembly"); while (pch) { // expected format of each line: // xxx.. .C:080e A9 22 LDA #$22 char* line = strstr(pch, ".C"); if (!line) break; uint16_t address = (uint16_t)strtol(&line[3], 0, 16); PDWrite_arrayEntryBegin(writer); PDWrite_u16(writer, "address", address); PDWrite_string(writer, "line", parseDisassemblyLine(&line[9])); PDWrite_arrayEntryEnd(writer); pch = strtok(0, "\n"); } PDWrite_arrayEnd(writer); PDWrite_eventEnd(writer); }