SparcSymbolsImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
written by Ch. Le Cocq, September 15, 1988
Christian Le Cocq September 21, 1988 11:17:56 am PDT
DIRECTORY
Basics USING [Card32FromF, CompareCard, FWORD],
IO,
RedBlackTree,
Rope,
SparcSymbols;
Symbols Input
GetUnsigned:
PROC [s:
IO.
STREAM]
RETURNS [u:
CARD32] ~ {
RETURN[Basics.Card32FromF[IO.GetFWord[s]]];
};
GetLocAndSize:
PROC [s:
IO.
STREAM]
RETURNS [off, size:
INT] ~ {
text, data, trsize, drsize: CARD32;
[] ← GetUnsigned[s]; --machine flags etc
text ← GetUnsigned[s];
data ← GetUnsigned[s];
[] ← GetUnsigned[s]; --bss not actually present in the file
size ← GetUnsigned[s];
[] ← GetUnsigned[s]; --entry point: don't care
trsize ← GetUnsigned[s];
drsize ← GetUnsigned[s];
off ← text+data+trsize+drsize;
};
StopOnZero:
IO.BreakProc ~ {
RETURN[
IF char='\000
THEN break
ELSE other]};
GetOneSymbol:
PROC [s:
IO.
STREAM, strOff:
INT]
RETURNS [sym: Symbol] ~ {
index: INT;
txtOff: INT ← GetUnsigned[s];
sym ← NEW[SymbolRec];
sym.type ← IO.GetFWord[s];
sym.val ← GetUnsigned[s];
index ← IO.GetIndex[s];
IF txtOff=0 THEN RETURN;
IO.SetIndex[s, strOff+txtOff];
sym.txt ← IO.GetTokenRope[stream: s, breakProc: StopOnZero].token;
IO.SetIndex[s, index];
};
XtractAddr: RedBlackTree.GetKey ~ {RETURN[data]};
XtractName: RedBlackTree.GetKey ~ {RETURN[NARROW[data, Symbol].txt]};
CompareAddr: RedBlackTree.Compare ~ {
RETURN[Basics.CompareCard[
NARROW[k, Symbol].val,
NARROW[data, Symbol].val
]]};
CompareName: RedBlackTree.Compare ~ {
RETURN[Rope.Compare[
NARROW[k],
NARROW[data, Symbol].txt
]]};
GetSymbols:
PUBLIC
PROC [s:
IO.
STREAM]
RETURNS [tables: Tables] ~ {
reads the symbols in from the a.out format. see man a.out.
symOff, strOff, symSize, strSize: INT;
IO.SetIndex[s, 0]; -- just in case the stream has already been red
[symOff, symSize] ← GetLocAndSize[s];
strOff ← symOff+symSize;
IO.SetIndex[s, strOff];
strSize ← GetUnsigned[s];
IO.SetIndex[s, symOff];
tables ←
NEW[SparcSymbols.TablesRec ← [
byAddr: RedBlackTree.Create[XtractAddr, CompareAddr],
byName: RedBlackTree.Create[XtractName, CompareName]
]];
WHILE
IO.GetIndex[s]<strOff
DO
sym: Symbol ← GetOneSymbol[s, strOff];
IF sym.type.hi.hi=05h THEN RedBlackTree.Insert[tables.byAddr, sym, sym];
IF sym.txt#NIL THEN RedBlackTree.Insert[tables.byName, sym, sym.txt ! RedBlackTree.DuplicateKey => CONTINUE];
ENDLOOP;
};
Table Access
GetClosestName:
PUBLIC
PROC [addr:
CARD32, tables: Tables]
RETURNS [name: Rope.
ROPE] ~ {
lookupSym: Symbol ← NEW[SymbolRec ← [val: addr]];
sym: Symbol ← NARROW[RedBlackTree.Lookup[tables.byAddr, lookupSym]];
IF sym=NIL THEN sym ← NARROW[RedBlackTree.LookupNextSmaller[tables.byAddr, lookupSym]];
RETURN[sym.txt];
};
GetAddress:
PUBLIC
PROC [name: Rope.
ROPE, tables: Tables]
RETURNS [addr:
CARD32] ~ {
sym: Symbol ← NARROW[RedBlackTree.Lookup[tables.byName, name]];
RETURN[IF sym=NIL THEN 0 ELSE sym.val];
};
Tests
ListTable:
PROC [out:
IO.
STREAM, table: RedBlackTree.Table] ~ {
PrintEachEntry: RedBlackTree.EachNode ~ {
sym: Symbol ← NARROW[data];
IO.PutF[out, "%g\t\t(%8x) =\t%d\n", IO.rope[sym.txt], IO.card[LOOPHOLE[sym.type]], IO.card[sym.val]];
};
RedBlackTree.EnumerateIncreasing[table, PrintEachEntry];
};
ListTables:
PUBLIC
PROC [out:
IO.
STREAM, tables: Tables] ~ {
IO.PutRope[out, "\nMap by address: \n"];
ListTable[out, tables.byAddr];
IO.PutRope[out, "\nMap by name: \n"];
ListTable[out, tables.byName];
};