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);
}
static void setExceptionLocation(PDWriter* writer)
{
    PDWrite_eventBegin(writer,PDEventType_setExceptionLocation); 
    PDWrite_u16(writer, "address", pc);
    PDWrite_u8(writer, "address_size", 2);
    PDWrite_eventEnd(writer);
}
Example #4
0
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_eventBegin(writer, PDEventType_setExceptionLocation);
    PDWrite_string(writer, "filename", filename);
    PDWrite_u32(writer, "line", line);
    PDWrite_eventEnd(writer);
}
static int update(void* userData, PDUI* uiFuncs, PDReader* inEvents, PDWriter* outEvents)
{
    uint32_t event = 0;

    while ((event = PDRead_getEvent(inEvents)) != 0)
    {
        switch (event)
        {
            case PDEventType_setLocals:
            {
                showInUI((LocalsData*)userData, inEvents, uiFuncs);
                break;
            }
        }
    }

    // Request callstack data
    // TODO: Dont' request locals all the time

    PDWrite_eventBegin(outEvents, PDEventType_getLocals);
    PDWrite_u8(outEvents, "dummy_remove", 0);   // TODO: Remove me
    PDWrite_eventEnd(outEvents);

    return 0;
}
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;

    }
}
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();
}
static int update(void* userData, PDUI* uiFuncs, PDReader* inEvents, PDWriter* writer)
{
    uint32_t event;

    DissassemblyData* data = (DissassemblyData*)userData;

    data->requestDisassembly = false;

    while ((event = PDRead_getEvent(inEvents)) != 0)
    {
        switch (event)
        {
            case PDEventType_setDisassembly:
            {
                setDisassemblyCode(data, inEvents);
                break;
            }

            case PDEventType_setExceptionLocation:
            {
                uint64_t location = 0;

                PDRead_findU64(inEvents, &location, "address", 0);

                if (location != data->location)
                {
                    data->location = location;
                    data->requestDisassembly = true;
                }

                PDRead_findU8(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_eventBegin(writer, PDEventType_getDisassembly);
        PDWrite_u64(writer, "address_start", (uint64_t)pc);
        PDWrite_u32(writer, "instruction_count", (uint32_t)BlockSize / 3);
        PDWrite_eventEnd(writer);
    }

    return 0;
}
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);
}
Example #10
0
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_eventBegin(writer, PDEventType_setCallstack);
    PDWrite_arrayBegin(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_arrayEntryBegin(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_arrayEntryEnd(writer);
    }

    PDWrite_arrayEnd(writer);
    PDWrite_eventEnd(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;
}
Example #12
0
static void parseForCallstack(PDWriter* writer, const char* data, int length)
{
	uint16_t callStackEntries[256 * 2];
	int callStackCount = 0;

	memcpy(s_tempBuffer, data, length);
	s_tempBuffer[length] = 0;

    char* pch = strtok(s_tempBuffer, "\n");

    while (pch)
    {
        // expected format of each line:
        // xxx.. .C:080e  A9 22       LDA #$22

        if (pch[0] == '(' &&  pch[1] != 'C')
		{
			uint32_t offset = (uint32_t)atoi(&pch[2]);

			char* endOffset = strstr(&pch[2], ") ");

			if (endOffset)
			{
				endOffset += 2;

				uint16_t address = (uint16_t)strtol(endOffset, 0, 16);

				callStackEntries[(callStackCount * 2) + 0] = address;
				callStackEntries[(callStackCount * 2) + 1] = (uint16_t)offset;

				callStackCount++;
			}
		}

		pch = strtok(0, "\n");
    }
	
	if (callStackCount == 0)
		return;

    PDWrite_eventBegin(writer, PDEventType_setCallstack);
    PDWrite_arrayBegin(writer, "callstack");

    for (int i = 0; i < callStackCount; ++i)
	{
        PDWrite_arrayEntryBegin(writer);
        PDWrite_u16(writer, "address", callStackEntries[(i * 2) + 0] + callStackEntries[(i * 2) + 1]);
        PDWrite_arrayEntryEnd(writer);
	}

    PDWrite_arrayEnd(writer);
    PDWrite_eventEnd(writer);
}
Example #13
0
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);
}
Example #14
0
static PDDebugState update(void* userData, PDAction action, PDReader* reader, PDWriter* writer)
{
    PluginData* plugin = (PluginData*)userData;

    plugin->hasUpdatedRegistes = false;
    plugin->hasUpdatedExceptionLocation = false;

    onAction(plugin, action);

    processEvents(plugin, reader, writer);

	updateEvents(plugin, writer);

    if (plugin->hasUpdatedRegistes)
    {
        PDWrite_eventBegin(writer, PDEventType_setRegisters);
        PDWrite_arrayBegin(writer, "registers");

        writeStatusRegister(writer, "flags", plugin->regs.flags);
        writeRegister(writer, "pc", 2, plugin->regs.pc, 1);
        writeRegister(writer, "sp", 1, plugin->regs.sp, 0);
        writeRegister(writer, "a", 1, plugin->regs.a, 0);
        writeRegister(writer, "x", 1, plugin->regs.x, 0);
        writeRegister(writer, "y", 1, plugin->regs.y, 0);

        PDWrite_arrayEnd(writer);
        PDWrite_eventEnd(writer);
    }

    if (plugin->hasUpdatedExceptionLocation)
    {
        PDWrite_eventBegin(writer, PDEventType_setExceptionLocation);
        PDWrite_u64(writer, "address", plugin->regs.pc);
        PDWrite_u8(writer, "address_size", 2);
        PDWrite_eventEnd(writer);
    }

    return plugin->state;
}
static void test_c64_vice_connect(void**)
{
    int count = 0;

    PluginData* pluginData;

    pluginData = PluginHandler_getBackendPlugins(&count)[0];

    // Lanuch C64 VICE
    // TODO: Fix hardcoded path

#ifdef PRODBG_MAC
    //const char* viceLaunchPath = "../../vice/x64.app/Contents/MacOS/x64";
    const char* viceLaunchPath = "/Applications/VICE/x64.app/Contents/MacOS/x64";
#elif PRODBG_WIN
    const char* viceLaunchPath = "..\\..\\vice\\x64.exe";
#else
    // Not supported on Linux yet
    const char* viceLaunchPath = 0;
#endif
    assert_non_null(viceLaunchPath);

    //const char* argv[] = { viceLaunchPath, "-remotemonitor", "-console", "examples/c64_vice/test.prg", 0 };
    const char* argv[] = { viceLaunchPath, "-remotemonitor", "-console", 0 };

    s_viceHandle = Process_spawn(viceLaunchPath, argv);

    assert_non_null(s_viceHandle);

    // Wait 3 sec for VICE to launch

    Time_sleepMs(3000);

    // TODO: Non hard-coded path

    s_session = Session_createLocal((PDBackendPlugin*)pluginData->plugin, 0);

    // make sure we attach to VICE

    PDWriter* writer = s_session->currentWriter;

    PDWrite_eventBegin(writer, PDEventType_menuEvent);
    PDWrite_u32(writer, "menu_id", 0);
    PDWrite_eventEnd(writer);

    Session_update(s_session);

    // We haven't setup vice at this point so no connect

    assert_int_not_equal(s_session->state, PDDebugState_noTarget);
}
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);
}
Example #17
0
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_eventBegin(writer, PDEventType_setTty);
        PDWrite_string(writer, "tty", buffer);
        PDWrite_eventEnd(writer);    
    }
}
Example #18
0
static void setRegisters(PDWriter* writer)
{
    PDWrite_eventBegin(writer, PDEventType_setRegisters);
    PDWrite_arrayBegin(writer, "registers");

    writeRegister(writer, "pc", 2, pc, 1);
    writeRegister(writer, "sp", 1, sp, 0);
    writeRegister(writer, "a", 1, a, 0);
    writeRegister(writer, "x", 1, x, 0);
    writeRegister(writer, "y", 1, y, 0);
    writeRegister(writer, "status", 1, status, 1);

    PDWrite_arrayEnd(writer);
    PDWrite_eventEnd(writer);
}
Example #19
0
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);
}
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);
}
Example #21
0
static void setSourceFiles(LLDBPlugin* plugin, PDWriter* writer)
{
	if (!plugin->hasValidTarget)
		return;

    PDWrite_eventBegin(writer, PDEventType_setSourceFiles);
    PDWrite_arrayBegin(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_arrayEntryBegin(writer);
				PDWrite_string(writer, "file", filename);
				PDWrite_arrayEntryEnd(writer);
			}
		}
	}

    PDWrite_arrayEnd(writer);
    PDWrite_eventEnd(writer);
}
Example #22
0
static void parseBreakpoint(PluginData* data, const char* res, PDWriter* writer)
{
	Breakpoint* bp = 0;

	// TODO: loop, look for more breakpoints

    const char* breakStrOffset = strstr(res, "BREAK:");

	if (!breakStrOffset) 
		return;

	int id = atoi(breakStrOffset + 7);

    const char* address = strstr(breakStrOffset, "C:$");

	if (!findBreakpointById(data, &bp, id))
	{
		bp = createBreakpoint();
		addBreakpoint(data, bp);
	}

	bp->id = id;

	if (address)
		bp->address = (uint16_t)strtol(address + 3, 0, 16);

	// add data or update existing

	PDWrite_eventBegin(writer, PDEventType_replyBreakpoint);
	PDWrite_u64(writer, "address", bp->address);
	PDWrite_u32(writer, "id", (uint32_t)id);
	PDWrite_eventEnd(writer);

	printf("sending reply back: breakpoint %x - %d\n", bp->address, id);

	// TODO: Condition

	//if (bp->condition)
	//	free(bp->condition);

	//if (condition)
	//	bp->condition = strdup(condition);
	// else
	// bp->condition = 0;
}
Example #23
0
static void setThreads(LLDBPlugin* plugin, PDWriter* writer)
{
    uint32_t threadCount = plugin->process.GetNumThreads();

    if (threadCount == 0)
    	return;

    PDWrite_eventBegin(writer, PDEventType_setThreads);
    PDWrite_arrayBegin(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_arrayEntryBegin(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_arrayEntryEnd(writer);
	}

    PDWrite_arrayEnd(writer);
    PDWrite_eventEnd(writer);
}
Example #24
0
static void selectThread(LLDBPlugin* plugin, PDReader* reader, PDWriter* writer)
{
	uint64_t threadId;

    PDRead_findU64(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_eventBegin(writer, PDEventType_selectFrame);
    PDWrite_u32(writer, "frame", getThreadFrame(plugin, threadId));
    PDWrite_eventEnd(writer);
}
static int update(void* userData, PDUI* uiFuncs, PDReader* inEvents, PDWriter* writer)
{
    uint32_t event;

    DissassemblyData* data = (DissassemblyData*)userData;

    while ((event = PDRead_getEvent(inEvents)) != 0)
    {
        switch (event)
        {
            case PDEventType_setDisassembly:
            {
                setDisassemblyCode(data, inEvents);
                break;
            }

            case PDEventType_setExceptionLocation:
            {
                PDRead_findU64(inEvents, &data->location, "address", 0);
                PDRead_findU8(inEvents, &data->locationSize, "address_size", 0);
                break;
            }

            case PDEventType_setRegisters:
                updateRegisters(data, inEvents); break;

        }
    }

    renderUI(data, uiFuncs);

    // Temporary req

    PDWrite_eventBegin(writer, PDEventType_getDisassembly);
    PDWrite_u64(writer, "address_start", 0);
    PDWrite_u32(writer, "instruction_count", (uint32_t)10);
    PDWrite_eventEnd(writer);

    return 0;
}
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;
}
Example #27
0
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_eventBegin(writer, PDEventType_setLocals);
    PDWrite_arrayBegin(writer, "locals");
        
    for (uint32_t i = 0; i < count; ++i)
    {
        lldb::SBValue value = variables.GetValueAtIndex(i);

        PDWrite_arrayEntryBegin(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_arrayEntryEnd(writer);
    }

    PDWrite_arrayEnd(writer);
    PDWrite_eventEnd(writer);
}
Example #28
0
static void getMemory(PluginData* data, PDReader* reader, PDWriter* writer)
{
    uint64_t address;
    uint64_t size;
    size_t readSize = 0;

    PDRead_findU64(reader, &address, "address_start", 0);
    PDRead_findU64(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)
		sendCommand(data, "bank io\n");

	uint8_t* memory = getMemoryInternal(data, data->tempFileFull, &readSize, (uint16_t)(address), (uint16_t)(address + size));

	if (address == 0xdd00)
		sendCommand(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
        //

    	printf("c64_vice: sending memory\n");

        PDWrite_eventBegin(writer, PDEventType_setMemory);
        PDWrite_u64(writer, "address", address);
        PDWrite_data(writer, "data", memory + 2, (uint32_t)(readSize - 3));
        PDWrite_eventEnd(writer);

        // writer takes a copy

        free(memory);
	}
}
Example #29
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);
}
static int update(void* userData, PDUI* uiFuncs, PDReader* inEvents, PDWriter* writer)
{
    uint32_t event;
    (void)uiFuncs;
    (void)writer;

    BreakpointsData* data = (BreakpointsData*)userData;

    while ((event = PDRead_getEvent(inEvents)) != 0)
    {
        switch (event)
        {
            case PDEventType_setBreakpoint:
            {
                toogleBreakpointFileLine(data, inEvents);
                break;
            }

            case PDEventType_replyBreakpoint:
            {
                uint64_t address = 0;
                uint32_t id = (uint32_t) ~0;

                PDRead_findU64(inEvents, &address, "address", 0);
                PDRead_findU32(inEvents, &id, "id", 0);

                for (Breakpoint* bp : data->breakpoints)
                {
                    if ((uint64_t)strtol(bp->location.address, 0, 16) == address)
                    {
                        bp->pendingCount = 0;       // breakpoint accepted
                        printf("bp view: updated breakpoint with id %d (was %d)\n", id, bp->id);
                        bp->id = (int)id;
                        break;
                    }
                }

                break;
            }
        }
    }

    uiFuncs->text("");

    if (uiFuncs->button("Add Breakpoint", { 0.0f, 0.0f } ))
    {
        Breakpoint* bp = createBreakpoint(data);
        data->breakpoints.push_back(bp);
    }

    uiFuncs->columns(4, "", true);
    //uiFuncs->text(""); uiFuncs->nextColumn();
    uiFuncs->text("Name/Address"); uiFuncs->nextColumn();
    uiFuncs->text("Label"); uiFuncs->nextColumn();
    uiFuncs->text("Condition"); uiFuncs->nextColumn();
    uiFuncs->text(""); uiFuncs->nextColumn();

    for (auto& i : data->breakpoints)
    {
        Breakpoint* bp = i;
        bool needUpdate = false;

        uiFuncs->pushIdPtr(bp);

        //if (uiFuncs->checkbox("Enabled", &bp->enabled))
        //	needUpdate = true;

        if (bp->location.filename)
        {
            uiFuncs->inputText("##filename", bp->location.filename, (int)data->maxPath, 0, 0, 0);
        }
        else
        {
            if (uiFuncs->inputText("##address", bp->location.address, (int)data->maxPath,
                                   PDUIInputTextFlags_CharsHexadecimal | PDUIInputTextFlags_EnterReturnsTrue, 0, 0))
                needUpdate = true;
        }

        uiFuncs->nextColumn();

        uiFuncs->text("");
        uiFuncs->nextColumn();

        uiFuncs->text(""); // no condition for now

        //if (uiFuncs->inputText("##condition", bp->condition, (int)data->maxPath, PDInputTextFlags_EnterReturnsTrue, 0, 0))
        //	needUpdate = true;

        uiFuncs->nextColumn();

        if (needUpdate)
        {
            // TODO: Add support for file/line

            PDWrite_eventBegin(writer, PDEventType_setBreakpoint);
            PDWrite_u64(writer, "address", (uint64_t)strtol(bp->location.address, 0, 16));

            //if (bp->condition[0] != 0)
            //	PDWrite_string(writer, "condition", bp->condition);

            if (bp->id != -1)
                PDWrite_u32(writer, "id", (uint32_t)bp->id);

            PDWrite_eventEnd(writer);

            printf("Sending breakpint\n");
        }

        if (uiFuncs->button("Delete", {0.0f, 0.0f}))
        {
            PDWrite_eventBegin(writer, PDEventType_deleteBreakpoint);
            PDWrite_u32(writer, "id", (uint32_t)bp->id);
            PDWrite_eventEnd(writer);
            bp->markDelete = true;
        }

        uiFuncs->nextColumn();

        uiFuncs->popId();
    }

    // Delete breakpoints that have been marked delete

    for (auto i = data->breakpoints.begin(); i != data->breakpoints.end(); ++i)
    {
        Breakpoint* bp = *i;

        if (bp->pendingCount > 1)
            bp->pendingCount++;

        if (bp->markDelete || bp->pendingCount >= 10)
            i = data->breakpoints.erase(i);
    }

    return 0;
}