obj.c 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538
  1. #define EXTERN
  2. #include "l.h"
  3. #include <ar.h>
  4. #ifndef DEFAULT
  5. #define DEFAULT '9'
  6. #endif
  7. char *noname = "<none>";
  8. char symname[] = SYMDEF;
  9. char thechar = '8';
  10. char *thestring = "386";
  11. /*
  12. * -H0 -T0x40004C -D0x10000000 is garbage unix
  13. * -H1 -T0xd0 -R4 is unix coff
  14. * -H2 -T4128 -R4096 is plan9 format
  15. * -H3 -Tx -Rx is MS-DOS .COM
  16. * -H4 -Tx -Rx is fake MS-DOS .EXE
  17. * -H5 -T0x80100020 -R4096 is ELF
  18. */
  19. static int
  20. isobjfile(char *f)
  21. {
  22. int n, v;
  23. Biobuf *b;
  24. char buf1[5], buf2[SARMAG];
  25. b = Bopen(f, OREAD);
  26. if(b == nil)
  27. return 0;
  28. n = Bread(b, buf1, 5);
  29. if(n == 5 && (buf1[2] == 1 && buf1[3] == '<' || buf1[3] == 1 && buf1[4] == '<'))
  30. v = 1; /* good enough for our purposes */
  31. else{
  32. Bseek(b, 0, 0);
  33. n = Bread(b, buf2, SARMAG);
  34. v = n == SARMAG && strncmp(buf2, ARMAG, SARMAG) == 0;
  35. }
  36. Bterm(b);
  37. return v;
  38. }
  39. void
  40. main(int argc, char *argv[])
  41. {
  42. int i, c;
  43. char *a;
  44. Binit(&bso, 1, OWRITE);
  45. cout = -1;
  46. listinit();
  47. memset(debug, 0, sizeof(debug));
  48. nerrors = 0;
  49. outfile = "8.out";
  50. HEADTYPE = -1;
  51. INITTEXT = -1;
  52. INITDAT = -1;
  53. INITRND = -1;
  54. INITENTRY = 0;
  55. ARGBEGIN {
  56. default:
  57. c = ARGC();
  58. if(c >= 0 && c < sizeof(debug))
  59. debug[c]++;
  60. break;
  61. case 'o': /* output to (next arg) */
  62. outfile = ARGF();
  63. break;
  64. case 'E':
  65. a = ARGF();
  66. if(a)
  67. INITENTRY = a;
  68. break;
  69. case 'H':
  70. a = ARGF();
  71. if(a)
  72. HEADTYPE = atolwhex(a);
  73. break;
  74. case 'T':
  75. a = ARGF();
  76. if(a)
  77. INITTEXT = atolwhex(a);
  78. break;
  79. case 'D':
  80. a = ARGF();
  81. if(a)
  82. INITDAT = atolwhex(a);
  83. break;
  84. case 'R':
  85. a = ARGF();
  86. if(a)
  87. INITRND = atolwhex(a);
  88. break;
  89. case 'x': /* produce export table */
  90. doexp = 1;
  91. if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1])){
  92. a = ARGF();
  93. if(strcmp(a, "*") == 0)
  94. allexport = 1;
  95. else
  96. readundefs(a, SEXPORT);
  97. }
  98. break;
  99. case 'u': /* produce dynamically loadable module */
  100. dlm = 1;
  101. debug['l']++;
  102. if(argv[1] != nil && argv[1][0] != '-' && !isobjfile(argv[1]))
  103. readundefs(ARGF(), SIMPORT);
  104. break;
  105. } ARGEND
  106. USED(argc);
  107. if(*argv == 0) {
  108. diag("usage: 8l [-options] objects");
  109. errorexit();
  110. }
  111. if(!debug['9'] && !debug['U'] && !debug['B'])
  112. debug[DEFAULT] = 1;
  113. if(HEADTYPE == -1) {
  114. if(debug['U'])
  115. HEADTYPE = 1;
  116. if(debug['B'])
  117. HEADTYPE = 2;
  118. if(debug['9'])
  119. HEADTYPE = 2;
  120. }
  121. switch(HEADTYPE) {
  122. default:
  123. diag("unknown -H option");
  124. errorexit();
  125. case 0: /* this is garbage */
  126. HEADR = 20L+56L;
  127. if(INITTEXT == -1)
  128. INITTEXT = 0x40004CL;
  129. if(INITDAT == -1)
  130. INITDAT = 0x10000000L;
  131. if(INITRND == -1)
  132. INITRND = 0;
  133. break;
  134. case 1: /* is unix coff */
  135. HEADR = 0xd0L;
  136. if(INITTEXT == -1)
  137. INITTEXT = 0xd0;
  138. if(INITDAT == -1)
  139. INITDAT = 0x400000;
  140. if(INITRND == -1)
  141. INITRND = 0;
  142. break;
  143. case 2: /* plan 9 */
  144. HEADR = 32L;
  145. if(INITTEXT == -1)
  146. INITTEXT = 4096+32;
  147. if(INITDAT == -1)
  148. INITDAT = 0;
  149. if(INITRND == -1)
  150. INITRND = 4096;
  151. break;
  152. case 3: /* MS-DOS .COM */
  153. HEADR = 0;
  154. if(INITTEXT == -1)
  155. INITTEXT = 0x0100;
  156. if(INITDAT == -1)
  157. INITDAT = 0;
  158. if(INITRND == -1)
  159. INITRND = 4;
  160. break;
  161. case 4: /* fake MS-DOS .EXE */
  162. HEADR = 0x200;
  163. if(INITTEXT == -1)
  164. INITTEXT = 0x0100;
  165. if(INITDAT == -1)
  166. INITDAT = 0;
  167. if(INITRND == -1)
  168. INITRND = 4;
  169. HEADR += (INITTEXT & 0xFFFF);
  170. if(debug['v'])
  171. Bprint(&bso, "HEADR = 0x%ld\n", HEADR);
  172. break;
  173. case 5: /* elf executable */
  174. HEADR = rnd(52L+3*32L, 16);
  175. if(INITTEXT == -1)
  176. INITTEXT = 0x80100020L;
  177. if(INITDAT == -1)
  178. INITDAT = 0;
  179. if(INITRND == -1)
  180. INITRND = 4096;
  181. break;
  182. }
  183. if(INITDAT != 0 && INITRND != 0)
  184. print("warning: -D0x%lux is ignored because of -R0x%lux\n",
  185. INITDAT, INITRND);
  186. if(debug['v'])
  187. Bprint(&bso, "HEADER = -H0x%ld -T0x%lux -D0x%lux -R0x%lux\n",
  188. HEADTYPE, INITTEXT, INITDAT, INITRND);
  189. Bflush(&bso);
  190. for(i=1; optab[i].as; i++)
  191. if(i != optab[i].as) {
  192. diag("phase error in optab: %d", i);
  193. errorexit();
  194. }
  195. for(i=0; i<Ymax; i++)
  196. ycover[i*Ymax + i] = 1;
  197. ycover[Yi0*Ymax + Yi8] = 1;
  198. ycover[Yi1*Ymax + Yi8] = 1;
  199. ycover[Yi0*Ymax + Yi32] = 1;
  200. ycover[Yi1*Ymax + Yi32] = 1;
  201. ycover[Yi8*Ymax + Yi32] = 1;
  202. ycover[Yal*Ymax + Yrb] = 1;
  203. ycover[Ycl*Ymax + Yrb] = 1;
  204. ycover[Yax*Ymax + Yrb] = 1;
  205. ycover[Ycx*Ymax + Yrb] = 1;
  206. ycover[Yrx*Ymax + Yrb] = 1;
  207. ycover[Yax*Ymax + Yrx] = 1;
  208. ycover[Ycx*Ymax + Yrx] = 1;
  209. ycover[Yax*Ymax + Yrl] = 1;
  210. ycover[Ycx*Ymax + Yrl] = 1;
  211. ycover[Yrx*Ymax + Yrl] = 1;
  212. ycover[Yf0*Ymax + Yrf] = 1;
  213. ycover[Yal*Ymax + Ymb] = 1;
  214. ycover[Ycl*Ymax + Ymb] = 1;
  215. ycover[Yax*Ymax + Ymb] = 1;
  216. ycover[Ycx*Ymax + Ymb] = 1;
  217. ycover[Yrx*Ymax + Ymb] = 1;
  218. ycover[Yrb*Ymax + Ymb] = 1;
  219. ycover[Ym*Ymax + Ymb] = 1;
  220. ycover[Yax*Ymax + Yml] = 1;
  221. ycover[Ycx*Ymax + Yml] = 1;
  222. ycover[Yrx*Ymax + Yml] = 1;
  223. ycover[Yrl*Ymax + Yml] = 1;
  224. ycover[Ym*Ymax + Yml] = 1;
  225. for(i=0; i<D_NONE; i++) {
  226. reg[i] = -1;
  227. if(i >= D_AL && i <= D_BH)
  228. reg[i] = (i-D_AL) & 7;
  229. if(i >= D_AX && i <= D_DI)
  230. reg[i] = (i-D_AX) & 7;
  231. if(i >= D_F0 && i <= D_F0+7)
  232. reg[i] = (i-D_F0) & 7;
  233. }
  234. zprg.link = P;
  235. zprg.pcond = P;
  236. zprg.back = 2;
  237. zprg.as = AGOK;
  238. zprg.from.type = D_NONE;
  239. zprg.from.index = D_NONE;
  240. zprg.from.scale = 1;
  241. zprg.to = zprg.from;
  242. pcstr = "%.6lux ";
  243. nuxiinit();
  244. histgen = 0;
  245. textp = P;
  246. datap = P;
  247. edatap = P;
  248. pc = 0;
  249. dtype = 4;
  250. cout = create(outfile, 1, 0775);
  251. if(cout < 0) {
  252. diag("cannot create %s", outfile);
  253. errorexit();
  254. }
  255. version = 0;
  256. cbp = buf.cbuf;
  257. cbc = sizeof(buf.cbuf);
  258. firstp = prg();
  259. lastp = firstp;
  260. if(INITENTRY == 0) {
  261. INITENTRY = "_main";
  262. if(debug['p'])
  263. INITENTRY = "_mainp";
  264. if(!debug['l'])
  265. lookup(INITENTRY, 0)->type = SXREF;
  266. } else
  267. lookup(INITENTRY, 0)->type = SXREF;
  268. while(*argv)
  269. objfile(*argv++);
  270. if(!debug['l'])
  271. loadlib();
  272. firstp = firstp->link;
  273. if(firstp == P)
  274. errorexit();
  275. if(doexp || dlm){
  276. EXPTAB = "_exporttab";
  277. zerosig(EXPTAB);
  278. zerosig("etext");
  279. zerosig("edata");
  280. zerosig("end");
  281. if(dlm){
  282. import();
  283. HEADTYPE = 2;
  284. INITTEXT = INITDAT = 0;
  285. INITRND = 8;
  286. INITENTRY = EXPTAB;
  287. }
  288. export();
  289. }
  290. patch();
  291. follow();
  292. dodata();
  293. dostkoff();
  294. if(debug['p'])
  295. if(debug['1'])
  296. doprof1();
  297. else
  298. doprof2();
  299. span();
  300. doinit();
  301. asmb();
  302. undef();
  303. if(debug['v']) {
  304. Bprint(&bso, "%5.2f cpu time\n", cputime());
  305. Bprint(&bso, "%ld symbols\n", nsymbol);
  306. Bprint(&bso, "%ld memory used\n", thunk);
  307. Bprint(&bso, "%d sizeof adr\n", sizeof(Adr));
  308. Bprint(&bso, "%d sizeof prog\n", sizeof(Prog));
  309. }
  310. Bflush(&bso);
  311. errorexit();
  312. }
  313. void
  314. loadlib(void)
  315. {
  316. int i;
  317. long h;
  318. Sym *s;
  319. loop:
  320. xrefresolv = 0;
  321. for(i=0; i<libraryp; i++) {
  322. if(debug['v'])
  323. Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]);
  324. objfile(library[i]);
  325. }
  326. if(xrefresolv)
  327. for(h=0; h<nelem(hash); h++)
  328. for(s = hash[h]; s != S; s = s->link)
  329. if(s->type == SXREF)
  330. goto loop;
  331. }
  332. void
  333. errorexit(void)
  334. {
  335. if(nerrors) {
  336. if(cout >= 0)
  337. remove(outfile);
  338. exits("error");
  339. }
  340. exits(0);
  341. }
  342. void
  343. objfile(char *file)
  344. {
  345. long off, esym, cnt, l;
  346. int f, work;
  347. Sym *s;
  348. char magbuf[SARMAG];
  349. char name[100], pname[150];
  350. struct ar_hdr arhdr;
  351. char *e, *start, *stop;
  352. if(file[0] == '-' && file[1] == 'l') {
  353. if(debug['9'])
  354. sprint(name, "/%s/lib/lib", thestring);
  355. else
  356. sprint(name, "/usr/%clib/lib", thechar);
  357. strcat(name, file+2);
  358. strcat(name, ".a");
  359. file = name;
  360. }
  361. if(debug['v'])
  362. Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file);
  363. Bflush(&bso);
  364. f = open(file, 0);
  365. if(f < 0) {
  366. diag("cannot open file: %s", file);
  367. errorexit();
  368. }
  369. l = read(f, magbuf, SARMAG);
  370. if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){
  371. /* load it as a regular file */
  372. l = seek(f, 0L, 2);
  373. seek(f, 0L, 0);
  374. ldobj(f, l, file);
  375. close(f);
  376. return;
  377. }
  378. l = read(f, &arhdr, SAR_HDR);
  379. if(l != SAR_HDR) {
  380. diag("%s: short read on archive file symbol header", file);
  381. goto out;
  382. }
  383. if(strncmp(arhdr.name, symname, strlen(symname))) {
  384. diag("%s: first entry not symbol header", file);
  385. goto out;
  386. }
  387. esym = SARMAG + SAR_HDR + atolwhex(arhdr.size);
  388. off = SARMAG + SAR_HDR;
  389. /*
  390. * just bang the whole symbol file into memory
  391. */
  392. seek(f, off, 0);
  393. cnt = esym - off;
  394. start = malloc(cnt + 10);
  395. cnt = read(f, start, cnt);
  396. if(cnt <= 0){
  397. close(f);
  398. return;
  399. }
  400. stop = &start[cnt];
  401. memset(stop, 0, 10);
  402. work = 1;
  403. while(work) {
  404. if(debug['v'])
  405. Bprint(&bso, "%5.2f library pass: %s\n", cputime(), file);
  406. Bflush(&bso);
  407. work = 0;
  408. for(e = start; e < stop; e = strchr(e+5, 0) + 1) {
  409. s = lookup(e+5, 0);
  410. if(s->type != SXREF)
  411. continue;
  412. sprint(pname, "%s(%s)", file, s->name);
  413. if(debug['v'])
  414. Bprint(&bso, "%5.2f library: %s\n", cputime(), pname);
  415. Bflush(&bso);
  416. l = e[1] & 0xff;
  417. l |= (e[2] & 0xff) << 8;
  418. l |= (e[3] & 0xff) << 16;
  419. l |= (e[4] & 0xff) << 24;
  420. seek(f, l, 0);
  421. l = read(f, &arhdr, SAR_HDR);
  422. if(l != SAR_HDR)
  423. goto bad;
  424. if(strncmp(arhdr.fmag, ARFMAG, sizeof(arhdr.fmag)))
  425. goto bad;
  426. l = atolwhex(arhdr.size);
  427. ldobj(f, l, pname);
  428. if(s->type == SXREF) {
  429. diag("%s: failed to load: %s", file, s->name);
  430. errorexit();
  431. }
  432. work = 1;
  433. xrefresolv = 1;
  434. }
  435. }
  436. return;
  437. bad:
  438. diag("%s: bad or out of date archive", file);
  439. out:
  440. close(f);
  441. }
  442. int
  443. zaddr(uchar *p, Adr *a, Sym *h[])
  444. {
  445. int c, t, i;
  446. long l;
  447. Sym *s;
  448. Auto *u;
  449. t = p[0];
  450. c = 1;
  451. if(t & T_INDEX) {
  452. a->index = p[c];
  453. a->scale = p[c+1];
  454. c += 2;
  455. } else {
  456. a->index = D_NONE;
  457. a->scale = 0;
  458. }
  459. a->offset = 0;
  460. if(t & T_OFFSET) {
  461. a->offset = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24);
  462. c += 4;
  463. }
  464. a->sym = S;
  465. if(t & T_SYM) {
  466. a->sym = h[p[c]];
  467. c++;
  468. }
  469. a->type = D_NONE;
  470. if(t & T_FCONST) {
  471. a->ieee.l = p[c] | (p[c+1]<<8) | (p[c+2]<<16) | (p[c+3]<<24);
  472. a->ieee.h = p[c+4] | (p[c+5]<<8) | (p[c+6]<<16) | (p[c+7]<<24);
  473. c += 8;
  474. a->type = D_FCONST;
  475. } else
  476. if(t & T_SCONST) {
  477. for(i=0; i<NSNAME; i++)
  478. a->scon[i] = p[c+i];
  479. c += NSNAME;
  480. a->type = D_SCONST;
  481. }
  482. if(t & T_TYPE) {
  483. a->type = p[c];
  484. c++;
  485. }
  486. s = a->sym;
  487. if(s == S)
  488. return c;
  489. t = a->type;
  490. if(t != D_AUTO && t != D_PARAM)
  491. return c;
  492. l = a->offset;
  493. for(u=curauto; u; u=u->link) {
  494. if(u->asym == s)
  495. if(u->type == t) {
  496. if(u->aoffset > l)
  497. u->aoffset = l;
  498. return c;
  499. }
  500. }
  501. while(nhunk < sizeof(Auto))
  502. gethunk();
  503. u = (Auto*)hunk;
  504. nhunk -= sizeof(Auto);
  505. hunk += sizeof(Auto);
  506. u->link = curauto;
  507. curauto = u;
  508. u->asym = s;
  509. u->aoffset = l;
  510. u->type = t;
  511. return c;
  512. }
  513. void
  514. addlib(char *obj)
  515. {
  516. char name[1024], comp[256], *p;
  517. int i;
  518. if(histfrogp <= 0)
  519. return;
  520. if(histfrog[0]->name[1] == '/') {
  521. sprint(name, "");
  522. i = 1;
  523. } else
  524. if(histfrog[0]->name[1] == '.') {
  525. sprint(name, ".");
  526. i = 0;
  527. } else {
  528. if(debug['9'])
  529. sprint(name, "/%s/lib", thestring);
  530. else
  531. sprint(name, "/usr/%clib", thechar);
  532. i = 0;
  533. }
  534. for(; i<histfrogp; i++) {
  535. snprint(comp, sizeof comp, histfrog[i]->name+1);
  536. for(;;) {
  537. p = strstr(comp, "$O");
  538. if(p == 0)
  539. break;
  540. memmove(p+1, p+2, strlen(p+2)+1);
  541. p[0] = thechar;
  542. }
  543. for(;;) {
  544. p = strstr(comp, "$M");
  545. if(p == 0)
  546. break;
  547. if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) {
  548. diag("library component too long");
  549. return;
  550. }
  551. memmove(p+strlen(thestring), p+2, strlen(p+2)+1);
  552. memmove(p, thestring, strlen(thestring));
  553. }
  554. if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) {
  555. diag("library component too long");
  556. return;
  557. }
  558. strcat(name, "/");
  559. strcat(name, comp);
  560. }
  561. for(i=0; i<libraryp; i++)
  562. if(strcmp(name, library[i]) == 0)
  563. return;
  564. if(libraryp == nelem(library)){
  565. diag("too many autolibs; skipping %s", name);
  566. return;
  567. }
  568. p = malloc(strlen(name) + 1);
  569. strcpy(p, name);
  570. library[libraryp] = p;
  571. p = malloc(strlen(obj) + 1);
  572. strcpy(p, obj);
  573. libraryobj[libraryp] = p;
  574. libraryp++;
  575. }
  576. void
  577. addhist(long line, int type)
  578. {
  579. Auto *u;
  580. Sym *s;
  581. int i, j, k;
  582. u = malloc(sizeof(Auto));
  583. s = malloc(sizeof(Sym));
  584. s->name = malloc(2*(histfrogp+1) + 1);
  585. u->asym = s;
  586. u->type = type;
  587. u->aoffset = line;
  588. u->link = curhist;
  589. curhist = u;
  590. j = 1;
  591. for(i=0; i<histfrogp; i++) {
  592. k = histfrog[i]->value;
  593. s->name[j+0] = k>>8;
  594. s->name[j+1] = k;
  595. j += 2;
  596. }
  597. }
  598. void
  599. histtoauto(void)
  600. {
  601. Auto *l;
  602. while(l = curhist) {
  603. curhist = l->link;
  604. l->link = curauto;
  605. curauto = l;
  606. }
  607. }
  608. void
  609. collapsefrog(Sym *s)
  610. {
  611. int i;
  612. /*
  613. * bad encoding of path components only allows
  614. * MAXHIST components. if there is an overflow,
  615. * first try to collapse xxx/..
  616. */
  617. for(i=1; i<histfrogp; i++)
  618. if(strcmp(histfrog[i]->name+1, "..") == 0) {
  619. memmove(histfrog+i-1, histfrog+i+1,
  620. (histfrogp-i-1)*sizeof(histfrog[0]));
  621. histfrogp--;
  622. goto out;
  623. }
  624. /*
  625. * next try to collapse .
  626. */
  627. for(i=0; i<histfrogp; i++)
  628. if(strcmp(histfrog[i]->name+1, ".") == 0) {
  629. memmove(histfrog+i, histfrog+i+1,
  630. (histfrogp-i-1)*sizeof(histfrog[0]));
  631. goto out;
  632. }
  633. /*
  634. * last chance, just truncate from front
  635. */
  636. memmove(histfrog+0, histfrog+1,
  637. (histfrogp-1)*sizeof(histfrog[0]));
  638. out:
  639. histfrog[histfrogp-1] = s;
  640. }
  641. void
  642. nopout(Prog *p)
  643. {
  644. p->as = ANOP;
  645. p->from.type = D_NONE;
  646. p->to.type = D_NONE;
  647. }
  648. uchar*
  649. readsome(int f, uchar *buf, uchar *good, uchar *stop, int max)
  650. {
  651. int n;
  652. n = stop - good;
  653. memmove(buf, good, stop - good);
  654. stop = buf + n;
  655. n = MAXIO - n;
  656. if(n > max)
  657. n = max;
  658. n = read(f, stop, n);
  659. if(n <= 0)
  660. return 0;
  661. return stop + n;
  662. }
  663. void
  664. ldobj(int f, long c, char *pn)
  665. {
  666. long ipc;
  667. Prog *p, *t;
  668. uchar *bloc, *bsize, *stop;
  669. int v, o, r, skip;
  670. Sym *h[NSYM], *s, *di;
  671. ulong sig;
  672. static int files;
  673. static char **filen;
  674. char **nfilen;
  675. if((files&15) == 0){
  676. nfilen = malloc((files+16)*sizeof(char*));
  677. memmove(nfilen, filen, files*sizeof(char*));
  678. free(filen);
  679. filen = nfilen;
  680. }
  681. filen[files++] = strdup(pn);
  682. bsize = buf.xbuf;
  683. bloc = buf.xbuf;
  684. di = S;
  685. newloop:
  686. memset(h, 0, sizeof(h));
  687. version++;
  688. histfrogp = 0;
  689. ipc = pc;
  690. skip = 0;
  691. loop:
  692. if(c <= 0)
  693. goto eof;
  694. r = bsize - bloc;
  695. if(r < 100 && r < c) { /* enough for largest prog */
  696. bsize = readsome(f, buf.xbuf, bloc, bsize, c);
  697. if(bsize == 0)
  698. goto eof;
  699. bloc = buf.xbuf;
  700. goto loop;
  701. }
  702. o = bloc[0] | (bloc[1] << 8);
  703. if(o <= AXXX || o >= ALAST) {
  704. if(o < 0)
  705. goto eof;
  706. diag("%s: opcode out of range %d", pn, o);
  707. print(" probably not a .8 file\n");
  708. errorexit();
  709. }
  710. if(o == ANAME || o == ASIGNAME) {
  711. sig = 0;
  712. if(o == ASIGNAME) {
  713. sig = bloc[2] | (bloc[3]<<8) | (bloc[4]<<16) | (bloc[5]<<24);
  714. bloc += 4;
  715. c -= 4;
  716. }
  717. stop = memchr(&bloc[4], 0, bsize-&bloc[4]);
  718. if(stop == 0){
  719. bsize = readsome(f, buf.xbuf, bloc, bsize, c);
  720. if(bsize == 0)
  721. goto eof;
  722. bloc = buf.xbuf;
  723. stop = memchr(&bloc[4], 0, bsize-&bloc[4]);
  724. if(stop == 0){
  725. fprint(2, "%s: name too long\n", pn);
  726. errorexit();
  727. }
  728. }
  729. v = bloc[2]; /* type */
  730. o = bloc[3]; /* sym */
  731. bloc += 4;
  732. c -= 4;
  733. r = 0;
  734. if(v == D_STATIC)
  735. r = version;
  736. s = lookup((char*)bloc, r);
  737. c -= &stop[1] - bloc;
  738. bloc = stop + 1;
  739. if(debug['S'] && r == 0)
  740. sig = 1729;
  741. if(sig != 0){
  742. if(s->sig != 0 && s->sig != sig)
  743. diag("incompatible type signatures %lux(%s) and %lux(%s) for %s", s->sig, filen[s->file], sig, pn, s->name);
  744. s->sig = sig;
  745. s->file = files-1;
  746. }
  747. if(debug['W'])
  748. print(" ANAME %s\n", s->name);
  749. h[o] = s;
  750. if((v == D_EXTERN || v == D_STATIC) && s->type == 0)
  751. s->type = SXREF;
  752. if(v == D_FILE) {
  753. if(s->type != SFILE) {
  754. histgen++;
  755. s->type = SFILE;
  756. s->value = histgen;
  757. }
  758. if(histfrogp < MAXHIST) {
  759. histfrog[histfrogp] = s;
  760. histfrogp++;
  761. } else
  762. collapsefrog(s);
  763. }
  764. goto loop;
  765. }
  766. while(nhunk < sizeof(Prog))
  767. gethunk();
  768. p = (Prog*)hunk;
  769. nhunk -= sizeof(Prog);
  770. hunk += sizeof(Prog);
  771. p->as = o;
  772. p->line = bloc[2] | (bloc[3] << 8) | (bloc[4] << 16) | (bloc[5] << 24);
  773. p->back = 2;
  774. r = zaddr(bloc+6, &p->from, h) + 6;
  775. r += zaddr(bloc+r, &p->to, h);
  776. bloc += r;
  777. c -= r;
  778. if(debug['W'])
  779. print("%P\n", p);
  780. switch(p->as) {
  781. case AHISTORY:
  782. if(p->to.offset == -1) {
  783. addlib(pn);
  784. histfrogp = 0;
  785. goto loop;
  786. }
  787. addhist(p->line, D_FILE); /* 'z' */
  788. if(p->to.offset)
  789. addhist(p->to.offset, D_FILE1); /* 'Z' */
  790. histfrogp = 0;
  791. goto loop;
  792. case AEND:
  793. histtoauto();
  794. if(curtext != P)
  795. curtext->to.autom = curauto;
  796. curauto = 0;
  797. curtext = P;
  798. if(c)
  799. goto newloop;
  800. return;
  801. case AGLOBL:
  802. s = p->from.sym;
  803. if(s->type == 0 || s->type == SXREF) {
  804. s->type = SBSS;
  805. s->value = 0;
  806. }
  807. if(s->type != SBSS) {
  808. diag("%s: redefinition: %s in %s",
  809. pn, s->name, TNAME);
  810. s->type = SBSS;
  811. s->value = 0;
  812. }
  813. if(p->to.offset > s->value)
  814. s->value = p->to.offset;
  815. goto loop;
  816. case ADYNT:
  817. if(p->to.sym == S) {
  818. diag("DYNT without a sym\n%P", p);
  819. break;
  820. }
  821. di = p->to.sym;
  822. p->from.scale = 4;
  823. if(di->type == SXREF) {
  824. if(debug['z'])
  825. Bprint(&bso, "%P set to %d\n", p, dtype);
  826. di->type = SCONST;
  827. di->value = dtype;
  828. dtype += 4;
  829. }
  830. if(p->from.sym == S)
  831. break;
  832. p->from.offset = di->value;
  833. p->from.sym->type = SDATA;
  834. if(curtext == P) {
  835. diag("DYNT not in text: %P", p);
  836. break;
  837. }
  838. p->to.sym = curtext->from.sym;
  839. p->to.type = D_ADDR;
  840. p->to.index = D_EXTERN;
  841. goto data;
  842. case AINIT:
  843. if(p->from.sym == S) {
  844. diag("INIT without a sym\n%P", p);
  845. break;
  846. }
  847. if(di == S) {
  848. diag("INIT without previous DYNT\n%P", p);
  849. break;
  850. }
  851. p->from.offset = di->value;
  852. p->from.sym->type = SDATA;
  853. goto data;
  854. case ADATA:
  855. data:
  856. if(edatap == P)
  857. datap = p;
  858. else
  859. edatap->link = p;
  860. edatap = p;
  861. p->link = P;
  862. goto loop;
  863. case AGOK:
  864. diag("%s: GOK opcode in %s", pn, TNAME);
  865. pc++;
  866. goto loop;
  867. case ATEXT:
  868. if(curtext != P) {
  869. histtoauto();
  870. curtext->to.autom = curauto;
  871. curauto = 0;
  872. }
  873. skip = 0;
  874. curtext = p;
  875. s = p->from.sym;
  876. if(s == S) {
  877. diag("%s: no TEXT symbol: %P", pn, p);
  878. errorexit();
  879. }
  880. if(s->type != 0 && s->type != SXREF) {
  881. if(p->from.scale & DUPOK) {
  882. skip = 1;
  883. goto casdef;
  884. }
  885. diag("%s: redefinition: %s\n%P", pn, s->name, p);
  886. }
  887. s->type = STEXT;
  888. s->value = pc;
  889. lastp->link = p;
  890. lastp = p;
  891. p->pc = pc;
  892. pc++;
  893. if(textp == P) {
  894. textp = p;
  895. etextp = p;
  896. goto loop;
  897. }
  898. etextp->pcond = p;
  899. etextp = p;
  900. goto loop;
  901. case AFMOVF:
  902. case AFADDF:
  903. case AFSUBF:
  904. case AFSUBRF:
  905. case AFMULF:
  906. case AFDIVF:
  907. case AFDIVRF:
  908. case AFCOMF:
  909. case AFCOMFP:
  910. if(skip)
  911. goto casdef;
  912. if(p->from.type == D_FCONST) {
  913. /* size sb 9 max */
  914. sprint(literal, "$%lux", ieeedtof(&p->from.ieee));
  915. s = lookup(literal, 0);
  916. if(s->type == 0) {
  917. s->type = SBSS;
  918. s->value = 4;
  919. t = prg();
  920. t->as = ADATA;
  921. t->line = p->line;
  922. t->from.type = D_EXTERN;
  923. t->from.sym = s;
  924. t->from.scale = 4;
  925. t->to = p->from;
  926. if(edatap == P)
  927. datap = t;
  928. else
  929. edatap->link = t;
  930. edatap = t;
  931. t->link = P;
  932. }
  933. p->from.type = D_EXTERN;
  934. p->from.sym = s;
  935. p->from.offset = 0;
  936. }
  937. goto casdef;
  938. case AFMOVD:
  939. case AFADDD:
  940. case AFSUBD:
  941. case AFSUBRD:
  942. case AFMULD:
  943. case AFDIVD:
  944. case AFDIVRD:
  945. case AFCOMD:
  946. case AFCOMDP:
  947. if(skip)
  948. goto casdef;
  949. if(p->from.type == D_FCONST) {
  950. /* size sb 18 max */
  951. sprint(literal, "$%lux.%lux",
  952. p->from.ieee.l, p->from.ieee.h);
  953. s = lookup(literal, 0);
  954. if(s->type == 0) {
  955. s->type = SBSS;
  956. s->value = 8;
  957. t = prg();
  958. t->as = ADATA;
  959. t->line = p->line;
  960. t->from.type = D_EXTERN;
  961. t->from.sym = s;
  962. t->from.scale = 8;
  963. t->to = p->from;
  964. if(edatap == P)
  965. datap = t;
  966. else
  967. edatap->link = t;
  968. edatap = t;
  969. t->link = P;
  970. }
  971. p->from.type = D_EXTERN;
  972. p->from.sym = s;
  973. p->from.offset = 0;
  974. }
  975. goto casdef;
  976. casdef:
  977. default:
  978. if(skip)
  979. nopout(p);
  980. if(p->to.type == D_BRANCH)
  981. p->to.offset += ipc;
  982. lastp->link = p;
  983. lastp = p;
  984. p->pc = pc;
  985. pc++;
  986. goto loop;
  987. }
  988. goto loop;
  989. eof:
  990. diag("truncated object file: %s", pn);
  991. }
  992. Sym*
  993. lookup(char *symb, int v)
  994. {
  995. Sym *s;
  996. char *p;
  997. long h;
  998. int l, c;
  999. h = v;
  1000. for(p=symb; c = *p; p++)
  1001. h = h+h+h + c;
  1002. l = (p - symb) + 1;
  1003. if(h < 0)
  1004. h = ~h;
  1005. h %= NHASH;
  1006. for(s = hash[h]; s != S; s = s->link)
  1007. if(s->version == v)
  1008. if(memcmp(s->name, symb, l) == 0)
  1009. return s;
  1010. while(nhunk < sizeof(Sym))
  1011. gethunk();
  1012. s = (Sym*)hunk;
  1013. nhunk -= sizeof(Sym);
  1014. hunk += sizeof(Sym);
  1015. s->name = malloc(l + 1);
  1016. memmove(s->name, symb, l);
  1017. s->link = hash[h];
  1018. s->type = 0;
  1019. s->version = v;
  1020. s->value = 0;
  1021. s->sig = 0;
  1022. hash[h] = s;
  1023. nsymbol++;
  1024. return s;
  1025. }
  1026. Prog*
  1027. prg(void)
  1028. {
  1029. Prog *p;
  1030. while(nhunk < sizeof(Prog))
  1031. gethunk();
  1032. p = (Prog*)hunk;
  1033. nhunk -= sizeof(Prog);
  1034. hunk += sizeof(Prog);
  1035. *p = zprg;
  1036. return p;
  1037. }
  1038. Prog*
  1039. copyp(Prog *q)
  1040. {
  1041. Prog *p;
  1042. p = prg();
  1043. *p = *q;
  1044. return p;
  1045. }
  1046. Prog*
  1047. appendp(Prog *q)
  1048. {
  1049. Prog *p;
  1050. p = prg();
  1051. p->link = q->link;
  1052. q->link = p;
  1053. p->line = q->line;
  1054. return p;
  1055. }
  1056. void
  1057. gethunk(void)
  1058. {
  1059. char *h;
  1060. long nh;
  1061. nh = NHUNK;
  1062. if(thunk >= 5L*NHUNK) {
  1063. nh = 5L*NHUNK;
  1064. if(thunk >= 25L*NHUNK)
  1065. nh = 25L*NHUNK;
  1066. }
  1067. h = mysbrk(nh);
  1068. if(h == (char*)-1) {
  1069. diag("out of memory");
  1070. errorexit();
  1071. }
  1072. hunk = h;
  1073. nhunk = nh;
  1074. thunk += nh;
  1075. }
  1076. void
  1077. doprof1(void)
  1078. {
  1079. Sym *s;
  1080. long n;
  1081. Prog *p, *q;
  1082. if(debug['v'])
  1083. Bprint(&bso, "%5.2f profile 1\n", cputime());
  1084. Bflush(&bso);
  1085. s = lookup("__mcount", 0);
  1086. n = 1;
  1087. for(p = firstp->link; p != P; p = p->link) {
  1088. if(p->as == ATEXT) {
  1089. q = prg();
  1090. q->line = p->line;
  1091. q->link = datap;
  1092. datap = q;
  1093. q->as = ADATA;
  1094. q->from.type = D_EXTERN;
  1095. q->from.offset = n*4;
  1096. q->from.sym = s;
  1097. q->from.scale = 4;
  1098. q->to = p->from;
  1099. q->to.type = D_CONST;
  1100. q = prg();
  1101. q->line = p->line;
  1102. q->pc = p->pc;
  1103. q->link = p->link;
  1104. p->link = q;
  1105. p = q;
  1106. p->as = AADDL;
  1107. p->from.type = D_CONST;
  1108. p->from.offset = 1;
  1109. p->to.type = D_EXTERN;
  1110. p->to.sym = s;
  1111. p->to.offset = n*4 + 4;
  1112. n += 2;
  1113. continue;
  1114. }
  1115. }
  1116. q = prg();
  1117. q->line = 0;
  1118. q->link = datap;
  1119. datap = q;
  1120. q->as = ADATA;
  1121. q->from.type = D_EXTERN;
  1122. q->from.sym = s;
  1123. q->from.scale = 4;
  1124. q->to.type = D_CONST;
  1125. q->to.offset = n;
  1126. s->type = SBSS;
  1127. s->value = n*4;
  1128. }
  1129. void
  1130. doprof2(void)
  1131. {
  1132. Sym *s2, *s4;
  1133. Prog *p, *q, *q2, *ps2, *ps4;
  1134. if(debug['v'])
  1135. Bprint(&bso, "%5.2f profile 2\n", cputime());
  1136. Bflush(&bso);
  1137. if(debug['e']){
  1138. s2 = lookup("_tracein", 0);
  1139. s4 = lookup("_traceout", 0);
  1140. }else{
  1141. s2 = lookup("_profin", 0);
  1142. s4 = lookup("_profout", 0);
  1143. }
  1144. if(s2->type != STEXT || s4->type != STEXT) {
  1145. if(debug['e'])
  1146. diag("_tracein/_traceout not defined %d %d", s2->type, s4->type);
  1147. else
  1148. diag("_profin/_profout not defined");
  1149. return;
  1150. }
  1151. ps2 = P;
  1152. ps4 = P;
  1153. for(p = firstp; p != P; p = p->link) {
  1154. if(p->as == ATEXT) {
  1155. if(p->from.sym == s2) {
  1156. p->from.scale = 1;
  1157. ps2 = p;
  1158. }
  1159. if(p->from.sym == s4) {
  1160. p->from.scale = 1;
  1161. ps4 = p;
  1162. }
  1163. }
  1164. }
  1165. for(p = firstp; p != P; p = p->link) {
  1166. if(p->as == ATEXT) {
  1167. curtext = p;
  1168. if(p->from.scale & NOPROF) { /* dont profile */
  1169. for(;;) {
  1170. q = p->link;
  1171. if(q == P)
  1172. break;
  1173. if(q->as == ATEXT)
  1174. break;
  1175. p = q;
  1176. }
  1177. continue;
  1178. }
  1179. /*
  1180. * JMPL profin
  1181. */
  1182. q = prg();
  1183. q->line = p->line;
  1184. q->pc = p->pc;
  1185. q->link = p->link;
  1186. if(debug['e']){ /* embedded tracing */
  1187. q2 = prg();
  1188. p->link = q2;
  1189. q2->link = q;
  1190. q2->line = p->line;
  1191. q2->pc = p->pc;
  1192. q2->as = AJMP;
  1193. q2->to.type = D_BRANCH;
  1194. q2->to.sym = p->to.sym;
  1195. q2->pcond = q->link;
  1196. }else
  1197. p->link = q;
  1198. p = q;
  1199. p->as = ACALL;
  1200. p->to.type = D_BRANCH;
  1201. p->pcond = ps2;
  1202. p->to.sym = s2;
  1203. continue;
  1204. }
  1205. if(p->as == ARET) {
  1206. /*
  1207. * RET (default)
  1208. */
  1209. if(debug['e']){ /* embedded tracing */
  1210. q = prg();
  1211. q->line = p->line;
  1212. q->pc = p->pc;
  1213. q->link = p->link;
  1214. p->link = q;
  1215. p = q;
  1216. }
  1217. /*
  1218. * RET
  1219. */
  1220. q = prg();
  1221. q->as = ARET;
  1222. q->from = p->from;
  1223. q->to = p->to;
  1224. q->link = p->link;
  1225. p->link = q;
  1226. /*
  1227. * JAL profout
  1228. */
  1229. p->as = ACALL;
  1230. p->from = zprg.from;
  1231. p->to = zprg.to;
  1232. p->to.type = D_BRANCH;
  1233. p->pcond = ps4;
  1234. p->to.sym = s4;
  1235. p = q;
  1236. continue;
  1237. }
  1238. }
  1239. }
  1240. void
  1241. nuxiinit(void)
  1242. {
  1243. int i, c;
  1244. for(i=0; i<4; i++) {
  1245. c = find1(0x04030201L, i+1);
  1246. if(i < 2)
  1247. inuxi2[i] = c;
  1248. if(i < 1)
  1249. inuxi1[i] = c;
  1250. inuxi4[i] = c;
  1251. fnuxi4[i] = c;
  1252. fnuxi8[i] = c;
  1253. fnuxi8[i+4] = c+4;
  1254. }
  1255. if(debug['v']) {
  1256. Bprint(&bso, "inuxi = ");
  1257. for(i=0; i<1; i++)
  1258. Bprint(&bso, "%d", inuxi1[i]);
  1259. Bprint(&bso, " ");
  1260. for(i=0; i<2; i++)
  1261. Bprint(&bso, "%d", inuxi2[i]);
  1262. Bprint(&bso, " ");
  1263. for(i=0; i<4; i++)
  1264. Bprint(&bso, "%d", inuxi4[i]);
  1265. Bprint(&bso, "\nfnuxi = ");
  1266. for(i=0; i<4; i++)
  1267. Bprint(&bso, "%d", fnuxi4[i]);
  1268. Bprint(&bso, " ");
  1269. for(i=0; i<8; i++)
  1270. Bprint(&bso, "%d", fnuxi8[i]);
  1271. Bprint(&bso, "\n");
  1272. }
  1273. Bflush(&bso);
  1274. }
  1275. int
  1276. find1(long l, int c)
  1277. {
  1278. char *p;
  1279. int i;
  1280. p = (char*)&l;
  1281. for(i=0; i<4; i++)
  1282. if(*p++ == c)
  1283. return i;
  1284. return 0;
  1285. }
  1286. int
  1287. find2(long l, int c)
  1288. {
  1289. short *p;
  1290. int i;
  1291. p = (short*)&l;
  1292. for(i=0; i<4; i+=2) {
  1293. if(((*p >> 8) & 0xff) == c)
  1294. return i;
  1295. if((*p++ & 0xff) == c)
  1296. return i+1;
  1297. }
  1298. return 0;
  1299. }
  1300. long
  1301. ieeedtof(Ieee *e)
  1302. {
  1303. int exp;
  1304. long v;
  1305. if(e->h == 0)
  1306. return 0;
  1307. exp = (e->h>>20) & ((1L<<11)-1L);
  1308. exp -= (1L<<10) - 2L;
  1309. v = (e->h & 0xfffffL) << 3;
  1310. v |= (e->l >> 29) & 0x7L;
  1311. if((e->l >> 28) & 1) {
  1312. v++;
  1313. if(v & 0x800000L) {
  1314. v = (v & 0x7fffffL) >> 1;
  1315. exp++;
  1316. }
  1317. }
  1318. if(exp <= -126 || exp >= 130)
  1319. diag("double fp to single fp overflow");
  1320. v |= ((exp + 126) & 0xffL) << 23;
  1321. v |= e->h & 0x80000000L;
  1322. return v;
  1323. }
  1324. double
  1325. ieeedtod(Ieee *ieeep)
  1326. {
  1327. Ieee e;
  1328. double fr;
  1329. int exp;
  1330. if(ieeep->h & (1L<<31)) {
  1331. e.h = ieeep->h & ~(1L<<31);
  1332. e.l = ieeep->l;
  1333. return -ieeedtod(&e);
  1334. }
  1335. if(ieeep->l == 0 && ieeep->h == 0)
  1336. return 0;
  1337. fr = ieeep->l & ((1L<<16)-1L);
  1338. fr /= 1L<<16;
  1339. fr += (ieeep->l>>16) & ((1L<<16)-1L);
  1340. fr /= 1L<<16;
  1341. fr += (ieeep->h & (1L<<20)-1L) | (1L<<20);
  1342. fr /= 1L<<21;
  1343. exp = (ieeep->h>>20) & ((1L<<11)-1L);
  1344. exp -= (1L<<10) - 2L;
  1345. return ldexp(fr, exp);
  1346. }
  1347. void
  1348. undefsym(Sym *s)
  1349. {
  1350. int n;
  1351. n = imports;
  1352. if(s->value != 0)
  1353. diag("value != 0 on SXREF");
  1354. if(n >= 1<<Rindex)
  1355. diag("import index %d out of range", n);
  1356. s->value = n<<Roffset;
  1357. s->type = SUNDEF;
  1358. imports++;
  1359. }
  1360. void
  1361. zerosig(char *sp)
  1362. {
  1363. Sym *s;
  1364. s = lookup(sp, 0);
  1365. s->sig = 0;
  1366. }
  1367. void
  1368. readundefs(char *f, int t)
  1369. {
  1370. int i, n;
  1371. Sym *s;
  1372. Biobuf *b;
  1373. char *l, buf[256], *fields[64];
  1374. if(f == nil)
  1375. return;
  1376. b = Bopen(f, OREAD);
  1377. if(b == nil){
  1378. diag("could not open %s: %r", f);
  1379. errorexit();
  1380. }
  1381. while((l = Brdline(b, '\n')) != nil){
  1382. n = Blinelen(b);
  1383. if(n >= sizeof(buf)){
  1384. diag("%s: line too long", f);
  1385. errorexit();
  1386. }
  1387. memmove(buf, l, n);
  1388. buf[n-1] = '\0';
  1389. n = getfields(buf, fields, nelem(fields), 1, " \t\r\n");
  1390. if(n == nelem(fields)){
  1391. diag("%s: bad format", f);
  1392. errorexit();
  1393. }
  1394. for(i = 0; i < n; i++){
  1395. s = lookup(fields[i], 0);
  1396. s->type = SXREF;
  1397. s->subtype = t;
  1398. if(t == SIMPORT)
  1399. nimports++;
  1400. else
  1401. nexports++;
  1402. }
  1403. }
  1404. Bterm(b);
  1405. }