ContextData getLocationContext(TextDocument *document, int lineNumber) { ContextData data; QTC_ASSERT(document, return data); if (document->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()) { QString line = document->document()->findBlockByNumber(lineNumber - 1).text(); DisassemblerLine l; l.fromString(line); if (l.address) { data.type = LocationByAddress; data.address = l.address; } else { QString fileName = document->property(Constants::DISASSEMBLER_SOURCE_FILE).toString(); if (!fileName.isEmpty()) { // Possibly one of the "27 [1] foo = x" lines int pos = line.indexOf(QLatin1Char('[')); int ln = line.left(pos - 1).toInt(); if (ln > 0) { data.type = LocationByFile; data.fileName = fileName; data.lineNumber = ln; } } } } else { data.type = LocationByFile; data.fileName = document->filePath().toString(); data.lineNumber = lineNumber; } return data; }
// ------------------------------------------------------------------------ bool CpuDisasmProcessor::getLine(DisassemblerLine &result, uint32_t &address) { SNES::CPU::Opcode opcode; uint8_t u = usagePointer[address & 0xFFFFFF]; bool e, m, x; e = u & SNES::CPUDebugger::UsageFlagE; m = u & SNES::CPUDebugger::UsageFlagM; x = u & SNES::CPUDebugger::UsageFlagX; switch (source) { case CPU: if (!u) { e = SNES::cpu.regs.e; m = SNES::cpu.regs.p.m; x = SNES::cpu.regs.p.x; } SNES::cpu.disassemble_opcode_ex(opcode, address, e, m, x); break; case SA1: if (!u) { e = SNES::sa1.regs.e; m = SNES::sa1.regs.p.m; x = SNES::sa1.regs.p.x; } SNES::sa1.disassemble_opcode_ex(opcode, address, e, m, x); break; } result.setOpcode(address, opcode.opcode); setOpcodeParams(result, opcode, address); if (opcode.isBra() || opcode.isBraWithContinue()) { result.setBra(decode(opcode.optype, opcode.opall(), address)); } if (opcode.returns()) { result.flags |= DisassemblerLine::FLAG_RETURN; } // Advance to next for (uint32_t i=1; i<=4; i++) { if ((usagePointer[(address + i) & 0xFFFFFF] & 0x10) == 0) { continue; } address += i; break; } return true; }
DisassemblerLines parseCdbDisassembler(const QList<QByteArray> &a) { DisassemblerLines result; quint64 functionAddress = 0; uint lastSourceLine = 0; QString currentFunction; quint64 functionOffset = 0; QString sourceFile; foreach (const QByteArray &lineBA, a) { const QString line = QString::fromLatin1(lineBA); // New function. Append as comment line. if (parseCdbDisassemblerFunctionLine(line, ¤tFunction, &functionOffset, &sourceFile)) { functionAddress = 0; DisassemblerLine commentLine; commentLine.data = line; result.appendLine(commentLine); } else { DisassemblerLine disassemblyLine; uint sourceLine; if (parseCdbDisassemblerLine(line, &disassemblyLine, &sourceLine)) { // New source line: Add source code if available. if (sourceLine && sourceLine != lastSourceLine) { lastSourceLine = sourceLine; result.appendSourceLine(sourceFile, sourceLine); } } else { qWarning("Unable to parse assembly line '%s'", lineBA.constData()); disassemblyLine.fromString(line); } // Determine address of function from the first assembler line after a // function header line. if (!functionAddress && disassemblyLine.address) { functionAddress = disassemblyLine.address - functionOffset; } if (functionAddress && disassemblyLine.address) disassemblyLine.offset = disassemblyLine.address - functionAddress; disassemblyLine.function = currentFunction; result.appendLine(disassemblyLine); } } return result; }