Пример #1
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);
}
Пример #2
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);
}
Пример #3
0
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);
}
Пример #4
0
static void writeStatusRegister(PDWriter* writer, const char* name, uint16_t reg)
{
    PDWrite_arrayEntryBegin(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_arrayEntryEnd(writer);
}
Пример #5
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);
}
Пример #6
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);
}
Пример #7
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);
}
Пример #8
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);
}