// BLDRFINISH.BCPL
// Taft, November 13, 1981 2:56 PM
// Swinehart, May 23, 1977 5:53 PM
// Copyright Xerox Corporation 1979, 1981
get "BLDR.DECL"
let FinishBldr() be
[
ENDBINFILE()
ENDSAVEFILE()
if MAPSW do WriteSyms()
//
FOO.RUN 45321b wds of code--24 undefs--56 warnings--34 errors
BeginReport(false)
PutTemplate(ESTREAM,"$S $6UOb wds of code",
SFILENAME,SFILE>>BFile.maxCodeLoc-CODESTART)
PRINTLISTINGS()
if WARNINGSW & (WARNINGCOUNT ne 0) then
PutTemplate(ESTREAM,"--$D warning$S",WARNINGCOUNT,
WARNINGCOUNT eq 1? "","s")
if ERRORCOUNT then
PutTemplate(ESTREAM,"--$D error$S",ERRORCOUNT,
ERRORCOUNT eq 1? "","s")
Puts(ESTREAM,$*N)
EndReport()
if LSTREAM ne dsp do Closes(LSTREAM) // will truncate
]
and ENDSAVEFILE() be
[ // write the common and static images
let endFa = vec lFA
GetCurrentFa(SSTREAM,endFa)
// Write static links
JumpToFa(SSTREAM,staticLinksFa)
for i = 0 to KSTATICCOUNT-1 do Puts(SSTREAM,CODE!i>>SYm.staticAddress)
if not BBINSAVESW then GetCurrentFa(SSTREAM, endFa)
Zero(CODE,STATICMAX-STATICSTART) // MAKE SURE IT FITS!!!!
for I = 1 to SYMTAB!0 do
[
let sym = SYMTAB!I
if sym>>SYm.jOnly loop
let ADDR = sym>>SYm.staticAddress
if INITSWAPSW eq 2 & sym>>SYm.initSwappedOut then
sym>>SYm.initialValue = SWAPPEDOUTSYM>>SYm.initialValue
let VALUE = sym>>SYm.initialValue
test sym>>SYm.z
then test VALUE & not BETWEEN(ADDR,#50,#400)
ifso OUTWARNING(sym)
ifnot ZCODE!ADDR = VALUE
or test VALUE & not BETWEEN(ADDR,STATICSTART,STATICMAX)
ifso OUTWARNING(sym)
ifnot CODE!(ADDR - STATICSTART) = VALUE
]
STATICLOC = Umax(STATICLOC, JSTATICMAX) // ****
if Usc(STATICLOC , STATICMAX) ge 0 do
WARNING("Not enough static space was reserved")
// Kludge to maintain compatibility with sifted format, which requires the
// statics to come first, hence requiring BLDR to assume the actual length
// of the statics before it can write out any code
let realStaticLoc = STATICLOC
STATICLOC=STATICMAX-1
PARAMLIST>>BLV.startOfStatics = STATICSTART
PARAMLIST>>BLV.endOfStatics = STATICLOC
PARAMLIST>>BLV.startOfCode = SFILE>>BFile.codeLoc + 1
PARAMLIST>>BLV.afterLastCodeWord = SFILE>>BFile.maxCodeLoc
PARAMLIST>>BLV.endCode = SFILE>>BFile.rFileCodeLoc
PARAMLIST>>BLV.relPairTable = SRELPAIRLOC
if COMMONLOC ge COMMONMAX do WARNING("Not enough common space")
Resets(SSTREAM) // back to word 0
Puts(SSTREAM,PARAMLIST>>BLV.startOfCode) // initial value for PC
Puts(SSTREAM,SFILE>>BFile.pageLength) // Length of .RUN File in pages (less BBs)
Puts(SSTREAM,0) // type
Puts(SSTREAM,KSTATICCOUNT)
Zero(BHEAD,#15-#4+1)
WriteBlock(SSTREAM,BHEAD,#15-#4+1)
WriteBlock(SSTREAM,PARAMLIST,#40)
WriteBlock(SSTREAM,ZCODE,#300)
WriteBlock(SSTREAM,CODE,STATICLOC-STATICSTART+1)
JumpToFa(SSTREAM, endFa)
Closes(SSTREAM)
for I=#300 to #377 do if ZCODE!I ne 0 then
[
let xcNum = SFILENUM+1 // they are created contiguous
let xcStream = Openfile(xcNum, ksTypeWriteOnly, wordItem)
PutTemplate(LSTREAM,
"*NWriting locations #300-#377 on $S", fileNameVec!xcNum)
WriteBlock(xcStream, ZCODE+#300, #100) // *****
Closes(xcStream)
break
]
PutTemplate(LSTREAM,"*NCOMMON *T$6UO*T$6UO*NSTATICS*T$6UO*T$6UO*N*N",
COMMONSTART, COMMONLOC, STATICSTART, realStaticLoc)
]
and WriteSyms() be
[
MHEAD!0 = verSyms
let symStream = Openfile(MFILENUM,ksTypeWriteOnly,wordItem)
WriteBlock(symStream,MHEAD,MHEADLENGTH)
MHEAD!2 = MHEADLENGTH
Puts(symStream,0)
let SLENGTH = 1
for i = 0 to DICTHEADLENGTH-1 do
[ // not the same order as before!
let d = DICT!i
while d do
[
let name = lv d>>DIct.name
let lN = name>>STRING.length/2+1
d>>DIct.mFileOffset = SLENGTH
WriteBlock(symStream,name,lN)
SLENGTH = SLENGTH + lN
d = @d
]
]
MHEAD!3 = CURBOPOS(symStream)
Puts(symStream,SYMTAB!0)
for i = 1 to SYMTAB!0 do
[ let sym = SYMTAB!i
if sym>>SYm.jOnly loop
Puts(symStream,sym>>SYm.dictEntry>>DIct.mFileOffset)
let T = sym>>SYm.type lshift 11
if sym>>SYm.local then T = T + #2000
if sym>>SYm.relocatable then T = T + #1000
T = T + sym>>SYm.rFile>>RFile.rFileId
Puts(symStream,T)
Puts(symStream,sym>>SYm.staticAddress)
Puts(symStream,sym>>SYm.initialValue)
]
for code = RFILECODE to BFILECODE do
[ // record RFile, BFile information in symbol file
MHEAD!(4+(code-RFILECODE)) = CURBOPOS(symStream)
Puts(symStream, code eq RFILECODE? rFileCount, bFileCount)
let nextFile = @eventList
while nextFile do
[ let file = nextFile; nextFile = @nextFile
unless file>>RFile.useCode eq code loop
let d = fileNameVec!(file>>RFile.fileNum) - offsetDIctName
Puts(symStream,d>>DIct.mFileOffset)
WriteBlock(symStream,lv file>>RFile.bFileId, 3)
]
]
MHEAD!1 = CURBOPOS(symStream)
let endFa = vec lFA; GetCurrentFa(symStream,endFa)
Resets(symStream)
WriteBlock(symStream,MHEAD,MHEADLENGTH)
Puts(symStream,SLENGTH)
JumpToFa(symStream,endFa)
Closes(symStream)
]
and PRINTLISTINGS() be
[
FIRSTSYM = 1
LASTSYM = SYMTAB!0
let UNDEFCOUNT = PRINTUNDEFINED()
if UNDEFCOUNT then
PutTemplate(ESTREAM,"--$D undef$S",UNDEFCOUNT,UNDEFCOUNT eq 1?"","s")
if LISTVARSW do [ Puts(LSTREAM,#14); PRINTVARS() ]
if LISTNUMSW do [ Puts(LSTREAM,#14); PRINTNUMERIC() ]
]
and PRINTUNDEFINED() = valof
[
let undefCt = 0
let firstRefSym = -1
for i = FIRSTSYM to LASTSYM do [
let sym = SYMTAB!i
if sym>>SYm.type eq 0 & sym>>SYm.jOnly eq 0 then [
if undefCt eq 0 do Wss(LSTREAM,"*NUndefined names*N")
if sym ne firstRefSym then
PutTemplate(LSTREAM," first referenced in $S:*N",NameOfRfile(sym))
firstRefSym = sym
PRINTSYM(sym)
undefCt = undefCt + 1
]
]
resultis undefCt
]
and PRINTVARS() be
[
let rFile = @eventList
while rFile do
[
if rFile>>RFile.useCode eq RFILECODE then
[
Wss(LSTREAM,fileNameVec!(rFile>>RFile.fileNum)); Puts(LSTREAM,$*N)
for i = FIRSTSYM to LASTSYM do
[
let sym = SYMTAB!i
unless sym>>SYm.jOnly % sym>>SYm.rFile ne rFile % sym>>SYm.type ne 1 do
PRINTSYM(sym)
]
]
rFile = @rFile
]
]
and PRINTNUMERIC() be
[
let sym = nil
for i = FIRSTSYM to LASTSYM do
[ sym = SYMTAB!i
if (not sym>>SYm.jOnly) & sym>>SYm.z then PRINTSYM(sym)
]
for i = FIRSTSYM to LASTSYM do
[ sym = SYMTAB!i
if (not sym>>SYm.jOnly) & (not sym>>SYm.z) then PRINTSYM(sym)
]
]