home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / asdt32.zip / ASDT32SM.CMD < prev    next >
OS/2 REXX Batch file  |  1992-04-24  |  9KB  |  263 lines

  1. /**/
  2. /*******************************************************/
  3. /* File Name: ASDT32SM                                 */
  4. /* Author: Dave Evans (DEVANS at LEXVMK)               */
  5. /* Date: 05/13/91                                      */
  6. /* Usage: ASDT32SM *.MAP | *.CMB [seg#=adjust]         */
  7. /* Description: Reads *.MAP and creates *.SYM to       */
  8. /*   contain Public symbols for ASDT32 to read.        */
  9. /*   Alternatively, reads *.CMB, which has multiple    */
  10. /*   MAPs specified, to create *.SYM.  In this case,   */
  11. /*   each new MAP's group of segment numbers will      */
  12. /*   receive a permuted number to distinguish it       */
  13. /*   from like-numbered segments in other MAPs.        */
  14. /*   You may specify a load address to augment one     */
  15. /*   segment's offsets; e.g., 3=12345678 tells         */
  16. /*   ASDT32SM to add 12345678 to all offsets           */
  17. /*   associated with segment number 3.  If you are     */
  18. /*   using a CMB file, you should ensure that the      */
  19. /*   segment you want augmented is in the first MAP    */
  20. /*   specified in the CMB file.  Last, ASDT32SM will   */
  21. /*   create a *.SPL file (spill file) when you want    */
  22. /*   to use a *.CMB file.  This will enable you to     */
  23. /*   see where ASDT32SM remapped your segments.        */
  24. /* Note: This is a REXX OS/2 CMD module.  If you wish  */
  25. /*   to improve the code that follows in terms of      */
  26. /*   accuracy, efficiency, breadth, or error checking, */
  27. /*   then please make the change(s) and send the       */
  28. /*   resulting file to the author.  Please add a note  */
  29. /*   to the history log as well.                       */
  30. /* History:  05/13/91 - created.                       */
  31. /*           06/19/91 - added code for multiple maps.  */
  32. /*           04/01/92 - added code for LINK maps.      */
  33. /*******************************************************/
  34. NOP
  35.  
  36. NUMERIC DIGITS 12
  37. masktable= ,
  38.           '80'x|| ,
  39.           '40'x|| ,
  40.           '20'x|| ,
  41.           '10'x|| ,
  42.           '08'x|| ,
  43.           '04'x|| ,
  44.           '02'x|| ,
  45.           '01'x;
  46.  
  47. /* initialize my existential dictionary table */
  48. dictstring.='00'x
  49.  
  50. /* initialize my segment number lengths array */
  51. lengthstring.='00000000'x
  52.  
  53. /* Read arguments to ASDT32SM */
  54. parse upper arg infile more
  55.  
  56. /* Display help when polled */
  57. if (infile='?') | (infile='') then
  58.   do
  59.     do i = 2 to 100 while(sourceline(i)<>'NOP')
  60.       say sourceline(i)
  61.     end;
  62.     exit
  63.   end;
  64.  
  65. /* separate filename and extension and possible parameter */
  66. parse var infile fname'.'ext
  67.  
  68. /* ensure file extension correct */
  69. if ext<>'MAP' & ,
  70.    ext<>'CMB' then do;
  71.   say 'File must have extension of MAP or CMB.';
  72.   return(100);
  73. end;
  74.  
  75. /* ensure parameter specification is of right form */
  76. augmentsegnum='';
  77. if more<>'' then do;
  78.   equalspos=POS('=',more);
  79.   if equalspos=0 then do;
  80. badparm:
  81.     say 'Parameter to augment offsets is of form:  seg#=adjust'
  82.     say '  where'
  83.     say '        - seg# is 1-256 (decimal)'
  84.     say '        - adjust is a 4-byte hex value (e.g., A234567E)'
  85.     return(100);
  86.   end;
  87.   augmentsegnum=left(more,equalspos-1);
  88.   v1=verify(augmentsegnum,XRANGE('0','9'));
  89.   if v1<>0 then
  90.     signal badparm;
  91.   augmentoffset=right(more,8);
  92.   v2=verify(augmentoffset,XRANGE('0','9')||XRANGE('A','F'));
  93.   if v2<>0 then
  94.     signal badparm;
  95. end;
  96.  
  97. /* erase *.SYM and temporary file and spill file */
  98. outfile=fname||'.SYM'
  99. 'ERASE ' outfile
  100. outtemp='';
  101. tempoutfile='$$TMPO$$.TMP';
  102. 'ERASE ' tempoutfile
  103. spillfile=fname||'.SPL';
  104. 'ERASE ' spillfile
  105.  
  106. /* see if input file exists */
  107. call PRESENCECHECK;
  108.  
  109. /* are we processing multiple maps ? */
  110. segsin=0;
  111. cmbfile=infile;
  112. CMBLOOP:
  113. if ext=CMB then do;
  114. /* get next line from .CMB file to tell us which new map to process */
  115.   if LINES(infile)=0 then
  116.     signal CMBEND;
  117.   infile=LINEIN(cmbfile);
  118.   if infile='' then
  119.     signal CMBEND;
  120.   call PRESENCECHECK;
  121. /* put MAP name into spill file */
  122.   RC=LINEOUT(spillfile,infile);
  123. end;
  124.  
  125. /* Here we need to tally the length of each segment before we process the
  126.    symbols in the Publics area.  This will help ASDT32 resolve a segment
  127.    number at run time */
  128. startword='';
  129. do while(startword<>'Start' & LINES(infile)>0);
  130.   textline=LINEIN(infile)
  131.   parse var textline startword more
  132. end;
  133. textline=LINEIN(infile)
  134. parse var textline ' 'segnum':'offset seglength more
  135. lastsegnum=segnum;
  136. currseg=segsin+1;
  137. /* put segment number and its mapped equivalent into spill file for .CMB */
  138. if ext=CMB then
  139.   RC=LINEOUT(spillfile,segnum||' '||D2X(currseg,4));
  140. do while(segnum<>'' & LINES(infile)>0);
  141.   if segnum<>lastsegnum then do;
  142.     currseg=currseg+1;
  143. /* check against ASDT32's limit for number of segments */
  144.     if currseg>256 then do;
  145.       say 'ASDT32 processes a maximum of 256 segments';
  146.       return(100);
  147.     end;
  148.     lastsegnum=segnum;
  149. /* put segment number and its mapped equivalent into spill file for .CMB */
  150.     if ext=CMB then
  151.       RC=LINEOUT(spillfile,segnum||' '||D2X(currseg,4));
  152.   end;
  153.  
  154. /* allow for link MAPs, which have 16-bit length information */
  155.   if length(seglength)=6 then
  156.     seglength='0000'||seglength;
  157. /* strip the leading '0' and trailing 'H' from the seglength */
  158.   seglength=substr(seglength,2,8);
  159.   if substr(seglength,5,1)='H' then
  160.    seglength='0000'||left(seglength,4);
  161. /* allow for LINK MAPs, which have 16-bit offset information */
  162.   if length(offset)=4 then
  163.     offset='0000'||offset;
  164.   lengthstring.currseg=reverse(X2C(D2X(X2D(offset)+X2D(seglength)-1,8)));
  165.   textline=LINEIN(infile)
  166.   parse var textline ' 'segnum':'offset seglength more
  167. end;
  168.  
  169. /* Look for Publics line in map.  It is important to grab the section which
  170.    has the Publics listed by value as this allows ASDT32 to assume an
  171.    ordering of the segment numbers and the offsets within the segment
  172.    numbers */
  173. pubword1=''; pubword2=''; pubword3='';
  174. do while(pubword1||pubword2||pubword3<>'PublicsbyValue' & LINES(infile)>0);
  175.   textline=LINEIN(infile)
  176.   parse var textline addrword pubword1 pubword2 pubword3 more
  177. end;
  178. if pubword1<>'Publics' then do;
  179.   say 'No Publics found in ' infile;
  180.   return(100);
  181. end;
  182.  
  183. /* Read blank line after Publics line */
  184. blankline=LINEIN(infile)
  185.  
  186. /* Build *.SYM from *.MAP Publics */
  187. do while(LINES(infile)>0);
  188.   textline=LINEIN(infile)
  189.   parse var textline ' 'segnum':'offset symbolname more
  190.   if segnum='' then
  191.     leave;
  192.  
  193.   if segnum<>'0000' then do;
  194. /* ASDT32 can only show 13 chars max (today) of a symbol.  So lets
  195.    reduce the bulk in the file for those who insist on long symbol
  196.    names */
  197.     if length(symbolname)>13 then
  198.       symbolname=left(symbolname,13);
  199.  
  200.     symlen=D2C(length(symbolname),1);
  201.     segnumd=X2D(segnum)+segsin;
  202.     segnumb=reverse(X2C(D2X(segnumd,4)));
  203. /* allow for LINK MAPs, which have 16-bit offset information */
  204.     if length(offset)=4 then
  205.       offset='0000'||offset;
  206.     offsetb=reverse(X2C(offset));
  207.     if segnum=augmentsegnum then
  208.       offsetb=reverse(X2C(D2X(X2D(offset)+X2D(augmentoffset),8)));
  209.     outtemp=outtemp||segnumb||offsetb||symlen||symbolname;
  210.     if length(outtemp)>1023 then do;
  211.       RC=CHAROUT(tempoutfile,outtemp);
  212.       outtemp='';
  213.     end;
  214.  
  215. /* Thanks to enormous symbol files (as used by the Bocans!), I have
  216.    a performance problem.  Hence, I'll build an existential
  217.    dictionary map (64KBits long) for a quick lookup (to see if the
  218.    segnum:offset does not exist) */
  219.     XORPiece=C2D(BITXOR(left(offsetb,2),right(offsetb,2)));
  220.     shift=TRUNC(segnumd//16);
  221. /* I don't know how to rotate a 16-bit value in REXX, so I'll shift the high
  222.    part left by the shift ct and the lo part right by the shift ct mod 16
  223.    and recombine them with an addition! */
  224.     hashhi=XORPiece*2**shift;
  225.     hashlo=TRUNC(XORPiece/(2**(16-shift)));
  226.     hashcode=C2D(right(D2C(hashhi+hashlo,2),2));
  227.     index=TRUNC(hashcode/8)+1;
  228.     mask=substr(masktable,TRUNC(hashcode//8)+1,1);
  229.     dictstring.index=BITOR(dictstring.index,mask);
  230.   end;
  231. end;
  232.  
  233. segsin=currseg;
  234. RC=stream(infile,'C','CLOSE');
  235. if ext=CMB then
  236.   signal CMBLOOP;
  237. CMBEND:
  238. RC=CHAROUT(tempoutfile,outtemp);
  239. RC=stream(tempoutfile,'C','CLOSE');
  240.  
  241. do i=1 to 8192;
  242.   RC=CHAROUT(outfile,dictstring.i);
  243. end;
  244. do i=1 to 256;
  245.   RC=CHAROUT(outfile,lengthstring.i);
  246. end;
  247. outsize=stream(tempoutfile,'C','query size');
  248. memtempout=CHARIN(tempoutfile,1,outsize);
  249. RC=CHAROUT(outfile,memtempout);
  250. RC=stream(outfile,'C','CLOSE');
  251.  
  252. RC=stream(tempoutfile,'C','CLOSE');
  253. 'ERASE ' tempoutfile
  254.  
  255. exit
  256.  
  257. PRESENCECHECK:
  258. if stream(infile,'c','query exists')='' then do;
  259.   say 'File '||infile||' not found.';
  260.   exit(100);
  261. end;
  262. RETURN
  263.