void test_c64_vice_basic_breakpoint(void**) { Session_action(s_session, PDAction_step); uint64_t breakAddress = 0x0813; stepToPC(0x080e); // Add a breakpoint at 0x0814 PDWriter* writer = s_session->currentWriter; PDWrite_eventBegin(writer, PDEventType_setBreakpoint); PDWrite_u64(writer, "address", breakAddress); PDWrite_eventEnd(writer); PDBinaryWriter_finalize(writer); Session_update(s_session); Session_action(s_session, PDAction_run); waitForBreak(breakAddress, 0, 0); stepToPC(0x080e); // Update the breakpoint to different address breakAddress = 0x0816; writer = s_session->currentWriter; PDWrite_eventBegin(writer, PDEventType_setBreakpoint); PDWrite_u64(writer, "address", breakAddress); PDWrite_u64(writer, "id", 1); PDWrite_eventEnd(writer); PDBinaryWriter_finalize(writer); Session_update(s_session); Session_action(s_session, PDAction_run); waitForBreak(breakAddress, 0, 0); // Delete the breakpoint stepToPC(0x080e); writer = s_session->currentWriter; PDWrite_eventBegin(writer, PDEventType_deleteBreakpoint); PDWrite_u32(writer, "id", 2); PDWrite_eventEnd(writer); PDBinaryWriter_finalize(writer); Session_update(s_session); Session_action(s_session, PDAction_run); }
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); }
void test_c64_vice_get_disassembly(void**) { static Assembly assembly[] = { { 0x080e, "A9 22 LDA #$22" }, { 0x0810, "A2 32 LDX #$32" }, { 0x0812, "C8 INY" }, { 0x0813, "EE 20 D0 INC $D020" }, { 0x0816, "EE 21 D0 INC $D021" }, { 0x0819, "4C 0E 08 JMP $080E" }, { 0, 0 }, }; PDWriter* writer = s_session->currentWriter; PDWrite_eventBegin(writer, PDEventType_getDisassembly); PDWrite_u64(writer, "address_start", 0x80e); PDWrite_u32(writer, "instruction_count", (uint32_t)4); PDWrite_eventEnd(writer); PDBinaryWriter_finalize(writer); Session_update(s_session); PDReader* reader = s_session->reader; PDBinaryReader_initStream(reader, PDBinaryWriter_getData(s_session->currentWriter), PDBinaryWriter_getSize(s_session->currentWriter)); uint32_t event; while ((event = PDRead_getEvent(reader)) != 0) { if (event != PDEventType_setDisassembly) continue; PDReaderIterator it; assert_false(PDRead_findArray(reader, &it, "disassembly", 0) == PDReadStatus_notFound); int i = 0; while (PDRead_getNextEntry(reader, &it)) { uint64_t address; const char* text; PDRead_findU64(reader, &address, "address", it); PDRead_findString(reader, &text, "line", it); assert_non_null(assembly[i].text); assert_int_equal((int)assembly[i].address, (int)address); assert_string_equal(assembly[i].text, text); i++; } return; } }
static void test_lldb(void** state) { (void)state; // we only do the LLDB test on Mac for now #ifdef __APPLE__ PluginData* pluginData; Session* session; int count = 0; assert_true(PluginHandler_addPlugin(OBJECT_DIR, "lldb_plugin")); assert_non_null(pluginData = PluginHandler_getBackendPlugins(&count)[0]); session = Session_createLocal((PDBackendPlugin*)pluginData->plugin, OBJECT_DIR "/crashing_native"); assert_non_null(session); // I hate to do this but there is really no good way to deal with this otherwise (at least currently) Time_sleepMs(800); Session_update(session); Session_update(session); // Expect that we have a crash here and thus are in PDDebugState_stopException state assert_int_equal(session->state, PDDebugState_StopException); // Request locals location. PDWriter* writer = session->currentWriter; PDReader* reader = session->reader; PDWrite_event_begin(writer, PDEventType_GetCallstack); PDWrite_u8(writer, "dummy", 0); PDWrite_event_end(writer); Session_update(session); PDBinaryWriter_finalize(session->currentWriter); PDBinaryReader_initStream(reader, PDBinaryWriter_getData(session->currentWriter), PDBinaryWriter_getSize(session->currentWriter)); uint32_t event; bool foundCallstack = false; while ((event = PDRead_get_event(reader)) != 0) { switch (event) { case PDEventType_SetCallstack: { foundCallstack = true; break; } } } assert_true(foundCallstack); #endif }
void test_c64_vice_callstack(void**) { uint32_t event; PDReaderIterator it; uint16_t refCallstack[] = { 0xe112 + 2, // (2) e112 0xa562 + 4, // (4) a562 0xa483 + 6, // (6) a483 0xa677 + 8, // (8) a677 0xe39a + 10, // (10) e39a }; PDWriter* writer = s_session->currentWriter; PDWrite_eventBegin(writer, PDEventType_getCallstack); PDWrite_eventEnd(writer); PDBinaryWriter_finalize(writer); Session_update(s_session); PDReader* reader = s_session->reader; PDBinaryReader_initStream(reader, PDBinaryWriter_getData(s_session->currentWriter), PDBinaryWriter_getSize(s_session->currentWriter)); while ((event = PDRead_getEvent(reader)) != 0) { switch (event) { case PDEventType_setCallstack: { if (PDRead_findArray(reader, &it, "callstack", 0) == PDReadStatus_notFound) return; int callstackSize = sizeof_array(refCallstack); int count = 0; while (PDRead_getNextEntry(reader, &it)) { uint16_t address; PDRead_findU16(reader, &address, "address", it); assert_true(count < callstackSize); assert_int_equal(refCallstack[count], address); count++; } return; } } } fail(); }
void test_c64_vice_step_cpu(void**) { CPUState state; Session_action(s_session, PDAction_step); assert_true(handleEvents(&state, s_session)); assert_true(state.pc >= 0x80e && state.pc <= 0x81a); assert_int_equal(state.a, 0x22); assert_int_equal(state.x, 0x32); Session_action(s_session, PDAction_step); assert_true(handleEvents(&state, s_session)); assert_true(state.pc >= 0x80e && state.pc <= 0x81a); Session_action(s_session, PDAction_step); assert_true(handleEvents(&state, s_session)); assert_true(state.pc >= 0x80e && state.pc <= 0x81a); // Get registers after some stepping PDWriter* writer = s_session->currentWriter; PDWrite_eventBegin(writer, PDEventType_getRegisters); PDWrite_eventEnd(writer); PDBinaryWriter_finalize(writer); assert_true(handleEvents(&state, s_session)); assert_true(state.pc >= 0x80e && state.pc <= 0x81a); writer = s_session->currentWriter; PDWrite_eventBegin(writer, PDEventType_getRegisters); PDWrite_eventEnd(writer); PDBinaryWriter_finalize(writer); assert_true(handleEvents(&state, s_session)); assert_true(state.pc >= 0x80e && state.pc <= 0x81a); }
void test_c64_vice_get_registers(void**) { CPUState state; PDWriter* writer = s_session->currentWriter; PDWrite_eventBegin(writer, PDEventType_getRegisters); PDWrite_eventEnd(writer); PDBinaryWriter_finalize(writer); Session_update(s_session); assert_true(handleEvents(&state, s_session)); assert_true(state.pc >= 0x80e && state.pc <= 0x81a); }
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); }
bool getMemory(void* dest, int* len, uint16_t inAddress, int readLength) { PDWriter* writer = s_session->currentWriter; PDWrite_eventBegin(writer, PDEventType_getMemory); PDWrite_u64(writer, "address_start", inAddress); PDWrite_u64(writer, "size", (uint32_t)readLength); PDWrite_eventEnd(writer); PDBinaryWriter_finalize(writer); Session_update(s_session); PDReader* reader = s_session->reader; PDBinaryReader_initStream(reader, PDBinaryWriter_getData(s_session->currentWriter), PDBinaryWriter_getSize(s_session->currentWriter)); uint32_t event; while ((event = PDRead_getEvent(reader)) != 0) { uint8_t* data; uint64_t dataSize; uint64_t address; if (event != PDEventType_setMemory) continue; assert_true(PDRead_findU64(reader, &address, "address", 0) & PDReadStatus_ok); assert_true((PDRead_findData(reader, (void**)&data, &dataSize, "data", 0) & PDReadStatus_typeMask) == PDReadType_data); memcpy(dest, data, dataSize); *len = (int)dataSize; return true; } return false; }