home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume35 / dis / part02 < prev    next >
Encoding:
Text File  |  1993-02-03  |  54.0 KB  |  2,075 lines

  1. Newsgroups: comp.sources.misc
  2. From: bediger@nugget.rmnug.org (Bruce Allen Ediger)
  3. Subject: v35i016:  dis - SPARC/SunOS disassembler, Part02/03
  4. Message-ID: <1993Feb2.064300.20999@sparky.imd.sterling.com>
  5. X-Md4-Signature: 8f8a1d5c909e54a9fe8b999e9619b4df
  6. Date: Tue, 2 Feb 1993 06:43:00 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: bediger@nugget.rmnug.org (Bruce Allen Ediger)
  10. Posting-number: Volume 35, Issue 16
  11. Archive-name: dis/part02
  12. Environment: SunOS4.1.x
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  arithmetic.c arithmetic.h decode.c dis.1 hash.h line.c
  19. #   memory.c printout.c relocation.c sparc_stuff.h
  20. # Wrapped by kent@sparky on Tue Feb  2 00:31:40 1993
  21. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  22. echo If this archive is complete, you will see the following message:
  23. echo '          "shar: End of archive 2 (of 3)."'
  24. if test -f 'arithmetic.c' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'arithmetic.c'\"
  26. else
  27.   echo shar: Extracting \"'arithmetic.c'\" \(7361 characters\)
  28.   sed "s/^X//" >'arithmetic.c' <<'END_OF_FILE'
  29. X#include <stdio.h>
  30. X#include <stdlib.h>
  31. X#include <string.h>
  32. X#include "formats.h"
  33. X#include "arithmetic.h"
  34. X
  35. X/*
  36. X * Decode integer arithmetic, logical, and shift instructions.
  37. X * Assume pre-allocated buffer "buf" can be filled with text
  38. X * describing the instruction.
  39. X */
  40. X
  41. Xvoid
  42. Xarithmetic(instr, buf)
  43. X    unsigned long   instr;
  44. X    char           *buf;
  45. X{
  46. X    struct format3a instr3a;
  47. X    struct format3b instr3b;
  48. X
  49. X    int             op3_5_4, op3_3_0;
  50. X    int             immediate;
  51. X    char           *opcode_ptr;
  52. X
  53. X    char           *user_mode();
  54. X
  55. X
  56. X
  57. X    bcopy((char *) &instr, (char *) &instr3a, 4);
  58. X
  59. X    /* trim off op3 <5:4> */
  60. X    op3_5_4 = (instr3a.op3 & 0x30) >> 4;
  61. X    /* trim off op3 <3:0> */
  62. X    op3_3_0 = (instr3a.op3 & 0x0f);
  63. X
  64. X    opcode_ptr = table_f_3[op3_3_0][op3_5_4];
  65. X
  66. X    if (immediate = instr3a.i)
  67. X        bcopy((char *) &instr, (char *) &instr3b, 4);
  68. X
  69. X    /* many different output formats: use switch */
  70. X    switch (instr3a.op3) {
  71. X    case 0x30:
  72. X        /* WRASR, WRY */
  73. X        if (instr3a.rd) {
  74. X            /* WRASR */
  75. X            if (immediate) {
  76. X                sprintf(buf, "wr %s, %d, %s ! WRASR", user_mode(instr3a.rs1),
  77. X                    SIGN_EXT13(instr3b.simm13),
  78. X                    user_mode(instr3a.rd));
  79. X            } else {
  80. X                sprintf(buf, "wr %s, %s, %s ! WRASR", user_mode(instr3a.rs1),
  81. X                    user_mode(instr3a.rs2), user_mode(instr3a.rd));
  82. X            }
  83. X        } else {
  84. X            /* WRY */
  85. X            if (immediate) {
  86. X                sprintf(buf, "wr %s, %d, %%y ! WRY", user_mode(instr3a.rs1),
  87. X                    SIGN_EXT13(instr3b.simm13));
  88. X
  89. X            } else {
  90. X                sprintf(buf, "wr %s, %s, %%y ! WRY", user_mode(instr3a.rs1),
  91. X                    user_mode(instr3a.rs2));
  92. X            }
  93. X        }
  94. X        break;
  95. X
  96. X    case 0x31:
  97. X        /* WRPSR */
  98. X        if (immediate) {
  99. X            sprintf(buf, "wr %s, %d, %%psr ! WRPSR", user_mode(instr3a.rs1),
  100. X                SIGN_EXT13(instr3b.simm13));
  101. X
  102. X        } else {
  103. X            sprintf(buf, "wr %s, %s, %%psr ! WRPSR", user_mode(instr3a.rs1),
  104. X                user_mode(instr3a.rs2));
  105. X        }
  106. X        break;
  107. X
  108. X    case 0x32:
  109. X        /* WRWIM */
  110. X        if (immediate) {
  111. X            sprintf(buf, "wr %s, %d, %%wim ! WRWIM", user_mode(instr3a.rs1),
  112. X                SIGN_EXT13(instr3b.simm13));
  113. X
  114. X        } else {
  115. X            sprintf(buf, "wr %s, %s, %%wim ! WRWIM", user_mode(instr3a.rs1),
  116. X                user_mode(instr3a.rs2));
  117. X        }
  118. X        break;
  119. X
  120. X    case 0x33:
  121. X        /* WRTBR */
  122. X        if (immediate) {
  123. X            sprintf(buf, "wr %s, %d, %%tbr ! WRTBR", user_mode(instr3a.rs1),
  124. X                SIGN_EXT13(instr3b.simm13));
  125. X
  126. X        } else {
  127. X            sprintf(buf, "wr %s, %s, %%tbr ! WRTBR", user_mode(instr3a.rs1),
  128. X                user_mode(instr3a.rs2));
  129. X        }
  130. X        break;
  131. X
  132. X    case 0x28:
  133. X        /* RDASR, RDY, STBAR */
  134. X        if (instr3a.rs1) {
  135. X            if (instr3a.rs1 == 15 && instr3a.rd == 0) {
  136. X                strcpy(buf, "stbar");
  137. X            } else {
  138. X                sprintf(buf, "rd %s, %s ! RDASR", user_mode(instr3a.rs1),
  139. X                    user_mode(instr3a.rd));
  140. X            }
  141. X        } else {
  142. X            sprintf(buf, "rd %%y, %s ! RDY", user_mode(instr3a.rd));
  143. X        }
  144. X        break;
  145. X
  146. X    case 0x29:
  147. X        /* RDPSR */
  148. X        sprintf(buf, "rd %%psr, %s ! RDPSR", user_mode(instr3a.rd));
  149. X        break;
  150. X
  151. X    case 0x2a:
  152. X        /* RDWIM */
  153. X        sprintf(buf, "rd %%wim, %s ! RDWIM", user_mode(instr3a.rd));
  154. X        break;
  155. X
  156. X    case 0x2b:
  157. X        /* RDTBR */
  158. X        sprintf(buf, "rd %%tbr, %s ! RDWIM", user_mode(instr3a.rd));
  159. X        break;
  160. X
  161. X    case 0x38:
  162. X        /* JMPL */
  163. X        if (immediate) {
  164. X            if (instr3a.rs1 > 0) {
  165. X                sprintf(buf, "%s [%s + %d], %s",
  166. X                    opcode_ptr, user_mode(instr3a.rs1),
  167. X                    SIGN_EXT13(instr3b.simm13),
  168. X                    user_mode(instr3a.rd));
  169. X            } else {
  170. X                /* %g0 is rs1: ignore it for clarity */
  171. X                sprintf(buf, "%s [%d], %s", opcode_ptr,
  172. X                    SIGN_EXT13(instr3b.simm13),
  173. X                    user_mode(instr3a.rd));
  174. X            }
  175. X        } else {
  176. X            sprintf(buf, "%s [%s + %s], %s",
  177. X                opcode_ptr, user_mode(instr3a.rs1),
  178. X                user_mode(instr3a.rs2),
  179. X                user_mode(instr3a.rd));
  180. X        }
  181. X        break;
  182. X
  183. X    case 0x39:
  184. X        /* RETT */
  185. X        if (immediate) {
  186. X            if (instr3a.rs1 > 0) {
  187. X                sprintf(buf, "%s [%s + %d]",
  188. X                    opcode_ptr, user_mode(instr3a.rs1),
  189. X                    SIGN_EXT13(instr3b.simm13));
  190. X            } else {
  191. X                /* %g0 is rs1: ignore it for clarity */
  192. X                sprintf(buf, "%s [%d]", opcode_ptr,
  193. X                    SIGN_EXT13(instr3b.simm13));
  194. X            }
  195. X        } else {
  196. X            sprintf(buf, "%s [%s + %s]",
  197. X                opcode_ptr, user_mode(instr3a.rs1),
  198. X                user_mode(instr3a.rs2));
  199. X        }
  200. X        break;
  201. X
  202. X    case 0x3b:
  203. X        /* FLUSH */
  204. X        if (immediate) {
  205. X            if (instr3a.rs1 > 0) {
  206. X                sprintf(buf, "%s [%s + %d]",
  207. X                    opcode_ptr, user_mode(instr3a.rs1),
  208. X                    SIGN_EXT13(instr3b.simm13));
  209. X            } else {
  210. X                /* %g0 is rs1: ignore it for clarity */
  211. X                sprintf(buf, "%s [%d]", opcode_ptr,
  212. X                    SIGN_EXT13(instr3b.simm13));
  213. X            }
  214. X        } else {
  215. X            sprintf(buf, "%s [%s + %s]",
  216. X                opcode_ptr, user_mode(instr3a.rs1),
  217. X                user_mode(instr3a.rs2));
  218. X        }
  219. X        break;
  220. X
  221. X    case 0x3a:
  222. X        /* Ticc */
  223. X        opcode_ptr = traps[instr3a.rd & 0x0f];
  224. X        if (immediate) {
  225. X            if (instr3a.rs1 > 0) {
  226. X                sprintf(buf, "%s %s + %d",
  227. X                    opcode_ptr, user_mode(instr3b.rs1),
  228. X                    SIGN_EXT13(instr3b.simm13));
  229. X            } else {
  230. X                sprintf(buf, "%s %d", opcode_ptr, SIGN_EXT13(instr3b.simm13));
  231. X            }
  232. X        } else {
  233. X            sprintf(buf, "%s %s + %s",
  234. X                opcode_ptr, user_mode(instr3a.rs1),
  235. X                user_mode(instr3a.rs2));
  236. X        }
  237. X        break;
  238. X
  239. X    /* invalid ops or stuff I haven't covered 
  240. X     * (floating point and co-processor) */
  241. X    case 0x34:
  242. X    case 0x35:
  243. X    case 0x36:
  244. X    case 0x37:
  245. X    case 0x09:
  246. X    case 0x19:
  247. X    case 0x2c:
  248. X    case 0x0d:
  249. X    case 0x1d:
  250. X    case 0x2d:
  251. X    case 0x2e:
  252. X    case 0x2f:
  253. X    case 0x3e:
  254. X    case 0x3f:
  255. X        strcpy(buf, opcode_ptr);
  256. X        break;
  257. X
  258. X    default:
  259. X        /* most of arithmetic, logical and shift instructions */
  260. X
  261. X        /* I am really proud of the nifty use of the "?:" tertiary
  262. X         * operator in the next two or three sprintf()s, but lint
  263. X         * hates it. */
  264. X#ifndef NOSYNTHETIC
  265. X        /* some "synthetic" instructions: special cases where %g0 is in it */
  266. X        if (instr3a.rd == 0 && instr3a.op3 == 0x14) {
  267. X            /* subcc becoming "cmp" */
  268. X            sprintf(buf, immediate?"cmp %s, %d":"cmp %s, %s",
  269. X                user_mode(instr3a.rs1),
  270. X                immediate?SIGN_EXT13(instr3b.simm13):user_mode(instr3a.rs2));
  271. X            break;
  272. X        }
  273. X        if (instr3a.rs1 == 0 && instr3a.op3 == 0x02) {
  274. X            if (!immediate && instr3a.rs2 == 0) {
  275. X                /* or %g0,%g0,rd becomes clr rd */
  276. X                sprintf(buf, "clr %s", user_mode(instr3a.rd));
  277. X            } else {
  278. X                /* or %g0,something,r[rd] turns into mov something, r[rd] */
  279. X                sprintf(buf, immediate?"mov %d, %s":"mov %s, %s",
  280. X                    immediate?SIGN_EXT13(instr3b.simm13):user_mode(instr3a.rs2),
  281. X                    user_mode(instr3a.rd));
  282. X            }
  283. X            break;
  284. X        }
  285. X        /* add rd,simm13,rd becomes inc something,rd */
  286. X        if (instr3a.op3 == 0x00
  287. X            && immediate 
  288. X            && instr3a.rs1 == instr3a.rd) {
  289. X            if (instr3b.simm13 == 0x01) {
  290. X                sprintf(buf, "inc %s", user_mode(instr3a.rd));
  291. X            } else {
  292. X                sprintf(buf, "inc %d, %s", instr3b.simm13, user_mode(instr3a.rd));
  293. X            }
  294. X            break;
  295. X        }
  296. X
  297. X        /* sub rd,simm13,rd becomes dec something,rd */
  298. X        if (instr3a.op3 == 0x04
  299. X            && immediate 
  300. X            && instr3a.rs1 == instr3a.rd) {
  301. X            if (instr3b.simm13 == 0x01) {
  302. X                sprintf(buf, "dec %s", user_mode(instr3a.rd));
  303. X            } else {
  304. X                sprintf(buf, "dec %d, %s", instr3b.simm13, user_mode(instr3a.rd));
  305. X            }
  306. X            break;
  307. X        }
  308. X        /* orcc %g0,rs2,%g0 becomes tst rs2 */
  309. X        if (instr3a.op3 == 0x12 && instr3a.rs1 == 0 && instr3a.rd == 0) {
  310. X            sprintf(buf, "tst %s", user_mode(instr3a.rs2));
  311. X            break;
  312. X        }
  313. X#endif
  314. X
  315. X
  316. X        
  317. X        if (immediate) {
  318. X            if (instr3a.rs1 > 0) {
  319. X                sprintf(buf, "%s %s, %d, %s",
  320. X                    opcode_ptr, user_mode(instr3a.rs1),
  321. X                    SIGN_EXT13(instr3b.simm13),
  322. X                    user_mode(instr3a.rd));
  323. X            } else {
  324. X                /* %g0 is rs1: ignore it for clarity */
  325. X                sprintf(buf, "%s %d, %s", opcode_ptr,
  326. X                    SIGN_EXT13(instr3b.simm13),
  327. X                    user_mode(instr3a.rd));
  328. X            }
  329. X        } else {
  330. X            sprintf(buf, "%s %s, %s, %s",
  331. X                opcode_ptr, user_mode(instr3a.rs1),
  332. X                user_mode(instr3a.rs2),
  333. X                user_mode(instr3a.rd));
  334. X        }
  335. X        break;
  336. X    }
  337. X
  338. X    return;
  339. X}
  340. END_OF_FILE
  341.   if test 7361 -ne `wc -c <'arithmetic.c'`; then
  342.     echo shar: \"'arithmetic.c'\" unpacked with wrong size!
  343.   fi
  344.   # end of 'arithmetic.c'
  345. fi
  346. if test -f 'arithmetic.h' -a "${1}" != "-c" ; then 
  347.   echo shar: Will not clobber existing file \"'arithmetic.h'\"
  348. else
  349.   echo shar: Extracting \"'arithmetic.h'\" \(1185 characters\)
  350.   sed "s/^X//" >'arithmetic.h' <<'END_OF_FILE'
  351. X#ifndef ARITHMETIC_H
  352. X#define ARITHMETIC_H
  353. X
  354. X/* Table F-3 in "The SPARC Architecture Manual", version 8 */
  355. X
  356. Xstatic char *table_f_3[16][4] = {
  357. X{ "add", "addcc", "taddcc", "XXXX" },  /* WRASR, WRY special case */
  358. X{ "and", "andcc", "tsubcc", "wrpsr" },
  359. X{ "or", "orcc", "taddcctv", "wrmwim" },
  360. X{ "xor", "xorcc", "tsubcctv", "wrtbr" },
  361. X{ "sub", "subcc", "mulscc", "fpop1" },
  362. X{ "andn", "andncc", "sll", "fpop2" },
  363. X{ "orn", "orncc", "srl", "cpop1" },
  364. X{ "xnor", "xnorcc", "sra", "cpop2" },
  365. X{ "addx", "addxcc",  "XXXX", "jmpl" }, /* RDASR, RDY, STBAR special case */
  366. X{ "invalid op3 (0x09)", "invalid op3 (0x19)", "rdpsr", "rett" },
  367. X{ "umul", "umulcc", "rdwim", "XXXX" }, /* Ticc special case */
  368. X{ "smul", "smulcc", "rdtbr", "flush" },
  369. X{ "subx", "subxcc", "invalid op3 (0x2c)", "save" },
  370. X{ "invalid op3 (0x0d)", "invalid op3 (0x1d)", "invalid op3 (0x2d)", "restore" },
  371. X{ "udiv", "udivcc", "invalid op3 (0x2e)", "invalid op3 (0x3e)" },
  372. X{ "sdiv", "sdivcc", "invalid op3 (0x2f)", "invalid op3 (0x3f)" }
  373. X};
  374. X
  375. X/* "Ticc" column of Table F-7 */
  376. Xstatic char *traps[16] = {
  377. X"tn", "te", "tle", "tl", "tleu", "tcs", "tneg", "tvs",
  378. X"ta", "tne", "tg", "tge", "tgu", "tcc", "tpos", "tvc"
  379. X};
  380. X
  381. X#endif ARITHMETIC_H
  382. END_OF_FILE
  383.   if test 1185 -ne `wc -c <'arithmetic.h'`; then
  384.     echo shar: \"'arithmetic.h'\" unpacked with wrong size!
  385.   fi
  386.   # end of 'arithmetic.h'
  387. fi
  388. if test -f 'decode.c' -a "${1}" != "-c" ; then 
  389.   echo shar: Will not clobber existing file \"'decode.c'\"
  390. else
  391.   echo shar: Extracting \"'decode.c'\" \(4080 characters\)
  392.   sed "s/^X//" >'decode.c' <<'END_OF_FILE'
  393. X#include <stdio.h>
  394. X#include <stdlib.h>
  395. X#include <string.h>
  396. X#include "formats.h"
  397. X
  398. X/*
  399. X * Given 32 bit instruction to decode, and current program counter,
  400. X * put a string in "buf" that represents the decoded intstruction.
  401. X * Hopefully, this is enough separation from the executable image
  402. X * format for this to be re-usable if/when Sun switches to another
  403. X * format (ELF?).
  404. X */
  405. Xchar *
  406. Xdecode_instr(instr, pc, buf)
  407. Xunsigned long   instr, pc; 
  408. Xchar           *buf;
  409. X{
  410. X    struct format1  *instr1;
  411. X    struct format2  *instr2;
  412. X
  413. X    char *user_mode(), *bicc(), *fbfcc(), *cbcc();
  414. X    void  memory(), arithmetic();
  415. X
  416. X    instr1 = (struct format1  *)&instr;
  417. X
  418. X    /*
  419. X     * handle simpler instructions here inside a switch, call
  420. X     * a function to do lookups for memory load/stores and
  421. X     * the arithmetic instructions.
  422. X     * This switch() is essentially tables F-1 and F-2 of
  423. X     * "The SPARC Architecture Manual: Version 8".
  424. X     */
  425. X    switch (instr1->op) {
  426. X    case 0:
  427. X        /* op == 0, UNIMP, Bicc, SETHI, NOP, FBfcc, CBccc */
  428. X        instr2 = (struct format2  *)&instr;
  429. X        switch (instr2->op2) {
  430. X        case 0:
  431. X            strcpy(buf, "UNIMP");
  432. X            break;
  433. X        case 1:
  434. X            strcpy(buf, "unimplemented, op2 = 1");
  435. X            break;
  436. X        case 2:
  437. X            /* BRANCH On Integer Condition Codes */
  438. X            sprintf(buf, "%s 0x%08x", bicc(instr2->rd),
  439. X                (unsigned int)pc + (unsigned int)(4 * (unsigned int)(SIGN_EXT22(instr2->imm22))));
  440. X            break;
  441. X        case 3:
  442. X            strcpy(buf, "unimplemented, op2 = 3");
  443. X            break;
  444. X        case 4:
  445. X            /* SETHI */
  446. X            if (instr2->rd == 0 && instr2->imm22 == 0)
  447. X                sprintf(buf, "nop");
  448. X            else
  449. X                sprintf(buf, "sethi %%hi(0x%x) %s",
  450. X                     instr2->imm22 << 10, user_mode(instr2->rd));
  451. X            break;
  452. X        case 5:
  453. X            strcpy(buf, "unimplemented, op2 = 5");
  454. X            break;
  455. X        case 6:
  456. X            /* BRANCH On Floating-point Condition Codes */
  457. X            sprintf(buf, "%s 0x%08x", fbfcc(instr2->rd),
  458. X                (unsigned int)pc + (unsigned int)(4 * (unsigned int)SIGN_EXT22(instr2->imm22)));
  459. X            break;
  460. X        case 7:
  461. X            /* BRANCH On Coprocessor Condition Codes */
  462. X            sprintf(buf, "%s 0x%08x", cbcc(instr2->rd),
  463. X                (unsigned int)pc + (unsigned int)(4 * (unsigned int)SIGN_EXT22(instr2->imm22)));
  464. X            break;
  465. X        default:
  466. X            /* bogus instruction */
  467. X            sprintf(buf, "bogus instruction: op = %d, op2 = %d",
  468. X                instr2->op, instr2->op2);
  469. X            break;
  470. X        }
  471. X
  472. X        break;
  473. X
  474. X    case 1:
  475. X        /* op == 1, CALL AND LINK */
  476. X        sprintf(buf, "call 0x%08x", 4 * instr1->disp30 + (unsigned int)pc);
  477. X        break;
  478. X
  479. X    case 2:
  480. X        /* op == 2, Arithmetic, logical, shift, misc */
  481. X        arithmetic(instr, buf);
  482. X        break;
  483. X
  484. X    case 3:
  485. X        /* op == 3, Memory Instructions */
  486. X        memory(instr, buf);
  487. X        break;
  488. X
  489. X    default:
  490. X        /* bogus */
  491. X        sprintf(buf, "bogus instruction: op = %d, bad value",
  492. X            instr1->op);
  493. X    }
  494. X
  495. X
  496. X    return buf;
  497. X}
  498. X
  499. Xstatic char     bozo[32];
  500. X
  501. X/*
  502. X * take a register number and transliterate it into a "user-mode" type of
  503. X * register name: the user mode is the name inside the current "window"
  504. X */
  505. Xchar *
  506. Xuser_mode(rd)
  507. Xunsigned int rd;
  508. X{
  509. X    char           *ptr;
  510. X
  511. X    switch (rd) {
  512. X    case 0:
  513. X        ptr = "%g0";
  514. X        break;
  515. X    case 1:
  516. X        ptr = "%g1";
  517. X        break;
  518. X    case 2:
  519. X        ptr = "%g2";
  520. X        break;
  521. X    case 3:
  522. X        ptr = "%g3";
  523. X        break;
  524. X    case 4:
  525. X        ptr = "%g4";
  526. X        break;
  527. X    case 5:
  528. X        ptr = "%g5";
  529. X        break;
  530. X    case 6:
  531. X        ptr = "%g6";
  532. X        break;
  533. X    case 7:
  534. X        ptr = "%g7";
  535. X        break;
  536. X    case 8:
  537. X        ptr = "%o0";
  538. X        break;
  539. X    case 9:
  540. X        ptr = "%o1";
  541. X        break;
  542. X    case 10:
  543. X        ptr = "%o2";
  544. X        break;
  545. X    case 11:
  546. X        ptr = "%o3";
  547. X        break;
  548. X    case 12:
  549. X        ptr = "%o4";
  550. X        break;
  551. X    case 13:
  552. X        ptr = "%o5";
  553. X        break;
  554. X    case 14:
  555. X        ptr = "%sp";
  556. X        break;
  557. X    case 15:
  558. X        ptr = "%o7";
  559. X        break;
  560. X    case 16:
  561. X        ptr = "%l0";
  562. X        break;
  563. X    case 17:
  564. X        ptr = "%l1";
  565. X        break;
  566. X    case 18:
  567. X        ptr = "%l2";
  568. X        break;
  569. X    case 19:
  570. X        ptr = "%l3";
  571. X        break;
  572. X    case 20:
  573. X        ptr = "%l4";
  574. X        break;
  575. X    case 21:
  576. X        ptr = "%l5";
  577. X        break;
  578. X    case 22:
  579. X        ptr = "%l6";
  580. X        break;
  581. X    case 23:
  582. X        ptr = "%l7";
  583. X        break;
  584. X    case 24:
  585. X        ptr = "%i0";
  586. X        break;
  587. X    case 25:
  588. X        ptr = "%i1";
  589. X        break;
  590. X    case 26:
  591. X        ptr = "%i2";
  592. X        break;
  593. X    case 27:
  594. X        ptr = "%i3";
  595. X        break;
  596. X    case 28:
  597. X        ptr = "%i4";
  598. X        break;
  599. X    case 29:
  600. X        ptr = "%i5";
  601. X        break;
  602. X    case 30:
  603. X        ptr = "%fp";
  604. X        break;
  605. X    case 31:
  606. X        ptr = "%i7";
  607. X        break;
  608. X    default:
  609. X        sprintf(bozo, "bozotic value: %d (0x%x)", rd, rd);
  610. X        ptr = bozo;
  611. X        break;
  612. X    }
  613. X
  614. X    return ptr;
  615. X}
  616. END_OF_FILE
  617.   if test 4080 -ne `wc -c <'decode.c'`; then
  618.     echo shar: \"'decode.c'\" unpacked with wrong size!
  619.   fi
  620.   # end of 'decode.c'
  621. fi
  622. if test -f 'dis.1' -a "${1}" != "-c" ; then 
  623.   echo shar: Will not clobber existing file \"'dis.1'\"
  624. else
  625.   echo shar: Extracting \"'dis.1'\" \(2140 characters\)
  626.   sed "s/^X//" >'dis.1' <<'END_OF_FILE'
  627. X.\" .TH name section cent-foot
  628. X.TH DIS 1 "22 December 1992"
  629. X.SH NAME
  630. X.\" name \- function
  631. Xdis \- disassemble SunOS 4.1 SPARC object files
  632. X.SH SYNOPSIS
  633. X.\" Bold keywords, Italic variables, [] options, | alternatives.
  634. X.B dis
  635. X[
  636. X.IR -rnlad
  637. X]
  638. X[
  639. X.IR -t filename
  640. X]
  641. X[
  642. X.IR -b hex
  643. X.IR address
  644. X]
  645. X<
  646. X.IR filename
  647. X| -
  648. X>
  649. X.SH DESCRIPTION
  650. X.\" Italic files, commands, IR manual-entry (manual-section)
  651. X.I dis
  652. Xproduces a disassembly of SunOS 4.1, 4.1.1 and 4.1.2
  653. X.IR a.out (5)
  654. Xfiles on standard output.
  655. X.SH OPTIONS
  656. X.\" Itemised list of options
  657. X.TP
  658. X.B \-r
  659. XAssume input file does not have an a.out header.
  660. X
  661. X.TP
  662. X.B \-n
  663. XDon't try to find symbolic names.
  664. X
  665. X.TP
  666. X.B \-l
  667. XDon't try to find source file line numbers.
  668. X
  669. X.TP
  670. X.B \-a
  671. XPrint disassembly without memory addresses.
  672. X
  673. X.TP
  674. X.B \-d
  675. XAttempt to symbolically indicate branch destinations.
  676. X
  677. X.TP
  678. X.B \-t filename
  679. XTry to get symbol table from file
  680. X.IR filename
  681. X
  682. X.TP
  683. X.B \-b hex address
  684. XSet initial program counter to
  685. X.IR hex
  686. X.IR address
  687. X
  688. X.LP
  689. XFile name of object file to disassemble
  690. Xor "-" (to indicate standard input) must be present.
  691. X
  692. X.\".SH FILES
  693. X.\" List of all files used by the program
  694. X.SH "SEE ALSO"
  695. X.\" List of references, textual, and MAN pages.
  696. XFor SunOS 4.1 and up,
  697. Xcc(1), ld(1), as(1), size(1), strip(1), a.out(5)
  698. X.br
  699. XThe SPARC Architecture Manual, version 8
  700. X.\".SH DIAGNOSTICS
  701. X.\" List of error messages and return codes the user may expect
  702. X.SH BUGS
  703. X.\" Known Limitations or Desirable additions to the command
  704. X.LP
  705. XIt doesn't do very well with floating point and coprocessor instructions.
  706. X.LP
  707. XIt does not put in symbolic labels of branch destinations.
  708. XThis leads to a disassembly that won't re-assemble without major
  709. Xmodifications.
  710. X.LP
  711. XRather firmly wedded to the
  712. X.IR a.out(5)
  713. Xformat of object files.
  714. X.LP
  715. XIt won't make any distinction between ASCII text included in the text segment,
  716. Xand a bunch of invalid opcodes.
  717. X.LP
  718. XSymbolic naming of branch destinations doesn't work as well as it could.
  719. XIn some cases the relocation information and/or symbol table information
  720. Xis misinterpreted.
  721. XThis leads to some bizarre assertions about where branches end up.
  722. X.LP
  723. XHasn't been tested very thoroughly on non-SPARC platforms.
  724. END_OF_FILE
  725.   if test 2140 -ne `wc -c <'dis.1'`; then
  726.     echo shar: \"'dis.1'\" unpacked with wrong size!
  727.   fi
  728.   # end of 'dis.1'
  729. fi
  730. if test -f 'hash.h' -a "${1}" != "-c" ; then 
  731.   echo shar: Will not clobber existing file \"'hash.h'\"
  732. else
  733.   echo shar: Extracting \"'hash.h'\" \(4509 characters\)
  734.   sed "s/^X//" >'hash.h' <<'END_OF_FILE'
  735. X/*
  736. X * $Author: djh $ $Date: 91/02/15 23:07:37 $
  737. X * $Header: hash.h,v 2.1 91/02/15 23:07:37 djh Rel $
  738. X * $Revision: 2.1 $
  739. X*/
  740. X
  741. X/*
  742. X * hash.h - external definitions for hash.c - generalized hashing function
  743. X *
  744. X *  written by Charlie C. Kim
  745. X *     Academic Networking, Communications and Systems Group
  746. X *     Center For Computing Activities
  747. X *     Columbia University
  748. X *   September 1988
  749. X *
  750. X *
  751. X * Copyright (c) 1988 by The Trustees of Columbia University 
  752. X *  in the City of New York.
  753. X *
  754. X * Permission is granted to any individual or institution to use,
  755. X * copy, or redistribute this software so long as it is not sold for
  756. X * profit, provided that this notice and the original copyright
  757. X * notices are retained.  Columbia University nor the author make no
  758. X * representations about the suitability of this software for any
  759. X * purpose.  It is provided "as is" without express or implied
  760. X * warranty.
  761. X *
  762. X *
  763. X * Edit History:
  764. X *
  765. X *  Sept 5, 1988  CCKim Created
  766. X *  Sept 6, 1988  CCKim Finished: level 0
  767. X *
  768. X*/
  769. X
  770. X#ifndef _HASH_HEADER_INCLUDED
  771. X#define _HASH_HEADER_INCLUDED "yes"
  772. X
  773. X/* hash table operations recognized */
  774. X#define HASH_OP_DELETE 2
  775. X#define HASH_OP_MEMBER 1 
  776. X#define HASH_OP_INSERT 0
  777. X#define HASH_OP_NUM 3
  778. X
  779. X#define HASH_OP_VALID(n) ((n) < HASH_OP_NUM && (n) >= HASH_OP_INSERT)
  780. X#define HASH_OP_INVALID(n) ((n) >= HASH_OP_NUM || (n) < HASH_OP_INSERT)
  781. X
  782. X/* hashing collision policies */
  783. X#define HASH_POLICY_OLD -1    /* old for redefine */
  784. X#define HASH_POLICY_CHAIN 0    /* chain on collisions */
  785. X#define HASH_POLICY_LINEAR_PROBE 1 /* linear probes on collisions */
  786. X#define HASH_POLICY_DOUBLE_HASH 2 /* double hash on collisions */
  787. X
  788. X/* given a hash policy, returns true if it is a valid policy */
  789. X#define HASH_POLICY_VALID(n) ((n) <= HASH_POLICY_DOUBLE_HASH && \
  790. X                  (n) >= HASH_POLICY_CHAIN)
  791. X#define HASH_POLICY_LINKSNEEDED(n) ((n) == HASH_POLICY_CHAIN)
  792. X
  793. X/* hash function types */
  794. X#define HASH_TYPE_OLD -1    /* old for redefine */
  795. X#define HASH_TYPE_OWN 0        /* our own */
  796. X#define HASH_TYPE_DIVISION 1    /* division method */
  797. X#define HASH_TYPE_MULTIPLICATIVE 2 /* multiplicative method */
  798. X/* for multiplicative mode: try for fibonacci */
  799. X/* only valid for 32 bit machines! */
  800. X#define A_MULTIPLIER 2630561063 /* gotta figure out a good one */
  801. X
  802. X#define HASH_TYPE_NUM 3
  803. X
  804. X#define HASH_TYPE_VALID(n) ((n) < HASH_TYPE_NUM && \
  805. X  (n) >= HASH_TYPE_OWN)
  806. X
  807. X
  808. X/*
  809. X * structure to allow operations other than a linear list off a hash
  810. X * bucket in the chain policy
  811. X *
  812. X*/
  813. Xstruct hash_bucket_list_ops {
  814. X  caddr_t (*hlo_find)();    /* find a member */
  815. X  caddr_t (*hlo_insert)();    /* insert a member (returns ptr to */
  816. X                /* data) */
  817. X  int (*hlo_delete)();        /* delete a member */
  818. X  caddr_t (*hlo_get)();        /* get any member and remove from list */
  819. X};
  820. X
  821. X/* averages are fixed decimal with 2 digits after the decimal */
  822. X/* they are kept in case we want to do something when average */
  823. X/* distances get too large */
  824. Xstruct hash_statistics {
  825. X  int hs_buckets;        /* number of buckets in table */
  826. X  /* describes # of entries in chain */
  827. X  int hs_used;            /* # of buckets filled */
  828. X  /* describes table (not accurate for chain policy) */
  829. X  int hs_davg;            /* average distance from hash index */
  830. X  int hs_dsum;            /* sum of distances from hash index */
  831. X  int hs_dmax;            /* maximum distance from hash index */
  832. X  /* describes lookup patterns (describes distance into linear table */
  833. X  /* if the policy is chain */
  834. X  int hs_lnum;            /* remember number of lookups */
  835. X  int hs_lsum;            /* sum of lookup distances */
  836. X  int hs_lavg;            /* average lookup distance */
  837. X  /* cumulative for lookup patterns (describes overall efficiency) */
  838. X  int hs_clnum;            /* remember number of lookups */
  839. X  int hs_clsum;            /* sum of lookup distances */
  840. X};
  841. X
  842. X/* function declarations */
  843. Xcaddr_t h_new();        /* create new table */
  844. Xcaddr_t h_operation();        /* hash operations */
  845. Xstruct hash_statistics *h_statistics(); /* returns stats on a table */
  846. Xvoid h_free();            /* free a table */
  847. X/* must specify policy and type */
  848. Xcaddr_t h_redefine();        /* redefine operating parameters for a */
  849. X                /* hash table, forces a rehash */
  850. X#define h_rehash(ht,M) (h_redefine((ht),HASH_POLICY_OLD,HASH_TYPE_OLD,\
  851. X                   (M),NULL,NULL,NULL,NULL,NULL,NULL))
  852. X/* call hash operation for these */
  853. X#define h_member(ht,key) (h_operation(HASH_OP_MEMBER,(ht),(key),-1,-1,\
  854. X                      NULL,NULL))
  855. X#define h_insert(ht,key) (h_operation(HASH_OP_INSERT,(ht),(key),\
  856. X                      -1,-1, NULL, NULL))
  857. X#define h_delete(ht,key) (h_operation(HASH_OP_DELETE,(ht),(key),-1,-1,\
  858. X                       NULL,NULL))
  859. X
  860. X
  861. X#endif /* _HASH_HEADER_INCLUDED */
  862. END_OF_FILE
  863.   if test 4509 -ne `wc -c <'hash.h'`; then
  864.     echo shar: \"'hash.h'\" unpacked with wrong size!
  865.   fi
  866.   # end of 'hash.h'
  867. fi
  868. if test -f 'line.c' -a "${1}" != "-c" ; then 
  869.   echo shar: Will not clobber existing file \"'line.c'\"
  870. else
  871.   echo shar: Extracting \"'line.c'\" \(4292 characters\)
  872.   sed "s/^X//" >'line.c' <<'END_OF_FILE'
  873. X#include <stdio.h>
  874. X#include <stdlib.h>
  875. X#include <string.h>
  876. X#include <stab.h>
  877. X#include <sys/types.h>
  878. X#include "hash.h"
  879. X#ifdef sparc
  880. X#include <a.out.h>
  881. X#else
  882. X#include "sparc_stuff.h"
  883. X#endif
  884. X
  885. X/*
  886. X * Functions for lookup of source code line numbers.
  887. X * Uses "CAP 2.0" hash functions to do so.
  888. X * line_at_address(), initialize_line() the only externally visible functions.
  889. X */
  890. X
  891. Xextern char         *string_table;
  892. Xextern struct nlist *symbol_table;
  893. X
  894. Xcaddr_t         line_hash_table;
  895. X
  896. Xstatic int
  897. Xline_address_compare(key, data)
  898. Xcaddr_t key, data;
  899. X{
  900. X    unsigned long   address = ((struct nlist *) key)->n_value;
  901. X
  902. X    if (address > ((struct nlist *) data)->n_value)
  903. X        return 1;
  904. X    if (address == ((struct nlist *) data)->n_value)
  905. X        return 0;
  906. X    if (address < ((struct nlist *) data)->n_value)
  907. X        return -1;
  908. X
  909. X    return 0;
  910. X}
  911. X
  912. Xstatic u_int
  913. Xline_address_compress(key)
  914. Xcaddr_t key;
  915. X{
  916. X    return ((struct nlist *) key)->n_value;
  917. X}
  918. X
  919. Xstatic caddr_t
  920. Xline_address_allocate(p)
  921. Xcaddr_t p;
  922. X{
  923. X    struct nlist *tmp
  924. X    = (struct nlist *) malloc(sizeof(struct nlist));
  925. X
  926. X    if (tmp != NULL)
  927. X        bcopy(p, (caddr_t) tmp, sizeof(struct nlist));
  928. X
  929. X    return (caddr_t) tmp;
  930. X}
  931. X
  932. Xint
  933. Xinitialize_line(exhdr_p, fp)
  934. Xstruct exec *exhdr_p;
  935. XFILE        *fp;
  936. X{
  937. X    int sym_number, string_table_size, i;
  938. X
  939. X    sym_number = exhdr_p->a_syms / sizeof(struct nlist);
  940. X    if (sym_number <= 0) {
  941. X        fprintf(stderr, "no symbol table\n");
  942. X        return 0;
  943. X    }
  944. X    /* read in symbol table, string table */
  945. X    if (symbol_table == NULL) {
  946. X        if ((symbol_table = (struct nlist *) malloc((unsigned) exhdr_p->a_syms))
  947. X            == NULL) {
  948. X            fprintf(stderr, "hosed malloc() on symbol table\n");
  949. X            return 0;
  950. X        }
  951. X        if (fseek(fp, (long)(N_SYMOFF(*exhdr_p)), 0) < 0) {
  952. X            fprintf(stderr, "buggered fseek to symbol table\n");
  953. X            return 0;
  954. X        }
  955. X        if (fread((char *) symbol_table, sizeof(struct nlist),
  956. X              sym_number, fp) != sym_number) {
  957. X            fprintf(stderr, "noinkered fread() of symbol table\n");
  958. X            return 0;
  959. X        }
  960. X    }
  961. X    if (string_table == NULL) {
  962. X        if (fseek(fp, (long)(N_STROFF(*exhdr_p)), 0) < 0) {
  963. X            fprintf(stderr, "screwed up fseek to string table\n");
  964. X            return 0;
  965. X        }
  966. X        if (fread((char *) &string_table_size, sizeof(int), 1, fp) != 1) {
  967. X            fprintf(stderr, "honked up fread() of string table size\n");
  968. X            return 0;
  969. X        }
  970. X        if ((string_table = malloc((unsigned) (string_table_size - 4))) == NULL) {
  971. X            fprintf(stderr, "crapped out on malloc() of string table\n");
  972. X            return 0;
  973. X        }
  974. X        if (fread(string_table, 1, string_table_size - 4, fp)
  975. X            != string_table_size - 4) {
  976. X            fprintf(stderr, "fucked up fread() of string table\n");
  977. X            return 0;
  978. X        }
  979. X    }
  980. X    /* initialize hash table */
  981. X    line_hash_table = h_new(HASH_POLICY_CHAIN, HASH_TYPE_DIVISION,
  982. X                sym_number > 100 ? sym_number / 2 : sym_number,
  983. X                line_address_compare, line_address_allocate, line_address_compress, NULL, NULL, NULL);
  984. X
  985. X    if (line_hash_table == NULL) {
  986. X        fprintf(stderr, "h_new() failed to allocate line number hash table\n");
  987. X        return 0;
  988. X    }
  989. X
  990. X    /* put N_SLINE and N_FUN things into line no. table */
  991. X    for (i = 0; i < sym_number; ++i) {
  992. X        int tmp;
  993. X        tmp = symbol_table[i].n_type;
  994. X        if ((tmp & N_STAB) && ((tmp & ~N_EXT) == N_SLINE || (tmp & ~N_EXT) == N_FUN)) {
  995. X            if (h_insert(line_hash_table, &(symbol_table[i])) == NULL) {
  996. X                fprintf(stderr, "botched adding reloc entry %d to hash table (h_insert)\n", i);
  997. X                return 0;
  998. X            }
  999. X        }
  1000. X    }
  1001. X    return 1;
  1002. X}
  1003. X
  1004. Xstatic struct nlist *
  1005. Xfind_nlist_at_addrs(addr)
  1006. Xunsigned long addr;
  1007. X{
  1008. X    struct nlist *ret, tmp;
  1009. X
  1010. X    tmp.n_value = addr;
  1011. X
  1012. X    if ((ret = (struct nlist *) h_member(line_hash_table,
  1013. X                          (caddr_t) & tmp)) != NULL)
  1014. X        return ret;
  1015. X    return NULL;
  1016. X}
  1017. X
  1018. Xstatic int
  1019. Xline_of_nlist(entry, buffer)
  1020. Xstruct nlist *entry;
  1021. Xchar         *buffer;
  1022. X{
  1023. X    int             str_table_index;
  1024. X
  1025. X    if (entry == NULL) {
  1026. X        buffer[0] = '\0';
  1027. X        return 0;
  1028. X    }
  1029. X    if ((entry->n_type & (~N_EXT)) == N_FUN) {
  1030. X        str_table_index = entry->n_un.n_strx;
  1031. X        if (str_table_index)
  1032. X            sprintf(buffer, "Function %s", &(string_table[str_table_index - 4]));
  1033. X        else
  1034. X            strcpy(buffer, "No Name Function");
  1035. X    } else {
  1036. X        sprintf(buffer, "source file line %d", entry->n_desc);
  1037. X    }
  1038. X
  1039. X    return 1;
  1040. X}
  1041. X
  1042. X/* fills in pre-allocated buffer with a string
  1043. X * derived from the symbol table line number and
  1044. X * function name info */
  1045. Xint
  1046. Xline_at_address(addr, buffer)
  1047. Xunsigned long   addr;
  1048. Xchar           *buffer;
  1049. X{
  1050. X    return line_of_nlist(find_nlist_at_addrs(addr), buffer);
  1051. X}
  1052. END_OF_FILE
  1053.   if test 4292 -ne `wc -c <'line.c'`; then
  1054.     echo shar: \"'line.c'\" unpacked with wrong size!
  1055.   fi
  1056.   # end of 'line.c'
  1057. fi
  1058. if test -f 'memory.c' -a "${1}" != "-c" ; then 
  1059.   echo shar: Will not clobber existing file \"'memory.c'\"
  1060. else
  1061.   echo shar: Extracting \"'memory.c'\" \(3396 characters\)
  1062.   sed "s/^X//" >'memory.c' <<'END_OF_FILE'
  1063. X#include <stdio.h>
  1064. X#include <stdlib.h>
  1065. X#include <string.h>
  1066. X#include "formats.h"
  1067. X#include "memory.h"
  1068. X
  1069. X/*
  1070. X * decode load, store and swap: all instructions that access memory
  1071. X */
  1072. X
  1073. Xvoid
  1074. Xmemory(instr, buf)
  1075. Xunsigned long instr;
  1076. Xchar *buf;
  1077. X{
  1078. X    struct format3a *instr3a;
  1079. X    struct format3b *instr3b;
  1080. X
  1081. X    int   op3_5_4, op3_3_0;
  1082. X    int   immediate;
  1083. X    int   asi;
  1084. X    char *opcode_ptr;
  1085. X
  1086. X    char *user_mode();
  1087. X
  1088. X    /* output formats */
  1089. X    static char *load_r_r        = "%s [%s + %s], %s";
  1090. X    static char *load_r_g0       = "%s [%s], %s";
  1091. X    static char *load_r_r_a      = "%s [%s + %s]%d, %s";
  1092. X    static char *load_r_i_plus   = "%s [%s + %d], %s";
  1093. X    static char *load_r_i_minus  = "%s [%s - %d], %s";
  1094. X
  1095. X    static char *store_r_r       = "%s %s, [%s + %s]";
  1096. X    static char *store_r_g0      = "%s %s, [%s]";
  1097. X    static char *store_r_r_a     = "%s %s, [%s + %s]%d";
  1098. X    static char *store_r_i_plus  = "%s %s, [%s + %d]";
  1099. X    static char *store_r_i_minus = "%s %s, [%s - %d]";
  1100. X    /*
  1101. X     * can't use these: in a .o file, can't tell if it's
  1102. X     * _really_ something that turns into a synthetic op
  1103. X     * or something that gets relocated.
  1104. X     * static char *load_r_i_zero =   "%s [%s], %s";
  1105. X     * static char *store_r_i_zero =  "%s %s, [%s]";
  1106. X     */
  1107. X
  1108. X    instr3a = (struct format3a *)&instr;
  1109. X
  1110. X    /* trim off op3 <5:4> */
  1111. X    op3_5_4 = (instr3a->op3 & 0x30) >> 4;
  1112. X    /* trim off op3 <3:0> */
  1113. X    op3_3_0 = (instr3a->op3 & 0x0f);
  1114. X
  1115. X    opcode_ptr = table_f_4[op3_3_0][op3_5_4];
  1116. X
  1117. X    if (immediate = instr3a->i)
  1118. X        instr3b = (struct format3b *)&instr;
  1119. X    asi = instr3a->asi;
  1120. X
  1121. X    switch (*opcode_ptr) {
  1122. X    case 'i':
  1123. X        /* check for invalid instruction */
  1124. X        strcpy(buf, opcode_ptr);
  1125. X        return;
  1126. X    case 'l':  /* load */
  1127. X        if (immediate) {
  1128. X            if (instr3b->simm13 & 0x1000) {
  1129. X                sprintf(buf, load_r_i_minus, opcode_ptr, user_mode(instr3b->rs1),
  1130. X                    0 - (instr3b->simm13 | 0xffffe000), user_mode(instr3b->rd));
  1131. X            } else {
  1132. X                sprintf(buf, load_r_i_plus, opcode_ptr, user_mode(instr3b->rs1),
  1133. X                    instr3b->simm13, user_mode(instr3b->rd));
  1134. X            }
  1135. X        } else {
  1136. X            if (asi) {
  1137. X                sprintf(buf, load_r_r_a, opcode_ptr, user_mode(instr3a->rs1),
  1138. X                    user_mode(instr3a->rs2), instr3a->asi, user_mode(instr3a->rd));
  1139. X            } else {
  1140. X                if (instr3a->rs2 == 0)
  1141. X                    sprintf(buf, load_r_g0, opcode_ptr, user_mode(instr3a->rs1),
  1142. X                        user_mode(instr3a->rd));
  1143. X                else
  1144. X                    sprintf(buf, load_r_r, opcode_ptr, user_mode(instr3a->rs1),
  1145. X                        user_mode(instr3a->rs2), user_mode(instr3a->rd));
  1146. X            }
  1147. X        }
  1148. X        break;
  1149. X    case 's':  /* store or swap */
  1150. X        if (opcode_ptr[1] == 'w') {
  1151. X            /* swap */
  1152. X            strcpy(buf, "??swap or swapa");
  1153. X        } else {
  1154. X            /* store */
  1155. X            if (immediate) {
  1156. X                if (instr3b->simm13 & 0x1000) {
  1157. X                    sprintf(buf, store_r_i_minus, opcode_ptr, user_mode(instr3b->rd),
  1158. X                        user_mode(instr3b->rs1), 0 - (instr3b->simm13 | 0xffffe000));
  1159. X                } else {
  1160. X                    sprintf(buf, store_r_i_plus, opcode_ptr, user_mode(instr3b->rd),
  1161. X                        user_mode(instr3b->rs1), instr3b->simm13);
  1162. X                }
  1163. X            } else {
  1164. X                if (asi) {
  1165. X                    sprintf(buf, store_r_r_a, opcode_ptr, user_mode(instr3a->rd),
  1166. X                        user_mode(instr3a->rs1), user_mode(instr3a->rs2), instr3a->asi);
  1167. X                } else {
  1168. X                    if (instr3a->rs2 == 0)
  1169. X                        sprintf(buf, store_r_g0, opcode_ptr, user_mode(instr3a->rd),
  1170. X                            user_mode(instr3a->rs1));
  1171. X                    else
  1172. X                        sprintf(buf, store_r_r, opcode_ptr, user_mode(instr3a->rd),
  1173. X                            user_mode(instr3a->rs1), user_mode(instr3a->rs2));
  1174. X                }
  1175. X            }
  1176. X        }
  1177. X        break;
  1178. X    default:
  1179. X        sprintf(buf, "bad opcode: \"%s\"", opcode_ptr);
  1180. X        break;
  1181. X    }
  1182. X
  1183. X    return;
  1184. X}
  1185. END_OF_FILE
  1186.   if test 3396 -ne `wc -c <'memory.c'`; then
  1187.     echo shar: \"'memory.c'\" unpacked with wrong size!
  1188.   fi
  1189.   # end of 'memory.c'
  1190. fi
  1191. if test -f 'printout.c' -a "${1}" != "-c" ; then 
  1192.   echo shar: Will not clobber existing file \"'printout.c'\"
  1193. else
  1194.   echo shar: Extracting \"'printout.c'\" \(5399 characters\)
  1195.   sed "s/^X//" >'printout.c' <<'END_OF_FILE'
  1196. X#include <stdio.h>
  1197. X#include <stdlib.h>
  1198. X#include <ctype.h>
  1199. X#include <string.h>
  1200. X
  1201. X
  1202. X/*
  1203. X * Functions dealing with output of data segment.
  1204. X *
  1205. X * finish_dumping(), dump_out(), line_break() are the only
  1206. X * externally callable functions.
  1207. X */
  1208. X
  1209. X/* internal use functions */
  1210. Xvoid printBuffer();
  1211. Xvoid addAByte();
  1212. Xvoid breakLine();
  1213. Xvoid setAddress();
  1214. X
  1215. X#define MIN_STRING_SIZE 7
  1216. X
  1217. Xvoid
  1218. Xdump_out(iChar, lAddr)
  1219. Xint iChar;
  1220. Xunsigned long lAddr;
  1221. X{
  1222. X    addAByte(iChar, lAddr);
  1223. X    return;
  1224. X}
  1225. X
  1226. Xvoid
  1227. Xfinish_dumping()
  1228. X{
  1229. X    printBuffer();
  1230. X}
  1231. X
  1232. Xvoid
  1233. Xline_break()
  1234. X{
  1235. X    printBuffer();
  1236. X    breakLine();
  1237. X}
  1238. X
  1239. Xchar bvBuffer[512];            /* buffer for composition of printable string */
  1240. Xunsigned long lLastAddress = 0;        /* data segment address of beginning of that string */
  1241. Xunsigned long lCurrentAddress = 0;    /* data segment address of byte being added */
  1242. Xchar *bpIntoBuffer = bvBuffer;        /* location of "end" of printable part of buffer */
  1243. Xint icInBuffer = 0;            /* "flatsize" of printable part of buffer */
  1244. X
  1245. Xint iAsciiCount = 0;            /* count of ASCII characters tenatively in a string */
  1246. Xint yInString = 0;            /* in a string or not? marker */
  1247. Xint ivTenativeString[MIN_STRING_SIZE];    /* values of bytes tenatively in printable string */
  1248. Xint ivStringSize[MIN_STRING_SIZE];    /* printable rep size of those bytes */
  1249. X
  1250. X/*
  1251. X * set _data_segment_address_ of beginning of the string
  1252. X * being formed in the buffer.
  1253. X */
  1254. Xvoid
  1255. XsetAddress(lBeginAddress)
  1256. Xunsigned long lBeginAddress;
  1257. X{
  1258. X    lCurrentAddress = lBeginAddress;
  1259. X    lLastAddress = lBeginAddress;
  1260. X    return;
  1261. X}
  1262. X
  1263. X/* a few special cases of "non-printing" ascii characters */
  1264. Xstatic char *bpvCharArray[] = { "\\0", NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
  1265. X    NULL, "\\t", "\\n", NULL, NULL, "\\r" };
  1266. X
  1267. X/* 
  1268. X * add this byte to end of current printable string
  1269. X */
  1270. Xvoid
  1271. XaddAByte(iChar, lAddr)
  1272. Xint iChar;
  1273. Xunsigned long lAddr;
  1274. X{
  1275. X    if (icInBuffer > 0) {
  1276. X        /* just tacking stuff on end of buffer */
  1277. X        ++lCurrentAddress;  /* change current address */
  1278. X        if (lAddr != lCurrentAddress)
  1279. X            fprintf(stderr, "Hoseup: byte should be at 0x%x, function called with 0x%x\n",
  1280. X                lCurrentAddress, lAddr);
  1281. X    } else {
  1282. X        /* first printable rep of bytes into buffer */
  1283. X        setAddress(lAddr);
  1284. X    }
  1285. X
  1286. X    /* small state machine. 2 states: "in string", "not in string", marked
  1287. X     * by yInString boolean.  Transitions occur on receipt of new byte whose
  1288. X     * printable representation is to be added to the buffer.
  1289. X     *
  1290. X     * Transition from "in string" to "not in string" occurs on receipt of
  1291. X     * non-ascii character, as defined by isascii().  If there are MIN_STRING_SIZE
  1292. X     * or more ascii chars in a row, a "string" has occurred, and gets printed out
  1293. X     * as such.  Otherwise, it backs up to beginning of what tenatively
  1294. X     * was considered a string, and replaces that printable rep with a hex
  1295. X     * digit rep.
  1296. X     *
  1297. X     * Transition from "not in string" to "in string" occurs on receipt of
  1298. X     * ascii character.
  1299. X     *
  1300. X     */
  1301. X    if (isascii(iChar)) {
  1302. X        if (!yInString) {
  1303. X            yInString = 1;
  1304. X            iAsciiCount = 0;
  1305. X        }
  1306. X        ivTenativeString[iAsciiCount % MIN_STRING_SIZE] = iChar;
  1307. X        if (iChar < ' ') {
  1308. X            /* handle some special case "ctrl" characters */
  1309. X            switch (iChar) {
  1310. X            case '\0':
  1311. X            case '\t':
  1312. X            case '\n':
  1313. X            case '\r':
  1314. X                strcpy(bpIntoBuffer, bpvCharArray[iChar]);
  1315. X                icInBuffer += 2;
  1316. X                bpIntoBuffer += 2;
  1317. X                ivStringSize[iAsciiCount % MIN_STRING_SIZE] = 2;
  1318. X                break;
  1319. X            default:
  1320. X                /* general case of a "ctrl" character */
  1321. X                sprintf(bpIntoBuffer, "\\%03o", iChar);
  1322. X                icInBuffer += 4;
  1323. X                bpIntoBuffer += 4;
  1324. X                ivStringSize[iAsciiCount % MIN_STRING_SIZE] = 4;
  1325. X                break;
  1326. X            }
  1327. X        } else {
  1328. X            /* general case printable char */
  1329. X            sprintf(bpIntoBuffer, "%c", iChar);
  1330. X            ++icInBuffer;
  1331. X            ++bpIntoBuffer;
  1332. X            ivStringSize[iAsciiCount % MIN_STRING_SIZE] = 1;
  1333. X        }
  1334. X        ++iAsciiCount;
  1335. X    } else {
  1336. X        /* not an ASCII character */
  1337. X        if (yInString) {
  1338. X            /* tenatively, we're in a string: check that */
  1339. X            if (iAsciiCount < MIN_STRING_SIZE) {
  1340. X                /* too few ascii chars in a row to be a real string.
  1341. X                 * back out the (tenative) printout, and replace. */
  1342. X                int icCnt, iPrintableLength = 0;;
  1343. X                
  1344. X                /* find printable length of last iAsciiCount bytes */
  1345. X                for (icCnt = 0; icCnt < iAsciiCount; ++icCnt)
  1346. X                    iPrintableLength += ivStringSize[icCnt];
  1347. X
  1348. X                /* back up pointer into buffer, flatsize of buffer */
  1349. X                bpIntoBuffer -= iPrintableLength;
  1350. X                icInBuffer   -= iPrintableLength;
  1351. X                /* copy last iAsciiCount bytes from tenative string into buffer */
  1352. X                for (icCnt = 0; icCnt < iAsciiCount; ++icCnt) {
  1353. X                    sprintf(bpIntoBuffer, "%02x ", ivTenativeString[icCnt]);
  1354. X                    icInBuffer += 3;
  1355. X                    bpIntoBuffer += 3;
  1356. X                }
  1357. X            } /* else, it was a string.  Leave it's printable rep in buffer. */
  1358. X            yInString = 0;
  1359. X            iAsciiCount = 0;
  1360. X        }
  1361. X        /* tack a printing representation of current byte onto end of buffer */
  1362. X        sprintf(bpIntoBuffer, "%02x ", iChar);
  1363. X        icInBuffer += 3;
  1364. X        bpIntoBuffer += 3;
  1365. X    }
  1366. X
  1367. X    /* check flatsize of buffer, print it if necessary */
  1368. X    if (icInBuffer >= 60) {
  1369. X        printBuffer();
  1370. X        breakLine();
  1371. X    }
  1372. X
  1373. X    return;
  1374. X}
  1375. X
  1376. Xvoid
  1377. XprintBuffer()
  1378. X{
  1379. X    int icOut;
  1380. X
  1381. X    if (icInBuffer == 0)
  1382. X        return;  /* no printable chars in buffer */
  1383. X
  1384. X    printf("0x%08x\t", lLastAddress);
  1385. X    for (icOut = 0; icOut < icInBuffer; ++icOut)
  1386. X        putc(bvBuffer[icOut], stdout);
  1387. X    putc('\n', stdout);
  1388. X}
  1389. X
  1390. Xvoid
  1391. XbreakLine()
  1392. X{
  1393. X    if (icInBuffer == 0)
  1394. X        return;  /* no printable chars in buffer */
  1395. X
  1396. X    /* reset static variables to "start of buffer" state */
  1397. X    icInBuffer = 0;
  1398. X    lLastAddress = lCurrentAddress;
  1399. X    bpIntoBuffer = bvBuffer;
  1400. X}
  1401. END_OF_FILE
  1402.   if test 5399 -ne `wc -c <'printout.c'`; then
  1403.     echo shar: \"'printout.c'\" unpacked with wrong size!
  1404.   fi
  1405.   # end of 'printout.c'
  1406. fi
  1407. if test -f 'relocation.c' -a "${1}" != "-c" ; then 
  1408.   echo shar: Will not clobber existing file \"'relocation.c'\"
  1409. else
  1410.   echo shar: Extracting \"'relocation.c'\" \(13113 characters\)
  1411.   sed "s/^X//" >'relocation.c' <<'END_OF_FILE'
  1412. X#include <stdio.h>
  1413. X#include <stdlib.h>
  1414. X#include <string.h>
  1415. X#ifdef sparc
  1416. X#include <a.out.h>
  1417. X#else
  1418. X#include "sparc_stuff.h"
  1419. X#endif
  1420. X#include <stab.h>
  1421. X#include <sys/types.h>
  1422. X#include "hash.h"
  1423. X
  1424. X/*
  1425. X * Functions dealing with lookup of addresses in relocation info
  1426. X * and in symbol table.
  1427. X */
  1428. X
  1429. X/* these two have to be global: persistent info */
  1430. Xchar                    *string_table = NULL;
  1431. Xstruct nlist            *symbol_table = NULL;
  1432. X
  1433. X/* pointers to hash tables for relocation info and symbol table.
  1434. X * hash tables will be full of pointers into tables above */
  1435. Xcaddr_t                 reloc_hash_table = NULL;    /* text and data */
  1436. Xcaddr_t                 symbol_hash_table = NULL;
  1437. X
  1438. X/*
  1439. X * function to allow ordering of pointers to "struct reloc_info_sparc" along
  1440. X * the hash chains.
  1441. X */
  1442. Xstatic int
  1443. Xreloc_address_compare(key, data)
  1444. Xcaddr_t  key, data;
  1445. X{
  1446. X    unsigned long   address = ((struct reloc_info_sparc *) key)->r_address;
  1447. X
  1448. X    if (address > ((struct reloc_info_sparc *) data)->r_address)
  1449. X        return 1;
  1450. X    if (address == ((struct reloc_info_sparc *) data)->r_address)
  1451. X        return 0;
  1452. X    if (address < ((struct reloc_info_sparc *) data)->r_address)
  1453. X        return -1;
  1454. X
  1455. X    return 0;
  1456. X}
  1457. X
  1458. X/* function to get the "hash value" of a "struct reloc_info_sparc" */
  1459. Xstatic u_int
  1460. Xreloc_address_compress(key)
  1461. Xcaddr_t key;
  1462. X{
  1463. X    return ((struct reloc_info_sparc *) key)->r_address;
  1464. X}
  1465. X
  1466. X/* function to allocate another "struct reloc_info_sparc" */
  1467. Xstatic caddr_t
  1468. Xreloc_address_allocate(p)
  1469. Xcaddr_t p;
  1470. X{
  1471. X    struct reloc_info_sparc *tmp
  1472. X    = (struct reloc_info_sparc *) malloc(sizeof(struct reloc_info_sparc));
  1473. X
  1474. X    if (tmp != NULL)
  1475. X        bcopy(p, (caddr_t) tmp, sizeof(struct reloc_info_sparc));
  1476. X
  1477. X    return (caddr_t) tmp;
  1478. X}
  1479. X
  1480. Xstatic int
  1481. Xsymbol_address_compare(key, data)
  1482. Xcaddr_t key, data;
  1483. X{
  1484. X    unsigned long   address = ((struct nlist *) key)->n_value;
  1485. X
  1486. X    if (address > ((struct nlist *) data)->n_value)
  1487. X        return 1;
  1488. X    if (address == ((struct nlist *) data)->n_value)
  1489. X        return 0;
  1490. X    if (address < ((struct nlist *) data)->n_value)
  1491. X        return -1;
  1492. X
  1493. X    return 0;
  1494. X}
  1495. X
  1496. Xstatic u_int
  1497. Xsymbol_address_compress(key)
  1498. Xcaddr_t key;
  1499. X{
  1500. X    return ((struct nlist *) key)->n_value;
  1501. X}
  1502. X
  1503. Xstatic caddr_t
  1504. Xsymbol_address_allocate(p)
  1505. Xcaddr_t p;
  1506. X{
  1507. X    struct nlist   *tmp
  1508. X    = (struct nlist *) malloc(sizeof(struct nlist));
  1509. X
  1510. X    if (tmp != NULL)
  1511. X        bcopy(p, (caddr_t) tmp, sizeof(struct nlist));
  1512. X
  1513. X    return (caddr_t) tmp;
  1514. X}
  1515. X
  1516. X/*
  1517. X * initialize hash table containing text and data
  1518. X * relocation info items.
  1519. X */
  1520. Xint
  1521. Xinitialize_relocation(exhdr_p, fp)
  1522. X    struct exec    *exhdr_p;
  1523. X    FILE           *fp;
  1524. X{
  1525. X    int             string_table_size, total_relocations;
  1526. X    struct reloc_info_sparc *text_reloc_table;
  1527. X    struct reloc_info_sparc *data_reloc_table;
  1528. X
  1529. X    void            initialize_text_reloc(), initialize_data_reloc();
  1530. X    void            initialize_sym_table(), initialize_string_table();
  1531. X    void            initialize_reloc();
  1532. X
  1533. X    if (exhdr_p == NULL) {
  1534. X        /* read in exec header */
  1535. X        if ((exhdr_p = (struct exec *) malloc(sizeof(struct exec))) == NULL)
  1536. X            return 0;;
  1537. X        if (fread((char *) exhdr_p, sizeof(struct exec), 1, fp) == NULL) {
  1538. X            return 0;    /* can't do anything from here */
  1539. X        }
  1540. X    }
  1541. X    total_relocations = (exhdr_p->a_trsize + exhdr_p->a_drsize)/sizeof(struct reloc_info_sparc);
  1542. X    if (total_relocations > 0) {
  1543. X        /* text segment relocations */
  1544. X        if (exhdr_p->a_trsize > 0) {
  1545. X            if (fseek(fp, (long)(N_TRELOFF(*exhdr_p)), 0) < 0) {
  1546. X                fprintf(stderr, "goofed fseek() to text relocation info\n");
  1547. X                text_reloc_table = NULL;
  1548. X            } else
  1549. X                initialize_reloc(fp, &text_reloc_table, 0, exhdr_p->a_trsize, total_relocations);
  1550. X        }
  1551. X        /* data segment relocations */
  1552. X        if (exhdr_p->a_drsize > 0) {
  1553. X            if (fseek(fp, N_DRELOFF(*exhdr_p), 0) < 0) {
  1554. X                fprintf(stderr, "goofed fseek() to data relocation info\n");
  1555. X                data_reloc_table = NULL;
  1556. X            } else
  1557. X                initialize_reloc(fp, &data_reloc_table, N_DATADDR(*exhdr_p),
  1558. X                    exhdr_p->a_drsize, total_relocations);
  1559. X        }
  1560. X    }
  1561. X    /* symbol table */
  1562. X    if (exhdr_p->a_syms > 0) {
  1563. X        if (fseek(fp, (long)(N_SYMOFF(*exhdr_p)), 0) < 0) {
  1564. X            fprintf(stderr, "goofed fseek() to symbol table\n");
  1565. X        } else
  1566. X            initialize_sym_table(exhdr_p, fp);
  1567. X    }
  1568. X    /* string table */
  1569. X    if (fseek(fp, (long)(N_STROFF(*exhdr_p)), 0) < 0) {
  1570. X        fprintf(stderr, "screwed up fseek to string table\n");
  1571. X        return 0;
  1572. X    }
  1573. X    if (fread((char *) &string_table_size, sizeof(int), 1, fp) != 1) {
  1574. X        fprintf(stderr, "honked up fread() of string table size\n");
  1575. X        return 0;
  1576. X    }
  1577. X    if (string_table_size > 4)
  1578. X        initialize_string_table(fp, string_table_size);
  1579. X
  1580. X    return 1;
  1581. X}
  1582. X
  1583. X/*
  1584. X * read string table into memory.
  1585. X * calling routine fseek()s to string table
  1586. X * before this is called.
  1587. X */
  1588. Xvoid
  1589. Xinitialize_string_table(psInputFile, iTableSize)
  1590. X    FILE    *psInputFile;
  1591. X    int      iTableSize;
  1592. X{
  1593. X    /* file pointer is right at string table */
  1594. X
  1595. X    if ((string_table = malloc((unsigned) (iTableSize - 4))) == NULL) {
  1596. X        fprintf(stderr, "crapped out on malloc() of string table\n");
  1597. X    } else if (fread(string_table, 1, iTableSize - 4, psInputFile)
  1598. X           != iTableSize - 4) {
  1599. X        fprintf(stderr, "fucked up fread() of string table\n");
  1600. X    }
  1601. X}
  1602. X
  1603. X/*
  1604. X * read relocation info into memory.
  1605. X * put pointers to text reloc info into reloc info hash table.
  1606. X */
  1607. Xvoid
  1608. Xinitialize_reloc(psInputFile, sppTablePointer, iOffset, iTableSize, iTotalRelocations)
  1609. X    FILE                     *psInputFile;
  1610. X    struct reloc_info_sparc **sppTablePointer;
  1611. X    int                       iTotalRelocations;
  1612. X    unsigned long             iTableSize, iOffset;
  1613. X{
  1614. X    int             inRelocations;
  1615. X
  1616. X    inRelocations = iTableSize / sizeof(struct reloc_info_sparc);
  1617. X
  1618. X    fprintf(stderr, "%d relocations\n", inRelocations);
  1619. X    if (inRelocations) {
  1620. X        /* fseek() to text relocation in file */
  1621. X        if ((*sppTablePointer = (struct reloc_info_sparc *)malloc((unsigned) iTableSize)) == NULL) {
  1622. X            /* allocation failed */
  1623. X            fprintf(stderr, "screwed up malloc() of some relocation info\n");
  1624. X        } else if (fread((char *)*sppTablePointer, sizeof(struct reloc_info_sparc),
  1625. X             inRelocations, psInputFile) != inRelocations) {
  1626. X            /* fread failed */
  1627. X            fprintf(stderr, "fread() of relocation done wrong\n");
  1628. X        } else {
  1629. X            if (!reloc_hash_table) {
  1630. X                /* initialize relocation info hash table */
  1631. X                reloc_hash_table = h_new(HASH_POLICY_CHAIN, HASH_TYPE_DIVISION,
  1632. X                  iTotalRelocations > 2 ? iTotalRelocations / 2 : 2,
  1633. X                  reloc_address_compare, reloc_address_allocate,
  1634. X                  reloc_address_compress, NULL, NULL, NULL);
  1635. X            }
  1636. X            if (reloc_hash_table == NULL) {
  1637. X                fprintf(stderr,
  1638. X                    "screwed up allocating relocation table hash table: %d relocations\n",
  1639. X                    iTotalRelocations);
  1640. X            } else {
  1641. X                /* put relocation info into hash table */
  1642. X                int             i;
  1643. X                for (i = 0; i < inRelocations; ++i) {
  1644. X                    (*sppTablePointer)[i].r_address += iOffset;
  1645. X                    if (h_insert(reloc_hash_table, &((*sppTablePointer)[i])) == NULL) {
  1646. X                        fprintf(stderr,
  1647. X                            "botched adding reloc entry %d to hash table (h_insert)\n", i);
  1648. X                    }
  1649. X                }
  1650. X            }
  1651. X            free((char *)*sppTablePointer);
  1652. X        }
  1653. X    }
  1654. X}
  1655. X
  1656. Xvoid
  1657. Xinitialize_sym_table(exhdr_p, fp)
  1658. X    struct exec    *exhdr_p;
  1659. X    FILE           *fp;
  1660. X{
  1661. X    int             sym_number, i;
  1662. X
  1663. X    /* do up symbol table */
  1664. X    if ((symbol_table = (struct nlist *) malloc((unsigned) exhdr_p->a_syms))
  1665. X        == NULL) {
  1666. X        fprintf(stderr, "hosed malloc() on symbol table\n");
  1667. X        return;
  1668. X    }
  1669. X    sym_number = exhdr_p->a_syms / sizeof(struct nlist);
  1670. X    if (fread((char *) symbol_table, sizeof(struct nlist),
  1671. X          sym_number, fp) != sym_number) {
  1672. X        fprintf(stderr, "noinkered fread() of symbol table\n");
  1673. X        return;
  1674. X    }
  1675. X    if (sym_number > 0) {
  1676. X        /* initialize relocation info hash table */
  1677. X        symbol_hash_table = h_new(HASH_POLICY_CHAIN, HASH_TYPE_DIVISION,
  1678. X                    sym_number > 2 ? sym_number / 2 : 2,
  1679. X                symbol_address_compare, symbol_address_allocate,
  1680. X                 symbol_address_compress, NULL, NULL, NULL);
  1681. X
  1682. X        if (symbol_hash_table == NULL)
  1683. X            fprintf(stderr, "screwed up allocating symbol table hash table\n");
  1684. X
  1685. X        else {
  1686. X            /* put symbol table info into hash table */
  1687. X            for (i = 0; i < sym_number; ++i) {
  1688. X                if (h_insert(symbol_hash_table, &(symbol_table[i])) == NULL) {
  1689. X                    fprintf(stderr,
  1690. X                        "botched adding symbol table entry %d to hash table (h_insert)\n", i);
  1691. X                    return;
  1692. X                }
  1693. X            }
  1694. X        }
  1695. X    } else {
  1696. X        if (symbol_hash_table) {
  1697. X            free(symbol_hash_table);
  1698. X            symbol_hash_table = NULL;
  1699. X        }
  1700. X    }
  1701. X}
  1702. X/*
  1703. X * look in relocation info hashtable to find
  1704. X * out if there's a relocation to be done at this address.
  1705. X */
  1706. Xstatic struct reloc_info_sparc *
  1707. Xfind_entry_at_addrs(addr)
  1708. Xunsigned long addr;
  1709. X{
  1710. X    struct reloc_info_sparc *ret, tmp;
  1711. X
  1712. X    tmp.r_address = addr;
  1713. X
  1714. X    if ((ret = (struct reloc_info_sparc *) h_member(reloc_hash_table,
  1715. X                          (caddr_t) & tmp)) != NULL)
  1716. X        return ret;
  1717. X
  1718. X    return NULL;
  1719. X}
  1720. X
  1721. Xstatic struct nlist *
  1722. Xfind_symbol_at_addrs(addr)
  1723. Xunsigned long addr;
  1724. X{
  1725. X    struct nlist   *ret, tmp;
  1726. X
  1727. X    bzero((char *)&tmp, sizeof(struct nlist));
  1728. X    tmp.n_value = addr;
  1729. X
  1730. X    if ((ret = (struct nlist *) h_member(symbol_hash_table,
  1731. X                         (caddr_t) & tmp)) != NULL)
  1732. X        return ret;
  1733. X    return NULL;
  1734. X}
  1735. X
  1736. Xstatic char *segment[9] = {
  1737. X"undef", "", "abs", "", "text", "", "data", "", "bss"};
  1738. X
  1739. Xchar *
  1740. Xname_of_reloc(entry, buffer)
  1741. Xstruct reloc_info_sparc *entry;
  1742. Xchar                    *buffer;
  1743. X{
  1744. X    int str_table_index;
  1745. X
  1746. X    if (entry == NULL)
  1747. X        return NULL;
  1748. X
  1749. X    str_table_index = symbol_table[entry->r_index].n_un.n_strx;
  1750. X    if (entry->r_extern) {
  1751. X        sprintf(buffer, "external relocation: %s", &(string_table[str_table_index - 4]));
  1752. X    } else {
  1753. X        struct nlist   *symb = find_symbol_at_addrs((unsigned long)entry->r_addend);
  1754. X        if (symb) {
  1755. X            sprintf(buffer, "relocation of 0x%x in %s segment: %s",
  1756. X                entry->r_addend, segment[entry->r_index & 0xf],
  1757. X                symb->n_un.n_strx ? &(string_table[symb->n_un.n_strx - 4]) : "no name"
  1758. X            );
  1759. X        } else {
  1760. X            sprintf(buffer, "relocation of 0x%x in %s segment",
  1761. X                entry->r_addend, segment[entry->r_index & 0xf]);
  1762. X        }
  1763. X    }
  1764. X    return buffer;
  1765. X}
  1766. X
  1767. Xstatic char *
  1768. Xname_of_symbol(entry, buffer)
  1769. Xstruct nlist   *entry;
  1770. Xchar           *buffer;
  1771. X{
  1772. X    int str_table_index;
  1773. X
  1774. X    if (entry == NULL)
  1775. X        return NULL;
  1776. X
  1777. X    str_table_index = entry->n_un.n_strx;
  1778. X    if (str_table_index > 0)
  1779. X        strcpy(buffer, &(string_table[str_table_index - 4]));
  1780. X    else {
  1781. X        /* what the hell goes here? */
  1782. X    }
  1783. X    return buffer;
  1784. X}
  1785. X
  1786. Xchar *
  1787. Xname_at_address(addr, buffer)
  1788. Xunsigned long   addr;
  1789. Xchar           *buffer;
  1790. X{
  1791. X    struct reloc_info_sparc *entry = find_entry_at_addrs(addr);
  1792. X    struct nlist   *symb;
  1793. X
  1794. X    if (entry)
  1795. X        return name_of_reloc(entry, buffer);    /* found in relocation info */
  1796. X
  1797. X    symb = find_symbol_at_addrs(addr);
  1798. X    if (symb)
  1799. X        return name_of_symbol(symb, buffer);    /* found in symbol table */
  1800. X    return NULL;
  1801. X}
  1802. X
  1803. Xchar *
  1804. Xname_at_destination(addr, buffer)
  1805. Xunsigned long   addr;
  1806. Xchar           *buffer;
  1807. X{
  1808. X    struct reloc_info_sparc *entry = find_entry_at_addrs(addr);
  1809. X    struct nlist   *symb = NULL;
  1810. X
  1811. X    /* try to get a symbol table entry */
  1812. X    if (entry) {
  1813. X        if (entry->r_index > 0)
  1814. X            symb = (&symbol_table[entry->r_index]);
  1815. X        /* else, r_index is segment number (???) */
  1816. X    } else {
  1817. X        symb = find_symbol_at_addrs(addr);
  1818. X    }
  1819. X
  1820. X    /* decide if this is a good symbol table entry */
  1821. X    if (symb) {
  1822. X        if (symb->n_type & N_EXT)
  1823. X            return name_of_symbol(symb, buffer);    /* found in symbol table */
  1824. X
  1825. X        /* is a switch or an if with a complicated condition better? */
  1826. X        switch ((symb->n_type & N_STAB) & (~N_EXT)) {
  1827. X        case N_FNAME:
  1828. X        case N_FUN:
  1829. X        case N_GSYM:
  1830. X        case N_ENTRY:
  1831. X            return name_of_symbol(symb, buffer);    /* found in symbol table */
  1832. X        }
  1833. X    }
  1834. X    buffer[0] = '\0';
  1835. X    return NULL;
  1836. X}
  1837. X
  1838. X#ifdef RELOCATIONS
  1839. X/* print out relocation type per /usr/include/machine/a.out.h */
  1840. Xstatic char *
  1841. Xprint_reloc(type)
  1842. Xenum reloc_type type;
  1843. X{
  1844. X    char *retptr = NULL;
  1845. X    if (type == RELOC_8) {
  1846. X        retptr = "8 bit simple\n" ;
  1847. X    } else if (type == RELOC_16) {
  1848. X        retptr = "16 bit simple\n";
  1849. X    } else if (type == RELOC_32) {
  1850. X        retptr = "32 bit simple\n";
  1851. X    } else if (type == RELOC_DISP8) {
  1852. X        retptr = "8 bit PC relative\n";
  1853. X    } else if (type == RELOC_DISP16) {
  1854. X        retptr = "16 bit PC relative\n";
  1855. X    } else if (type == RELOC_DISP32) {
  1856. X        retptr = "32 bit PC relative\n";
  1857. X    } else if (type == RELOC_WDISP30) {
  1858. X        retptr = "30 bit PC relative CALL\n";
  1859. X    } else if (type == RELOC_WDISP22) {
  1860. X        retptr = "22 bit PC relative BRANCH\n";
  1861. X    } else if (type == RELOC_HI22) {
  1862. X        retptr = "RELOC_HI22\n";
  1863. X    } else if (type == RELOC_22) {
  1864. X        retptr = "RELOC_22\n";
  1865. X    } else if (type == RELOC_13) {
  1866. X        retptr = "RELOC_13\n";
  1867. X    } else if (type == RELOC_LO10) {
  1868. X        retptr = "RELOC_LO10\n";
  1869. X    } else if (type == RELOC_SFA_BASE) {
  1870. X        retptr = "RELOC_SFA_BASE\n";
  1871. X    } else if (type == RELOC_SFA_OFF13) {
  1872. X        retptr = "RELOC_SFA_OFF13\n";
  1873. X    } else if (type == RELOC_BASE10) {
  1874. X        retptr = "RELOC_BASE10\n";
  1875. X    } else if (type == RELOC_BASE13) {
  1876. X        retptr = "RELOC_BASE13\n";
  1877. X    } else if (type == RELOC_BASE22) {
  1878. X        retptr = "RELOC_BASE22\n";
  1879. X    } else if (type == RELOC_PC10) {
  1880. X        retptr = "10 bit PC relative PIC\n";
  1881. X    } else if (type == RELOC_PC22) {
  1882. X        retptr = "22 bit PC relative PIC\n";
  1883. X    } else if (type == RELOC_JMP_TBL) {
  1884. X        retptr = "jump table relative PIC\n";
  1885. X    } else if (type == RELOC_SEGOFF16) {
  1886. X        retptr = "ShLib offset-in-seg\n";
  1887. X    } else if (type == RELOC_GLOB_DAT) {
  1888. X        retptr = "rtld global data\n";
  1889. X    } else if (type == RELOC_JMP_SLOT) {
  1890. X        retptr = "rtld jump slot\n";
  1891. X    } else if (type == RELOC_RELATIVE) {
  1892. X        retptr = "rtld relative\n";
  1893. X    } else {
  1894. X        retptr = "some unknown reloc type...\n";
  1895. X    }
  1896. X
  1897. X    return retptr;
  1898. X}
  1899. X#endif
  1900. END_OF_FILE
  1901.   if test 13113 -ne `wc -c <'relocation.c'`; then
  1902.     echo shar: \"'relocation.c'\" unpacked with wrong size!
  1903.   fi
  1904.   # end of 'relocation.c'
  1905. fi
  1906. if test -f 'sparc_stuff.h' -a "${1}" != "-c" ; then 
  1907.   echo shar: Will not clobber existing file \"'sparc_stuff.h'\"
  1908. else
  1909.   echo shar: Extracting \"'sparc_stuff.h'\" \(2818 characters\)
  1910.   sed "s/^X//" >'sparc_stuff.h' <<'END_OF_FILE'
  1911. X#ifndef SPARC_STUFF_H
  1912. X#define SPARC_STUFF_H
  1913. X
  1914. Xstruct exec {
  1915. X    unsigned char    a_dynamic:1;
  1916. X    unsigned char    a_toolversion:7;
  1917. X    unsigned char    a_machtype;    
  1918. X    unsigned short    a_magic;
  1919. X    unsigned long    a_text;
  1920. X    unsigned long    a_data;
  1921. X    unsigned long    a_bss;
  1922. X    unsigned long    a_syms;
  1923. X    unsigned long    a_entry;
  1924. X    unsigned long    a_trsize;
  1925. X    unsigned long    a_drsize;
  1926. X};
  1927. X
  1928. X#define    OMAGIC    0407
  1929. X#define    NMAGIC    0410
  1930. X#define    ZMAGIC    0413
  1931. X
  1932. X#define M_OLDSUN2    0
  1933. X#define M_68010        1
  1934. X#define M_68020        2
  1935. X#define M_SPARC        3
  1936. X
  1937. X#define TV_SUN2_SUN3    0
  1938. X#define TV_SUN4        1
  1939. X
  1940. X#define PAGSIZ        0x02000
  1941. X#define SEGSIZ        PAGSIZ
  1942. X#define    OLD_PAGSIZ    0x00800
  1943. X#define    OLD_SEGSIZ    0x08000
  1944. X
  1945. X#define    N_BADMAG(x) \
  1946. X    ((x).a_magic!=OMAGIC && (x).a_magic!=NMAGIC && (x).a_magic!=ZMAGIC)
  1947. X
  1948. X#define    N_PAGSIZ(x) \
  1949. X    ((x).a_machtype == M_OLDSUN2? OLD_PAGSIZ : PAGSIZ)
  1950. X#define    N_SEGSIZ(x) \
  1951. X    ((x).a_machtype == M_OLDSUN2? OLD_SEGSIZ : SEGSIZ)
  1952. X
  1953. X#define    N_TXTOFF(x) \
  1954. X    /* text segment */ \
  1955. X    ( (x).a_machtype == M_OLDSUN2 \
  1956. X    ? ((x).a_magic==ZMAGIC ? N_PAGSIZ(x) : sizeof (struct exec)) \
  1957. X    : ((x).a_magic==ZMAGIC ? 0 : sizeof (struct exec)) )
  1958. X
  1959. X#define    N_DATOFF(x)   \
  1960. X    (N_TXTOFF(x) + (x).a_text)
  1961. X
  1962. X#define    N_TRELOFF(x)  \
  1963. X    (N_DATOFF(x) + (x).a_data)
  1964. X
  1965. X#define    N_DRELOFF(x) \
  1966. X    (N_TRELOFF(x) + (x).a_trsize)
  1967. X
  1968. X#define    N_SYMOFF(x) \
  1969. X     \
  1970. X    (N_TXTOFF(x)+(x).a_text+(x).a_data+(x).a_trsize+(x).a_drsize)
  1971. X
  1972. X#define    N_STROFF(x) \
  1973. X     \
  1974. X    (N_SYMOFF(x) + (x).a_syms)
  1975. X
  1976. X#define    _N_BASEADDR(x) \
  1977. X    (((x).a_magic == ZMAGIC) && ((x).a_entry < N_PAGSIZ(x)) ? \
  1978. X        0 : N_PAGSIZ(x))
  1979. X
  1980. X#define N_TXTADDR(x) \
  1981. X    ((x).a_machtype == M_OLDSUN2 ? N_SEGSIZ(x) : _N_BASEADDR(x))
  1982. X
  1983. X#define N_DATADDR(x) \
  1984. X    (((x).a_magic==OMAGIC)? (N_TXTADDR(x)+(x).a_text) \
  1985. X    : (N_SEGSIZ(x)+((N_TXTADDR(x)+(x).a_text-1) & ~(N_SEGSIZ(x)-1))))
  1986. X
  1987. X#define N_BSSADDR(x)  (N_DATADDR(x)+(x).a_data)
  1988. X
  1989. Xenum reloc_type
  1990. X{
  1991. X    RELOC_8,    RELOC_16,    RELOC_32,
  1992. X    RELOC_DISP8,    RELOC_DISP16,    RELOC_DISP32,
  1993. X    RELOC_WDISP30,    RELOC_WDISP22,
  1994. X    RELOC_HI22,    RELOC_22,
  1995. X    RELOC_13,    RELOC_LO10,
  1996. X    RELOC_SFA_BASE,    RELOC_SFA_OFF13,
  1997. X    RELOC_BASE10,    RELOC_BASE13,    RELOC_BASE22,
  1998. X    RELOC_PC10,    RELOC_PC22,
  1999. X    RELOC_JMP_TBL,
  2000. X    RELOC_SEGOFF16,
  2001. X    RELOC_GLOB_DAT, RELOC_JMP_SLOT, RELOC_RELATIVE,
  2002. X};
  2003. X
  2004. Xstruct reloc_info_sparc
  2005. X{
  2006. X    unsigned long int r_address;
  2007. X    unsigned int    r_index   :24;
  2008. X    unsigned int    r_extern  : 1;
  2009. X    int              : 2;
  2010. X    enum reloc_type r_type    : 5;
  2011. X    long int    r_addend;
  2012. X};
  2013. X
  2014. X
  2015. X
  2016. Xstruct    nlist {
  2017. X    union {
  2018. X        char    *n_name;
  2019. X        long    n_strx;
  2020. X    } n_un;
  2021. X    unsigned char    n_type;
  2022. X    char    n_other;
  2023. X    short    n_desc;
  2024. X    unsigned long    n_value;
  2025. X};
  2026. X
  2027. X#define    N_UNDF    0x0
  2028. X#define    N_ABS    0x2
  2029. X#define    N_TEXT    0x4
  2030. X#define    N_DATA    0x6
  2031. X#define    N_BSS    0x8
  2032. X#define    N_COMM    0x12
  2033. X#define    N_FN    0x1e
  2034. X
  2035. X#define    N_EXT    01
  2036. X#define    N_TYPE    0x1e
  2037. X
  2038. X#define    N_STAB    0xe0
  2039. X
  2040. X#define    N_FORMAT    "%08x"
  2041. X
  2042. X#define EXTRA_MAGIC     1040
  2043. X#define EXTRA_IDENT     0
  2044. X
  2045. Xstruct extra_sections {
  2046. X           int     extra_magic;
  2047. X           int     extra_nsects;
  2048. X};
  2049. X
  2050. X#endif SPARC_STUFF_H
  2051. END_OF_FILE
  2052.   if test 2818 -ne `wc -c <'sparc_stuff.h'`; then
  2053.     echo shar: \"'sparc_stuff.h'\" unpacked with wrong size!
  2054.   fi
  2055.   # end of 'sparc_stuff.h'
  2056. fi
  2057. echo shar: End of archive 2 \(of 3\).
  2058. cp /dev/null ark2isdone
  2059. MISSING=""
  2060. for I in 1 2 3 ; do
  2061.     if test ! -f ark${I}isdone ; then
  2062.     MISSING="${MISSING} ${I}"
  2063.     fi
  2064. done
  2065. if test "${MISSING}" = "" ; then
  2066.     echo You have unpacked all 3 archives.
  2067.     rm -f ark[1-9]isdone
  2068. else
  2069.     echo You still must unpack the following archives:
  2070.     echo "        " ${MISSING}
  2071. fi
  2072. exit 0
  2073. exit 0 # Just in case...
  2074.