ObjectFilesPrivate.mesa
Copyright Ó 1990, 1991, 1992 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
DIRECTORY
IO USING[STREAM],
ObjectFiles USING[BracketPairKind, CGrammar, FileSegmentPC, GlobalVarLoc, Stab, VarLoc, VersionStampInfo],
PFSNames USING [PATH],
Rope USING[ROPE],
SystemInterface USING[CirioFile];
ObjectFilesPrivate: CEDAR DEFINITIONS =
BEGIN
This definitions file contains the definitions of types that are exported from ObjectFilesPrivateImpl.
The hope is that this will reduce exported type conflicts in the DMachine world.
We begin with types defined in ObjectFiles.
ROPE: TYPE ~ Rope.ROPE;
Stab: TYPE = ObjectFiles.Stab;
StabList: TYPE ~ LIST OF Stab;
VersionStampInfo: TYPE = ObjectFiles.VersionStampInfo;
Next, the exported types
Parsed: TYPE = REF ParsedBody;
ParsedBody: TYPE = RECORD[
file: SystemInterface.CirioFile,
targetData: REF ANY,
formatSpecificString: ROPE,
cGrammar: ObjectFiles.CGrammar,
header: Header,
privateInfo: REF ANYNIL, -- 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: BOOLEANFALSE,
versionStampStab: Stab,
globalFrameStab: Stab,
versionStampInfo: REF VersionStampInfo,
globalFrameGvl: ObjectFiles.GlobalVarLoc,
funStabsInstalled: BOOLEANFALSE,
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];
And finally, types needed to define the exported types.
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 ANYNIL
];
MemorySegmentInfo: TYPE ~ RECORD [byteOffset, byteLength: CARD];
PCtoLineNumMap: TYPE = REF PCtoLineNumMapBody;
PCtoLineNumMapBody: TYPE = RECORD[
SEQUENCE nSlines: CARDINAL OF SLineData];
sorted by PC
LineNumToPCMap: TYPE = REF LineNumToPCMapBody;
LineNumToPCMapBody: TYPE = RECORD[
SEQUENCE nSlines: CARDINAL OF SLineData];
sorted by Line Num
SLineData: TYPE = RECORD[cLineNum: CARD, parsedRelPC: ObjectFiles.FileSegmentPC];
Functions
FunHandle: TYPE = REF FunHandleBody;
FunHandleBody: TYPE = RECORD[
module: Module,
index: CARD];
Bracket Pairs
BracketPair: TYPE = REF BracketPairBody;
BracketPairBody: TYPE = RECORD[
module: Module,
kind: ObjectFiles.BracketPairKind,
firstX, limitX: CARD, -- pair covers [firstX, limitX)
firstPC, pcLimit: CARD, -- pair's instructions start in [firstPC, pcLimit)
funStab: Stab, -- NIL if not a syntheticFun bracket pair
funIndex: CARD, -- 0 for outermost bracket pair
symbols: StabList,
innerBrackets: LIST OF BracketPair]; -- in increasing numerical order
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: ROPENIL] 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];
END..