home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume4 / 68kdisasm / part02 < prev    next >
Internet Message Format  |  1989-02-03  |  54KB

  1. Path: xanth!mcnc!rutgers!tut.cis.ohio-state.edu!cwjcc!hal!ncoast!allbery
  2. From: alex@umbc3.UUCP (Alex S. Crain)
  3. Newsgroups: comp.sources.misc
  4. Subject: v04i126: 680x0 COFF disassembler (2 of 2)
  5. Message-ID: <8810102104.AA05934@umbc3.UMD.EDU>
  6. Date: 14 Oct 88 23:39:52 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: alex@umbc3.UUCP (Alex S. Crain)
  9. Lines: 2299
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 4, Issue 126
  13. Submitted-by: "Alex S. Crain" <alex@umbc3.UUCP>
  14. Archive-name: 68kdisasm/Part2
  15.  
  16.     This is part 2 of the dissassembler.
  17.  
  18.                     :alex.
  19.                     Systems Programmer
  20. nerwin!alex@umbc3.umd.edu        UMBC
  21. alex@umbc3.umd.edu
  22.  
  23. #!/bin/sh
  24. # shar:    Shell Archiver  (v1.22)
  25. #
  26. #    Run the following text with /bin/sh to create:
  27. #      Makefile
  28. #      README.FIRST
  29. #      README.orig
  30. #      README.unixpc
  31. #      alloc.c
  32. #      conv.c
  33. #      doc.nr
  34. #      file.c
  35. #      heur.c
  36. #      main.c
  37. #      prin.c
  38. #      unc.h
  39. #
  40. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  41. XCFLAGS=-O
  42. XLDFLAGS=-s
  43. XOBJS=alloc.o file.o libmtch.o robj.o iset.o prin.o heur.o main.o conv.o
  44. XSHAREDLIB=/lib/shlib.ifile /lib/crt0s.o
  45. X
  46. Xdis:    $(OBJS)
  47. X    $(LD) $(LDFLAGS) -o dis $(OBJS) $(SHAREDLIB) -lld
  48. X
  49. X$(OBJS):    unc.h
  50. SHAR_EOF
  51. chmod 0644 Makefile || echo "restore of Makefile fails"
  52. sed 's/^X//' << 'SHAR_EOF' > README.FIRST &&
  53. X WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING 
  54. X                   
  55. X      The AT&T licence agreement specifically prohibits the dissassembly
  56. X   of propritory AT&T software. Be aware that use of this program on system
  57. X   software is in clear violation of that agreement. The author(s) of this
  58. X  software in no way incourage its use in any way shape or form for any reason
  59. X  whatsoever, and will not be held liable for anything ever if we can help it.
  60. X
  61. X WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING 
  62. SHAR_EOF
  63. chmod 0644 README.FIRST || echo "restore of README.FIRST fails"
  64. sed 's/^X//' << 'SHAR_EOF' > README.orig &&
  65. XI have gotten many many requests to email this or post it, because of
  66. Xits size email'ing it screws up most mailers, so i am submitting it to
  67. Xmod.sources to be posted.  Please note a major cavaet with this, it was
  68. Xwritten under Unisoft's port of Unix so the a.out file that it uses
  69. Xmore closely resembles the b.out.h file that most cross assemblers
  70. X(e.g.  greenhills) use. For the obvious reasons i have not included that
  71. Xfile with the posting. I did not write this nor do i make any claim to
  72. Xthat effect.
  73. X
  74. X    turner@imagen.UUCP <talcott!topaz!Shasta!imagen!Jim.Turner>
  75. X
  76. X----------------------------
  77. XThis is the 68000 disassembler mentioned on the net.
  78. XIt is not my final version by any means, but I have found it extremely
  79. Xuseful and it represents several weeks' work.
  80. X
  81. X    John Collins. <jmc@inset.UUCP>
  82. SHAR_EOF
  83. chmod 0644 README.orig || echo "restore of README.orig fails"
  84. sed 's/^X//' << 'SHAR_EOF' > README.unixpc &&
  85. X***** README *****
  86. X
  87. XThis README superceeds all other README's.
  88. X
  89. XProgram History:
  90. X    This started out as the unc program, by John Collins. At that
  91. Xtime it was a 68000 assembler for the UNISOFT unix environment. It was
  92. Xposted to the net as a dissasembler for Suns, I don't know who
  93. Xmodified it for the sun environment or if that was ever done, but
  94. XJanet Walz taught it about COFF, using the existing assembly syntax, I
  95. Xreworked the syntax to match the SGS syntax used by the unixpc (and
  96. Xthe HP9000, I believe). Surprisingly, the code has remained resonably
  97. Xcoherent during this time, and has remained well structured.
  98. X
  99. X
  100. XCurrent Status:
  101. X    At best, dissassemblers are of dubious value to anyone but system
  102. Xhackers and compiler writers. As I am both, I expect that this tool will 
  103. Xget used a great deal on *my* machine.
  104. X
  105. X    The following features are supported
  106. X    1) symbol resolution is done whenever possible. addresses abouve
  107. X0x300000 are considered constants (on a unix-pc, ths shared libraries are
  108. Xmapped in the address space above 0x300000)
  109. X    2) the dissassembler will attempt to convert pc relative addresses
  110. Xto label jumps, in that it will calculate the destination address and insert
  111. Xa label at that point, if one is not already present.
  112. X    3) the dissassembler decodes jump tables by recognising the swbeg
  113. Xpsuedo instuction and treating the table as a list of offsets relative
  114. Xto the start of the table. Again, label insertion is done where neccessary.
  115. X
  116. XTHe idea is that you should be able to do 
  117. X
  118. X    % dis foo > foo.s
  119. X    % as foo.s
  120. X    % ld foo.o
  121. X
  122. XThis is never completely possible, but it will work on some things. Remember
  123. Xthat code originally linked to the shared libraries must be loaded with
  124. X/lib/shlib.ifile. dis output will need a _start symbol inserted at the top
  125. Xof the output file, as in:
  126. X
  127. X    text
  128. X    global _start    # insert this
  129. X_start:            # and this
  130. X    ...
  131. X    ...
  132. X
  133. XAlso note that the assembly output will already contain any necessary 
  134. Xlibrary routines, so linking to libraries will not be neccessary.
  135. X
  136. XBUGS:
  137. X    THere are certainly bugs present, and I while I offer no support,
  138. XI will gladly accept bug reports and publish fixes as I have time. Send
  139. Xbug reports to:
  140. X
  141. X    alex@umbc3.ume.edu
  142. X    uunet!umbc3!nerwin!alex
  143. X
  144. X                    Alex Crain
  145. X
  146. X
  147. SHAR_EOF
  148. chmod 0644 README.unixpc || echo "restore of README.unixpc fails"
  149. sed 's/^X//' << 'SHAR_EOF' > alloc.c &&
  150. X/*
  151. X *    SCCS:    @(#)alloc.c    1.2    11/2/84    14:17:20
  152. X *    Allocate space etc.
  153. X *
  154. X ***********************************************************************
  155. X *    This software is copyright of
  156. X *
  157. X *        John M Collins
  158. X *        47 Cedarwood Drive
  159. X *        St Albans
  160. X *        Herts, AL4 0DN
  161. X *        England            +44 727 57267
  162. X *
  163. X *    and is released into the public domain on the following conditions:
  164. X *
  165. X *        1.  No free maintenance will be guaranteed.
  166. X *        2.  Nothing may be based on this software without
  167. X *            acknowledgement, including incorporation of this
  168. X *            notice.
  169. X *
  170. X *    Notwithstanding the above, the author welcomes correspondence and bug
  171. X *    fixes.
  172. X ***********************************************************************
  173. X */
  174. X
  175. X#include <stdio.h>
  176. X#include <a.out.h>
  177. X#include <setjmp.h>
  178. X#include <ldfcn.h>
  179. X#include "unc.h"
  180. X
  181. X#define    STINC    10
  182. X
  183. Xchar    *malloc(), *realloc();
  184. Xchar    *strncpy();
  185. Xvoid    gette(), getde(), setde(), putte(), putde();
  186. Xvoid    unimpl();
  187. Xlong    gettw();
  188. X
  189. Xef_fids    mainfile;
  190. X
  191. X/*
  192. X *    Oops! out of memory.....
  193. X */
  194. X
  195. Xvoid    nomem()
  196. X{
  197. X    (void) fprintf(stderr, "Sorry - run out of memory\n");
  198. X    exit(255);
  199. X}
  200. X
  201. X/*
  202. X *    Look up hash value of symbol.
  203. X */
  204. X
  205. Xunsigned  shash(str)
  206. Xregister  char    *str;
  207. X{
  208. X    register  unsigned  result = 0;
  209. X    register  int    cnt = 0;
  210. X    
  211. X    while  (*str  &&  cnt < MAXCHARS)  {
  212. X        result += *str++;
  213. X        cnt++;
  214. X    }
  215. X    return  result % HASHMOD;
  216. X}
  217. X
  218. X/*
  219. X *    Look up hash value of symbol, possibly allocating a new symbol.
  220. X */
  221. X
  222. Xsymbol    lookup(str)
  223. Xchar    *str;
  224. X{
  225. X    register  symbol  res, *pp;
  226. X    register  int    len;
  227. X    
  228. X    pp = &symbhash[shash(str)];
  229. X    res = *pp;
  230. X    while  (res != NULL)  {
  231. X        if  (strncmp(res->s_name, str, MAXCHARS) == 0)
  232. X            return    res;
  233. X        pp = &res->s_next;
  234. X        res = *pp;
  235. X    }
  236. X    for  (len = 0;  len < MAXCHARS;  len++)
  237. X        if  (str[len] == '\0')
  238. X            break;
  239. X    len++;
  240. X    res = (symbol) malloc(sizeof(struct symstr) + len);
  241. X    if  (res == NULL)
  242. X        nomem();
  243. X    *pp = res;
  244. X    res->s_next = NULL;
  245. X    (void) strncpy(res->s_name, str, len);
  246. X    res->s_name[len] = '\0';        /*  Null-terminate  */
  247. X    res->s_newsym = 1;
  248. X    res->s_glob = 0;
  249. X    res->s_invent = 0;
  250. X    res->s_link = NULL;
  251. X    res->s_used = 0;
  252. X    res->s_defs = 0;
  253. X    res->s_lsymb = 0;
  254. X    return  res;
  255. X}
  256. X
  257. X/*
  258. X *    Invent a symbol, making sure that we don't know it.
  259. X */
  260. X
  261. Xsymbol    inventsymb(prefix)
  262. Xchar    *prefix;
  263. X{
  264. X    static    int  nsymb = 0;
  265. X    char    schars[10];
  266. X    register  symbol  res;
  267. X    
  268. X    do    (void) sprintf(schars, "%s%d", prefix, ++nsymb);
  269. X    while  (!(res = lookup(schars))->s_newsym);
  270. X    
  271. X    res->s_newsym = 0;
  272. X    res->s_invent = 1;
  273. X    return    res;
  274. X}
  275. X     
  276. X/*
  277. X *    Reallocate symbol table.
  278. X */
  279. X
  280. Xvoid    reallst(outf)
  281. Xregister  ef_fid  outf;
  282. X{
  283. X    outf->ef_stmax += STINC;
  284. X    if  (outf->ef_stvec == NULL)
  285. X        outf->ef_stvec = (symbol *) malloc(outf->ef_stmax * sizeof(symbol));
  286. X    else
  287. X        outf->ef_stvec = (symbol *) realloc(outf->ef_stvec,
  288. X                    outf->ef_stmax * sizeof(symbol));
  289. X    if  (outf->ef_stvec == NULL)
  290. X        nomem();
  291. X}
  292. X
  293. X/*
  294. X *    Search through existing symbol table for symbol with given
  295. X *    value.  Invent a new one if needed.
  296. X */
  297. X
  298. Xsymbol    getnsymb(fid, seg, pos)
  299. Xregister  ef_fid  fid;
  300. Xunsigned  seg;
  301. Xlong    pos;
  302. X{
  303. X    register  int    i;
  304. X    register  symbol  res;
  305. X    
  306. X    /***********  MACHINE DEPENDENT  ******************************
  307. X     *    Convert relocation segment type (argument) to symbol type
  308. X     *    (as remembered in symbol table).  Don't ask me why they
  309. X     *    have to be different.....
  310. X     */
  311. X    
  312. X    /*
  313. X     *    See if the reference is to an external symbol.
  314. X     *    If so, use that.
  315. X     */
  316. X    
  317. X    for  (i = 0;  i < fid->ef_stcnt;  i++)  {
  318. X        res = fid->ef_stvec[i];
  319. X        if  (res->s_type == seg  &&  res->s_value == pos)
  320. X            return    res;
  321. X    }
  322. X    
  323. X    /*
  324. X     *    Invent a symbol and use that.
  325. X     */
  326. X    
  327. X    res = inventsymb("RS");
  328. X    if  (fid->ef_stcnt >= fid->ef_stmax)
  329. X        reallst(fid);
  330. X    fid->ef_stvec[fid->ef_stcnt++] = res;
  331. X    res->s_type = seg;
  332. X    res->s_value = pos;
  333. X    if  (seg == S_TEXT)  {
  334. X        t_entry    tent;
  335. X        gette(fid, pos, &tent);
  336. X        tent.t_bdest = 1;
  337. X        tent.t_lab = res;
  338. X        putte(fid, pos, &tent);
  339. X    }
  340. X    else  if  (seg == S_DATA  ||  seg == S_BSS)  {
  341. X        d_entry dent;
  342. X        getde(fid, pos, &dent);
  343. X        dent.d_lab = res;
  344. X        putde(fid, pos, &dent);
  345. X    }
  346. X
  347. X    return    res;
  348. X}
  349. X
  350. X/*
  351. X *    Assuming address given is in text segment, find its label, or invent
  352. X *    one.  Also set where refered from.
  353. X */
  354. X
  355. Xsymbol    textlab(loc, refpos)
  356. Xlong    loc, refpos;
  357. X{
  358. X    t_entry    tent;
  359. X
  360. X    gette(&mainfile, loc, &tent);
  361. X    if  (tent.t_type == T_CONT)
  362. X        return    NULL;
  363. X    if  (tent.t_lab == NULL)  {
  364. X        tent.t_lab = inventsymb("TS");
  365. X        tent.t_lab->s_type = S_TEXT;
  366. X        tent.t_lab->s_value = loc;
  367. X        tent.t_bdest = 1;
  368. X        putte(&mainfile, loc, &tent);
  369. X    }
  370. X    else
  371. X        tent.t_lab->s_used++;
  372. X    if  (tent.t_refhi < refpos)  {
  373. X        tent.t_refhi = refpos;
  374. X        putte(&mainfile, loc, &tent);
  375. X    }
  376. X    if  (tent.t_reflo > refpos)  {
  377. X        tent.t_reflo = refpos;
  378. X        putte(&mainfile, loc, &tent);
  379. X    }
  380. X    return    tent.t_lab;
  381. X}
  382. X
  383. X/*
  384. X *    Note references to data.
  385. X */
  386. X
  387. Xvoid    mkdref(tpos, size)
  388. Xlong    tpos;
  389. Xunsigned  size;
  390. X{
  391. X    t_entry    tent;
  392. X    d_entry    dent;
  393. X    register  symbol  ds;
  394. X    int    dchng = 0;
  395. X    int    wsize;
  396. X    long    dpos;
  397. X    
  398. X    gette(&mainfile, tpos, &tent);
  399. X    if  (tent.t_relsymb != NULL)
  400. X        return;
  401. X        
  402. X    dpos = gettw(&mainfile, tpos, R_LONG);
  403. X    if  (dpos < mainfile.ef_dbase  ||  dpos > mainfile.ef_end)
  404. X        return;
  405. X    
  406. X    switch  (size)  {
  407. X    default:
  408. X        wsize = D_BYTE;
  409. X        break;
  410. X    case  2:
  411. X        wsize = D_WORD;
  412. X        break;
  413. X    case  4:
  414. X        wsize = D_LONG;
  415. X        break;
  416. X    }
  417. X    
  418. X    getde(&mainfile, dpos, &dent);
  419. X    if  ((ds = dent.d_lab) == NULL)  {
  420. X        if  (dpos >= mainfile.ef_bbase)  {
  421. X            ds = inventsymb("BS");
  422. X            ds->s_type = S_BSS;
  423. X        }
  424. X        else  {
  425. X            ds = inventsymb("DS");
  426. X            ds->s_type = S_DATA;
  427. X        }
  428. X        ds->s_value = dpos;
  429. X        dent.d_lab = ds;
  430. X        dchng++;
  431. X    }
  432. X    else
  433. X        ds->s_used++;
  434. X
  435. X    if  (dent.d_type != D_BYTE)  {
  436. X        if  (dent.d_type != wsize)  {
  437. X            if  (dent.d_type == D_ADDR)  {
  438. X                if  (wsize != D_LONG)
  439. X                    unimpl("Addr word usage");
  440. X            }
  441. X            else  if  (dent.d_type > wsize)  {
  442. X                dchng++;
  443. X                dent.d_type = wsize;
  444. X                dent.d_lng = size;
  445. X            }
  446. X        }
  447. X    }
  448. X    else  {
  449. X        dent.d_type = wsize;
  450. X        dent.d_lng = size;
  451. X        dchng++;
  452. X    }
  453. X    if  (dchng)  {
  454. X        putde(&mainfile, dpos, &dent);
  455. X        for  (dchng = 1;  dchng < size; dchng++)
  456. X            setde(&mainfile, dpos+dchng, D_CONT, 1);
  457. X    }
  458. X        
  459. X    tent.t_relsymb = ds;
  460. X    putte(&mainfile, tpos, &tent);
  461. X}
  462. X
  463. X/*
  464. X *    Add item to common or abs list.
  465. X */
  466. X
  467. X#define    COMINC    10
  468. X
  469. Xvoid    addit(cp, symb)
  470. Xregister  struct  commit  *cp;
  471. Xsymbol    symb;
  472. X{
  473. X    if  (cp->c_int >= cp->c_max)  {
  474. X        cp->c_max += COMINC;
  475. X        if  (cp->c_symb == NULL)
  476. X            cp->c_symb = (symbol *) malloc(COMINC*sizeof(symbol));
  477. X        else
  478. X            cp->c_symb = (symbol *)
  479. X                    realloc(cp->c_symb,
  480. X                        cp->c_max * sizeof(symbol));
  481. X        if  (cp->c_symb == NULL)
  482. X            nomem();
  483. X    }
  484. X    cp->c_symb[cp->c_int++] = symb;
  485. X}
  486. SHAR_EOF
  487. chmod 0644 alloc.c || echo "restore of alloc.c fails"
  488. sed 's/^X//' << 'SHAR_EOF' > conv.c &&
  489. X#include <stdio.h>
  490. X#include <a.out.h>
  491. X#include <ldfcn.h>
  492. X#include "unc.h"
  493. X
  494. Xunsigned convtosun(sym)
  495. Xstruct syment *sym;
  496. X{
  497. X    unsigned suntype;
  498. X
  499. X    /*    everything in shlib is an external constant    */
  500. X    if (sym->n_value >= 0x300000) {
  501. X    sym->n_scnum = N_ABS;
  502. X         sym->n_sclass = C_EXT;
  503. X    }
  504. X    switch(sym->n_scnum) {
  505. X    case N_UNDEF:
  506. X    case N_DEBUG:    /* call things that don't map well "undefined" */
  507. X    case N_TV:
  508. X    case P_TV:
  509. X    suntype = S_UNDF;
  510. X    break;
  511. X    case N_ABS:
  512. X    suntype = S_ABS;
  513. X    break;
  514. X    case 1:
  515. X    suntype = S_TEXT;
  516. X    break;
  517. X    case 2:
  518. X    suntype = S_DATA;
  519. X    break;
  520. X    case 3:
  521. X    suntype = S_BSS;
  522. X    break;
  523. X    }
  524. X
  525. X    if (sym->n_sclass == C_EXT)
  526. X    suntype = suntype | S_EXT;
  527. X
  528. X    return(suntype);
  529. X}
  530. SHAR_EOF
  531. chmod 0644 conv.c || echo "restore of conv.c fails"
  532. sed 's/^X//' << 'SHAR_EOF' > doc.nr &&
  533. X.\"/*%    nroff -cm -rL72 %|epson|spr -f plain.a -h uncdoc -w
  534. X.nr Hb 7
  535. X.nr Hs 3
  536. X.ds HF 3 3 3 3 3 3 3
  537. X.nr Hu 5
  538. X.nr Hc 1
  539. X.SA 1
  540. X.PH "''A Disassembler''"
  541. X.PF "'Issue %I%'- Page \\\\nP -'%G%'"
  542. X.H 1 "Introduction"
  543. XThis document describes the first release of a disassembler for UNIX
  544. Xexecutable files.
  545. XThe key features are:
  546. X.AL
  547. X.LI
  548. XFor object files the output can be assembled to generate the same
  549. Xobject module, (apart from minor variations in symbol table ordering) as the
  550. Xinput.
  551. X.LI
  552. XFor stripped executable files object modules and libraries may be scanned,
  553. Xmodules in the main input identified and the appropriate names automatically
  554. Xinserted into the output.
  555. X.LI
  556. XAn option is available to convert most non-global names into local symbols,
  557. Xwhich cuts down the symbols in the generated assembler file.
  558. X.LI
  559. XThe disassembler copes reasonably with modules merged with the
  560. X.B "-r"
  561. Xoption to
  562. X.B "ld" ,
  563. Xgenerating a warning message as to the number of modules involved.
  564. X.LE
  565. X.P
  566. XAt present this is available for certain Motorola 68000 ports of UNIX
  567. XSystem III and System V. Dependencies on
  568. X.AL a
  569. X.LI
  570. XInstruction set.
  571. X.LI
  572. XObject module format.
  573. X.LI
  574. XLibrary module format.
  575. X.LI
  576. XAssembler output format.
  577. X.LE
  578. X.P
  579. Xare hopefully sufficiently localised to make the product useful as a
  580. Xbasis for other disassemblers for other versions of UNIX.
  581. X.P
  582. XThe product is thus distributed in source form at present.
  583. X.H 1 "Use"
  584. XThe disassembler is run by entering:
  585. X.DS I
  586. Xunc mainfile lib1 lib2 ...
  587. X.DE
  588. X.P
  589. XThe first named file is the file to be disassembled, which should be
  590. Xa single file, either an object module, a (possibly stripped) executable
  591. Xfile, or a library member. Library members are designated using a
  592. Xparenthesis notation, thus:
  593. X.DS I
  594. Xunc '/lib/libc.a(printf.o)'
  595. X.DE
  596. X.P
  597. XIt is usually necessary to escape the arguments in this case to prevent
  598. Xmisinterpretation by the shell. Libraries in standard places such as
  599. X.I "/lib"
  600. Xand
  601. X.I "/usr/lib"
  602. Xmay be specified in the same way as to
  603. X.B "ld" ,
  604. Xthus
  605. X.DS I
  606. Xunc '-lc(printf.o)'
  607. Xunc '-lcurses(wmove.o)'
  608. X.DE
  609. X.P
  610. XAs an additional facility, the list of directories searched for
  611. Xlibraries may be varied by setting the environment variable
  612. X.B "LDPATH" ,
  613. Xwhich is interpreted similarly to the shell
  614. X.B "PATH"
  615. Xvariable, and of course defaults to
  616. X.DS I
  617. XLDPATH=/lib:/usr/lib
  618. X.DE
  619. X.P
  620. XAs a further facility, the insertion of
  621. X.B "lib"
  622. Xbefore and
  623. X.B ".a"
  624. Xafter the argument may be suppressed by using a capital
  625. X.B "-L"
  626. Xargument, thus to print out the assembler for
  627. X.I "/lib/crt0.o" ,
  628. Xthen the command
  629. X.DS I
  630. Xunc -Lcrt0.o
  631. X.DE
  632. X.P
  633. Xshould have the desired effect.
  634. X.P
  635. XSecond and subsequent file arguments are only referenced for stripped
  636. Xexecutable files, and may consist of single object files and library
  637. Xmembers, using the same syntax as before, or whole libraries of object
  638. Xfiles, thus:
  639. X.DS I
  640. Xunc strippedfile -Lcrt0.o -lcurses -ltermcap '-lm(sqrt.o)' -lc
  641. X.DE
  642. X.P
  643. XIt is advisable to make some effort to put the libraries to be searched
  644. Xin the order in which they were originally loaded. This is because the
  645. Xsearch for each module starts where the previously matched module ended.
  646. XHowever, no harm is done if this rule is not adhered to apart from
  647. Xincreased execution time except in the rare cases where the disassembler
  648. Xis confused by object modules which are very nearly similar.
  649. X.H 1 "Additional options"
  650. XThe following options are available to modify the behaviour of the
  651. Xdisassembler.
  652. X.VL 15 2
  653. X.LI "-o file"
  654. XCauses output to be sent to the specified file instead of the standard
  655. Xoutput.
  656. X.LI "-t prefix"
  657. XCauses temporary files to be created with the given prefix. The default
  658. Xprefix is
  659. X.B "split" ,
  660. Xthus causing two temporary files to be created with this prefix in the
  661. Xcurrent directory. If it is desired, for example, to create the files as
  662. X.B "/tmp/xx*" ,
  663. Xthen the argument
  664. X.B "-t /tmp/xx"
  665. Xshould be given. Note that the temporary files may be very large as a
  666. Xcomplete map of the text and data segments is generated.
  667. X.LI "-a"
  668. XSuppresses the generation of non-global absolute symbols from the
  669. Xoutput. This saves output from C compilations without any obvious
  670. Xproblems, but the symbols are by default included in the name of
  671. Xproducing as nearly identical output as possible to the original source.
  672. X.LI "-s"
  673. XCauses an additional scan to take place where all possible labels are
  674. Xreplaced by local symbols. The local symbols are inserted in strictly
  675. Xascending order, starting at 1.
  676. X.LI "-v"
  677. XCauses a blow-by-blow account of activities to be output on the standard
  678. Xerror.
  679. X.LI "-V"
  680. XCauses shlib symbol values to be printed at the top of the output, if they
  681. Xexist in the symbol table. normally these are ommited because they are constant
  682. Xvalues derived form the file /lib/shlib.ifile
  683. X.LE
  684. X.H 1 "Diagnostics etc"
  685. XTruncated or garbled object and library files usually cause processing
  686. Xto stop with an explanatory message.
  687. X.P
  688. XThe only other kinds of message are some passing warnings concerning
  689. Xobscure constructs not handled, such as the relocation of byte fields,
  690. Xor the relocation of overlapping fields. Occasionally a message
  691. X.DS I
  692. XLibrary clash: message
  693. X.DE
  694. X.P
  695. Xmay appear and processing cease. This message is found where at a late
  696. Xstage in processing libraries, the program discovers that due to the
  697. Xextreme similarity of two or more library members, it has come to the
  698. Xwrong conclusion about which one to use. The remedy here is to spell out
  699. Xto the program which members to take in which order.
  700. X.H 1 "Future development"
  701. XIn the future it is hoped to devise ways of making the disassembler
  702. Xindependent of all the above-mentioned version dependencies, by first
  703. Xreading a files defining these things. This will probably be applied
  704. Xafter the Common Object Format becomes more standard.
  705. X.P
  706. XIn the long term it would be desirable and useful to enhance the product
  707. Xto produce compilable C in addition to assemblable assembler. Stages in
  708. Xthe process are seen as follows:
  709. X.AL
  710. X.LI
  711. XBetter identification of basic blocks in the code. Switch statements are
  712. Xa major problem here, as are constant data held in the text segment.
  713. X.LI
  714. XMarrying of data to the corresponding text. It is in various places hard
  715. Xto divorce static references "on the fly" (e.g. strings, and switch
  716. Xlists in some implementations) from static at the head of a module. This
  717. Xis part of the problem of identifying basic blocks.
  718. X.LI
  719. XCompilation of header files to work out structure references within the
  720. Xtext. At this stage some interaction may be needed.
  721. X.LE
  722. X.P
  723. XMeanwhile the product is one which is a useful tool to the author in its
  724. Xpresent form. Comments and suggestions as to the most practical method
  725. Xof improving the product in the ways suggested or in other ways would be
  726. Xgratefully considered.
  727. SHAR_EOF
  728. chmod 0644 doc.nr || echo "restore of doc.nr fails"
  729. sed 's/^X//' << 'SHAR_EOF' > file.c &&
  730. X/*
  731. X *    SCCS:    @(#)file.c    1.2    11/2/84    14:17:35
  732. X *    Various operations on files.
  733. X *
  734. X ***********************************************************************
  735. X *    This software is copyright of
  736. X *
  737. X *        John M Collins
  738. X *        47 Cedarwood Drive
  739. X *        St Albans
  740. X *        Herts, AL4 0DN
  741. X *        England            +44 727 57267
  742. X *
  743. X *    and is released into the public domain on the following conditions:
  744. X *
  745. X *        1.  No free maintenance will be guaranteed.
  746. X *        2.  Nothing may be based on this software without
  747. X *            acknowledgement, including incorporation of this
  748. X *            notice.
  749. X *
  750. X *    Notwithstanding the above, the author welcomes correspondence and bug
  751. X *    fixes.
  752. X ***********************************************************************
  753. X */
  754. X
  755. X#include <stdio.h>
  756. X#include <a.out.h>
  757. X#include <ldfcn.h>
  758. X#include "unc.h"
  759. X    
  760. Xlong    lseek();
  761. Xvoid    unimpl();
  762. X
  763. X/*
  764. X *    Validate addr and get text entry corresponding to it from the given
  765. X *    file.
  766. X */
  767. X
  768. Xvoid    gette(fid, addr, te)
  769. Xregister  ef_fid  fid;
  770. Xregister  long    addr;
  771. Xt_entry    *te;
  772. X{
  773. X    addr -= fid->ef_tbase;
  774. X    if  (addr < 0x300000 && 
  775. X         (addr < 0  ||  addr > fid->ef_tsize  || (addr & 1) != 0))  
  776. X     {
  777. X        (void) fprintf(stderr, "Invalid text address %lx\n", addr);
  778. X        exit(200);
  779. X     }
  780. X    (void) lseek(fid->ef_t, (long)(addr * sizeof(t_entry)/2), 0);
  781. X    if  (read(fid->ef_t, (char *) te, sizeof(t_entry)) != sizeof(t_entry))  {
  782. X        (void) fprintf(stderr, "Trouble reading text at %lx\n", addr);
  783. X        exit(201);
  784. X    }
  785. X}
  786. X
  787. X/*
  788. X *    Store a text entry.
  789. X */
  790. X
  791. Xvoid    putte(fid, addr, te)
  792. Xregister  ef_fid  fid;
  793. Xregister  long    addr;
  794. Xt_entry    *te;
  795. X{
  796. X    addr -= fid->ef_tbase;
  797. X    if  (addr < 0x300000 &&
  798. X         (addr < 0  ||  addr > fid->ef_tsize  ||  (addr & 1) != 0))
  799. X     {
  800. X        (void) fprintf(stderr, "Invalid text address %lx\n", addr);
  801. X        exit(200); 
  802. X     }
  803. X    (void) lseek(fid->ef_t, (long)(addr * sizeof(t_entry)/2), 0);
  804. X    (void) write(fid->ef_t, (char *) te, sizeof(t_entry));
  805. X}
  806. X
  807. X/*
  808. X *    Validate addr and get data entry corresponding to it from the given
  809. X *    file.
  810. X */
  811. X
  812. Xvoid    getde(fid, addr, de)
  813. Xregister  ef_fid  fid;
  814. Xregister  long    addr;
  815. Xd_entry    *de;
  816. X{
  817. X    if  (addr < 0x300000 && (addr < fid->ef_dbase  ||  addr > fid->ef_end))
  818. X     {
  819. X        (void) fprintf(stderr, "Invalid data address %lx\n", addr);
  820. X        exit(200);
  821. X     }
  822. X    addr -= fid->ef_dbase;
  823. X    (void) lseek(fid->ef_d, (long)(addr * sizeof(d_entry)), 0);
  824. X    if  (read(fid->ef_d, (char *) de, sizeof(d_entry)) != sizeof(d_entry))  {
  825. X        (void) fprintf(stderr, "Trouble reading data at %lx\n", addr);
  826. X        exit(201);
  827. X    }
  828. X}
  829. X
  830. X/*
  831. X *    Store a data entry.
  832. X */
  833. X
  834. Xvoid    putde(fid, addr, de)
  835. Xregister  ef_fid  fid;
  836. Xregister  long    addr;
  837. Xd_entry    *de;
  838. X{
  839. X    if  (addr < 0x300000 &&
  840. X         (addr < fid->ef_dbase  ||  addr > fid->ef_end))
  841. X     {
  842. X        (void) fprintf(stderr, "Invalid data address %lx\n", addr);
  843. X        exit(200);
  844. X     }
  845. X    addr -= fid->ef_dbase;
  846. X    (void) lseek(fid->ef_d, (long)(addr * sizeof(d_entry)), 0);
  847. X    (void) write(fid->ef_d, (char *) de, sizeof(d_entry));
  848. X}
  849. X
  850. X/*
  851. X *    Set type and length of given data entry.
  852. X */
  853. X
  854. Xvoid    setde(fid, addr, type, lng)
  855. Xef_fid    fid;
  856. Xlong    addr;
  857. Xunsigned  type;
  858. Xint    lng;
  859. X{
  860. X    d_entry    dat;
  861. X
  862. X    if  (addr > fid->ef_end)
  863. X        return;
  864. X    getde(fid, addr, &dat);
  865. X    if  (type == D_CONT  &&  dat.d_reloc != R_NONE)  {
  866. X        char    obuf[30];
  867. X        (void) sprintf(obuf, "overlapped reloc 0x%x", addr);
  868. X        unimpl(obuf);
  869. X    }
  870. X    dat.d_type = type;
  871. X    dat.d_lng = lng;
  872. X    putde(fid, addr, &dat);
  873. X}
  874. X    
  875. X/*
  876. X *    Get a word of data file, size as requested.
  877. X */
  878. X
  879. Xlong    getdw(fid, pos, size)
  880. Xregister  ef_fid  fid;
  881. Xlong    pos;
  882. Xint    size;
  883. X{
  884. X    d_entry    dat;
  885. X    register  long    res;
  886. X    register  int    i, lt;
  887. X    
  888. X    getde(fid, pos, &dat);
  889. X    
  890. X    switch  (size)  {
  891. X    case  R_BYTE:
  892. X        return    dat.d_contents;
  893. X        
  894. X    case  R_LONG:
  895. X        lt = 4;
  896. X        goto  rest;
  897. X        
  898. X    case  R_WORD:
  899. X        lt = 2;
  900. X    rest:
  901. X        res = dat.d_contents;
  902. X        for  (i = 1;  i < lt; i++)  {
  903. X            getde(fid, pos+i, &dat);
  904. X            res = (res << 8) + dat.d_contents;
  905. X        }
  906. X        return    res;
  907. X        
  908. X    default:
  909. X        (void) fprintf(stderr, "Data word size error\n");
  910. X        exit(20);
  911. X    }
  912. X    /*NOTREACHED*/
  913. X}
  914. X
  915. X/*
  916. X *    Get a word of text file.
  917. X */
  918. X
  919. Xlong    gettw(fid, pos, size)
  920. Xregister  ef_fid  fid;
  921. Xlong    pos;
  922. Xint    size;
  923. X{
  924. X    t_entry    tex;
  925. X    long    res;
  926. X    
  927. X    gette(fid, pos, &tex);
  928. X    
  929. X    switch  (size)  {
  930. X    case  R_BYTE:
  931. X        return    tex.t_contents >> 8;
  932. X        
  933. X    case  R_WORD:
  934. X        return    tex.t_contents;
  935. X        
  936. X    case  R_LONG:
  937. X        res = tex.t_contents;
  938. X        gette(fid, pos+2, &tex);
  939. X        return    (res << 16) + tex.t_contents;
  940. X    default:
  941. X        (void) fprintf(stderr, "Text< word size error\n");
  942. X        exit(20);
  943. X    }
  944. X    /*NOTREACHED*/
  945. X}
  946. SHAR_EOF
  947. chmod 0644 file.c || echo "restore of file.c fails"
  948. sed 's/^X//' << 'SHAR_EOF' > heur.c &&
  949. X/*
  950. X *    SCCS:    @(#)heur.c    1.2    11/2/84    14:17:46
  951. X *    Attempt to guess things about the file.
  952. X *
  953. X ***********************************************************************
  954. X *    This software is copyright of
  955. X *
  956. X *        John M Collins
  957. X *        47 Cedarwood Drive
  958. X *        St Albans
  959. X *        Herts, AL4 0DN
  960. X *        England            +44 727 57267
  961. X *
  962. X *    and is released into the public domain on the following conditions:
  963. X *
  964. X *        1.  No free maintenance will be guaranteed.
  965. X *        2.  Nothing may be based on this software without
  966. X *            acknowledgement, including incorporation of this
  967. X *            notice.
  968. X *
  969. X *    Notwithstanding the above, the author welcomes correspondence and bug
  970. X *    fixes.
  971. X ***********************************************************************
  972. X */
  973. X
  974. X#include <stdio.h>
  975. X#include <a.out.h>
  976. X#include <ldfcn.h>
  977. X#include "unc.h"
  978. X
  979. X#define    INITDAT    256
  980. X#define    INCDAT    128
  981. X
  982. X#define    STRSCNT    3
  983. X#define    STRECNT    3
  984. X
  985. Xchar    *malloc(), *realloc();
  986. X
  987. Xvoid    gette(), getde(), setde(), putte(), putde();
  988. Xvoid    nomem();
  989. Xlong    getdw();
  990. Xsymbol    inventsymb();
  991. X
  992. Xlong    endt;
  993. Xef_fids    mainfile;
  994. X
  995. X/*
  996. X *    Talk about implemented things.....
  997. X */
  998. X
  999. Xvoid    unimpl(msg)
  1000. Xchar    *msg;
  1001. X{
  1002. X    (void) fprintf(stderr, "Warning: handling of \"%s\" not implemented\n", msg);
  1003. X}
  1004. X
  1005. X/*
  1006. X *    Return 1 if string char, otherwise 0.
  1007. X */
  1008. X
  1009. Xint    possstr(x)
  1010. Xunsigned  x;
  1011. X{
  1012. X    if  (x >= ' '  &&  x <= '~')
  1013. X        return    1;
  1014. X    if  (x == '\n'  ||  x == '\t')
  1015. X        return    1;
  1016. X    return    0;
  1017. X}
  1018. X
  1019. X/*
  1020. X *    Guess things about data files.
  1021. X */
  1022. X
  1023. Xvoid    intudat(fid)
  1024. Xef_fid  fid;
  1025. X{
  1026. X    register  int    i, j;
  1027. X    int    lt, input, invcnt;
  1028. X    long    offs, soffs, endd;
  1029. X    d_entry    fdat;
  1030. X    unsigned  char    *inbuf;
  1031. X    int    ibsize;
  1032. X    
  1033. X    inbuf = (unsigned  char *)malloc(INITDAT);
  1034. X    if  (inbuf == NULL)
  1035. X        nomem();
  1036. X    ibsize = INITDAT;
  1037. X    
  1038. X    offs = fid->ef_dbase;
  1039. X    endd = fid->ef_bbase;
  1040. X
  1041. X    while  (offs < endd)  {
  1042. X        getde(fid, offs, &fdat);
  1043. X        if  (fdat.d_type != D_BYTE)  {
  1044. X            offs += fdat.d_lng;
  1045. X            continue;
  1046. X        }
  1047. X        
  1048. X        /*
  1049. X         *    Looks like general data.  Read in as much as possible.
  1050. X         */
  1051. X        
  1052. X        input = 0;
  1053. X        soffs = offs;
  1054. X        do  {
  1055. X            if  (input >= ibsize)  {
  1056. X                ibsize += INCDAT;
  1057. X                inbuf = (unsigned  char *)
  1058. X                    realloc((char *)inbuf, (unsigned)ibsize);
  1059. X                if  (inbuf == NULL)
  1060. X                    nomem();
  1061. X            }
  1062. X            inbuf[input++] = fdat.d_contents;
  1063. X            offs++;
  1064. X            if  (offs >= endd)
  1065. X                break;
  1066. X            getde(fid, offs, &fdat);
  1067. X        }  while  (fdat.d_type == D_BYTE && fdat.d_lab == NULL);
  1068. X        
  1069. X        /*
  1070. X         *    Now split up the data.
  1071. X         */
  1072. X        
  1073. X        for  (i = 0;  i < input;  )  {
  1074. X            
  1075. X            /*
  1076. X             *    Might be a string.
  1077. X             */
  1078. X            
  1079. X            if  (possstr(inbuf[i]))  {
  1080. X                lt = input;
  1081. X                if  (i + STRSCNT < lt)
  1082. X                    lt = i + STRSCNT;
  1083. X                for  (j = i + 1;  j < lt;  j++)  {
  1084. X                    if  (inbuf[j] == '\0')
  1085. X                        break;
  1086. X                    if  (!possstr(inbuf[j]))
  1087. X                        goto  notstr;
  1088. X                }
  1089. X                
  1090. X                /*
  1091. X                 *    Looks like a string then.
  1092. X                 */
  1093. X                
  1094. X                invcnt = 0;
  1095. X                for  (j = i + 1; j < input;  j++)  {
  1096. X                    if  (inbuf[j] == '\0')  {
  1097. X                        j++;
  1098. X                        break;
  1099. X                    }
  1100. X                    if  (possstr(inbuf[j]))
  1101. X                        invcnt = 0;
  1102. X                    else  {
  1103. X                        invcnt++;
  1104. X                        if  (invcnt >= STRECNT)  {
  1105. X                            j -= invcnt - 1;
  1106. X                            break;
  1107. X                        }
  1108. X                    }
  1109. X                }
  1110. X
  1111. X                setde(fid,
  1112. X                      soffs+i,
  1113. X                      (unsigned)(inbuf[j-1]=='\0'?D_ASCZ:D_ASC),
  1114. X                      j - i);
  1115. X                for  (i++;  i < j;  i++)
  1116. X                    setde(fid, soffs+i, D_CONT, 1); 
  1117. X                continue;
  1118. X            }
  1119. X
  1120. Xnotstr:
  1121. X            /*
  1122. X             *    If on odd boundary, treat as a byte.
  1123. X             */
  1124. X            
  1125. X            if  ((soffs + i) & 1  ||  i + 1 >= input)  {
  1126. X                setde(fid, soffs + i, D_BYTE, 1);
  1127. X                i++;
  1128. X                continue;
  1129. X            }
  1130. X
  1131. X            /*
  1132. X             *    Treat as longs unless not enough.
  1133. X             */
  1134. X            
  1135. X            if  (i + 3 >= input)  {
  1136. X                setde(fid, soffs + i, D_WORD, 2);
  1137. X                setde(fid, soffs + i + 1, D_CONT, -1);
  1138. X                i += 2;
  1139. X                continue;
  1140. X            }
  1141. X
  1142. X            /*
  1143. X             *    Treat as a long but mark changable.
  1144. X             */
  1145. X            
  1146. X            setde(fid, soffs + i, D_LONG, 4);
  1147. X            for  (j = 1;  j < 4;  j++)
  1148. X                setde(fid, soffs + i + j, D_CONT, -j);
  1149. X            i += 4;
  1150. X        }
  1151. X    }
  1152. X    free((char *)inbuf);
  1153. X    
  1154. X    /*
  1155. X     *    Now zap bss segment.
  1156. X     */
  1157. X    
  1158. X    offs = fid->ef_bbase;
  1159. X    endd = fid->ef_end;
  1160. X
  1161. X    while  (offs < endd)  {
  1162. X        getde(fid, offs, &fdat);
  1163. X        if  (fdat.d_type != D_BYTE)  {
  1164. X            offs += fdat.d_lng;
  1165. X            continue;
  1166. X        }
  1167. X
  1168. X        soffs = offs;
  1169. X        do  {
  1170. X            offs++;
  1171. X            if  (offs >= endd)
  1172. X                break;
  1173. X            getde(fid, offs, &fdat);
  1174. X        }  while  (fdat.d_type == D_BYTE && fdat.d_lab == NULL);
  1175. X        
  1176. X        setde(fid, soffs, D_BYTE, (int)(offs-soffs));
  1177. X        for  (i = -1, soffs++;  soffs < offs; i--, soffs++)
  1178. X            setde(fid, soffs, D_CONT, i); 
  1179. X    }
  1180. X}
  1181. X
  1182. X/*
  1183. X *    For non relocatable files, try to identify address pointers in
  1184. X *    the data.
  1185. X */
  1186. X
  1187. Xvoid    inturdat(fid)
  1188. Xef_fid    fid;
  1189. X{
  1190. X    register  long    offs = fid->ef_dbase;
  1191. X    register  int    i;
  1192. X    register  symbol  ds;
  1193. X    long  endd = fid->ef_bbase;
  1194. X    long  cont;
  1195. X    d_entry    dent, refdent;
  1196. X
  1197. X    while  (offs < endd)  {
  1198. X        getde(fid, offs, &dent);
  1199. X        if  (dent.d_type != D_LONG)
  1200. X            goto  endit;
  1201. X        cont = getdw(fid, offs, R_LONG);
  1202. X        if  (cont < fid->ef_dbase || cont > fid->ef_end)
  1203. X            goto  endit;
  1204. X        getde(fid, cont, &refdent);
  1205. X        if  (refdent.d_type == D_CONT)  {
  1206. X            d_entry    pdent;
  1207. X            int    siz;
  1208. X            
  1209. X            if  (refdent.d_lng >= 0)
  1210. X                goto  endit;
  1211. X            getde(fid, cont+refdent.d_lng, &pdent);
  1212. X            i = -refdent.d_lng;
  1213. X            refdent.d_lng += pdent.d_lng;
  1214. X            pdent.d_lng = i;
  1215. X            if  (pdent.d_type == D_LONG  &&  i == 2)
  1216. X                siz = D_WORD;
  1217. X            else
  1218. X                siz = D_BYTE;
  1219. X            refdent.d_type = siz;
  1220. X            pdent.d_type = siz;
  1221. X            putde(fid, cont - i, &pdent);
  1222. X            for  (i = 1;  i < refdent.d_lng;  i++)
  1223. X                setde(fid, cont+i, D_CONT, -i);
  1224. X        }
  1225. X        if  ((ds = refdent.d_lab) == NULL)  {
  1226. X            if  (cont >= fid->ef_bbase)  {
  1227. X                ds = inventsymb("BS");
  1228. X                ds->s_type = S_BSS;
  1229. X            }
  1230. X            else  {
  1231. X                ds = inventsymb("DS");
  1232. X                ds->s_type = S_DATA;
  1233. X            }
  1234. X            ds->s_value = cont;
  1235. X            refdent.d_lab = ds;
  1236. X            putde(fid, cont, &refdent);
  1237. X        }
  1238. X        else
  1239. X            ds->s_used++;
  1240. X        dent.d_type = D_ADDR;
  1241. X        dent.d_relsymb = ds;
  1242. X        dent.d_rptr = ds->s_type;
  1243. X        putde(fid, offs, &dent);
  1244. X        for  (i = 1;  i < 4;  i++)
  1245. X            setde(fid, offs+i, D_CONT, 1);
  1246. Xendit:
  1247. X        offs += dent.d_lng;
  1248. X    }
  1249. X}
  1250. X
  1251. X/*
  1252. X *    Recursively follow through the code, stopping at unconditional
  1253. X *    branches and invalid instructions.
  1254. X */
  1255. X
  1256. Xvoid    follseq(pos)
  1257. Xlong    pos;
  1258. X{
  1259. X    t_entry    tent;
  1260. X    int    lng;
  1261. X    long    npos;
  1262. X
  1263. X    while  (pos < endt)  {
  1264. X        gette(&mainfile, pos, &tent);
  1265. X        if  (tent.t_amap)    /*  Been here  */
  1266. X            return;
  1267. X        tent.t_amap = 1;
  1268. X        lng = findinst(&tent, pos);
  1269. X        npos = pos + lng*2;
  1270. X        if  (npos > endt)  {
  1271. X            tent.t_vins = 0;
  1272. X            tent.t_lng = 1;
  1273. X            tent.t_type = T_UNKNOWN;
  1274. X            lng = 0;
  1275. X            npos = endt;
  1276. X        }
  1277. X        putte(&mainfile, pos, &tent);
  1278. X        pos = npos;
  1279. X        
  1280. X        if  (lng <= 0)
  1281. X            return;
  1282. X
  1283. X        switch  (tent.t_bchtyp)  {
  1284. X        case  T_UNBR:
  1285. X            if  (tent.t_relsymb == NULL)
  1286. X                return;
  1287. X            pos = tent.t_relsymb->s_value;
  1288. X            continue;
  1289. X        case  T_JSR:
  1290. X            if  (tent.t_relsymb != NULL)
  1291. X                follseq(tent.t_relsymb->s_value);
  1292. X            continue;
  1293. X        case  T_CONDBR:
  1294. X            follseq(tent.t_relsymb->s_value);
  1295. X        default:
  1296. X            continue;
  1297. X        }
  1298. X    }
  1299. X}
  1300. X            
  1301. X            
  1302. X/*
  1303. X *    Try to work out things about text files.
  1304. X */
  1305. X
  1306. Xvoid    intutext()
  1307. X{
  1308. X    long    pos;
  1309. X    t_entry    tent;
  1310. X    int    lng;
  1311. X    
  1312. X    endt = mainfile.ef_tbase + mainfile.ef_tsize;
  1313. X    pos = mainfile.ef_entry;
  1314. Xnextv:
  1315. X    for  (;  pos < endt;)  {
  1316. X        gette(&mainfile, pos, &tent);
  1317. X        if  (!tent.t_amap && tent.t_vins)  {
  1318. X            follseq(pos);
  1319. X            pos += 2;
  1320. X            goto  nextiv;
  1321. X        }
  1322. X        pos += tent.t_lng * 2;
  1323. X        if  (tent.t_bchtyp == T_UNBR)
  1324. X            goto  nextiv;
  1325. X    }
  1326. X    goto    dorest;
  1327. Xnextiv:
  1328. X    for  (;  pos < endt;  pos += 2)  {
  1329. X        gette(&mainfile, pos, &tent);
  1330. X        if  (tent.t_bdest)
  1331. X            goto  nextv;
  1332. X    }
  1333. Xdorest:
  1334. X    /*
  1335. X     *    Deal with unmapped instructions.
  1336. X     */
  1337. X    
  1338. X     for  (pos = mainfile.ef_tbase;  pos < endt;)  {
  1339. X        gette(&mainfile, pos, &tent);
  1340. X        switch  (tent.t_type)  {
  1341. X        case  T_BEGIN:
  1342. X            pos += tent.t_lng * 2;
  1343. X            continue;
  1344. X        case  T_UNKNOWN:
  1345. X            if  (tent.t_vins)  {
  1346. X                lng = findinst(&tent, pos);
  1347. X                putte(&mainfile, pos, &tent);
  1348. X                if  (lng > 0)  {
  1349. X                    pos += lng * 2;
  1350. X                    continue;
  1351. X                }
  1352. X            }
  1353. X        default:
  1354. X            pos += 2;
  1355. X            continue;
  1356. X        }
  1357. X    }
  1358. X}
  1359. X
  1360. X/*
  1361. X *    Invent local symbols.
  1362. X */
  1363. X
  1364. Xvoid    intlsym()
  1365. X{
  1366. X    long    bpos, epos, hiref, hipos;
  1367. X    unsigned  llnum;
  1368. X    t_entry    tent;
  1369. X    register  symbol  tl;
  1370. X    
  1371. X    endt = mainfile.ef_tbase + mainfile.ef_tsize;
  1372. X    epos = mainfile.ef_entry;
  1373. X    for  (;;)  {
  1374. X        bpos = epos;
  1375. X        hiref = bpos;
  1376. X        if  (epos >= endt)
  1377. X            return;
  1378. X        gette(&mainfile, epos, &tent);
  1379. X        epos += tent.t_lng * 2;
  1380. X        for  (;  epos < endt;)  {
  1381. X            gette(&mainfile, epos, &tent);
  1382. X            if  (tent.t_gbdest  ||  tent.t_dref)
  1383. X                break;
  1384. X            if  (tent.t_reflo < bpos)
  1385. X                break;
  1386. X            if  (tent.t_refhi > hiref)  {
  1387. X                hiref = tent.t_refhi;
  1388. X                hipos = epos;
  1389. X            }
  1390. X            epos += tent.t_lng * 2;
  1391. X        }
  1392. X        if  (hiref > epos)
  1393. X            epos = hipos;
  1394. X        llnum = 0;
  1395. X        for  (hipos = bpos;  hipos < epos;)  {
  1396. X            gette(&mainfile, hipos, &tent);
  1397. X            if  (!tent.t_gbdest && !tent.t_dref &&
  1398. X             tent.t_reflo >= bpos && tent.t_refhi < epos &&
  1399. X             (tl = tent.t_lab) != NULL)
  1400. X                tl->s_lsymb = ++llnum;
  1401. X            hipos += tent.t_lng * 2;
  1402. X        }
  1403. X    }
  1404. X}
  1405. X
  1406. X/*
  1407. X *    Given the main file, a possible candidate for matching in the
  1408. X *    file and an offset, see if text matches.  Return 1 if matches,
  1409. X *    or 0 if no match.
  1410. X */
  1411. X
  1412. Xint    matchup(mf, lf, startpos)
  1413. Xregister  ef_fid  mf, lf;
  1414. Xlong    startpos;
  1415. X{
  1416. X    register  int    i, matches = 0;
  1417. X    t_entry    ltent, mtent;
  1418. X
  1419. X    if  (lf->ef_tsize > mf->ef_tsize - startpos + mf->ef_tbase)
  1420. X        return    0;    /*  At end - can't fit  */
  1421. X
  1422. X    for  (i = 0;  i < lf->ef_tsize;  i += 2)  {
  1423. X        gette(lf, lf->ef_tbase + i, <ent);
  1424. X        if  (ltent.t_isrel)
  1425. X            continue;
  1426. X        gette(mf, startpos + i, &mtent);
  1427. X        if  (mtent.t_contents != ltent.t_contents)
  1428. X            return    0;
  1429. X        matches++;
  1430. X    }
  1431. X    
  1432. X    /*
  1433. X     *    Give up on zero length or all relocatable files.
  1434. X     */
  1435. X    
  1436. X    return    matches > 0;
  1437. X}
  1438. X
  1439. X/*
  1440. X *    Scan through main file looking for a match.
  1441. X */
  1442. X
  1443. Xlong    findstart(mf, lf)
  1444. Xregister  ef_fid  mf, lf;
  1445. X{
  1446. X    register  long    res = mf->ef_tbase;
  1447. X    long    lim = mf->ef_tbase + mf->ef_tsize - lf->ef_tsize;
  1448. X    t_entry    tent;
  1449. X    
  1450. Xrestart:
  1451. X    for  (;  res <= lim;  res += 2)  {
  1452. X        gette(mf, res, &tent);
  1453. X        if  (tent.t_match != 0)  {
  1454. X            res += tent.t_match;
  1455. X            goto  restart;
  1456. X        }
  1457. X        if  (matchup(mf, lf, res))
  1458. X            return    res;
  1459. X    }
  1460. X    return    -1;
  1461. X}
  1462. X
  1463. X/*
  1464. X *    Mark the head of a matched module to save searching.
  1465. X */
  1466. X
  1467. Xvoid    markmatch(mf, lf, pos)
  1468. Xef_fid    mf, lf;
  1469. Xlong    pos;
  1470. X{
  1471. X    t_entry    tent;
  1472. X    
  1473. X    gette(mf, pos, &tent);
  1474. X    tent.t_match = (unsigned) lf->ef_tsize;
  1475. X    putte(mf, pos, &tent);
  1476. X}
  1477. SHAR_EOF
  1478. chmod 0644 heur.c || echo "restore of heur.c fails"
  1479. sed 's/^X//' << 'SHAR_EOF' > main.c &&
  1480. X/*
  1481. X *    SCCS:    @(#)main.c    1.2    11/2/84    14:19:31
  1482. X *    Main routine etc.
  1483. X *
  1484. X ***********************************************************************
  1485. X *    This software is copyright of
  1486. X *
  1487. X *        John M Collins
  1488. X *        47 Cedarwood Drive
  1489. X *        St Albans
  1490. X *        Herts, AL4 0DN
  1491. X *        England            +44 727 57267
  1492. X *
  1493. X *    and is released into the public domain on the following conditions:
  1494. X *
  1495. X *        1.  No free maintenance will be guaranteed.
  1496. X *        2.  Nothing may be based on this software without
  1497. X *            acknowledgement, including incorporation of this
  1498. X *            notice.
  1499. X *
  1500. X *    Notwithstanding the above, the author welcomes correspondence and bug
  1501. X *    fixes.
  1502. X ***********************************************************************
  1503. X */
  1504. X
  1505. X#include <stdio.h>
  1506. X#include <fcntl.h>
  1507. X#include <a.out.h>
  1508. X#include <ldfcn.h>
  1509. X#include "unc.h"
  1510. X
  1511. X#define    LINELNG    70
  1512. X
  1513. Xvoid    inturdat(), intutext(), intudat(), intlsym();
  1514. Xvoid    ptext(), pdata(), pabs(), pbss(), lscan();
  1515. X
  1516. Xef_fids    mainfile;
  1517. X
  1518. Xint    nmods;            /*  Number of modules it looks like  */
  1519. X
  1520. Xchar    *tfnam = "split";
  1521. X
  1522. Xchar    lsyms;            /*  Generate local symbols  */
  1523. Xchar    verbose;        /*  Tell the world what we are doing  */
  1524. Xchar    noabs;            /*  No non-global absolutes  */
  1525. Xint    rel;            /*  File being analysed is relocatable  */
  1526. Xint    lpos;
  1527. Xchar    shlibout;        /*  output values for shlib constants */
  1528. X
  1529. Xsymbol    dosymb();
  1530. Xstruct    libit    *getfnam();
  1531. X
  1532. X/*
  1533. X *    Get hex characters, also allowing for 'k' and 'm'.
  1534. X */
  1535. X
  1536. Xint    ghex(str)
  1537. Xregister  char    *str;
  1538. X{
  1539. X    register  int    result = 0;
  1540. X    register  int    lt;
  1541. X
  1542. X    for  (;;)  {
  1543. X        lt = *str++;
  1544. X        switch  (lt)  {
  1545. X        default:
  1546. Xerr:            (void) fprintf(stderr, "Invalid hex digit \'%c\'\n", lt);
  1547. X            exit(1);
  1548. X            
  1549. X        case '\0':
  1550. X            return    result;
  1551. X            
  1552. X        case '0':case '1':case '2':case '3':case '4':
  1553. X        case '5':case '6':case '7':case '8':case '9':
  1554. X            result = (result << 4) + lt - '0';
  1555. X            continue;
  1556. X            
  1557. X        case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':
  1558. X            result = (result << 4) + lt - 'a' + 10;
  1559. X            continue;
  1560. X
  1561. X        case 'A':case 'B':case 'C':case 'D':case 'E':case 'F':
  1562. X            result = (result << 4) + lt - 'A' + 10;
  1563. X            continue;
  1564. X        
  1565. X        case 'k':case 'K':
  1566. X            if  (*str != '\0')
  1567. X                goto  err;
  1568. X            return  result << 10;
  1569. X            
  1570. X        case 'm':case 'M':
  1571. X            if  (*str != '\0')
  1572. X                goto  err;
  1573. X            return  result << 20;
  1574. X        }
  1575. X    }
  1576. X}
  1577. X
  1578. X/*
  1579. X *    Process entry line options.  Return number dealt with.
  1580. X */
  1581. X
  1582. Xint    doopts(av)
  1583. Xchar    *av[];
  1584. X{
  1585. X    register  int    cnt = 0, lt;
  1586. X    register  char    *arg;
  1587. X    
  1588. X    for  (;;)  {
  1589. X        arg = *++av;
  1590. X        if  (*arg++ != '-')
  1591. X            return    cnt;
  1592. X        cnt++;
  1593. X        
  1594. Xnx:        switch  (lt = *arg++)  {
  1595. X        default:
  1596. X            (void) fprintf(stderr, "Bad option -%c\n", lt);
  1597. X            exit(1);
  1598. X            
  1599. X        case  '\0':
  1600. X            continue;
  1601. X            
  1602. X        case  'l':    /*  A file name  */
  1603. X        case  'L':
  1604. X            return    cnt - 1;
  1605. X            
  1606. X        case  's':
  1607. X            lsyms++;
  1608. X            goto  nx;
  1609. X            
  1610. X        case  'v':
  1611. X            verbose++;
  1612. X            goto  nx;
  1613. X
  1614. X        case  'V':
  1615. X            shlibout++;
  1616. X            goto  nx;
  1617. X
  1618. X        case  'a':
  1619. X            noabs++;
  1620. X            goto  nx;
  1621. X
  1622. X        case  't':
  1623. X            if  (*arg == '\0')  {
  1624. X                cnt++;
  1625. X                arg = *++av;
  1626. X                if  (arg == NULL) {
  1627. Xbo:                    (void) fprintf(stderr,"Bad -%c option\n",lt);
  1628. X                    exit(1);
  1629. X                       }
  1630. X            }
  1631. X            tfnam = arg;
  1632. X            continue;
  1633. X            
  1634. X        case  'o':
  1635. X            if  (*arg == '\0')  {
  1636. X                cnt++;
  1637. X                arg = *++av;
  1638. X                if  (arg == NULL)
  1639. X                    goto  bo;
  1640. X            }
  1641. X            if  (freopen(arg, "w", stdout) == NULL)  {
  1642. X                (void) fprintf(stderr, "Help! cant open %s\n", arg);
  1643. X                exit(20);
  1644. X            }
  1645. X            continue;
  1646. X        }
  1647. X    }
  1648. X}
  1649. X    
  1650. X/*
  1651. X *    Open binary files.  Arrange to erase them when finished.
  1652. X */
  1653. X
  1654. Xvoid    bfopen(nam, fid)
  1655. Xchar    *nam;
  1656. Xef_fid    fid;
  1657. X{
  1658. X    char    fnam[80];
  1659. X    
  1660. X    (void) sprintf(fnam, "%s.tx", nam);
  1661. X    if  ((fid->ef_t = open(fnam, O_RDWR|O_CREAT, 0666)) < 0)  {
  1662. Xefil:        (void) fprintf(stderr, "Help could not open %s\n", fnam);
  1663. X        exit(4);
  1664. X    }
  1665. X    (void) unlink(fnam);
  1666. X    (void) sprintf(fnam, "%s.dt", nam);
  1667. X    if  ((fid->ef_d = open(fnam, O_RDWR|O_CREAT, 0666)) < 0)
  1668. X        goto  efil;
  1669. X    (void) unlink(fnam);
  1670. X}
  1671. X
  1672. X/*
  1673. X *    Close binary files.  They should get zapped anyway.
  1674. X */
  1675. X
  1676. Xvoid    bfclose(fid)
  1677. Xef_fid    fid;
  1678. X{
  1679. X    (void) close(fid->ef_t);
  1680. X    (void) close(fid->ef_d);
  1681. X}
  1682. X
  1683. X/*
  1684. X *    Main routine.
  1685. X */
  1686. X
  1687. Xmain(argc, argv)
  1688. Xint    argc;
  1689. Xchar    *argv[];
  1690. X{
  1691. X    int    i;
  1692. X    char    *progname = argv[0];
  1693. X    char    *msg;
  1694. X    register  struct  libit  *lfd;
  1695. X    
  1696. X    setbuf(stdout,NULL);
  1697. X    setbuf(stderr,NULL);
  1698. X
  1699. X    i = doopts(argv);
  1700. X    argc -= i;
  1701. X    argv += i;
  1702. X    
  1703. X    if  (argc < 2)  {
  1704. X        (void) fprintf(stderr, "Usage: %s [ options ] file\n", progname);
  1705. X        exit(1);
  1706. X    }
  1707. X    
  1708. X    lfd = getfnam(argv[1]);
  1709. X    if  (TYPE(lfd->ldptr) == ARTYPE)  {
  1710. X        (void) fprintf(stderr, "Main file (%s) cannot be library\n", argv[1]);
  1711. X        exit(2);
  1712. X    }
  1713. X    
  1714. X    bfopen(tfnam, &mainfile);
  1715. X    if  (verbose)
  1716. X        (void) fprintf(stderr, "Scanning text\n");
  1717. X    if  (!rtext(lfd->ldptr, &mainfile))  {
  1718. X        msg = "text";
  1719. Xbf:        (void) fprintf(stderr, "Bad format input file - reading %s\n", msg);
  1720. X        exit(5);
  1721. X    }
  1722. X    if  (verbose)
  1723. X        (void) fprintf(stderr, "Scanning data\n");
  1724. X    if  (!rdata(lfd->ldptr, &mainfile))  {
  1725. X        msg = "data";
  1726. X        goto  bf;
  1727. X    }
  1728. X    if  (verbose)
  1729. X        (void) fprintf(stderr, "Scanning symbols\n");
  1730. X    if  (!rsymb(lfd->ldptr, dosymb, &mainfile))  {
  1731. X        msg = "symbols";
  1732. X        goto  bf;
  1733. X    }
  1734. X    if  (verbose)
  1735. X        (void) fprintf(stderr, "Scanning for relocation\n");
  1736. X    if  ((rel = rrel(lfd->ldptr, lfd->ldptr2, &mainfile)) < 0)  {
  1737. X        msg = "reloc";
  1738. X        goto  bf;
  1739. X    }
  1740. X    
  1741. X    if  (rel)  {
  1742. X        if  (verbose)
  1743. X            (void) fprintf(stderr, "File is relocatable\n");
  1744. X        if  (argc > 2)
  1745. X            (void) fprintf(stderr, "Sorry - no scan on reloc files\n");
  1746. X    }
  1747. X    else
  1748. X        lscan(argc - 2, &argv[2]);
  1749. X
  1750. X    if  (verbose)
  1751. X        (void) fprintf(stderr, "End of input\n");
  1752. X    
  1753. X    ldaclose(lfd->ldptr2);
  1754. X    ldclose(lfd->ldptr);
  1755. X    if  (nmods > 0)
  1756. X        (void) fprintf(stderr, "Warning: at least %d merged modules\n",
  1757. X            nmods + 1);
  1758. X
  1759. X    if  (mainfile.ef_stvec != NULL)  {
  1760. X        free(mainfile.ef_stvec);
  1761. X        mainfile.ef_stvec = NULL;
  1762. X        mainfile.ef_stcnt = 0;
  1763. X    }
  1764. X    
  1765. X    if  (verbose)
  1766. X        (void) fprintf(stderr, "Text anal 1\n");
  1767. X    intutext();
  1768. X    if  (verbose)
  1769. X        (void) fprintf(stderr, "Data anal 1\n");
  1770. X    intudat(&mainfile);
  1771. X    if  (!rel)  {
  1772. X        if  (verbose)
  1773. X            (void) fprintf(stderr, "Data anal 2\n");
  1774. X        inturdat(&mainfile);
  1775. X    }
  1776. X    if  (lsyms)  {
  1777. X        if  (verbose)
  1778. X            (void) fprintf(stderr, "Local symbol scan\n");
  1779. X        intlsym();
  1780. X    }
  1781. X    pabs();
  1782. X    ptext(&mainfile);
  1783. X    pdata(&mainfile);
  1784. X    pbss(&mainfile);
  1785. X    bfclose(&mainfile);
  1786. X    exit(0);
  1787. X}
  1788. SHAR_EOF
  1789. chmod 0644 main.c || echo "restore of main.c fails"
  1790. sed 's/^X//' << 'SHAR_EOF' > prin.c &&
  1791. X/*
  1792. X *    SCCS:    @(#)prin.c    1.2    11/2/84    14:19:47
  1793. X *    Print stuff.
  1794. X *
  1795. X ***********************************************************************
  1796. X *    This software is copyright of
  1797. X *
  1798. X *        John M Collins
  1799. X *        47 Cedarwood Drive
  1800. X *        St Albans
  1801. X *        Herts, AL4 0DN
  1802. X *        England            +44 727 57267
  1803. X *
  1804. X *    and is released into the public domain on the following conditions:
  1805. X *
  1806. X *        1.  No free maintenance will be guaranteed.
  1807. X *        2.  Nothing may be based on this software without
  1808. X *            acknowledgement, including incorporation of this
  1809. X *            notice.
  1810. X *
  1811. X *    Notwithstanding the above, the author welcomes correspondence and bug
  1812. X *    fixes.
  1813. X ***********************************************************************
  1814. X */
  1815. X
  1816. X#include <stdio.h>
  1817. X#include <a.out.h>
  1818. X#include <ldfcn.h>
  1819. X#include "unc.h"
  1820. X
  1821. X#define    LINELNG    70
  1822. X
  1823. Xvoid    gette(), getde();
  1824. Xlong    gettw(), getdw();
  1825. Xvoid    prinst();
  1826. X
  1827. Xchar    noabs;            /*  No non-global absolutes  */
  1828. Xint    rel;            /*  File being analysed is relocatable  */
  1829. Xint    lpos;
  1830. X
  1831. Xstruct    commit    abstab, comtab;
  1832. Xextern char shlibout;
  1833. X
  1834. X/*
  1835. X *    Print absolute and common values.
  1836. X */
  1837. X
  1838. Xvoid    pabs()
  1839. X{
  1840. X    register  int    i;
  1841. X    register  symbol  cs;
  1842. X
  1843. X    for  (i = 0;  i < abstab.c_int;  i++)
  1844. X    
  1845. X    for  (i = 0;  i < abstab.c_int;  i++)  {
  1846. X        cs = abstab.c_symb[i];
  1847. X        if (cs->s_value >= 0x300000 && ! shlibout)
  1848. X            continue;
  1849. X        if  (cs->s_glob)
  1850. X            (void) printf("#\tglobal\t%s\n", cs->s_name);
  1851. X        else  if  (noabs)
  1852. X            continue;
  1853. X        (void) printf("# %s\t= 0x%lx\n", cs->s_name, cs->s_value);
  1854. X    }
  1855. X    for  (i = 0;  i < comtab.c_int;  i++)  {
  1856. X        cs = comtab.c_symb[i];
  1857. X        (void) printf("\tcomm\t%s,%d\n", cs->s_name, cs->s_value);
  1858. X    }
  1859. X}
  1860. X
  1861. X/*
  1862. X *    Print out labels.
  1863. X */
  1864. X
  1865. Xvoid    plabs(ls, seg)
  1866. Xregister  symbol  ls;
  1867. Xint    seg;
  1868. X{
  1869. X    for  (; ls != NULL;  ls = ls->s_link)  {
  1870. X        if  (ls->s_type != seg)
  1871. X            continue;
  1872. X        if  (ls->s_lsymb)  {
  1873. X            (void) printf("L%%%u:\n", ls->s_lsymb);
  1874. X            return;        /*  Set last  */
  1875. X        }
  1876. X        if  (ls->s_glob)
  1877. X            (void) printf("\n\tglobal\t%s", ls->s_name);
  1878. X        if (ls->s_name[0] == '.')
  1879. X            (void) printf("\n# %s:\n", ls->s_name);
  1880. X        else
  1881. X            (void) printf("\n%s:\n", ls->s_name);
  1882. X    }
  1883. X}
  1884. X
  1885. X/*
  1886. X *    Print out text.
  1887. X */
  1888. X
  1889. Xvoid    ptext(fid)
  1890. Xregister  ef_fid  fid;
  1891. X{
  1892. X    register  long    tpos, endt;
  1893. X    t_entry    tstr;
  1894. X
  1895. X    (void) fputs("\ttext\n", stdout);
  1896. X    
  1897. X    tpos = fid->ef_tbase;
  1898. X    endt = tpos + fid->ef_tsize;
  1899. Xcontin:    
  1900. X    for  (;  tpos < endt;  tpos += tstr.t_lng * 2)  {
  1901. X        gette(fid, tpos, &tstr);
  1902. X        plabs(tstr.t_lab, S_TEXT);
  1903. X        if  (tstr.t_type == T_BEGIN)
  1904. X            prinst(&tstr, tpos);
  1905. X        else  if  (tstr.t_relsymb != NULL)  {
  1906. X            (void) printf("\tlong\t%s", tstr.t_relsymb->s_name);
  1907. X            if  (tstr.t_relsymb->s_type!=S_TEXT &&
  1908. X                tstr.t_relsymb->s_type!=S_DATA)
  1909. X                (void) printf("+0x%x", gettw(fid, tpos, R_LONG));
  1910. X            (void) putchar('\n');
  1911. X            tpos += 4;
  1912. X            goto  contin;
  1913. X        }
  1914. X        else
  1915. X            (void) printf("\tshort\t0x%x\n", tstr.t_contents);
  1916. X    }
  1917. X
  1918. X    /*
  1919. X     *    Print out any trailing label.
  1920. X     */
  1921. X    
  1922. X    gette(fid, tpos, &tstr);
  1923. X    plabs(tstr.t_lab, S_TEXT);
  1924. X}
  1925. X
  1926. X/*
  1927. X *    Print out data.
  1928. X */
  1929. X
  1930. Xvoid    pdata(fid)
  1931. Xregister  ef_fid  fid;
  1932. X{
  1933. X    register  long    dpos, endd;
  1934. X    register  int    lng, ccnt;
  1935. X    unsigned  ctyp;
  1936. X    int    had, par, inc;
  1937. X    char    *msg;
  1938. X    d_entry    dstr;
  1939. X    
  1940. X    (void) fputs("\n\tdata\n", stdout);
  1941. X    
  1942. X    dpos = fid->ef_dbase;
  1943. X    endd = dpos + fid->ef_dsize;
  1944. X
  1945. X    while  (dpos < endd)  {
  1946. X        
  1947. X        getde(fid, dpos, &dstr);
  1948. X        plabs(dstr.d_lab, S_DATA);
  1949. X            
  1950. X        switch  (dstr.d_type)  {
  1951. X        case  D_CONT:
  1952. X            (void) fprintf(stderr, "Data sync error\n");
  1953. X            dpos++;
  1954. X            break;
  1955. X            
  1956. X        case  D_ASC:
  1957. X        case  D_ASCZ:
  1958. X            ctyp = dstr.d_type;
  1959. X            lng = dstr.d_lng;
  1960. X        nextline:
  1961. X            (void) fputs("\tbyte\t", stdout);
  1962. X            ccnt=0;
  1963. X            while  (lng > 0)  {
  1964. X                if (ccnt) (void) putchar(',');
  1965. X                getde(fid, dpos, &dstr);
  1966. X                switch  (dstr.d_contents)  {
  1967. X                default:
  1968. X                    if  (dstr.d_contents < ' ' ||
  1969. X                        dstr.d_contents > '~')
  1970. X                        ccnt += printf("0x%x", dstr.d_contents);
  1971. X                    else {
  1972. X                        (void) putchar('\'');
  1973. X                        (void)putchar(dstr.d_contents);
  1974. X                        ccnt += 2;
  1975. X                    }
  1976. X                    break;
  1977. X                case  '\\':
  1978. X                    (void) putchar('\'');
  1979. X                    (void) putchar('\\');
  1980. X                    (void) putchar('\\');
  1981. X                    ccnt+=2;
  1982. X                    break;
  1983. X                case  '\b':
  1984. X                    (void) putchar('\'');
  1985. X                    (void) putchar('\\');
  1986. X                    (void) putchar('b');
  1987. X                    ccnt+=2;
  1988. X                    break;
  1989. X                case  '\n':
  1990. X                    (void) putchar('\'');
  1991. X                    (void) putchar('\\');
  1992. X                    (void) putchar('n');
  1993. X                    ccnt+=2;
  1994. X                    break;
  1995. X                case  '\r':
  1996. X                    (void) putchar('\'');
  1997. X                    (void) putchar('\\');
  1998. X                    (void) putchar('r');
  1999. X                    ccnt+=2;
  2000. X                    break;
  2001. X                case  '\f':
  2002. X                    (void) putchar('\'');
  2003. X                    (void) putchar('\\');
  2004. X                    (void) putchar('f');
  2005. X                    ccnt+=2;
  2006. X                    break;
  2007. X                case  '\t':
  2008. X                    (void) putchar('\'');
  2009. X                    (void) putchar('\\');
  2010. X                    (void) putchar('t');
  2011. X                    ccnt+=2;
  2012. X                    break;
  2013. X                }
  2014. X
  2015. X                lng--;
  2016. X                dpos++;
  2017. X                if (++ccnt > 40 && lng > 0) {
  2018. X                    (void) putchar('\n');
  2019. X                    goto nextline;
  2020. X                }
  2021. X            }
  2022. X            (void) putchar('\n');
  2023. X            break;
  2024. X
  2025. X        case  D_BYTE:
  2026. X            msg = "byte";
  2027. X            par = R_BYTE;
  2028. X            inc = 1;
  2029. X            goto  wrest;
  2030. X            
  2031. X        case  D_WORD:
  2032. X            msg = "short";
  2033. X            par = R_WORD;
  2034. X            inc = 2;
  2035. X            goto  wrest;
  2036. X            
  2037. X        case  D_LONG:
  2038. X            msg = "long";
  2039. X            par = R_LONG;
  2040. X            inc = 4;
  2041. X        wrest:
  2042. X            (void) putchar('\t');
  2043. X            (void) fputs(msg, stdout);
  2044. X            (void) putchar('\t');
  2045. X            lng = dstr.d_lng;
  2046. X            lpos = 16;
  2047. X            had = 0;
  2048. X            while  (lng > 0)  {
  2049. X                if  (lpos > LINELNG) {
  2050. X                    (void) putchar('\n');
  2051. X                    (void) putchar('\t');
  2052. X                    (void) fputs(msg, stdout);
  2053. X                    (void) putchar('\t');
  2054. X                    lpos = 16;
  2055. X                }
  2056. X                else  if  (had) {
  2057. X                    (void) putchar(',');
  2058. X                    (void) putchar(' ');
  2059. X                    lpos += 2;
  2060. X                }
  2061. X                lpos += printf("0x%x", getdw(fid, dpos, par));
  2062. X                lng -= inc;
  2063. X                dpos += inc;
  2064. X                had++;
  2065. X            }
  2066. X            (void) putchar('\n');
  2067. X            break;
  2068. X
  2069. X        case  D_ADDR:
  2070. X            (void) fputs("\tlong\t", stdout);
  2071. X            lng = dstr.d_lng;
  2072. X            lpos = 16;
  2073. X            had = 0;
  2074. X            while  (lng > 0)  {
  2075. X                if  (lpos > LINELNG)  {
  2076. X                    (void) fputs("\n\tlong\t", stdout);
  2077. X                    lpos = 16;
  2078. X                }
  2079. X                else  if  (had) {
  2080. X                    (void) putchar(',');
  2081. X                    (void) putchar(' ');
  2082. X                    lpos += 2;
  2083. X                }
  2084. X
  2085. X                getde(fid, dpos, &dstr);
  2086. X                lpos += printf("%s", dstr.d_relsymb->s_name);
  2087. X                lng -= sizeof(long);
  2088. X                dpos += sizeof(long);
  2089. X                had++;
  2090. X            }
  2091. X            (void) putchar('\n');
  2092. X            break;
  2093. X        }
  2094. X    }
  2095. X    
  2096. X    /*
  2097. X     *    Print trailing label.
  2098. X     */
  2099. X    
  2100. X    getde(fid, dpos, &dstr);
  2101. X    plabs(dstr.d_lab, S_DATA);
  2102. X}
  2103. X
  2104. Xvoid    pbss(fid)
  2105. Xregister  ef_fid  fid;
  2106. X{
  2107. X    register  long    bpos = fid->ef_bbase;
  2108. X    long    endb = fid->ef_end;
  2109. X    d_entry    bstr;
  2110. X    
  2111. X    (void) fputs("\n# .bss\n", stdout);
  2112. X    
  2113. X    while  (bpos < endb)  {
  2114. X        getde(fid, bpos, &bstr);
  2115. X        plabs(bstr.d_lab, S_BSS);
  2116. X        (void) printf("\tspace\t%d\n", bstr.d_lng);
  2117. X        bpos += bstr.d_lng;
  2118. X    }
  2119. X    
  2120. X    getde(fid, endb, &bstr);
  2121. X    plabs(bstr.d_lab, S_BSS);
  2122. X}
  2123. X
  2124. X
  2125. SHAR_EOF
  2126. chmod 0644 prin.c || echo "restore of prin.c fails"
  2127. sed 's/^X//' << 'SHAR_EOF' > unc.h &&
  2128. X/*
  2129. X *    SCCS:    @(#)unc.h    1.2    11/2/84    14:21:02
  2130. X *    Header file for uncompile program.
  2131. X *
  2132. X ***********************************************************************
  2133. X *    This software is copyright of
  2134. X *
  2135. X *        John M Collins
  2136. X *        47 Cedarwood Drive
  2137. X *        St Albans
  2138. X *        Herts, AL4 0DN
  2139. X *        England            +44 727 57267
  2140. X *
  2141. X *    and is released into the public domain on the following conditions:
  2142. X *
  2143. X *        1.  No free maintenance will be guaranteed.
  2144. X *        2.  Nothing may be based on this software without
  2145. X *            acknowledgement, including incorporation of this
  2146. X *            notice.
  2147. X *
  2148. X *    Notwithstanding the above, the author welcomes correspondence and bug
  2149. X *    fixes.
  2150. X ***********************************************************************
  2151. X */
  2152. X
  2153. X#define    MAXCHARS    50
  2154. X#define    HASHMOD        97
  2155. X
  2156. X/*
  2157. X *    The following structure is used to keep track of symbols.
  2158. X */
  2159. X
  2160. Xstruct    symstr    {
  2161. X    struct    symstr    *s_next;        /*  Next in hash chain  */
  2162. X    struct    symstr    *s_link;        /*  Next in duplicate labels */
  2163. X    unsigned    s_type    :  5;        /*  Symbol type  */
  2164. X    unsigned    s_newsym:  1;        /*  A new symbol  */
  2165. X    unsigned    s_invent:  1;        /*  Invented symbol  */
  2166. X    unsigned    s_glob    :  1;        /*  Global symbol  */
  2167. X    long        s_value;        /*  Value if defined  */
  2168. X    short        s_defs;            /*  Defined count  */
  2169. X    short        s_used;            /*  Used count  */
  2170. X    unsigned short    s_lsymb;        /*  Local symbol  */
  2171. X    char        s_name[1];        /*  Chars of name null term */
  2172. X};
  2173. X
  2174. Xtypedef    struct    symstr    *symbol;
  2175. X
  2176. Xsymbol    symbhash[HASHMOD];
  2177. X
  2178. Xtypedef    struct    {
  2179. X    int    ef_t;            /*  Text file fd  */
  2180. X    int    ef_d;            /*  Data file fd  */
  2181. X    long    ef_entry;        /*  Entry point  */
  2182. X    long    ef_tsize;        /*  Text size  */
  2183. X    long    ef_dsize;        /*  Data size  */
  2184. X    long    ef_bsize;        /*  Bss size  */
  2185. X    long    ef_end;            /*  End of it all  */
  2186. X    long    ef_tbase;        /*  Text base  */
  2187. X    long    ef_dbase;        /*  Data base  */
  2188. X    long    ef_bbase;        /*  Bss base  */
  2189. X    int    ef_stcnt;        /*  Number of symbols  */
  2190. X    int    ef_stmax;        /*  Max number of symbols  */
  2191. X    symbol    *ef_stvec;        /*  Symbol vector  */
  2192. X}  ef_fids;
  2193. X
  2194. Xtypedef    ef_fids    *ef_fid;
  2195. X
  2196. X/*
  2197. X *    Description of word in text file.  This entry is held in the place
  2198. X *    corresponding to the address in the text file.
  2199. X */
  2200. X
  2201. Xtypedef    struct    {
  2202. X    unsigned  short    t_contents;        /*  Actual contents  */
  2203. X    unsigned  short t_iindex;        /*  Index in table  */
  2204. X    unsigned    t_type    :  2;        /*  Type  */
  2205. X    unsigned    t_vins  :  1;        /*  Valid instruction  */
  2206. X    unsigned    t_bdest    :  1;        /*  Is branch dest  */
  2207. X    unsigned    t_gbdest:  1;        /*  Is global dest  */
  2208. X    unsigned    t_dref    :  1;        /*  Refered to in data  */
  2209. X    unsigned    t_bchtyp:  2;        /*  Branch type  */
  2210. X    unsigned    t_zilch    :  3;        /*  used to be t_lng */
  2211. X    unsigned    t_reloc :  2;        /*  Relocatable  */
  2212. X    unsigned    t_rptr    :  2;        /*  Where relocated  */
  2213. X    unsigned    t_rdisp :  1;        /*  Relocatable displacement */
  2214. X    unsigned    t_isrel :  1;        /*  Relocated  */
  2215. X    unsigned    t_amap    :  1;        /*  Worked out  */
  2216. X    short        t_lng;            /*  Length in words */
  2217. X    symbol        t_relsymb;        /*  Relocation symbol  */
  2218. X    long        t_reldisp;        /*  Offset + or - from symb */
  2219. X    symbol        t_lab;            /*  Label  */
  2220. X    unsigned  short    t_lsymb;        /*  Local symbol  */
  2221. X    long        t_reflo;        /*  Lowest place referred  */
  2222. X    long        t_refhi;        /*  Highest place referred  */
  2223. X    unsigned  short    t_match;        /*  Lib match lng  */
  2224. X}  t_entry;
  2225. X
  2226. X/*
  2227. X *    Types ......
  2228. X */
  2229. X
  2230. X#define    T_UNKNOWN    0
  2231. X#define    T_BEGIN        1
  2232. X#define    T_CONT        2
  2233. X
  2234. X#define    R_NONE        0        /*  No relocation  */
  2235. X#define    R_BYTE        1        /*  Byte relocation  */
  2236. X#define    R_WORD        2        /*  Word relocation  */
  2237. X#define    R_LONG        3        /*  Long relocation  */
  2238. X
  2239. X/*
  2240. X *    Branch types.
  2241. X */
  2242. X
  2243. X#define    T_NOBR        0
  2244. X#define    T_CONDBR    1
  2245. X#define    T_UNBR        2
  2246. X#define    T_JSR        3
  2247. X
  2248. Xtypedef    struct    {
  2249. X    unsigned  char    d_contents;        /*  Actual contents  */
  2250. X    unsigned    d_type  :  4;        /*  Data type  */
  2251. X    unsigned    d_reloc :  2;        /*  Relocatable  */
  2252. X    unsigned    d_rptr    :  2;        /*  Where relocated  */
  2253. X    short        d_lng;            /*  Length -ve for D_CONT */
  2254. X    symbol        d_relsymb;        /*  Relocation symbol  */
  2255. X    long        d_reldisp;        /*  Offset + or - from symb */
  2256. X    symbol        d_lab;            /*  Label  */
  2257. X}  d_entry;
  2258. X
  2259. X/*
  2260. X *    Data types.
  2261. X */
  2262. X
  2263. X#define    D_ASC        0        /*  Ascii chars  */
  2264. X#define    D_ASCZ        1        /*  Null-term ascii  */
  2265. X#define    D_BYTE        2        /*  Decimal bytes  */
  2266. X#define    D_WORD        3        /*  Words  */
  2267. X#define    D_LONG        4        /*  Longs  */
  2268. X#define    D_ADDR        5        /*  Address pointer  */
  2269. X#define    D_CONT        6        /*  Continuation of last  */
  2270. X
  2271. X/*
  2272. X *    'Common' items.
  2273. X */
  2274. X
  2275. Xstruct    commit    {
  2276. X    symbol    *c_symb;        /*  List of symbols  */
  2277. X    int    c_int;            /*  Current number  */
  2278. X    int    c_max;            /*  Maximum  */
  2279. X};
  2280. X
  2281. X/*
  2282. X *    Library file description.
  2283. X */
  2284. X
  2285. Xstruct    libit    {
  2286. X    LDFILE *ldptr,*ldptr2;        /*  independent file pointer packages
  2287. X                        for the same file */
  2288. X    char    lf_name[14];        /*  Name of item  */
  2289. X};
  2290. X
  2291. X/* magic number stuff like Sun */
  2292. X#define OMAGIC 0407
  2293. X#define NMAGIC 0410
  2294. X#define ZMAGIC 0413
  2295. X#define N_BADMAG(x) \
  2296. X    (((x).magic)!=OMAGIC && ((x).magic)!=NMAGIC && ((x).magic)!=ZMAGIC)
  2297. X
  2298. X/* definitions of type for Sun -- used for symstr.type, d_entry.d_rptr */
  2299. X#define S_UNDF 0x0        /* undefined */
  2300. X#define S_ABS  0x2        /* absolute */
  2301. X#define S_TEXT 0x4        /* text */
  2302. X#define S_DATA 0x6        /* data */
  2303. X#define S_BSS  0x8        /* bss */
  2304. X#define S_COMM 0x12        /* common (internal to ld) */
  2305. X#define S_FN   0x1f        /* file name symbol */
  2306. X#define S_EXT  01        /* external bit, or'ed in */
  2307. X#define S_TYPE 0x1e        /* mask for all the type bits */
  2308. SHAR_EOF
  2309. chmod 0644 unc.h || echo "restore of unc.h fails"
  2310. exit 0
  2311.