rd.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. /* $Id$ */
  2. /* a.out file reading ... */
  3. #include "rd.h"
  4. #include "misc.h"
  5. #include <assert.h>
  6. #include <alloc.h>
  7. #if defined(__sun)
  8. #if ! defined(sun)
  9. #define sun
  10. #endif
  11. #endif
  12. #if defined(__i386)
  13. #define i386
  14. #endif
  15. #if defined(__mc68020)
  16. #define mc68020
  17. #endif
  18. #if defined(__sparc)
  19. #if ! defined(sparc)
  20. #define sparc
  21. #endif
  22. #endif
  23. #if defined(__vax)
  24. #define vax
  25. #endif
  26. #if defined(__solaris) || defined(__solaris__)
  27. #define solaris
  28. #endif
  29. #if ! defined(solaris)
  30. #if defined(sun) || defined(vax)
  31. struct exec {
  32. #ifdef sun
  33. short a_x;
  34. unsigned short a_magic;
  35. #else
  36. unsigned long a_magic;
  37. #endif
  38. unsigned long a_text;
  39. unsigned long a_data;
  40. unsigned long a_bss;
  41. unsigned long a_syms;
  42. unsigned long a_entry;
  43. unsigned long a_trsize;
  44. unsigned long a_drsize;
  45. };
  46. #define OMAGIC 0407
  47. #define NMAGIC 0410
  48. #define ZMAGIC 0413
  49. #define N_BADMAG(x) \
  50. ((x).a_magic!=OMAGIC && (x).a_magic!=NMAGIC && (x).a_magic!=ZMAGIC)
  51. #ifdef sun
  52. #define N_TXTOFF(x) ((x).a_magic == ZMAGIC ? 0 : sizeof(struct exec))
  53. #else
  54. #define N_TXTOFF(x) (sizeof(struct exec))
  55. #endif
  56. #define N_STROFF(x) (N_TXTOFF(x)+(x).a_text+(x).a_data+(x).a_trsize+(x).a_drsize+(x).a_syms)
  57. #ifdef sparc
  58. #define RELOC_SIZE 12
  59. #else
  60. #define RELOC_SIZE 8
  61. #endif
  62. struct nlist {
  63. union {
  64. char *n_name;
  65. long n_strx;
  66. } n_un;
  67. unsigned char n_type;
  68. char n_other;
  69. short n_desc;
  70. unsigned long n_value;
  71. };
  72. #define N_UNDF 0
  73. #define N_ABS 2
  74. #define N_TEXT 4
  75. #define N_DATA 6
  76. #define N_BSS 8
  77. #define N_FN 0x1e
  78. #define N_EXT 01
  79. #define N_STAB 0xe0
  80. #include <stdio.h>
  81. static FILE *inf;
  82. static struct exec bh;
  83. static long seg_strings;
  84. static struct outhead hh;
  85. #define readf(a, b, c) (fread((char *)(a), (b), (int)(c), inf))
  86. int
  87. rd_open(f)
  88. char *f;
  89. {
  90. if ((inf = fopen(f, "r")) == NULL) return 0;
  91. return 1;
  92. }
  93. rd_ohead(h)
  94. struct outhead *h;
  95. {
  96. if (! readf(&bh, sizeof(struct exec), 1)) rd_fatal();
  97. if (N_BADMAG(bh)) rd_fatal();
  98. h->oh_magic = O_CONVERTED;
  99. h->oh_stamp = 0;
  100. h->oh_nsect = 4;
  101. h->oh_nname = 3 + bh.a_syms / sizeof(struct nlist);
  102. h->oh_nrelo = (bh.a_trsize + bh.a_drsize) / RELOC_SIZE;
  103. h->oh_flags = h->oh_nrelo ? HF_LINK : 0;
  104. #if defined(sun)
  105. if (bh.a_magic == ZMAGIC) bh.a_text -= sizeof(struct exec);
  106. #endif
  107. h->oh_nemit = bh.a_text + bh.a_data;
  108. #if defined(sun)
  109. if (bh.a_magic == ZMAGIC) bh.a_text += sizeof(struct exec);
  110. #endif
  111. fseek(inf, N_STROFF(bh), 0);
  112. h->oh_nchar = getw(inf) + 6 + 6 + 5 - 4; /* ".text", ".data", ".bss",
  113. minus the size word */
  114. seg_strings = h->oh_nchar - 17;
  115. fseek(inf, N_TXTOFF(bh)+bh.a_text+bh.a_data, 0);
  116. hh = *h;
  117. #if defined(sun)
  118. if (bh.a_magic == ZMAGIC) bh.a_text -= sizeof(struct exec);
  119. #endif
  120. }
  121. /*ARGSUSED1*/
  122. rd_name(names, count)
  123. register struct outname *names;
  124. unsigned int count; /* ignored; complete namelist is read */
  125. {
  126. names->on_valu = 0; names->on_foff = seg_strings + OFF_CHAR(hh);
  127. names->on_desc = 0; names->on_type = S_MIN | S_SCT;
  128. names++;
  129. names->on_valu = 0; names->on_foff = seg_strings + OFF_CHAR(hh) + 6;
  130. names->on_desc = 0; names->on_type = (S_MIN+2) | S_SCT;
  131. names++;
  132. names->on_valu = 0; names->on_foff = seg_strings + OFF_CHAR(hh) + 12;
  133. names->on_desc = 0; names->on_type = (S_MIN+3) | S_SCT;
  134. names++;
  135. count = bh.a_syms / sizeof(struct nlist);
  136. while (count > 0) {
  137. struct nlist n;
  138. if (! readf(&n, sizeof(struct nlist), 1)) rd_fatal();
  139. count--;
  140. names->on_desc = n.n_desc;
  141. if (n.n_un.n_strx - 4 < 0) names->on_foff = 0;
  142. else names->on_foff = OFF_CHAR(hh) - 4 + n.n_un.n_strx;
  143. names->on_valu = n.n_value;
  144. if (n.n_type & N_STAB) {
  145. names->on_type = n.n_type << 8;
  146. names++;
  147. continue;
  148. }
  149. switch(n.n_type & ~N_EXT) {
  150. case N_ABS:
  151. names->on_type = S_ABS;
  152. break;
  153. case N_TEXT:
  154. names->on_type = S_MIN;
  155. break;
  156. case N_DATA:
  157. names->on_type = S_MIN + 2;
  158. names->on_valu -= bh.a_text;
  159. break;
  160. case N_BSS:
  161. names->on_type = S_MIN + 3;
  162. names->on_valu -= bh.a_text + bh.a_data;
  163. break;
  164. case N_UNDF:
  165. if (! names->on_valu) {
  166. names->on_type = S_UND;
  167. break;
  168. }
  169. names->on_type = (S_MIN + 3) | S_COM;
  170. break;
  171. case N_FN:
  172. names->on_type = S_FIL;
  173. break;
  174. default:
  175. rd_fatal();
  176. }
  177. if (n.n_type & N_EXT) names->on_type |= S_EXT;
  178. names++;
  179. }
  180. }
  181. extern char *strcpy();
  182. rd_string(strings, count)
  183. register char *strings;
  184. long count;
  185. {
  186. #if defined(sun)
  187. if (bh.a_magic == ZMAGIC) bh.a_text += sizeof(struct exec);
  188. #endif
  189. fseek(inf, N_STROFF(bh)+4, 0);
  190. if (! readf(strings, (int)count-17, 1)) rd_fatal();
  191. strings += count-17;
  192. strcpy(strings, ".text"); strings += 6;
  193. strcpy(strings, ".data"); strings += 6;
  194. strcpy(strings, ".bss");
  195. }
  196. rd_close()
  197. {
  198. fclose(inf);
  199. }
  200. #endif
  201. #endif
  202. #if defined(i386)
  203. #include <stdio.h>
  204. #include <alloc.h>
  205. struct xexec {
  206. unsigned short x_magic;
  207. #define XMAGIC 01006
  208. unsigned short x_ext;
  209. long x_text;
  210. long x_data;
  211. long x_bss;
  212. long x_syms;
  213. long x_reloc;
  214. long x_entry;
  215. char x_cpu;
  216. char x_relsym;
  217. unsigned short x_renv;
  218. };
  219. struct xseg {
  220. unsigned short xs_type;
  221. unsigned short xs_attr;
  222. unsigned short xs_seg;
  223. unsigned short xs_sres;
  224. long xs_filpos;
  225. long xs_psize;
  226. long xs_vsize;
  227. long xs_rbase;
  228. long xs_lres;
  229. long xs_lres2;
  230. };
  231. static FILE *inf;
  232. static struct outname *names;
  233. static char *strings;
  234. #define readf(a, b, c) (fread((char *)(a), (b), (int)(c), inf))
  235. #define getshort(val, p) (val = (*p++ & 0377), val |= (*p++ & 0377) << 8)
  236. #define getlong(val, p) (val = (*p++ & 0377), \
  237. val |= (*p++ & 0377) << 8, \
  238. val |= (*p++ & 0377L) << 16, \
  239. val |= (*p++ & 0377L) << 24)
  240. static
  241. get_names(h, sz)
  242. struct outhead *h;
  243. long sz;
  244. {
  245. register char *xnms = malloc((unsigned) sz);
  246. register char *p;
  247. register struct outname *onm = (struct outname *) malloc((((unsigned)sz+8)/9)*sizeof(struct outname));
  248. struct xnm {
  249. unsigned short s_type, s_seg;
  250. long s_value;
  251. } xnm;
  252. if (xnms == 0 || onm == 0) No_Mem();
  253. if (!readf(xnms, (unsigned) sz, 1)) rd_fatal();
  254. names = onm;
  255. strings = p = xnms;
  256. while (sz > 0) {
  257. getshort(xnm.s_type, xnms);
  258. getshort(xnm.s_seg, xnms);
  259. getlong(xnm.s_value, xnms);
  260. onm->on_desc = 0;
  261. if (xnm.s_type & S_STB) {
  262. onm->on_type = xnm.s_type;
  263. onm->on_desc = xnm.s_seg;
  264. }
  265. else {
  266. switch(xnm.s_type & 0x1f) {
  267. case 0x1f:
  268. onm->on_type = S_FIL;
  269. break;
  270. case 0x8:
  271. onm->on_type = S_SCT;
  272. break;
  273. case 0:
  274. onm->on_type = S_UND;
  275. break;
  276. case 1:
  277. onm->on_type = S_ABS;
  278. break;
  279. default:
  280. onm->on_type = xnm.s_type & 0x1f;
  281. break;
  282. }
  283. }
  284. if (xnm.s_type & 0x20) onm->on_type |= S_EXT;
  285. onm->on_valu = xnm.s_value;
  286. sz -= 9;
  287. if (*xnms == '\0') {
  288. onm->on_foff = -1;
  289. xnms++;
  290. }
  291. else {
  292. onm->on_foff = p - strings;
  293. while (*p++ = *xnms++) sz--;
  294. }
  295. onm++;
  296. }
  297. h->oh_nname = onm - names;
  298. h->oh_nchar = p - strings;
  299. while (--onm >= names) {
  300. if (onm->on_foff == -1) onm->on_foff = 0;
  301. else onm->on_foff += OFF_CHAR(*h);
  302. }
  303. names = (struct outname *) realloc((char *) names, h->oh_nname * sizeof(struct outname));
  304. strings = realloc(strings, (unsigned) h->oh_nchar);
  305. }
  306. int
  307. rd_open(f)
  308. char *f;
  309. {
  310. if ((inf = fopen(f, "r")) == NULL) return 0;
  311. return 1;
  312. }
  313. rd_ohead(h)
  314. struct outhead *h;
  315. {
  316. int sepid;
  317. struct xexec xhdr;
  318. struct xseg xseg[3];
  319. if (! readf(&xhdr, sizeof(xhdr), 1)) rd_fatal();
  320. if (xhdr.x_magic != XMAGIC) rd_fatal();
  321. h->oh_magic = O_CONVERTED;
  322. h->oh_stamp = 0;
  323. h->oh_nsect = 4;
  324. h->oh_nrelo = 0;
  325. h->oh_flags = 0;
  326. h->oh_nemit = xhdr.x_text+xhdr.x_data;
  327. sepid = (xhdr.x_renv & 02) ? 1 : 0;
  328. fseek(inf, 0140L, 0);
  329. if (! readf(&xseg[0], sizeof(xseg[0]), sepid + 2)) rd_fatal();
  330. fseek(inf, xseg[sepid+1].xs_filpos, 0);
  331. get_names(h, xhdr.x_syms);
  332. fclose(inf);
  333. }
  334. rd_name(nm, count)
  335. struct outname *nm;
  336. unsigned int count;
  337. {
  338. memcpy(nm, names, (int) count * sizeof(struct outname));
  339. free((char *) names);
  340. }
  341. rd_string(nm, count)
  342. char *nm;
  343. long count;
  344. {
  345. memcpy(nm, strings, (int) count);
  346. free((char *) strings);
  347. }
  348. rd_close()
  349. {
  350. }
  351. #endif
  352. #if defined(solaris)
  353. #include <libelf.h>
  354. #include <sys/elf_M32.h>
  355. #include <stb.h>
  356. struct nlist {
  357. union {
  358. char *n_name;
  359. long n_strx;
  360. } n_un;
  361. unsigned char n_type;
  362. char n_other;
  363. short n_desc;
  364. unsigned long n_value;
  365. };
  366. static int fildes;
  367. static Elf *elf;
  368. static Elf32_Ehdr *ehdr;
  369. static struct nlist *dbtab;
  370. static char *dbstringtab;
  371. static Elf32_Sym *tab;
  372. static char *stringtab;
  373. static struct outhead hh;
  374. static struct nlist *maxdn;
  375. #define N_STAB 0xe0
  376. int
  377. rd_open(f)
  378. char *f;
  379. {
  380. if ((fildes = open(f, 0)) < 0) return 0;
  381. elf_version(EV_CURRENT);
  382. if ((elf = elf_begin(fildes, ELF_C_READ, (Elf *) 0)) == 0) {
  383. close(fildes);
  384. return 0;
  385. }
  386. if ((ehdr = elf32_getehdr(elf)) == NULL) {
  387. elf_end(elf);
  388. close(fildes);
  389. return 0;
  390. }
  391. return 1;
  392. }
  393. rd_ohead(h)
  394. struct outhead *h;
  395. {
  396. Elf_Scn *scn = 0;
  397. Elf32_Shdr *shdr;
  398. Elf_Data *sectnames;
  399. Elf_Data *dt;
  400. register struct nlist *dn;
  401. register Elf32_Sym *n;
  402. long text_offset, data_offset, bss_offset, fun_offset;
  403. int fixnamoff = 0, newfixnamoff = 0;
  404. h->oh_magic = O_CONVERTED;
  405. h->oh_stamp = 0;
  406. h->oh_nsect = 4;
  407. h->oh_nrelo = 0;
  408. h->oh_flags = 0;
  409. h->oh_nemit = 0;
  410. h->oh_nname = 0;
  411. scn = elf_getscn(elf, (size_t) ehdr->e_shstrndx);
  412. sectnames = elf_getdata(scn, (Elf_Data *) 0);
  413. scn = 0;
  414. while ((scn = elf_nextscn(elf, scn)) != 0) {
  415. shdr = elf32_getshdr(scn);
  416. switch(shdr->sh_type) {
  417. case SHT_PROGBITS:
  418. /* Get stab symbol table. Elf does not know about it,
  419. and, unfortunately, no relocation is done on it.
  420. */
  421. h->oh_nemit += shdr->sh_size;
  422. if (! strcmp(".stab", (char *)(sectnames->d_buf)+shdr->sh_name)) {
  423. dt = elf_getdata(scn, (Elf_Data *) 0);
  424. if (dt->d_size == 0) {
  425. fatal("(part of) symbol table is missing");
  426. }
  427. dbtab = (struct nlist *) Malloc(dt->d_size);
  428. memcpy((char *) dbtab, (char *) dt->d_buf, dt->d_size);
  429. maxdn = (struct nlist *)((char *)dbtab+dt->d_size);
  430. break;
  431. }
  432. break;
  433. case SHT_STRTAB:
  434. /* Get the stab string table, as well as the usual string
  435. table.
  436. */
  437. if (! strcmp(".stabstr", (char *)(sectnames->d_buf)+shdr->sh_name)) {
  438. dt = elf_getdata(scn, (Elf_Data *) 0);
  439. if (dt->d_size == 0) {
  440. fatal("(part of) symbol table is missing");
  441. }
  442. dbstringtab = dt->d_buf;
  443. h->oh_nchar = dt->d_size;
  444. break;
  445. }
  446. if (! strcmp(".strtab", (char *)(sectnames->d_buf)+shdr->sh_name)) {
  447. dt = elf_getdata(scn, (Elf_Data *) 0);
  448. if (dt->d_size == 0) {
  449. fatal("(part of) symbol table is missing");
  450. }
  451. stringtab = dt->d_buf;
  452. }
  453. break;
  454. case SHT_SYMTAB:
  455. /* Get the symbol table. */
  456. if (! strcmp(".symtab", (char *)(sectnames->d_buf)+shdr->sh_name)) {
  457. dt = elf_getdata(scn, (Elf_Data *) 0);
  458. if (dt->d_size == 0) {
  459. fatal("(part of) symbol table is missing");
  460. }
  461. tab = dt->d_buf;
  462. }
  463. break;
  464. }
  465. }
  466. /* Convert offsets in stab symbol table. */
  467. n = tab;
  468. dn = dbtab;
  469. while (dn < maxdn) {
  470. int i;
  471. if (dn->n_un.n_strx) {
  472. dn->n_un.n_strx += fixnamoff;
  473. }
  474. switch(dn->n_type) {
  475. case 0:
  476. fixnamoff = newfixnamoff;
  477. newfixnamoff += dn->n_value;
  478. break;
  479. case N_SO:
  480. h->oh_nname++;
  481. i = 0;
  482. while (i < 3) {
  483. while (stringtab[n->st_name] != 'B') n++;
  484. if (! strcmp("Btext.text", &(stringtab[n->st_name]))) {
  485. text_offset = n->st_value; i++;
  486. }
  487. else if (! strcmp("Bdata.data", &(stringtab[n->st_name]))) {
  488. data_offset = n->st_value; i++;
  489. }
  490. else if (! strcmp("Bbss.bss", &(stringtab[n->st_name]))) {
  491. bss_offset = n->st_value; i++;
  492. }
  493. n++;
  494. }
  495. break;
  496. case N_GSYM:
  497. h->oh_nname++;
  498. /* Fortunately, we don't use this in ACK, so we don't
  499. have to handle it here. The problem is that we don't know
  500. which segment it comes from.
  501. */
  502. break;
  503. case N_STSYM:
  504. h->oh_nname++;
  505. dn->n_value += data_offset;
  506. break;
  507. case N_LCSYM:
  508. h->oh_nname++;
  509. dn->n_value += bss_offset;
  510. break;
  511. case N_FUN:
  512. h->oh_nname++;
  513. dn->n_value += text_offset;
  514. fun_offset = dn->n_value;
  515. break;
  516. case N_MAIN:
  517. dn->n_value += text_offset;
  518. break;
  519. case N_LBRAC:
  520. case N_RBRAC:
  521. case N_SLINE:
  522. h->oh_nname++;
  523. dn->n_value += fun_offset;
  524. break;
  525. case N_SOL:
  526. case N_EINCL:
  527. case N_BINCL:
  528. case N_PSYM:
  529. case N_SSYM:
  530. case N_SCOPE:
  531. case N_RSYM:
  532. case N_LSYM:
  533. h->oh_nname++;
  534. /* Nothing to be done. */
  535. break;
  536. }
  537. dn++;
  538. }
  539. hh = *h;
  540. }
  541. rd_name(nm, count)
  542. struct outname *nm;
  543. unsigned int count;
  544. {
  545. register struct nlist *dn = dbtab;
  546. register struct outname *n = nm;
  547. while (dn < maxdn) {
  548. if (dn->n_type & N_STAB) {
  549. n->on_type = dn->n_type << 8;
  550. n->on_valu = dn->n_value;
  551. n->on_desc = dn->n_desc;
  552. if (dn->n_un.n_strx == 0) n->on_foff = 0;
  553. else n->on_foff = OFF_CHAR(hh) + dn->n_un.n_strx;
  554. n++;
  555. }
  556. dn++;
  557. }
  558. free(dbtab);
  559. }
  560. rd_string(nm, count)
  561. char *nm;
  562. long count;
  563. {
  564. memcpy(nm, dbstringtab, count);
  565. }
  566. rd_close()
  567. {
  568. elf_end(elf);
  569. close(fildes);
  570. }
  571. #endif