home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
asdt32.zip
/
ASDT32SM.CMD
< prev
next >
Wrap
OS/2 REXX Batch file
|
1992-04-24
|
9KB
|
263 lines
/**/
/*******************************************************/
/* File Name: ASDT32SM */
/* Author: Dave Evans (DEVANS at LEXVMK) */
/* Date: 05/13/91 */
/* Usage: ASDT32SM *.MAP | *.CMB [seg#=adjust] */
/* Description: Reads *.MAP and creates *.SYM to */
/* contain Public symbols for ASDT32 to read. */
/* Alternatively, reads *.CMB, which has multiple */
/* MAPs specified, to create *.SYM. In this case, */
/* each new MAP's group of segment numbers will */
/* receive a permuted number to distinguish it */
/* from like-numbered segments in other MAPs. */
/* You may specify a load address to augment one */
/* segment's offsets; e.g., 3=12345678 tells */
/* ASDT32SM to add 12345678 to all offsets */
/* associated with segment number 3. If you are */
/* using a CMB file, you should ensure that the */
/* segment you want augmented is in the first MAP */
/* specified in the CMB file. Last, ASDT32SM will */
/* create a *.SPL file (spill file) when you want */
/* to use a *.CMB file. This will enable you to */
/* see where ASDT32SM remapped your segments. */
/* Note: This is a REXX OS/2 CMD module. If you wish */
/* to improve the code that follows in terms of */
/* accuracy, efficiency, breadth, or error checking, */
/* then please make the change(s) and send the */
/* resulting file to the author. Please add a note */
/* to the history log as well. */
/* History: 05/13/91 - created. */
/* 06/19/91 - added code for multiple maps. */
/* 04/01/92 - added code for LINK maps. */
/*******************************************************/
NOP
NUMERIC DIGITS 12
masktable= ,
'80'x|| ,
'40'x|| ,
'20'x|| ,
'10'x|| ,
'08'x|| ,
'04'x|| ,
'02'x|| ,
'01'x;
/* initialize my existential dictionary table */
dictstring.='00'x
/* initialize my segment number lengths array */
lengthstring.='00000000'x
/* Read arguments to ASDT32SM */
parse upper arg infile more
/* Display help when polled */
if (infile='?') | (infile='') then
do
do i = 2 to 100 while(sourceline(i)<>'NOP')
say sourceline(i)
end;
exit
end;
/* separate filename and extension and possible parameter */
parse var infile fname'.'ext
/* ensure file extension correct */
if ext<>'MAP' & ,
ext<>'CMB' then do;
say 'File must have extension of MAP or CMB.';
return(100);
end;
/* ensure parameter specification is of right form */
augmentsegnum='';
if more<>'' then do;
equalspos=POS('=',more);
if equalspos=0 then do;
badparm:
say 'Parameter to augment offsets is of form: seg#=adjust'
say ' where'
say ' - seg# is 1-256 (decimal)'
say ' - adjust is a 4-byte hex value (e.g., A234567E)'
return(100);
end;
augmentsegnum=left(more,equalspos-1);
v1=verify(augmentsegnum,XRANGE('0','9'));
if v1<>0 then
signal badparm;
augmentoffset=right(more,8);
v2=verify(augmentoffset,XRANGE('0','9')||XRANGE('A','F'));
if v2<>0 then
signal badparm;
end;
/* erase *.SYM and temporary file and spill file */
outfile=fname||'.SYM'
'ERASE ' outfile
outtemp='';
tempoutfile='$$TMPO$$.TMP';
'ERASE ' tempoutfile
spillfile=fname||'.SPL';
'ERASE ' spillfile
/* see if input file exists */
call PRESENCECHECK;
/* are we processing multiple maps ? */
segsin=0;
cmbfile=infile;
CMBLOOP:
if ext=CMB then do;
/* get next line from .CMB file to tell us which new map to process */
if LINES(infile)=0 then
signal CMBEND;
infile=LINEIN(cmbfile);
if infile='' then
signal CMBEND;
call PRESENCECHECK;
/* put MAP name into spill file */
RC=LINEOUT(spillfile,infile);
end;
/* Here we need to tally the length of each segment before we process the
symbols in the Publics area. This will help ASDT32 resolve a segment
number at run time */
startword='';
do while(startword<>'Start' & LINES(infile)>0);
textline=LINEIN(infile)
parse var textline startword more
end;
textline=LINEIN(infile)
parse var textline ' 'segnum':'offset seglength more
lastsegnum=segnum;
currseg=segsin+1;
/* put segment number and its mapped equivalent into spill file for .CMB */
if ext=CMB then
RC=LINEOUT(spillfile,segnum||' '||D2X(currseg,4));
do while(segnum<>'' & LINES(infile)>0);
if segnum<>lastsegnum then do;
currseg=currseg+1;
/* check against ASDT32's limit for number of segments */
if currseg>256 then do;
say 'ASDT32 processes a maximum of 256 segments';
return(100);
end;
lastsegnum=segnum;
/* put segment number and its mapped equivalent into spill file for .CMB */
if ext=CMB then
RC=LINEOUT(spillfile,segnum||' '||D2X(currseg,4));
end;
/* allow for link MAPs, which have 16-bit length information */
if length(seglength)=6 then
seglength='0000'||seglength;
/* strip the leading '0' and trailing 'H' from the seglength */
seglength=substr(seglength,2,8);
if substr(seglength,5,1)='H' then
seglength='0000'||left(seglength,4);
/* allow for LINK MAPs, which have 16-bit offset information */
if length(offset)=4 then
offset='0000'||offset;
lengthstring.currseg=reverse(X2C(D2X(X2D(offset)+X2D(seglength)-1,8)));
textline=LINEIN(infile)
parse var textline ' 'segnum':'offset seglength more
end;
/* Look for Publics line in map. It is important to grab the section which
has the Publics listed by value as this allows ASDT32 to assume an
ordering of the segment numbers and the offsets within the segment
numbers */
pubword1=''; pubword2=''; pubword3='';
do while(pubword1||pubword2||pubword3<>'PublicsbyValue' & LINES(infile)>0);
textline=LINEIN(infile)
parse var textline addrword pubword1 pubword2 pubword3 more
end;
if pubword1<>'Publics' then do;
say 'No Publics found in ' infile;
return(100);
end;
/* Read blank line after Publics line */
blankline=LINEIN(infile)
/* Build *.SYM from *.MAP Publics */
do while(LINES(infile)>0);
textline=LINEIN(infile)
parse var textline ' 'segnum':'offset symbolname more
if segnum='' then
leave;
if segnum<>'0000' then do;
/* ASDT32 can only show 13 chars max (today) of a symbol. So lets
reduce the bulk in the file for those who insist on long symbol
names */
if length(symbolname)>13 then
symbolname=left(symbolname,13);
symlen=D2C(length(symbolname),1);
segnumd=X2D(segnum)+segsin;
segnumb=reverse(X2C(D2X(segnumd,4)));
/* allow for LINK MAPs, which have 16-bit offset information */
if length(offset)=4 then
offset='0000'||offset;
offsetb=reverse(X2C(offset));
if segnum=augmentsegnum then
offsetb=reverse(X2C(D2X(X2D(offset)+X2D(augmentoffset),8)));
outtemp=outtemp||segnumb||offsetb||symlen||symbolname;
if length(outtemp)>1023 then do;
RC=CHAROUT(tempoutfile,outtemp);
outtemp='';
end;
/* Thanks to enormous symbol files (as used by the Bocans!), I have
a performance problem. Hence, I'll build an existential
dictionary map (64KBits long) for a quick lookup (to see if the
segnum:offset does not exist) */
XORPiece=C2D(BITXOR(left(offsetb,2),right(offsetb,2)));
shift=TRUNC(segnumd//16);
/* I don't know how to rotate a 16-bit value in REXX, so I'll shift the high
part left by the shift ct and the lo part right by the shift ct mod 16
and recombine them with an addition! */
hashhi=XORPiece*2**shift;
hashlo=TRUNC(XORPiece/(2**(16-shift)));
hashcode=C2D(right(D2C(hashhi+hashlo,2),2));
index=TRUNC(hashcode/8)+1;
mask=substr(masktable,TRUNC(hashcode//8)+1,1);
dictstring.index=BITOR(dictstring.index,mask);
end;
end;
segsin=currseg;
RC=stream(infile,'C','CLOSE');
if ext=CMB then
signal CMBLOOP;
CMBEND:
RC=CHAROUT(tempoutfile,outtemp);
RC=stream(tempoutfile,'C','CLOSE');
do i=1 to 8192;
RC=CHAROUT(outfile,dictstring.i);
end;
do i=1 to 256;
RC=CHAROUT(outfile,lengthstring.i);
end;
outsize=stream(tempoutfile,'C','query size');
memtempout=CHARIN(tempoutfile,1,outsize);
RC=CHAROUT(outfile,memtempout);
RC=stream(outfile,'C','CLOSE');
RC=stream(tempoutfile,'C','CLOSE');
'ERASE ' tempoutfile
exit
PRESENCECHECK:
if stream(infile,'c','query exists')='' then do;
say 'File '||infile||' not found.';
exit(100);
end;
RETURN