uae-dap
Version:
Debug Adapter Protocol for Amiga development with FS-UAE or WinUAE
107 lines • 4.32 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const debugadapter_1 = require("@vscode/debugadapter");
const path_1 = require("path");
const gdbClient_1 = require("./gdbClient");
const hardware_1 = require("./hardware");
const registers_1 = require("./registers");
const strings_1 = require("./utils/strings");
class StackManager {
constructor(gdb, sourceMap, disassembly) {
this.gdb = gdb;
this.sourceMap = sourceMap;
this.disassembly = disassembly;
}
/**
* Get stack trace for thread
*/
async getStackTrace(threadId, stackPositions) {
const stackFrames = [];
for (const p of stackPositions) {
let sf;
if (p.pc >= 0) {
try {
const location = this.sourceMap.lookupAddress(p.pc);
const source = new debugadapter_1.Source((0, path_1.basename)(location.path), location.path);
sf = new debugadapter_1.StackFrame(p.index, location.symbol ?? "__MAIN__", source, location.line);
sf.instructionPointerReference = (0, strings_1.formatHexadecimal)(p.pc);
}
catch (_) {
// Will get processed with disassembler
}
}
// Get disassembled stack frame if not set
if (!sf) {
sf = await this.disassembly.getStackFrame(p, threadId);
}
// TODO:
// Only include frames with a source, but make sure we have at least one frame
// Others are likely to be ROM system calls
// if (sf.source || !stackFrames.length) {
stackFrames.push(sf);
// }
}
return stackFrames;
}
async getPositions(threadId) {
const stackPositions = [];
let stackPosition = await this.getStackPosition(threadId, gdbClient_1.DEFAULT_FRAME_INDEX);
stackPositions.push(stackPosition);
if (threadId === hardware_1.Threads.CPU) {
// Retrieve the current frame count
const stackSize = await this.gdb.getFramesCount();
for (let i = stackSize - 1; i >= 0; i--) {
try {
stackPosition = await this.getStackPosition(threadId, i);
stackPositions.push(stackPosition);
}
catch (err) {
if (err instanceof Error)
debugadapter_1.logger.error(err.message);
}
}
}
return stackPositions;
}
async getStackPosition(threadId, frameIndex = gdbClient_1.DEFAULT_FRAME_INDEX) {
if (threadId === hardware_1.Threads.CPU) {
debugadapter_1.logger.log("Getting position at frame " + frameIndex);
// Get the current frame
return this.gdb.withFrame(frameIndex, async (index) => {
const pc = await this.gdb.getRegister(registers_1.REGISTER_PC_INDEX);
if (pc) {
return {
index: frameIndex,
stackFrameIndex: index + 1,
pc: pc,
};
}
else {
throw new Error("Error retrieving stack frame for index " +
frameIndex +
": pc not retrieved");
}
});
}
else if (threadId === hardware_1.Threads.COPPER) {
// Retrieve the stack position from the copper
const haltStatus = await this.gdb.getHaltStatus();
if (haltStatus) {
const registersValues = await this.gdb.getRegisters(threadId);
if (registersValues) {
return {
index: frameIndex * 1000,
stackFrameIndex: 1,
pc: registersValues[registers_1.REGISTER_PC_INDEX] || 0,
};
}
else {
throw new Error("No stack frame returned");
}
}
}
throw new Error("No frames for thread: " + threadId);
}
}
exports.default = StackManager;
//# sourceMappingURL=stackManager.js.map