v1.19.6: Improved restartability of stack-related instructions

This commit is contained in:
Jeff Parsons 2015-09-14 16:53:57 -07:00
commit deeac4902d
174 changed files with 9030 additions and 1736 deletions

View file

@ -155,14 +155,18 @@ function Debugger(parmsDbg)
this.dbgAddrAssemble = this.newAddr();
/*
* aSymbolTable is an array of 5-element arrays, one per ROM or other chunk of address space.
* Each 5-element arrays contains:
* aSymbolTable is an array of SymbolTable objects, one per ROM or other chunk of address space.
*
* [0]: sel
* [1]: addr
* [2]: len
* [3]: aSymbols
* [4]: aOffsetPairs
* Each SymbolTable object contains the following properties:
*
* sModule
* nSegment
* sel
* off
* addr (physical address, if any; eg, if symbols are for a ROM)
* len
* aSymbols
* aOffsetPairs
*
* See addSymbols() for more details, since that's how callers add sets of symbols to the table.
*/
@ -1288,28 +1292,47 @@ if (DEBUGGER) {
if (Interrupts.WINDBG.ENABLED || Interrupts.WINDBGRM.ENABLED) {
/**
* addSegmentInfo(dbgAddr, nSeg, sel, fCode, fPrint)
* addSegmentInfo(dbgAddr, nSegment, sel, fCode, fPrint)
*
* @this {Debugger}
* @param {DbgAddr} dbgAddr (address of module name)
* @param {number} nSeg (logical segment number)
* @param {number} nSegment (logical segment number)
* @param {number} sel (current selector)
* @param {boolean} fCode (true if code segment, false if data segment)
* @param {boolean} [fPrint]
*/
Debugger.prototype.addSegmentInfo = function(dbgAddr, nSeg, sel, fCode, fPrint)
Debugger.prototype.addSegmentInfo = function(dbgAddr, nSegment, sel, fCode, fPrint)
{
var sModule = this.getSZ(dbgAddr);
var seg = this.getSegment(sel);
var len = seg? seg.limit + 1 : 0;
var sSection = (fCode? "_CODE" : "_DATA") + str.toHex(nSeg, 2);
var sSection = (fCode? "_CODE" : "_DATA") + str.toHex(nSegment, 2);
if (fPrint) {
this.println(sModule + "!undefined " + (fCode? "code" : "data") + '(' + str.toHex(nSeg, 4) + ")=#" + str.toHex(sel, 4) + " len " + str.toHex(len));
this.println(sModule + ' ' + (fCode? "code" : "data") + '(' + str.toHex(nSegment, 4) + ")=#" + str.toHex(sel, 4) + " len " + str.toHex(len));
}
var aSymbols = {};
var off = 0;
var aSymbols = this.findModuleInfo(sModule, nSegment);
aSymbols[sModule + sSection] = off;
this.addSymbols(sel, off, len, aSymbols);
this.addSymbols(sModule, nSegment, sel, off, null, len, aSymbols);
};
/**
* removeSegmentInfo(sel, fPrint)
*
* @this {Debugger}
* @param {number} sel
* @param {boolean} [fPrint]
*/
Debugger.prototype.removeSegmentInfo = function(sel, fPrint)
{
var sModuleRemoved = this.removeSymbols(null, sel);
if (fPrint) {
if (sModuleRemoved) {
this.println(sModuleRemoved + " #" + str.toHex(sel, 4) + " removed");
} else {
this.println("unable to remove module for segment #" + str.toHex(sel, 4));
}
}
};
/**
@ -1320,8 +1343,8 @@ if (DEBUGGER) {
* DD_actual_sel dw ? ; actual selector value
* DD_base dd ? ; linear address offset for start of segment
* DD_length dd ? ; actual length of segment
* DD_name df ? ; 16:32 ptr to null terminated device name
* DD_sym_name df ? ; 16:32 ptr to null terminated symbolic module name (i.e. Win386)
* DD_name df ? ; 16:32 ptr to null terminated module name
* DD_sym_name df ? ; 16:32 ptr to null terminated parent name (eg, "DOS386")
* DD_alias_sel dw ? ; alias selector value (0 = none)
*
* @this {Debugger}
@ -1331,34 +1354,63 @@ if (DEBUGGER) {
*/
Debugger.prototype.addSectionInfo = function(dbgAddr, fCode, fPrint)
{
var nSeg = this.getShort(dbgAddr, 2);
var nSegment = this.getShort(dbgAddr, 2);
var sel = this.getShort(dbgAddr, 2);
var off = this.getLong(dbgAddr, 4);
var len = this.getLong(dbgAddr, 4);
var dbgAddrDevice = this.newAddr(this.getLong(dbgAddr, 4), this.getShort(dbgAddr, 2));
var dbgAddrModule = this.newAddr(this.getLong(dbgAddr, 4), this.getShort(dbgAddr, 2));
var dbgAddrParent = this.newAddr(this.getLong(dbgAddr, 4), this.getShort(dbgAddr, 2));
// sel = this.getShort(dbgAddr, 2) || sel;
var sParent = this.getSZ(dbgAddrParent).toUpperCase();
var sModule = this.getSZ(dbgAddrModule).toUpperCase();
var sDevice = this.getSZ(dbgAddrDevice).toUpperCase();
var sSection = (fCode? "_CODE" : "_DATA") + str.toHex(nSeg, 2);
if (sParent == sModule) {
sParent = "";
} else {
sParent += '!';
}
var sSection = (fCode? "_CODE" : "_DATA") + str.toHex(nSegment, 2);
if (fPrint) {
/*
* Mimics WDEB386 output, except that WDEB386 only displays a linear address, omitting the selector.
*/
this.println(sModule + '!' + sDevice + "!undefined " + (fCode? "code" : "data") + '(' + str.toHex(nSeg, 4) + ")=" + str.toHex(sel, 4) + ':' + str.toHex(off) + " len " + str.toHex(len));
this.println(sParent + sModule + ' ' + (fCode? "code" : "data") + '(' + str.toHex(nSegment, 4) + ")=" + str.toHex(sel, 4) + ':' + str.toHex(off) + " len " + str.toHex(len));
}
/*
* TODO: Add support for 32-bit symbols; findModuleInfo() relies on Disk.getModuleInfo(), and the Disk
* component doesn't yet know how to parse 32-bit executables.
*/
var aSymbols = this.findModuleInfo(sModule, nSegment);
aSymbols[sModule + sSection] = off;
this.addSymbols(sModule, nSegment, sel, off, null, len, aSymbols);
};
/**
* removeSectionInfo(nSegment, dbgAddr, fPrint)
*
* @this {Debugger}
* @param {DbgAddr} dbgAddr (address of module)
* @param {boolean} [fPrint]
*/
Debugger.prototype.removeSectionInfo = function(nSegment, dbgAddr, fPrint)
{
var sModule = this.getSZ(dbgAddr).toUpperCase();
var sModuleRemoved = this.removeSymbols(sModule, nSegment);
if (fPrint) {
if (sModuleRemoved) {
this.println(sModule + ' ' + str.toHex(nSegment, 4) + " removed");
} else {
this.println("unable to remove " + sModule + " for section " + str.toHex(nSegment, 4));
}
}
var aSymbols = {};
aSymbols[sDevice + sSection] = off;
this.addSymbols(sel, off, len, aSymbols);
};
/**
* intWindowsCallBack()
*
* This intercepts calls to Windows callback addresses, which use INT 0x30 (aka Transfer Space Fault).
* This intercepts calls to Windows callback addresses, which use INT 0x30 (aka Transfer Space Faults).
*
* We're only interested in one particular callback: the one specifying VW32_Int41Dispatch (0x002A002A)
* in EAX.
* We're only interested in one particular callback: the VW32_Int41Dispatch (0x002A002A) that KERNEL32
* issues as 32-bit executable sections are loaded.
*
* At the time that INT 0x30 occurs, a far 32-bit call has been made, preceded by a near 32-bit call,
* preceded by a 32-bit push of the Windows Debugger function # that would normally be in EAX if this had
@ -1369,7 +1421,12 @@ if (DEBUGGER) {
* instruction following an INT 0x30; in fact, execution doesn't even continue after the far 32-bit call
* (even though the kernel places a "RET 4" after that call). So, rather than recreate all that automatic
* address popping, we let the system do it for us, since it's designed to work whether a debugger (eg,
* WDEB386's Debug VXD) is installed or not.
* WDEB386's DEBUG VxD) is installed or not.
*
* TODO: Consider "consuming" all VW32_Int41Dispatch callbacks, because the Windows 95 kernel goes to
* great effort to pass those requests on to the DEBUG VxD, which end up going nowhere when the VxD isn't
* loaded (to load it, you must either run WDEB386.EXE or install it via your SYSTEM.INI). Regrettably,
* Windows 95 assumes that if WDEB386 support is present, then a DEBUG VxD must be present as well.
*
* @this {Debugger}
* @param {number} addr
@ -1387,7 +1444,7 @@ if (DEBUGGER) {
var EAX = this.getLong(dbgAddr);
switch(EAX) {
case Interrupts.WINDBG.LOAD_SEG32:
case Interrupts.WINDBG.LOADSEG32:
/*
* SI == segment type:
* 0x0 code selector
@ -1462,14 +1519,60 @@ if (DEBUGGER) {
case Interrupts.WINDBG.IS_LOADED:
if (this.fWinDbg) {
cpu.regEAX = (cpu.regEAX & ~0xffff) | Interrupts.WINDBG.LOADED;
this.println("INT 0x41 handling enabled");
}
break;
case Interrupts.WINDBG.LOAD_SEG:
case Interrupts.WINDBG.LOADSEG:
this.addSegmentInfo(this.newAddr(DI, ES), BX+1, CX, !(SI & 0x1), this.fWinDbg);
break;
case Interrupts.WINDBG.LOAD_SEG32:
case Interrupts.WINDBG.FREESEG:
this.removeSegmentInfo(BX);
break;
case Interrupts.WINDBG.KRNLVARS:
/*
* BX = version number of this data (0x3A0)
* DX:CX points to:
* WORD hGlobalHeap ****
* WORD pGlobalHeap ****
* WORD hExeHead ****
* WORD hExeSweep
* WORD topPDB
* WORD headPDB
* WORD topsizePDB
* WORD headTDB ****
* WORD curTDB ****
* WORD loadTDB
* WORD LockTDB
* WORD SelTableLen ****
* DWORD SelTableStart ****
*/
break;
case Interrupts.WINDBG.RELSEG:
case Interrupts.WINDBG.LOADDLL:
case Interrupts.WINDBG.DELMODULE:
/*
* TODO: Figure out what to do with these notifications, if anything
*/
break;
case Interrupts.WINDBG.REGDOTCMD:
case Interrupts.WINDBG.CONDBP:
case Interrupts.WINDBG.LOADHIGH:
break;
case Interrupts.WINDBG.GETSYMBOL:
if (this.fWinDbg) cpu.regEAX = (cpu.regEAX & ~0xffff)|1; // AX == 1 means not found
break;
case Interrupts.WINDBG.CHECKFAULT:
if (this.fWinDbg) cpu.regEAX = (cpu.regEAX & ~0xffff)|0; // AX == 0 means handle fault normally
break;
case Interrupts.WINDBG.LOADSEG32:
/*
* SI == segment type:
* 0x0 code selector
@ -1479,8 +1582,16 @@ if (DEBUGGER) {
this.addSectionInfo(this.newAddr(cpu.regEBX, DX), !SI, this.fWinDbg);
break;
case Interrupts.WINDBG.FREESEG32:
/*
* BX == segment number
* DX:EDI -> module name
*/
this.removeSectionInfo(BX, this.newAddr(cpu.regEDI, DX));
break;
default:
if (MAXDEBUG && this.fWinDbg) {
if (DEBUG && this.fWinDbg) {
this.println("INT 0x41: " + str.toHexWord(AX));
}
break;
@ -1506,6 +1617,9 @@ if (DEBUGGER) {
var cpu = this.cpu;
var AL = cpu.regEAX & 0xff;
var AH = (cpu.regEAX >> 8) & 0xff;
var BX = cpu.regEBX & 0xffff;
var CX = cpu.regECX & 0xffff;
var DX = cpu.regEDX & 0xffff;
var DI = cpu.regEDI & 0xffff;
var ES = cpu.segES.sel;
@ -1573,13 +1687,25 @@ if (DEBUGGER) {
}
break;
case Interrupts.WINDBGRM.LOAD_SEG:
case Interrupts.WINDBGRM.FREESEG:
this.removeSegmentInfo(BX);
break;
case Interrupts.WINDBGRM.REMOVESEGS:
/*
* TODO: This probably just signals the end of module loading; nothing is required, but we should
* clean up whatever we can....
*/
break;
case Interrupts.WINDBGRM.LOADSEG:
if (AL == 0x20) {
/*
* Real-mode EXE
* CX == paragraph
* ES:DI -> module name
*/
this.addSegmentInfo(this.newAddr(DI, ES), 0, CX, true, this.fWinDbgRM);
}
else if (AL < 0x80) {
/*
@ -1595,6 +1721,7 @@ if (DEBUGGER) {
* DX == actual selector (if 0x40 or 0x41)
* ES:DI -> module name
*/
this.addSegmentInfo(this.newAddr(DI, ES), BX+1, (AL & 0x40)? DX : CX, !(AL & 0x1), this.fWinDbgRM);
}
else {
/*
@ -1611,7 +1738,7 @@ if (DEBUGGER) {
break;
default:
if (MAXDEBUG && this.fWinDbgRM) {
if (DEBUG && this.fWinDbgRM) {
this.println("INT 0x68: " + str.toHexByte(AH));
}
break;
@ -2776,6 +2903,30 @@ if (DEBUGGER) {
this.println(sDump);
};
/**
* findModuleInfo(sModule, nSegment)
*
* Since we're not sure what Disk the module was loaded from, we have to check all of them.
*
* @this {Debugger}
* @param {string} sModule
* @param {number} nSegment
* @return {Array}
*/
Debugger.prototype.findModuleInfo = function(sModule, nSegment)
{
var aSymbols = [];
if (SYMBOLS) {
var component, componentPrev = null;
while (component = this.cmp.getComponentByType("Disk", componentPrev)) {
aSymbols = component.getModuleInfo(sModule, nSegment);
if (aSymbols.length) break;
componentPrev = component;
}
}
return aSymbols;
};
/**
* messageInit(sEnable)
*
@ -3841,15 +3992,21 @@ if (DEBUGGER) {
{
var i;
this.aBreakExec = ["bp"];
/*
* TODO: Each read breakpoint needs to keep track of whether it's linear or physical.
*/
if (this.aBreakRead !== undefined) {
for (i = 1; i < this.aBreakRead.length; i++) {
this.bus.removeMemBreak(this.getAddr(this.aBreakRead[i]), false);
this.cpu.removeMemBreak(this.getAddr(this.aBreakRead[i]), false, true);
}
}
this.aBreakRead = ["br"];
/*
* TODO: Each write breakpoint needs to keep track of whether it's linear or physical.
*/
if (this.aBreakWrite !== undefined) {
for (i = 1; i < this.aBreakWrite.length; i++) {
this.bus.removeMemBreak(this.getAddr(this.aBreakWrite[i]), true);
this.cpu.removeMemBreak(this.getAddr(this.aBreakWrite[i]), true, true);
}
}
this.aBreakWrite = ["bw"];
@ -3939,7 +4096,10 @@ if (DEBUGGER) {
this.println("invalid address: " + this.hexAddr(dbgAddr));
fSuccess = false;
} else {
this.bus.addMemBreak(addr, aBreak == this.aBreakWrite);
/*
* TODO: Add some UI that allows a physical address (fLinear is currently hard-coded to true)
*/
this.cpu.addMemBreak(addr, aBreak == this.aBreakWrite, true);
/*
* Force memory breakpoints to use their linear address, by zapping the selector.
*/
@ -3998,7 +4158,10 @@ if (DEBUGGER) {
}
aBreak.splice(i, 1);
if (aBreak != this.aBreakExec) {
this.bus.removeMemBreak(addr, aBreak == this.aBreakWrite);
/*
* TODO: Add some UI that allows a physical address (fLinear is currently hard-coded to true)
*/
this.cpu.removeMemBreak(addr, aBreak == this.aBreakWrite, true);
}
this.historyInit();
break;
@ -5175,7 +5338,7 @@ if (DEBUGGER) {
};
/**
* addSymbols(sel, addr, len, aSymbols)
* addSymbols(sModule, nSegment, sel, off, addr, len, aSymbols)
*
* As filedump.js (formerly convrom.php) explains, aSymbols is a JSON-encoded object whose properties consist
* of all the symbols (in upper-case), and the values of those properties are objects containing any or all of
@ -5231,7 +5394,7 @@ if (DEBUGGER) {
* We add all these entries to our internal symbol table, which is an array of 4-element arrays, each of which
* look like:
*
* [sel, addr, len, aSymbols, aOffsetPairs]
* [sel, off, addr, len, aSymbols, aOffsetPairs]
*
* There are two basic symbol operations: findSymbol(), which takes an address and finds the symbol, if any,
* at that address, and findSymbolAddr(), which takes a string and attempts to match it to a non-anonymous
@ -5246,12 +5409,15 @@ if (DEBUGGER) {
* properly.
*
* @this {Debugger}
* @param {string|null} sModule
* @param {number} nSegment (zero if undefined)
* @param {number} sel (the default segment/selector for all symbols in this group)
* @param {number} addr (the physical address of the region where the given symbols are located)
* @param {number} off (from the base of the given selector)
* @param {number|null} addr (physical address where the symbols are located, if the memory is physical; eg, ROM)
* @param {number} len (the size of the region, in bytes)
* @param {Object} aSymbols (collection of symbols in this group; the format of this collection is described below)
*/
Debugger.prototype.addSymbols = function(sel, addr, len, aSymbols)
Debugger.prototype.addSymbols = function(sModule, nSegment, sel, off, addr, len, aSymbols)
{
var dbgAddr = {};
var aOffsetPairs = [];
@ -5260,12 +5426,12 @@ if (DEBUGGER) {
if (typeof symbol == "number") {
aSymbols[sSymbol] = symbol = {'o': symbol};
}
var off = symbol['o'];
var offSymbol = symbol['o'];
var selSymbol = symbol['s'];
var sAnnotation = symbol['a'];
if (off !== undefined) {
if (offSymbol !== undefined) {
if (selSymbol !== undefined) {
dbgAddr.off = off;
dbgAddr.off = offSymbol;
dbgAddr.sel = selSymbol;
dbgAddr.addr = null;
/*
@ -5282,11 +5448,44 @@ if (DEBUGGER) {
}
symbol['p'] = dbgAddr.addr;
}
usr.binaryInsert(aOffsetPairs, [off >>> 0, sSymbol], this.comparePairs);
usr.binaryInsert(aOffsetPairs, [offSymbol >>> 0, sSymbol], this.comparePairs);
}
if (sAnnotation) symbol['a'] = sAnnotation.replace(/''/g, "\"");
}
this.aSymbolTable.push([sel, addr, len, aSymbols, aOffsetPairs]);
var symbolTable = {
sModule: sModule,
nSegment: nSegment,
sel: sel,
off: off,
addr: addr,
len: len,
aSymbols: aSymbols,
aOffsetPairs: aOffsetPairs
};
this.aSymbolTable.push(symbolTable);
};
/**
* removeSymbols(sModule, nSegment)
*
* @this {Debugger}
* @param {string|null} sModule
* @param {number} [nSegment] (segment # if sModule set, selector if sModule clear)
* @return {string|null} name of the module removed, or null if no module was found
*/
Debugger.prototype.removeSymbols = function(sModule, nSegment)
{
var sModuleRemoved = null;
for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {
var symbolTable = this.aSymbolTable[iTable];
if (sModule && symbolTable.sModule != sModule) continue;
if (sModule && nSegment == symbolTable.nSegment || !sModule && nSegment == symbolTable.sel) {
sModuleRemoved = symbolTable.sModule;
this.aSymbolTable.splice(iTable, 1);
break;
}
}
return sModuleRemoved;
};
/**
@ -5299,21 +5498,18 @@ if (DEBUGGER) {
*/
Debugger.prototype.dumpSymbols = function()
{
for (var i = 0; i < this.aSymbolTable.length; i++) {
var sel = this.aSymbolTable[i][0];
var addr = this.aSymbolTable[i][1];
//var len = this.aSymbolTable[i][2];
var aSymbols = this.aSymbolTable[i][3];
for (var sSymbol in aSymbols) {
for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {
var symbolTable = this.aSymbolTable[iTable];
for (var sSymbol in symbolTable.aSymbols) {
if (sSymbol.charAt(0) == '.') continue;
var symbol = aSymbols[sSymbol];
var off = symbol['o'];
if (off === undefined) continue;
var selSym = symbol['s'];
if (selSym === undefined) selSym = sel;
var sSymbolOrig = aSymbols[sSymbol]['l'];
var symbol = symbolTable.aSymbols[sSymbol];
var offSymbol = symbol['o'];
if (offSymbol === undefined) continue;
var selSymbol = symbol['s'];
if (selSymbol === undefined) selSymbol = symbolTable.sel;
var sSymbolOrig = symbolTable.aSymbols[sSymbol]['l'];
if (sSymbolOrig) sSymbol = sSymbolOrig;
this.println(this.hexOffset(off, selSym) + ' ' + sSymbol);
this.println(this.hexOffset(offSymbol, selSymbol) + ' ' + sSymbol);
}
}
};
@ -5334,26 +5530,27 @@ if (DEBUGGER) {
Debugger.prototype.findSymbol = function(dbgAddr, fNearest)
{
var aSymbol = [];
var offSymbol = dbgAddr.off >>> 0;
var addrSymbol = this.getAddr(dbgAddr) >>> 0;
for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {
var sel = this.aSymbolTable[iTable][0];
var addr = this.aSymbolTable[iTable][1] >>> 0;
var len = this.aSymbolTable[iTable][2];
if (sel == dbgAddr.sel || (sel == 0x28 || sel == 0x30) && (dbgAddr.sel == 0x28 || dbgAddr.sel == 0x30)) {
if (addrSymbol >= addr && addrSymbol < addr + len) {
var off = dbgAddr.off >>> 0;
var aOffsetPairs = this.aSymbolTable[iTable][4];
var result = usr.binarySearch(aOffsetPairs, [off], this.comparePairs);
if (result >= 0) {
this.returnSymbol(iTable, result, aSymbol);
}
else if (fNearest) {
result = ~result;
this.returnSymbol(iTable, result-1, aSymbol);
this.returnSymbol(iTable, result, aSymbol);
}
break;
var symbolTable = this.aSymbolTable[iTable];
var sel = symbolTable.sel;
var off = symbolTable.off >>> 0;
var addr = symbolTable.addr;
if (addr != null) addr >>>= 0;
var len = symbolTable.len;
if (sel == 0x30) sel = 0x28; // TODO: Remove this hack once we're able to differentiate Windows 95 ring 0 code and data
if (sel == dbgAddr.sel && offSymbol >= off && offSymbol < off + len || addr != null && addrSymbol >= addr && addrSymbol < addr + len) {
var result = usr.binarySearch(symbolTable.aOffsetPairs, [offSymbol], this.comparePairs);
if (result >= 0) {
this.returnSymbol(iTable, result, aSymbol);
}
else if (fNearest) {
result = ~result;
this.returnSymbol(iTable, result-1, aSymbol);
this.returnSymbol(iTable, result, aSymbol);
}
break;
}
}
if (!aSymbol.length) {
@ -5380,24 +5577,21 @@ if (DEBUGGER) {
var dbgAddr;
if (sSymbol.match(/^[a-z_][a-z0-9_]*$/i)) {
var sUpperCase = sSymbol.toUpperCase();
for (var i = 0; i < this.aSymbolTable.length; i++) {
var sel = this.aSymbolTable[i][0];
var addr = this.aSymbolTable[i][1];
//var len = this.aSymbolTable[i][2];
var aSymbols = this.aSymbolTable[i][3];
var symbol = aSymbols[sUpperCase];
for (var iTable = 0; iTable < this.aSymbolTable.length; iTable++) {
var symbolTable = this.aSymbolTable[iTable];
var symbol = symbolTable.aSymbols[sUpperCase];
if (symbol !== undefined) {
var off = symbol['o'];
if (off !== undefined) {
var offSymbol = symbol['o'];
if (offSymbol !== undefined) {
/*
* We assume that every ROM is ORG'ed at 0x0000, and therefore unless the symbol has an
* explicitly-defined segment, we return the segment associated with the entire group; for
* a ROM, that segment is normally "addrROM >>> 4". Down the road, we may want/need to
* support a special symbol entry (eg, ".ORG") that defines an alternate origin.
*/
var selSym = symbol['s'];
if (selSym === undefined) selSym = sel;
dbgAddr = this.newAddr(off, selSym, symbol['p']);
var selSymbol = symbol['s'];
if (selSymbol === undefined) selSymbol = symbolTable.sel;
dbgAddr = this.newAddr(offSymbol, selSymbol, symbol['p']);
}
/*
* The symbol matched, but it wasn't for an address (no 'o' offset), and there's no point
@ -5422,14 +5616,14 @@ if (DEBUGGER) {
Debugger.prototype.returnSymbol = function(iTable, iOffset, aSymbol)
{
var symbol = {};
var aOffsetPairs = this.aSymbolTable[iTable][4];
var aOffsetPairs = this.aSymbolTable[iTable].aOffsetPairs;
var offset = 0, sSymbol = null;
if (iOffset >= 0 && iOffset < aOffsetPairs.length) {
offset = aOffsetPairs[iOffset][0];
sSymbol = aOffsetPairs[iOffset][1];
}
if (sSymbol) {
symbol = this.aSymbolTable[iTable][3][sSymbol];
symbol = this.aSymbolTable[iTable].aSymbols[sSymbol];
sSymbol = (sSymbol.charAt(0) == '.'? null : (symbol['l'] || sSymbol));
}
aSymbol.push(sSymbol);