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;

    }
}
Example #4
0
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;
}