ObjectFilesPrivate.mesa
Copyright Ó 1990, 1991, 1992, 1993 by Xerox Corporation. All rights reserved.
Adapted from DotOAccessPrivate
Laurie Horton, June 10, 1992 12:14 pm PDT
Philip James, February 10, 1992 1:05 pm PST
Katsuyuki Komatsu January 23, 1993 10:20 am PST
Last tweaked by Mike Spreitzer January 21, 1993 4:41 pm PST
Jas, January 5, 1993 11:11 am PST
Parsed: TYPE = REF ParsedBody;
ParsedBody:
TYPE =
RECORD[
file: SystemInterface.CirioFile,
targetData: REF ANY,
formatSpecificString: ROPE,
cGrammar: ObjectFiles.CGrammar,
header: Header,
privateInfo: REF ANY ¬ NIL, -- needed for SGI
stabLimit: CARD,
modules: LIST OF Module];
Module: TYPE = REF ModuleBody;
ModuleBody:
TYPE =
RECORD[
whole: Parsed,
moduleWhole: Parsed ¬ NIL, -- for SunOS5.x
fileName: PFSNames.PATH,
instance: INT ¬ 0,
firstPC: CARD ¬ 0, -- also, the amount by which the pcs on bracket stabs need to be relocated
limitPC: CARD ¬ 0, -- ObjectFiles.FileSegmentPC ¬ ObjectFiles.NoFileSegmentPC PJ CARD ¬ 0 one greater than last mentioned pc among the dbx stabs (note, code may actually reach higher pcs, but the pc of any function start will be < limitPC)
dataReloc: CARD ¬ 0, -- data segment relocation for SunOS5.x
firstStabX: CARD ¬ 0,
limitStabX: CARD ¬ 0, -- all stabX lie in [firstStabX..limitStabX)
outerBracket: BracketPair,
stabs: REF StabSet ¬ NIL,
staticVarsInstalled: BOOLEAN ¬ FALSE,
versionStampStab: Stab,
globalFrameStab: Stab,
versionStampInfo: REF VersionStampInfo,
globalFrameGvl: ObjectFiles.GlobalVarLoc,
funStabsInstalled: BOOLEAN ¬ FALSE,
funStabs: FunStabSet,
fdIndex: INT32,
pcToLineNum: PCtoLineNumMap,
lineNumToPC: LineNumToPCMap];
StabRange: TYPE = RECORD[first, count: CARD];
StabSet: TYPE = RECORD[SEQUENCE nStabs: CARDINAL OF Stab];
FunStabSet: TYPE = REF FunStabSetBody;
FunStabSetBody: TYPE = RECORD[firstX: CARD, funStabs: SEQUENCE nFunStabs: CARDINAL OF FunStabInfo];
FunStabInfo:
TYPE =
RECORD[
stab: Stab,
firstX, count: CARD, --the X range of this fn
firstLocal: Stab ¬ NIL, --of the Scan{Module,Fn}Structure protocol
nextX: CARD, --of the Scan{Module,Fn}Structure protocol
funHandle: FunHandle,
bracketsScanned: BOOLEAN,
brackets: BracketPair];
Header: TYPE = REF HeaderBody;
HeaderBody:
TYPE =
RECORD[
dynamic: BOOL, -- bits [0..0]
toolversion: BYTE, -- bits [1..7]
machtype: BYTE,
magic: CARD16,
flags: CARD16 ¬ 0,
text, iData, textReloc, dataReloc, symsReloc, syms, extSyms, auxSyms, debug, linno, fileDescr, procDescr: MemorySegmentInfo ¬ [0, 0],
textLoadOffset: CARD32,
bssSize: CARD32,
entryPoint: CARD32,
nPageSize: CARD32,
nEntries, nExtEntries, nAuxEntries, nFileDescr, nProcDescr, nLinnoEntries: CARD32 ¬ 0,
stringOffset, stringIndexLimit, extStringOffset, extStringIndexLimit: CARD32 ¬ 0,
clientData: REF ANY ¬ NIL
];
Parsing the sequence of Stabs in a Module
Here is a parser for the sequence of Stabs in a Module. The grammar depends on the object file format, and is documented in CirioReverseEngineering.tioga for each object file format. This interface uses enumeration procedures that take callbacks, instead of procedures that return lists. The hypothesis is that the consumer of this parse can be common across all object file formats and live in ObjectFilesImpl, whereas the actual parser appears in each format-specific implementation.
ScanModuleStructure: PROC [module: Module, perFn: FnConsumer];
FnConsumer:
TYPE ~
PROC [funStab: Stab, firstLocal: Stab ¬
NIL, nextX:
CARD]
RETURNS [limitX:
CARD];
firstLocal is NIL if there are no local declarations.
nextX is the X after the argument declarations, and =firstLocal.stabX if firstLocal isn't NIL.
Must call ScanFnStructure exactly once, and return the limitX.
ScanFnStructure: FnFinisher;
FnFinisher:
TYPE ~
PROC [
module: Module,
funStab: Stab,
firstLocal: Stab ¬ NIL,
nextX: CARD,
perParm: PROC [Stab] ¬ NIL,
perBracket: BracketConsumer ¬ NIL
] RETURNS [limitX, limitPc: CARD];
Args 2-4 are those given to the FnConsumer.
perParm, if not NIL, is called for each Stab that concerns a parameter.
perBracket, if not NIL, is called some number of times.
BracketConsumer:
TYPE ~
PROC [first: Stab]
RETURNS [limitX:
CARD];
Must call ScanBracketStructure exactly once.
ScanBracketStructure: BracketFinisher;
BracketFinisher:
TYPE ~
PROC [
module: Module,
funStab: Stab,
first: Stab,
perLocal: PROC [Stab] ¬ NIL,
perSubBracket: BracketConsumer ¬ NIL
] RETURNS [limitX, firstPc, limitPc: CARD];
Calls perLocal, if not NIL, for each local declaration Stab.
Calls perSubBracket, if not NIL, for each bracket pair directly nested in this one.
ObjectFile implementation registration
TranslationTable: TYPE ~ REF TranslationTableBody ¬ NIL;
TranslationTableBody:
TYPE ~
RECORD[
SEQUENCE length: CARD OF Translation];
Translation:
TYPE ~
RECORD[
byteOffset, length, compareValue: CARD,
format: ROPE, type: {point, first, middle, last} ¬ point];
ObjectFileFlavor: TYPE = REF ObjectFileFlavorBody ¬ NIL;
ObjectFileFlavorBody:
TYPE =
RECORD[
formatSpecificString: ROPE,
cGrammar: ObjectFiles.CGrammar,
readHeaderProc: ReadHeaderProcType,
moduleFromParsedAndPCProc: ModuleFromParsedAndPCProcType,
varLocFromStabProc: VarLocFromStabProcType,
getTypeRefProc: GetTypeRefProcType,
installBracketPairsForOneFunStabProc: InstallBracketPairsForOneFunStabProcType ¬ NIL,
scanModuleStructure: PROC [module: Module, perFn: FnConsumer] ¬ NIL,
scanFnStructure: FnFinisher ¬ NIL,
scanBktStructure: BracketFinisher ¬ NIL,
fnsOrderedByStart: BOOL,
installStaticVarsProc: InstallStaticVarsType,
alterFunStabProc: AlterFunStabType,
getSPOffsetProc: GetSPOffsetType];
Either installBracketPairsForOneFunStabProc is filled in or scanModuleStructure, scanFnStructure, & scanBktStructure are.
AlterFunStabType: TYPE ~ PROC[module: Module, funStabX: CARD] RETURNS [Stab];
GetSPOffsetType: TYPE ~ PROC[module: Module, spc: ObjectFiles.FileSegmentPC] RETURNS [INT];
InstallStaticVarsType: TYPE ~ PROC[module: Module];
ReadHeaderProcType: TYPE ~ PROC[stream: IO.STREAM] RETURNS[Header];
ModuleFromParsedAndPCProcType: TYPE ~ PROC[whole: Parsed, spc: ObjectFiles.FileSegmentPC, moduleRope: ROPE ¬ NIL] RETURNS[Module];
VarLocFromStabProcType: TYPE ~ PROC [stab: Stab] RETURNS[ObjectFiles.VarLoc];
GetTypeRefProcType: TYPE ~ PROC[sourceStream:IO.STREAM] RETURNS [ROPE];
InstallBracketPairsForOneFunStabProcType: TYPE ~ PROC[module: Module, funStabIndex: CARD];
OFFFromStream: PROC[stream: IO.STREAM] RETURNS [ROPE];
RegisterObjectFileFlavor: PROC[flavor: ObjectFileFlavor, table: TranslationTable];
RetrieveObjectFileFlavor: PROC[formatSpecificString: ROPE] RETURNS[flavor: ObjectFileFlavor];
CheckStaticVar: PROC[stab: Stab, namePrefix: ROPE, allowSuffix: BOOL] RETURNS [ObjectFiles.VarLoc];
ScanSymbolStabs: PROC[module: Module, firstX: CARD, head, tail: StabList] RETURNS[--nextX-- CARD, --head, tail of collected symbols-- StabList, StabList];
ReadInitialDataAsRope: PROC[module: Module, fileByteOffset: CARD] RETURNS[ROPE];
ReadStabRope: PROC[stab: Stab] RETURNS [rope: ROPE];
ReadStab: PROC[module: Module, stabX: CARD] RETURNS[Stab];
RaiseUnreadableObjectFileForFun: PROC[msg: ROPE, module: Module, fun: Stab];