uae-dap
Version:
Debug Adapter Protocol for Amiga development with FS-UAE or WinUAE
112 lines • 4.09 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
class SourceMap {
constructor(hunks, offsets) {
this.sources = new Set();
this.symbols = {};
this.locationsBySource = new Map();
this.locationsByAddress = new Map();
this.segments = offsets.map((address, i) => {
const hunk = hunks[i];
return {
address,
name: `Seg${i}_${hunk.hunkType}_${hunk.memType}`,
size: hunk.dataSize ?? hunk.allocSize,
memType: hunk.memType,
};
});
for (let i = 0; i < this.segments.length; i++) {
const seg = this.segments[i];
const hunk = hunks[i];
for (const { offset, name } of hunk.symbols) {
this.symbols[name] = seg.address + offset;
}
// Add first source from each hunk
// This should be the entry point. Others files may be includes.
if (hunk.lineDebugInfo[0]) {
this.sources.add((0, path_1.normalize)(hunk.lineDebugInfo[0].sourceFilename));
}
for (const debugInfo of hunk.lineDebugInfo) {
const path = (0, path_1.normalize)(debugInfo.sourceFilename);
const pathKey = path.toUpperCase();
const linesMap = this.locationsBySource.get(pathKey) || new Map();
for (const lineInfo of debugInfo.lines) {
const address = seg.address + lineInfo.offset;
let symbol;
let symbolOffset;
for (const { offset, name } of hunk.symbols) {
if (offset > lineInfo.offset)
break;
symbol = name;
symbolOffset = lineInfo.offset - offset;
}
const location = {
path,
line: lineInfo.line,
symbol,
symbolOffset,
segmentIndex: i,
segmentOffset: lineInfo.offset,
address,
};
linesMap.set(lineInfo.line, location);
this.locationsByAddress.set(address, location);
}
this.locationsBySource.set(pathKey, linesMap);
}
}
}
getSourceFiles() {
return Array.from(this.sources.values());
}
getSegmentsInfo() {
return this.segments;
}
getSymbols() {
return this.symbols;
}
lookupAddress(address) {
let location = this.locationsByAddress.get(address);
if (!location) {
for (const [a, l] of this.locationsByAddress.entries()) {
if (a > address)
break;
if (address - a <= 10)
location = l;
}
}
if (!location) {
throw new Error("Location not found for address " + address);
}
return location;
}
lookupSourceLine(path, line) {
const pathKey = (0, path_1.normalize)(path).toUpperCase();
const fileMap = this.locationsBySource.get(pathKey);
if (!fileMap) {
throw new Error("File not found in source map: " + path);
}
let location = fileMap.get(line);
if (!location) {
for (const [ln, loc] of fileMap.entries()) {
if (ln > line)
break;
location = loc;
}
}
if (!location) {
throw new Error("Location not found for line " + line);
}
return location;
}
getSegmentInfo(segmentId) {
const segment = this.segments[segmentId];
if (!segment) {
throw new Error("Invalid segment: " + segmentId);
}
return segment;
}
}
exports.default = SourceMap;
//# sourceMappingURL=sourceMap.js.map