kid.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  1. /* kid.c -- ARMulator RDP/RDI interface: ARM6 Instruction Emulator.
  2. Copyright (C) 1994 Advanced RISC Machines Ltd.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, see <http://www.gnu.org/licenses/>. */
  13. /*****************************************************************/
  14. /* The child process continues here... */
  15. /* It waits on a pipe from the parent and translates the RDP */
  16. /* messages into RDI calls to the ARMulator passing RDP replies */
  17. /* back up a pipe to the parent. */
  18. /*****************************************************************/
  19. #include <sys/types.h>
  20. #include <signal.h>
  21. #include "armdefs.h"
  22. #include "dbg_conf.h"
  23. #include "dbg_hif.h"
  24. #include "dbg_rdi.h"
  25. #include "gdbhost.h"
  26. #include "communicate.h"
  27. /* The pipes between the two processes */
  28. extern int mumkid[2];
  29. extern int kidmum[2];
  30. /* The maximum number of file descriptors */
  31. extern int nfds;
  32. /* The machine name */
  33. #define MAXHOSTNAMELENGTH 64
  34. extern char localhost[MAXHOSTNAMELENGTH + 1];
  35. /* The socket number */
  36. extern unsigned int socketnumber;
  37. /* RDI interface */
  38. extern const struct RDIProcVec armul_rdi;
  39. static int MYrdp_level = 0;
  40. static int rdi_state = 0;
  41. /**************************************************************/
  42. /* Signal handler that terminates excecution in the ARMulator */
  43. /**************************************************************/
  44. void
  45. kid_handlesignal (int sig)
  46. {
  47. #ifdef DEBUG
  48. fprintf (stderr, "Terminate ARMulator excecution\n");
  49. #endif
  50. if (sig != SIGUSR1)
  51. {
  52. fprintf (stderr, "Unsupported signal.\n");
  53. return;
  54. }
  55. armul_rdi.info (RDISignal_Stop, (unsigned long *) 0, (unsigned long *) 0);
  56. }
  57. /********************************************************************/
  58. /* Waits on a pipe from the socket demon for RDP and */
  59. /* acts as an RDP to RDI interpreter on the front of the ARMulator. */
  60. /********************************************************************/
  61. void
  62. kid ()
  63. {
  64. char *p, *q;
  65. int i, j, k;
  66. long outofthebag;
  67. unsigned char c, d, message;
  68. ARMword x, y, z;
  69. struct sigaction action;
  70. PointHandle point;
  71. Dbg_ConfigBlock config;
  72. Dbg_HostosInterface hostif;
  73. struct Dbg_MCState *MCState;
  74. char command_line[256];
  75. struct fd_set readfds;
  76. /* Setup a signal handler for SIGUSR1 */
  77. action.sa_handler = kid_handlesignal;
  78. action.sa_mask = 0;
  79. action.sa_flags = 0;
  80. sigaction (SIGUSR1, &action, (struct sigaction *) 0);
  81. while (1)
  82. {
  83. /* Wait for ever */
  84. FD_ZERO (&readfds);
  85. FD_SET (mumkid[0], &readfds);
  86. i = select (nfds, &readfds,
  87. (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
  88. if (i < 0)
  89. {
  90. perror ("select");
  91. }
  92. if (read (mumkid[0], &message, 1) < 1)
  93. {
  94. perror ("read");
  95. }
  96. switch (message)
  97. {
  98. case RDP_Start:
  99. /* Open and/or Initialise */
  100. BAG_newbag ();
  101. MYread_char (mumkid[0], &c); /* type */
  102. MYread_word (mumkid[0], &x); /* memorysize */
  103. if (c & 0x2)
  104. MYread_char (mumkid[0], &d); /* speed */
  105. config.processor = 0;
  106. config.memorysize = x;
  107. config.bytesex = (c & 0x4) ? RDISex_Big : RDISex_Little;
  108. if (c & 0x8)
  109. config.bytesex = RDISex_DontCare;
  110. hostif.dbgprint = myprint;
  111. hostif.dbgpause = mypause;
  112. hostif.dbgarg = stdout;
  113. hostif.writec = mywritec;
  114. hostif.readc = myreadc;
  115. hostif.write = mywrite;
  116. hostif.gets = mygets;
  117. hostif.reset = mypause; /* do nothing */
  118. hostif.resetarg = "Do I love resetting or what!\n";
  119. if (rdi_state)
  120. {
  121. /* we have restarted, so kill off the existing run. */
  122. /* armul_rdi.close(); */
  123. }
  124. i = armul_rdi.open (c & 0x3, &config, &hostif, MCState);
  125. rdi_state = 1;
  126. MYwrite_char (kidmum[1], RDP_Return);
  127. MYwrite_char (kidmum[1], (unsigned char) i);
  128. x = ~0x4;
  129. armul_rdi.info (RDIVector_Catch, &x, 0);
  130. break;
  131. case RDP_End:
  132. /* Close and Finalise */
  133. i = armul_rdi.close ();
  134. rdi_state = 0;
  135. MYwrite_char (kidmum[1], RDP_Return);
  136. MYwrite_char (kidmum[1], (unsigned char) i);
  137. break;
  138. case RDP_Read:
  139. /* Read Memory Address */
  140. MYread_word (mumkid[0], &x); /* address */
  141. MYread_word (mumkid[0], &y); /* nbytes */
  142. p = (char *) malloc (y);
  143. i = armul_rdi.read (x, p, (unsigned *) &y);
  144. MYwrite_char (kidmum[1], RDP_Return);
  145. for (k = 0; k < y; k++)
  146. MYwrite_char (kidmum[1], p[k]);
  147. free (p);
  148. MYwrite_char (kidmum[1], (unsigned char) i);
  149. if (i)
  150. MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
  151. break;
  152. case RDP_Write:
  153. /* Write Memory Address */
  154. MYread_word (mumkid[0], &x); /* address */
  155. MYread_word (mumkid[0], &y); /* nbytes */
  156. p = (char *) malloc (y);
  157. for (k = 0; k < y; k++)
  158. MYread_char (mumkid[0], &p[k]);
  159. i = armul_rdi.write (p, x, (unsigned *) &y);
  160. free (p);
  161. MYwrite_char (kidmum[1], RDP_Return);
  162. MYwrite_char (kidmum[1], (unsigned char) i);
  163. if (i)
  164. MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
  165. break;
  166. case RDP_CPUread:
  167. /* Read CPU State */
  168. MYread_char (mumkid[0], &c); /* mode */
  169. MYread_word (mumkid[0], &x); /* mask */
  170. p = (char *) malloc (4 * RDINumCPURegs);
  171. i = armul_rdi.CPUread (c, x, (ARMword *) p);
  172. MYwrite_char (kidmum[1], RDP_Return);
  173. for (k = 1, j = 0; k != 0x80000000; k *= 2)
  174. if (k & x)
  175. MYwrite_word (kidmum[1], ((ARMword *) p)[j++]);
  176. free (p);
  177. if (i)
  178. MYwrite_char (kidmum[1], (unsigned char) j);
  179. MYwrite_char (kidmum[1], (unsigned char) i);
  180. break;
  181. case RDP_CPUwrite:
  182. /* Write CPU State */
  183. MYread_char (mumkid[0], &c); /* mode */
  184. MYread_word (mumkid[0], &x); /* mask */
  185. p = (char *) malloc (4 * RDINumCPURegs);
  186. for (k = 1, j = 0; k != 0x80000000; k *= 2)
  187. if (k & x)
  188. MYread_word (mumkid[0], &(((ARMword *) p)[j++]));
  189. i = armul_rdi.CPUwrite (c, x, (ARMword *) p);
  190. MYwrite_char (kidmum[1], RDP_Return);
  191. MYwrite_char (kidmum[1], (unsigned char) i);
  192. free (p);
  193. break;
  194. case RDP_CPread:
  195. /* Read Co-Processor State */
  196. MYread_char (mumkid[0], &c); /* CPnum */
  197. MYread_word (mumkid[0], &x); /* mask */
  198. p = q = (char *) malloc (16 * RDINumCPRegs);
  199. i = armul_rdi.CPread (c, x, (ARMword *) p);
  200. MYwrite_char (kidmum[1], RDP_Return);
  201. for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
  202. if (k & x)
  203. {
  204. if ((c == 1 || c == 2) && k <= 128)
  205. {
  206. MYwrite_FPword (kidmum[1], q);
  207. q += 16;
  208. }
  209. else
  210. {
  211. MYwrite_word (kidmum[1], *q);
  212. q += 4;
  213. }
  214. }
  215. free (p);
  216. if (i)
  217. MYwrite_char (kidmum[1], (unsigned char) j);
  218. MYwrite_char (kidmum[1], (unsigned char) i);
  219. break;
  220. case RDP_CPwrite:
  221. /* Write Co-Processor State */
  222. MYread_char (mumkid[0], &c); /* CPnum */
  223. MYread_word (mumkid[0], &x); /* mask */
  224. p = q = (char *) malloc (16 * RDINumCPURegs);
  225. for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
  226. if (k & x)
  227. {
  228. if ((c == 1 || c == 2) && k <= 128)
  229. {
  230. MYread_FPword (kidmum[1], q);
  231. q += 16;
  232. }
  233. else
  234. {
  235. MYread_word (mumkid[0], (ARMword *) q);
  236. q += 4;
  237. }
  238. }
  239. i = armul_rdi.CPwrite (c, x, (ARMword *) p);
  240. MYwrite_char (kidmum[1], RDP_Return);
  241. MYwrite_char (kidmum[1], (unsigned char) i);
  242. free (p);
  243. break;
  244. case RDP_SetBreak:
  245. /* Set Breakpoint */
  246. MYread_word (mumkid[0], &x); /* address */
  247. MYread_char (mumkid[0], &c); /* type */
  248. if ((c & 0xf) >= 5)
  249. MYread_word (mumkid[0], &y); /* bound */
  250. i = armul_rdi.setbreak (x, c, y, &point);
  251. if (!MYrdp_level)
  252. BAG_putpair ((long) x, (long) point);
  253. MYwrite_char (kidmum[1], RDP_Return);
  254. if (MYrdp_level)
  255. MYwrite_word (kidmum[1], point);
  256. MYwrite_char (kidmum[1], (unsigned char) i);
  257. break;
  258. case RDP_ClearBreak:
  259. /* Clear Breakpoint */
  260. MYread_word (mumkid[0], &point); /* PointHandle */
  261. if (!MYrdp_level)
  262. {
  263. BAG_getsecond ((long) point, &outofthebag); /* swap pointhandle for address */
  264. BAG_killpair_byfirst (outofthebag);
  265. point = outofthebag;
  266. }
  267. i = armul_rdi.clearbreak (point);
  268. MYwrite_char (kidmum[1], RDP_Return);
  269. MYwrite_char (kidmum[1], (unsigned char) i);
  270. break;
  271. case RDP_SetWatch:
  272. /* Set Watchpoint */
  273. MYread_word (mumkid[0], &x); /* address */
  274. MYread_char (mumkid[0], &c); /* type */
  275. MYread_char (mumkid[0], &d); /* datatype */
  276. if ((c & 0xf) >= 5)
  277. MYread_word (mumkid[0], &y); /* bound */
  278. i = armul_rdi.setwatch (x, c, d, y, &point);
  279. MYwrite_char (kidmum[1], RDP_Return);
  280. MYwrite_word (kidmum[1], point);
  281. MYwrite_char (kidmum[1], (unsigned char) i);
  282. break;
  283. case RDP_ClearWatch:
  284. /* Clear Watchpoint */
  285. MYread_word (mumkid[0], &point); /* PointHandle */
  286. i = armul_rdi.clearwatch (point);
  287. MYwrite_char (kidmum[1], RDP_Return);
  288. MYwrite_char (kidmum[1], (unsigned char) i);
  289. break;
  290. case RDP_Execute:
  291. /* Excecute */
  292. MYread_char (mumkid[0], &c); /* return */
  293. #ifdef DEBUG
  294. fprintf (stderr, "Starting execution\n");
  295. #endif
  296. i = armul_rdi.execute (&point);
  297. #ifdef DEBUG
  298. fprintf (stderr, "Completed execution\n");
  299. #endif
  300. MYwrite_char (kidmum[1], RDP_Return);
  301. if (c & 0x80)
  302. MYwrite_word (kidmum[1], point);
  303. MYwrite_char (kidmum[1], (unsigned char) i);
  304. break;
  305. case RDP_Step:
  306. /* Step */
  307. MYread_char (mumkid[0], &c); /* return */
  308. MYread_word (mumkid[0], &x); /* ninstr */
  309. point = 0x87654321;
  310. i = armul_rdi.step (x, &point);
  311. MYwrite_char (kidmum[1], RDP_Return);
  312. if (c & 0x80)
  313. MYwrite_word (kidmum[1], point);
  314. MYwrite_char (kidmum[1], (unsigned char) i);
  315. break;
  316. case RDP_Info:
  317. /* Info */
  318. MYread_word (mumkid[0], &x);
  319. switch (x)
  320. {
  321. case RDIInfo_Target:
  322. i = armul_rdi.info (RDIInfo_Target, &y, &z);
  323. MYwrite_char (kidmum[1], RDP_Return);
  324. MYwrite_word (kidmum[1], y); /* Loads of info... */
  325. MYwrite_word (kidmum[1], z); /* Model */
  326. MYwrite_char (kidmum[1], (unsigned char) i);
  327. break;
  328. case RDISet_RDILevel:
  329. MYread_word (mumkid[0], &x); /* arg1, debug level */
  330. i = armul_rdi.info (RDISet_RDILevel, &x, 0);
  331. if (i == RDIError_NoError)
  332. MYrdp_level = x;
  333. MYwrite_char (kidmum[1], RDP_Return);
  334. MYwrite_char (kidmum[1], (unsigned char) i);
  335. break;
  336. case RDISet_Cmdline:
  337. for (p = command_line; MYread_char (mumkid[0], p), *p; p++)
  338. ; /* String */
  339. i = armul_rdi.info (RDISet_Cmdline,
  340. (unsigned long *) command_line, 0);
  341. MYwrite_char (kidmum[1], RDP_Return);
  342. MYwrite_char (kidmum[1], (unsigned char) i);
  343. break;
  344. case RDIInfo_Step:
  345. i = armul_rdi.info (RDIInfo_Step, &x, 0);
  346. MYwrite_char (kidmum[1], RDP_Return);
  347. MYwrite_word (kidmum[1], x);
  348. MYwrite_char (kidmum[1], (unsigned char) i);
  349. break;
  350. case RDIVector_Catch:
  351. MYread_word (mumkid[0], &x);
  352. i = armul_rdi.info (RDIVector_Catch, &x, 0);
  353. MYwrite_char (kidmum[1], RDP_Return);
  354. MYwrite_char (kidmum[1], i);
  355. break;
  356. case RDIInfo_Points:
  357. i = armul_rdi.info (RDIInfo_Points, &x, 0);
  358. MYwrite_char (kidmum[1], RDP_Return);
  359. MYwrite_word (kidmum[1], x);
  360. MYwrite_char (kidmum[1], (unsigned char) i);
  361. break;
  362. default:
  363. fprintf (stderr, "Unsupported info code %d\n", x);
  364. break;
  365. }
  366. break;
  367. case RDP_OSOpReply:
  368. /* OS Operation Reply */
  369. MYwrite_char (kidmum[1], RDP_Fatal);
  370. break;
  371. case RDP_Reset:
  372. /* Reset */
  373. for (i = 0; i < 50; i++)
  374. MYwrite_char (kidmum[1], RDP_Reset);
  375. p = (char *) malloc (MAXHOSTNAMELENGTH + 5 + 20);
  376. sprintf (p, "Running on %s:%d\n", localhost, socketnumber);
  377. MYwrite_string (kidmum[1], p);
  378. free (p);
  379. break;
  380. default:
  381. fprintf (stderr, "Oh dear: Something is seriously wrong :-(\n");
  382. /* Hmm.. bad RDP operation */
  383. break;
  384. }
  385. }
  386. }
  387. /* Handles memory read operations until an OS Operation Reply Message is */
  388. /* encounterd. It then returns the byte info value (0, 1, or 2) and fills */
  389. /* in 'putinr0' with the data if appropriate. */
  390. int
  391. wait_for_osreply (ARMword * reply)
  392. {
  393. char *p, *q;
  394. int i, j, k;
  395. unsigned char c, d, message;
  396. ARMword x, y, z;
  397. struct sigaction action;
  398. PointHandle point;
  399. Dbg_ConfigBlock config;
  400. Dbg_HostosInterface hostif;
  401. struct Dbg_MCState *MCState;
  402. char command_line[256];
  403. struct fd_set readfds;
  404. #ifdef DEBUG
  405. fprintf (stderr, "wait_for_osreply ().\n");
  406. #endif
  407. /* Setup a signal handler for SIGUSR1 */
  408. action.sa_handler = kid_handlesignal;
  409. action.sa_mask = 0;
  410. action.sa_flags = 0;
  411. sigaction (SIGUSR1, &action, (struct sigaction *) 0);
  412. while (1)
  413. {
  414. /* Wait for ever */
  415. FD_ZERO (&readfds);
  416. FD_SET (mumkid[0], &readfds);
  417. i = select (nfds, &readfds,
  418. (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
  419. if (i < 0)
  420. {
  421. perror ("select");
  422. }
  423. if (read (mumkid[0], &message, 1) < 1)
  424. {
  425. perror ("read");
  426. }
  427. switch (message)
  428. {
  429. case RDP_Read:
  430. /* Read Memory Address */
  431. MYread_word (mumkid[0], &x); /* address */
  432. MYread_word (mumkid[0], &y); /* nbytes */
  433. p = (char *) malloc (y);
  434. i = armul_rdi.read (x, p, (unsigned *) &y);
  435. MYwrite_char (kidmum[1], RDP_Return);
  436. for (k = 0; k < y; k++)
  437. MYwrite_char (kidmum[1], p[k]);
  438. free (p);
  439. MYwrite_char (kidmum[1], (unsigned char) i);
  440. if (i)
  441. MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
  442. break;
  443. case RDP_Write:
  444. /* Write Memory Address */
  445. MYread_word (mumkid[0], &x); /* address */
  446. MYread_word (mumkid[0], &y); /* nbytes */
  447. p = (char *) malloc (y);
  448. for (k = 0; k < y; k++)
  449. MYread_char (mumkid[0], &p[k]);
  450. i = armul_rdi.write (p, x, (unsigned *) &y);
  451. free (p);
  452. MYwrite_char (kidmum[1], RDP_Return);
  453. MYwrite_char (kidmum[1], (unsigned char) i);
  454. if (i)
  455. MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
  456. break;
  457. case RDP_OSOpReply:
  458. /* OS Operation Reply */
  459. MYread_char (mumkid[0], &c);
  460. if (c == 1)
  461. MYread_char (mumkid[0], (char *) reply);
  462. if (c == 2)
  463. MYread_word (mumkid[0], reply);
  464. return c;
  465. break;
  466. default:
  467. fprintf (stderr,
  468. "HELP! Unaccounted-for message during OS request. \n");
  469. MYwrite_char (kidmum[1], RDP_Fatal);
  470. }
  471. }
  472. }