void getRegisterString(char* value, PDReader* reader, PDReaderIterator it) { uint64_t regValue = 0; const char* regString = 0; // Support that backend can write down value in custom format if (PDRead_find_string(reader, ®String, "register_string", it) & PDReadStatus_Ok) { strncpy(value, regString, ValueSize); return; } uint32_t type = PDRead_find_u64(reader, ®Value, "register", it); switch (type & PDReadStatus_TypeMask) { case PDReadType_U8: sprintf(value, "0x%02x", (uint8_t)regValue); break; case PDReadType_S8: sprintf(value, "0x%02x", (int8_t)regValue); break; case PDReadType_U16: sprintf(value, "0x%04x", (uint16_t)regValue); break; case PDReadType_S16: sprintf(value, "0x%04x", (int16_t)regValue); break; case PDReadType_U32: sprintf(value, "0x%08x", (uint32_t)regValue); break; case PDReadType_S32: sprintf(value, "0x%08x", (int32_t)regValue); break; } }
static int update(void* user_data, PDUI* uiFuncs, PDReader* inEvents, PDWriter* writer) { uint32_t event; DissassemblyData* data = (DissassemblyData*)user_data; data->requestDisassembly = false; while ((event = PDRead_get_event(inEvents)) != 0) { switch (event) { case PDEventType_SetDisassembly: { setDisassemblyCode(data, inEvents); break; } case PDEventType_SetExceptionLocation: { uint64_t location = 0; PDRead_find_u64(inEvents, &location, "address", 0); if (location != data->location) { data->location = location; data->requestDisassembly = true; } PDRead_find_u8(inEvents, &data->locationSize, "address_size", 0); break; } case PDEventType_SetRegisters: { updateRegisters(data, inEvents); break; } } } renderUI(data, uiFuncs); if (data->requestDisassembly) { int pc = (int)(data->pc) & ~(BlockSize - 1); PDWrite_event_begin(writer, PDEventType_GetDisassembly); PDWrite_u64(writer, "address_start", (uint64_t)pc); PDWrite_u32(writer, "instruction_count", (uint32_t)BlockSize / 3); PDWrite_event_end(writer); } return 0; }
static void get_memory(PluginData* data, PDReader* reader, PDWriter* writer) { uint64_t address; uint64_t size; size_t read_size = 0; PDRead_find_u64(reader, &address, "address_start", 0); PDRead_find_u64(reader, &size, "size", 0); // so this is a bit of a hack. If we request memory d000 we switch to io and then back // this isn't really correct but will do for now if (address == 0xdd00) { send_command(data, "bank io\n"); } uint8_t* memory = get_memory_internal(data, data->temp_file_full, &read_size, (uint16_t)(address), (uint16_t)(address + size)); if (address == 0xdd00) { send_command(data, "bank ram\n"); } if (memory) { // Lets do this! // + 2 is because VICE writes address at the start of the block and at the end // log_debug("c64_vice: sending memory\n", ""); PDWrite_event_begin(writer, PDEventType_SetMemory); PDWrite_u64(writer, "address", address); PDWrite_data(writer, "data", memory + 2, (uint32_t)(read_size - 3)); PDWrite_event_end(writer); // writer takes a copy free(memory); } }
static void showInUI(ThreadsData* user_data, PDReader* reader, PDUI* uiFuncs) { PDReaderIterator it; ThreadsData* data = (ThreadsData*)user_data; if (PDRead_find_array(reader, &it, "threads", 0) == PDReadStatus_NotFound) return; uiFuncs->text(""); uiFuncs->columns(3, "threads", true); uiFuncs->text("Id"); uiFuncs->next_column(); uiFuncs->text("Name"); uiFuncs->next_column(); uiFuncs->text("Function"); uiFuncs->next_column(); int i = 0; PDVec2 size = { 0.0f, 0.0f }; data->setSelectedThread = false; int oldSelectedThread = data->selectedThread; while (PDRead_get_next_entry(reader, &it)) { uint64_t id; const char* name = ""; const char* function = ""; PDRead_find_u64(reader, &id, "id", it); PDRead_find_string(reader, &name, "name", it); PDRead_find_string(reader, &function, "function", it); char label[32]; sprintf(label, "%llx", id); if (uiFuncs->selectable(label, data->selectedThread == i, 1 << 1, size)) { data->selectedThread = i; data->threadId = (int)id; } uiFuncs->next_column(); uiFuncs->text(name); uiFuncs->next_column(); uiFuncs->text(function); uiFuncs->next_column(); i++; } if (oldSelectedThread != data->selectedThread) { data->setSelectedThread = true; } }
static bool get_disassembly(PluginData* data, PDReader* reader, PDWriter* writer) { char temp[2048]; uint64_t address_start = 0; uint32_t instruction_count = 0; PDRead_find_u64(reader, &address_start, "address_start", 0); PDRead_find_u32(reader, &instruction_count, "instruction_count", 0); // assume that one instruction is 3 bytes which is high but that gives us more data back than we need which is better than too little sprintf(temp, "disass $%04x $%04x\n", (uint16_t)address_start, (uint16_t)(address_start + instruction_count * 3)); return send_command_get_data(data, temp, parse_disassassembly_call, reader, writer, 20); }
static void updateRegisters(DissassemblyData* data, PDReader* reader) { PDReaderIterator it; if (PDRead_find_array(reader, &it, "registers", 0) == PDReadStatus_NotFound) return; while (PDRead_get_next_entry(reader, &it)) { const char* name = ""; PDRead_find_string(reader, &name, "name", it); if (!strcmp(name, "pc")) { PDRead_find_u64(reader, &data->pc, "register", it); } } }
static void setDisassemblyCode(DissassemblyData* data, PDReader* reader) { PDReaderIterator it; if (PDRead_find_array(reader, &it, "disassembly", 0) == PDReadStatus_NotFound) return; while (PDRead_get_next_entry(reader, &it)) { uint64_t address; const char* text; PDRead_find_u64(reader, &address, "address", it); PDRead_find_string(reader, &text, "line", it); insertLine(data, address, text); } }
static void selectThread(LLDBPlugin* plugin, PDReader* reader, PDWriter* writer) { uint64_t threadId; PDRead_find_u64(reader, &threadId, "thread_id", 0); printf("trying te set thread %llu\n", threadId); if (plugin->selectedThreadId == threadId) return; printf("selecting thread %llu\n", threadId); plugin->selectedThreadId = threadId; setCallstack(plugin, writer); PDWrite_event_begin(writer, PDEventType_SelectFrame); PDWrite_u32(writer, "frame", getThreadFrame(plugin, threadId)); PDWrite_event_end(writer); }
static void getAddressString(char* value, PDReader* reader, PDReaderIterator it) { uint64_t regValue; uint32_t type = PDRead_find_u64(reader, ®Value, "address", it); switch (type & PDReadStatus_TypeMask) { case PDReadType_U8: sprintf(value, "0x%02x", (uint8_t)regValue); break; case PDReadType_S8: sprintf(value, "0x%02x", (int8_t)regValue); break; case PDReadType_U16: sprintf(value, "0x%04x", (uint16_t)regValue); break; case PDReadType_S16: sprintf(value, "0x%04x", (int16_t)regValue); break; case PDReadType_U32: sprintf(value, "0x%08x", (uint32_t)regValue); break; case PDReadType_S32: sprintf(value, "0x%08x", (int32_t)regValue); break; case PDReadType_U64: sprintf(value, "0x%014llx", (uint64_t)regValue); break; case PDReadType_S64: sprintf(value, "0x%014llx", (int64_t)regValue); break; } }
static bool set_breakpoint(PluginData* data, PDReader* reader, PDWriter* writer) { uint64_t address = 0; int32_t id = -1; const char* condition = 0; PDRead_find_s32(reader, &id, "id", 0); PDRead_find_u64(reader, &address, "address", 0); PDRead_find_string(reader, &condition, "condition", 0); log_debug("got breakpoint %d %llu %s\n", id, address, condition); if (id != -1) del_breakpoint_by_id(data, id); char temp[1024]; if (condition) { sprintf(temp, "break $%04x if %s\n", (uint16_t)address, condition); } else { sprintf(temp, "break $%04x\n", (uint16_t)address); } return send_command_get_data(data, temp, parse_breakpoint_call, reader, writer, 20); }
static int update(void* user_data, PDUI* uiFuncs, PDReader* reader, PDWriter* writer) { uint32_t event; CallstackData* data = (CallstackData*)user_data; data->request = false; data->setSelectedFrame = false; while ((event = PDRead_get_event(reader)) != 0) { switch (event) { case PDEventType_SetCallstack: { updateCallstack(data, reader); break; } case PDEventType_SelectFrame: { PDRead_find_u32(reader, &data->selectedFrame, "frame", 0); break; } case PDEventType_SetExceptionLocation: { const char* filename = 0; uint32_t line = 0; uint64_t location = 0; PDRead_find_u64(reader, &location, "address", 0); if (location != data->location) { data->location = location; data->request = true; } PDRead_find_string(reader, &filename, "filename", 0); PDRead_find_u32(reader, &line, "line", 0); if (!filename || line == 0) break; if (strcmp(data->filename, filename)) { strcpy(data->filename, filename); data->line = (int)line; data->request = true; } } } } showUI(uiFuncs, data); if (data->setSelectedFrame) { PDWrite_event_begin(writer, PDEventType_SelectFrame); PDWrite_u32(writer, "frame", (uint32_t)data->selectedFrame); PDWrite_event_end(writer); } if (data->request) { PDWrite_event_begin(writer, PDEventType_GetCallstack); PDWrite_event_end(writer); } return 0; }