tree.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. /* $Header$ */
  2. #include <stdio.h>
  3. #include <varargs.h>
  4. #include <assert.h>
  5. #include <alloc.h>
  6. #include <out.h>
  7. #include "operator.h"
  8. #include "position.h"
  9. #include "file.h"
  10. #include "idf.h"
  11. #include "tree.h"
  12. #include "message.h"
  13. #include "scope.h"
  14. #include "symbol.h"
  15. #include "langdep.h"
  16. #include "type.h"
  17. #include "expr.h"
  18. extern FILE *db_out;
  19. extern t_lineno currline, listline;
  20. extern long pointer_size;
  21. extern char *strrindex();
  22. p_tree run_command;
  23. /*VARARGS1*/
  24. p_tree
  25. mknode(va_alist)
  26. va_dcl
  27. {
  28. va_list ap;
  29. register p_tree p = new_tree();
  30. va_start(ap);
  31. {
  32. register int i, na;
  33. p->t_oper = va_arg(ap, int);
  34. switch(p->t_oper) {
  35. case OP_NAME:
  36. p->t_idf = va_arg(ap, struct idf *);
  37. p->t_str = va_arg(ap, char *);
  38. break;
  39. case OP_STRING:
  40. p->t_sval = va_arg(ap, char *);
  41. break;
  42. case OP_REAL:
  43. p->t_fval = va_arg(ap, double);
  44. break;
  45. case OP_AT:
  46. p->t_lino = va_arg(ap, long);
  47. p->t_filename = va_arg(ap, char *);
  48. break;
  49. case OP_INTEGER:
  50. case OP_NEXT:
  51. case OP_STEP:
  52. case OP_REGS:
  53. case OP_DELETE:
  54. case OP_RESTORE:
  55. case OP_WHERE:
  56. p->t_ival = va_arg(ap, long);
  57. break;
  58. default:
  59. na = nargs(p->t_oper);
  60. assert(na <= MAXARGS);
  61. for (i = 0; i < na; i++) {
  62. p->t_args[i] = va_arg(ap, p_tree);
  63. }
  64. break;
  65. }
  66. }
  67. va_end(ap);
  68. return p;
  69. }
  70. adjust_oper(pp)
  71. p_tree *pp;
  72. {
  73. register p_tree p = *pp, p1;
  74. switch(p->t_whichoper) {
  75. case E_DERSELECT:
  76. p1 = mknode(OP_UNOP, p->t_args[0]);
  77. p1->t_whichoper = E_DEREF;
  78. p->t_args[0] = p1;
  79. p->t_whichoper = E_SELECT;
  80. break;
  81. }
  82. }
  83. freenode(p)
  84. register p_tree p;
  85. {
  86. register int na, i;
  87. if (! p) return;
  88. na = nargs(p->t_oper);
  89. assert(na <= MAXARGS);
  90. for (i = 0; i < na; i++) {
  91. freenode(p->t_args[i]);
  92. }
  93. free_tree(p);
  94. }
  95. static t_addr
  96. get_addr_from_node(p)
  97. p_tree p;
  98. {
  99. t_addr a = ILL_ADDR;
  100. register p_symbol sym;
  101. if (! p) return NO_ADDR;
  102. if (p->t_address != 0) return p->t_address;
  103. switch(p->t_oper) {
  104. case OP_AT:
  105. if (! p->t_filename &&
  106. (! listfile || ! (p->t_filename = listfile->sy_idf->id_text))) {
  107. error("no current file");
  108. break;
  109. }
  110. a = get_addr_from_position(&(p->t_pos));
  111. if (a == ILL_ADDR) {
  112. error("could not determine address of \"%s\":%d",
  113. p->t_filename, p->t_lino);
  114. break;
  115. }
  116. p->t_address = a;
  117. break;
  118. case OP_IN:
  119. a = get_addr_from_node(p->t_args[0]);
  120. p->t_address = a;
  121. break;
  122. case OP_NAME:
  123. case OP_SELECT:
  124. sym = identify(p, FUNCTION|PROC|MODULE);
  125. if (! sym) {
  126. break;
  127. }
  128. if (! sym->sy_name.nm_scope || ! sym->sy_name.nm_scope->sc_bp_opp) {
  129. error("could not determine address of \"%s\"", p->t_str);
  130. break;
  131. }
  132. a = sym->sy_name.nm_scope->sc_bp_opp;
  133. break;
  134. default:
  135. assert(0);
  136. }
  137. return a;
  138. }
  139. print_node(p, top_level)
  140. register p_tree p;
  141. {
  142. if (!p) return;
  143. switch(p->t_oper) {
  144. case OP_LIST:
  145. fputs("list ", db_out);
  146. if (p->t_args[0]) {
  147. print_node(p->t_args[0], 0);
  148. if (p->t_args[1]) {
  149. fputs(", ", db_out);
  150. print_node(p->t_args[1], 0);
  151. }
  152. }
  153. break;
  154. case OP_PRINT:
  155. fputs("print ", db_out);
  156. print_node(p->t_args[0], 0);
  157. break;
  158. case OP_DISPLAY:
  159. fputs("display ", db_out);
  160. print_node(p->t_args[0], 0);
  161. break;
  162. case OP_FILE:
  163. fputs("file ", db_out);
  164. print_node(p->t_args[0], 0);
  165. break;
  166. case OP_SET:
  167. fputs("set ", db_out);
  168. print_node(p->t_args[0], 0);
  169. fputs(" to ", db_out);
  170. print_node(p->t_args[1], 0);
  171. break;
  172. case OP_FIND:
  173. fputs("find ", db_out);
  174. print_node(p->t_args[0], 0);
  175. break;
  176. case OP_WHICH:
  177. fputs("which ", db_out);
  178. print_node(p->t_args[0], 0);
  179. break;
  180. case OP_DELETE:
  181. fprintf(db_out, "delete %ld", p->t_ival);
  182. break;
  183. case OP_REGS:
  184. fprintf(db_out, "regs %ld", p->t_ival);
  185. break;
  186. case OP_NEXT:
  187. fprintf(db_out, "next %ld", p->t_ival);
  188. break;
  189. case OP_STEP:
  190. fprintf(db_out, "step %ld", p->t_ival);
  191. break;
  192. case OP_STATUS:
  193. fputs("status", db_out);
  194. break;
  195. case OP_DUMP:
  196. fputs("dump ", db_out);
  197. print_position(p->t_address, 1);
  198. break;
  199. case OP_RESTORE:
  200. fprintf(db_out, "restore %ld", p->t_ival);
  201. break;
  202. case OP_WHERE:
  203. fputs("where", db_out);
  204. if (p->t_ival != 0x7fffffff) fprintf(db_out, " %ld", p->t_ival);
  205. break;
  206. case OP_CONT:
  207. fputs("cont", db_out);
  208. if (p->t_args[0]) {
  209. fprintf(db_out, " %ld", p->t_args[0]->t_ival);
  210. }
  211. if (p->t_args[1]) {
  212. fputs(" ", db_out);
  213. print_node(p->t_args[1], 0);
  214. }
  215. break;
  216. case OP_WHEN:
  217. fputs("when ", db_out);
  218. if (p->t_address != NO_ADDR) {
  219. print_position(p->t_address, 1);
  220. }
  221. else print_node(p->t_args[0], 0);
  222. if (p->t_args[1]) {
  223. fputs(" if ", db_out);
  224. print_node(p->t_args[1], 0);
  225. }
  226. p = p->t_args[2];
  227. fputs(" { ", db_out);
  228. while (p->t_oper == OP_LINK) {
  229. print_node(p->t_args[0], 0);
  230. fputs("; ", db_out);
  231. p = p->t_args[1];
  232. }
  233. print_node(p, 0);
  234. fputs(" }", db_out);
  235. break;
  236. case OP_STOP:
  237. fputs("stop ", db_out);
  238. if (p->t_address != NO_ADDR) {
  239. print_position(p->t_address, 1);
  240. }
  241. else print_node(p->t_args[0], 0);
  242. if (p->t_args[1]) {
  243. fputs(" if ", db_out);
  244. print_node(p->t_args[1], 0);
  245. }
  246. break;
  247. case OP_TRACE:
  248. fputs("trace ", db_out);
  249. if (p->t_args[2]) {
  250. fputs("on ", db_out);
  251. print_node(p->t_args[2], 0);
  252. fputs(" ", db_out);
  253. }
  254. if (p->t_address != NO_ADDR) {
  255. print_position(p->t_address, 1);
  256. }
  257. else print_node(p->t_args[0], 0);
  258. if (p->t_args[1]) {
  259. fputs(" if ", db_out);
  260. print_node(p->t_args[1], 0);
  261. }
  262. break;
  263. case OP_AT:
  264. fprintf(db_out, "at \"%s\":%ld", p->t_filename, p->t_lino);
  265. break;
  266. case OP_IN:
  267. fputs("in ", db_out);
  268. print_node(p->t_args[0], 0);
  269. break;
  270. case OP_SELECT:
  271. print_node(p->t_args[0], 0);
  272. fputs("`", db_out);
  273. print_node(p->t_args[1], 0);
  274. break;
  275. case OP_NAME:
  276. fputs(p->t_str, db_out);
  277. break;
  278. case OP_INTEGER:
  279. fprintf(db_out, currlang->decint_fmt, p->t_ival);
  280. break;
  281. case OP_STRING:
  282. (*currlang->printstring)(p->t_sval, strlen(p->t_sval));
  283. break;
  284. case OP_REAL:
  285. fprintf(db_out, currlang->real_fmt, p->t_fval);
  286. break;
  287. case OP_UNOP:
  288. case OP_BINOP:
  289. (*currlang->printop)(p);
  290. break;
  291. }
  292. if (top_level) fputs("\n", db_out);
  293. }
  294. int
  295. repeatable(com)
  296. p_tree com;
  297. {
  298. switch(com->t_oper) {
  299. case OP_CONT:
  300. case OP_NEXT:
  301. case OP_STEP:
  302. case OP_LIST:
  303. case OP_STATUS:
  304. case OP_PRINT:
  305. return 1;
  306. }
  307. return 0;
  308. }
  309. int
  310. in_status(com)
  311. p_tree com;
  312. {
  313. switch(com->t_oper) {
  314. case OP_STOP:
  315. case OP_WHEN:
  316. case OP_TRACE:
  317. case OP_DUMP:
  318. case OP_DISPLAY:
  319. return 1;
  320. }
  321. return 0;
  322. }
  323. eval(p)
  324. p_tree p;
  325. {
  326. if (p) (*operators[p->t_oper].op_fun)(p);
  327. }
  328. do_list(p)
  329. p_tree p;
  330. {
  331. int l1, l2;
  332. if (! p->t_args[0]) {
  333. l1 = listline;
  334. l2 = listline + 9;
  335. }
  336. else {
  337. if (p->t_args[0]->t_oper == OP_INTEGER) {
  338. l1 = p->t_args[0]->t_ival;
  339. assert(p->t_args[1] != 0);
  340. l2 = p->t_args[1]->t_ival;
  341. }
  342. else {
  343. t_addr a = get_addr_from_node(p->t_args[0]);
  344. p_position pos;
  345. if (a == ILL_ADDR) {
  346. error("could not determine address");
  347. return;
  348. }
  349. pos = get_position_from_addr(a);
  350. newfile(str2idf(pos->filename, 1));
  351. l1 = pos->lineno - 5;
  352. if (l1 < 1) l1 = 1;
  353. l2 = l1+9;
  354. }
  355. }
  356. if (listfile) {
  357. lines(listfile->sy_file, l1, l2);
  358. listline = l2+1;
  359. }
  360. else fprintf(db_out, "no current file\n");
  361. }
  362. do_file(p)
  363. p_tree p;
  364. {
  365. if (p->t_args[0]) {
  366. newfile(p->t_args[0]->t_idf);
  367. }
  368. else if (listfile) fprintf(db_out, "%s\n", listfile->sy_idf->id_text);
  369. else fprintf(db_out, "no current file\n");
  370. }
  371. newfile(id)
  372. register struct idf *id;
  373. {
  374. register p_symbol sym = Lookup(id, PervasiveScope, FILESYM);
  375. if (listfile != sym) listline = 1;
  376. listfile = sym;
  377. if (! listfile) {
  378. listline = 1;
  379. listfile = add_file(id->id_text);
  380. listfile->sy_file->f_scope = FileScope;
  381. }
  382. find_language(strrindex(id->id_text, '.'));
  383. }
  384. do_stop(p)
  385. p_tree p;
  386. {
  387. t_addr a = get_addr_from_node(p->t_args[0]);
  388. if (a == ILL_ADDR) {
  389. return;
  390. }
  391. p->t_address = a;
  392. add_to_item_list(p);
  393. if (a != NO_ADDR) {
  394. if (! set_or_clear_breakpoint(a, SETBP)) {
  395. error("could not set breakpoint");
  396. }
  397. }
  398. }
  399. do_trace(p)
  400. p_tree p;
  401. {
  402. t_addr a;
  403. t_addr e;
  404. p->t_address = NO_ADDR;
  405. if (p->t_args[0]) {
  406. a = get_addr_from_node(p->t_args[0]);
  407. if (a == ILL_ADDR) return;
  408. if (p->t_args[0]->t_oper == OP_AT) {
  409. e = a;
  410. p->t_address = a;
  411. }
  412. else {
  413. p_scope sc = get_next_scope_from_addr(a+1);
  414. if (sc) e = sc->sc_start - 1;
  415. else e = 0xffffffff;
  416. }
  417. if (! set_or_clear_trace(a, e, SETTRACE)) {
  418. error("could not set trace");
  419. }
  420. }
  421. add_to_item_list(p);
  422. }
  423. do_continue(p)
  424. p_tree p;
  425. {
  426. int count;
  427. if (p) {
  428. count = p->t_args[0]->t_ival;
  429. if (p->t_args[1]) {
  430. t_addr a = get_addr_from_position(&(p->t_args[1]->t_pos));
  431. p_scope sc = get_scope_from_addr(a);
  432. if (a == ILL_ADDR || base_scope(sc) != base_scope(CurrentScope) ||
  433. ! set_pc(a)) {
  434. error("cannot continue at line %d",
  435. p->t_args[1]->t_lino);
  436. return;
  437. }
  438. }
  439. }
  440. else count = 1;
  441. while (count--) {
  442. if (! send_cont(count==0)) {
  443. error("no debuggee");
  444. break;
  445. }
  446. }
  447. }
  448. do_step(p)
  449. p_tree p;
  450. {
  451. if (! do_single_step(SETSS, p->t_ival)) {
  452. error("no debuggee");
  453. }
  454. }
  455. do_next(p)
  456. p_tree p;
  457. {
  458. if (! do_single_step(SETSSF, p->t_ival)) {
  459. error("no debuggee");
  460. }
  461. }
  462. extern t_addr *get_EM_regs();
  463. do_regs(p)
  464. p_tree p;
  465. {
  466. t_addr *buf;
  467. int n = p->t_ival;
  468. if (! (buf = get_EM_regs(n))) {
  469. error("no debuggee");
  470. return;
  471. }
  472. fprintf(db_out, "EM registers %d levels back:\n", n);
  473. fprintf(db_out, "\tLocalBase =\t0x%lx\n\tArgumentBase =\t0x%lx\n",
  474. (long) buf[LB_OFF], (long) buf[AB_OFF]);
  475. fprintf(db_out, "\tProgramCounter=\t0x%lx\n\tHeapPointer = \t0x%lx\n",
  476. (long) buf[PC_OFF],
  477. (long) buf[HP_OFF]);
  478. fprintf(db_out, "\tStackPointer =\t0x%lx\n", (long) buf[SP_OFF]);
  479. }
  480. /*ARGSUSED*/
  481. do_where(p)
  482. p_tree p;
  483. {
  484. int i = 0;
  485. unsigned int cnt;
  486. for (cnt = p->t_ival; cnt != 0; cnt--) {
  487. t_addr AB;
  488. t_addr PC;
  489. p_scope sc;
  490. t_addr *buf;
  491. if (! (buf = get_EM_regs(i++))) {
  492. error("no debuggee");
  493. return;
  494. }
  495. AB = buf[AB_OFF];
  496. PC = buf[PC_OFF];
  497. if (! AB) break;
  498. sc = base_scope(get_scope_from_addr(PC));
  499. if (! sc || sc->sc_start > PC) break;
  500. fprintf(db_out, "%s(", sc->sc_definedby->sy_idf->id_text);
  501. print_params(sc->sc_definedby->sy_type, AB, has_static_link(sc));
  502. fputs(") ", db_out);
  503. print_position(PC, 0);
  504. fputs("\n", db_out);
  505. }
  506. }
  507. /*ARGSUSED*/
  508. do_status(p)
  509. p_tree p;
  510. {
  511. print_items();
  512. }
  513. extern p_tree remove_from_item_list();
  514. do_delete(p)
  515. p_tree p;
  516. {
  517. p = remove_from_item_list((int) p->t_ival);
  518. if (p) switch(p->t_oper) {
  519. case OP_WHEN:
  520. case OP_STOP: {
  521. t_addr a = get_addr_from_node(p->t_args[0]);
  522. if (a != ILL_ADDR && a != NO_ADDR) {
  523. set_or_clear_breakpoint(a, CLRBP);
  524. }
  525. break;
  526. }
  527. case OP_TRACE: {
  528. t_addr a = get_addr_from_node(p->t_args[0]);
  529. if (a != ILL_ADDR && a != NO_ADDR) {
  530. t_addr e;
  531. if (p->t_args[0]->t_oper == OP_AT) {
  532. e = a;
  533. }
  534. else {
  535. p_scope sc = get_next_scope_from_addr(a+1);
  536. if (sc) e = sc->sc_start - 1;
  537. else e = 0xffffffff;
  538. }
  539. set_or_clear_trace(a, e, CLRTRACE);
  540. }
  541. break;
  542. }
  543. case OP_DUMP:
  544. free_dump(p);
  545. }
  546. freenode(p);
  547. }
  548. do_print(p)
  549. p_tree p;
  550. {
  551. char *buf;
  552. long size;
  553. p_type tp;
  554. switch(p->t_oper) {
  555. case OP_PRINT:
  556. case OP_DISPLAY:
  557. do_print(p->t_args[0]);
  558. break;
  559. case OP_LINK:
  560. do_print(p->t_args[0]);
  561. do_print(p->t_args[1]);
  562. break;
  563. default:
  564. if (! eval_expr(p, &buf, &size, &tp)) return;
  565. print_node(p, 0);
  566. fputs(" = ", db_out);
  567. print_val(tp, size, buf, 0, 0);
  568. if (buf) free(buf);
  569. fputs("\n", db_out);
  570. break;
  571. }
  572. }
  573. do_set(p)
  574. p_tree p;
  575. {
  576. char *buf = 0;
  577. long size, size2;
  578. p_type tp, tp2;
  579. t_addr a;
  580. if (! eval_desig(p->t_args[0], &a, &size, &tp) ||
  581. ! eval_expr(p->t_args[1], &buf, &size2, &tp2) ||
  582. ! convert(&buf, &size2, &tp2, tp, size)) {
  583. if (buf) free(buf);
  584. return;
  585. }
  586. if (! set_bytes(size, buf, a)) {
  587. error("could not handle this SET request");
  588. }
  589. free(buf);
  590. }
  591. perform(p, a)
  592. register p_tree p;
  593. t_addr a;
  594. {
  595. switch(p->t_oper) {
  596. case OP_WHEN:
  597. p = p->t_args[2];
  598. while (p->t_oper == OP_LINK) {
  599. eval(p->t_args[0]);
  600. p = p->t_args[1];
  601. }
  602. eval(p);
  603. break;
  604. case OP_TRACE:
  605. if (p->t_args[0] && p->t_args[0]->t_oper == OP_IN) {
  606. register p_scope sc = base_scope(CurrentScope);
  607. if (sc != get_scope_from_addr(p->t_args[0]->t_address)) {
  608. break;
  609. }
  610. }
  611. list_position(get_position_from_addr(a));
  612. if (p->t_args[2]) do_print(p->t_args[2]);
  613. break;
  614. default:
  615. assert(0);
  616. }
  617. }
  618. list_position(pos)
  619. p_position pos;
  620. {
  621. newfile(str2idf(pos->filename, 1));
  622. currfile = listfile;
  623. currline = pos->lineno;
  624. listline = currline-5;
  625. lines(currfile->sy_file, (int)currline, (int)currline);
  626. }