tree.c 10 KB

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