interp.c 33 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243
  1. /* Simulator for Analog Devices Blackfin processors.
  2. Copyright (C) 2005-2015 Free Software Foundation, Inc.
  3. Contributed by Analog Devices, Inc.
  4. This file is part of simulators.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. #include "config.h"
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <signal.h>
  20. #include <errno.h>
  21. #include <fcntl.h>
  22. #include <unistd.h>
  23. #include <sys/time.h>
  24. #include "gdb/callback.h"
  25. #include "gdb/signals.h"
  26. #include "sim-main.h"
  27. #include "sim-syscall.h"
  28. #include "sim-hw.h"
  29. #include "targ-vals.h"
  30. /* The numbers here do not matter. They just need to be unique. They also
  31. need not be static across releases -- they're used internally only. The
  32. mapping from the Linux ABI to the CB values is in linux-targ-map.h. */
  33. #define CB_SYS_ioctl 201
  34. #define CB_SYS_mmap2 202
  35. #define CB_SYS_munmap 203
  36. #define CB_SYS_dup2 204
  37. #define CB_SYS_getuid 205
  38. #define CB_SYS_getuid32 206
  39. #define CB_SYS_getgid 207
  40. #define CB_SYS_getgid32 208
  41. #define CB_SYS_setuid 209
  42. #define CB_SYS_setuid32 210
  43. #define CB_SYS_setgid 211
  44. #define CB_SYS_setgid32 212
  45. #define CB_SYS_pread 213
  46. #define CB_SYS__llseek 214
  47. #define CB_SYS_getcwd 215
  48. #define CB_SYS_stat64 216
  49. #define CB_SYS_lstat64 217
  50. #define CB_SYS_fstat64 218
  51. #define CB_SYS_ftruncate64 219
  52. #define CB_SYS_gettimeofday 220
  53. #define CB_SYS_access 221
  54. #include "linux-targ-map.h"
  55. #include "linux-fixed-code.h"
  56. #include "elf/common.h"
  57. #include "elf/external.h"
  58. #include "elf/internal.h"
  59. #include "elf/bfin.h"
  60. #include "elf-bfd.h"
  61. #include "dv-bfin_cec.h"
  62. #include "dv-bfin_mmu.h"
  63. #ifndef HAVE_GETUID
  64. # define getuid() 0
  65. #endif
  66. #ifndef HAVE_GETGID
  67. # define getgid() 0
  68. #endif
  69. #ifndef HAVE_GETEUID
  70. # define geteuid() 0
  71. #endif
  72. #ifndef HAVE_GETEGID
  73. # define getegid() 0
  74. #endif
  75. #ifndef HAVE_SETUID
  76. # define setuid(uid) -1
  77. #endif
  78. #ifndef HAVE_SETGID
  79. # define setgid(gid) -1
  80. #endif
  81. static const char cb_linux_stat_map_32[] =
  82. /* Linux kernel 32bit layout: */
  83. "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
  84. "space,2:st_size,4:st_blksize,4:st_blocks,4:st_atime,4:st_atimensec,4:"
  85. "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:space,4";
  86. /* uClibc public ABI 32bit layout:
  87. "st_dev,8:space,2:space,2:st_ino,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:"
  88. "st_rdev,8:space,2:space,2:st_size,4:st_blksiez,4:st_blocks,4:st_atime,4:"
  89. "st_atimensec,4:st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:"
  90. "space,4"; */
  91. static const char cb_linux_stat_map_64[] =
  92. "st_dev,8:space,4:space,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:st_rdev,8:"
  93. "space,4:st_size,8:st_blksize,4:st_blocks,8:st_atime,4:st_atimensec,4:"
  94. "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:st_ino,8";
  95. static const char cb_libgloss_stat_map_32[] =
  96. "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
  97. "st_size,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:"
  98. "space,4:st_blksize,4:st_blocks,4:space,8";
  99. static const char *stat_map_32, *stat_map_64;
  100. /* Count the number of arguments in an argv. */
  101. static int
  102. count_argc (const char * const *argv)
  103. {
  104. int i;
  105. if (! argv)
  106. return -1;
  107. for (i = 0; argv[i] != NULL; ++i)
  108. continue;
  109. return i;
  110. }
  111. /* Simulate a monitor trap, put the result into r0 and errno into r1
  112. return offset by which to adjust pc. */
  113. void
  114. bfin_syscall (SIM_CPU *cpu)
  115. {
  116. SIM_DESC sd = CPU_STATE (cpu);
  117. const char * const *argv = (void *)STATE_PROG_ARGV (sd);
  118. host_callback *cb = STATE_CALLBACK (sd);
  119. bu32 args[6];
  120. CB_SYSCALL sc;
  121. char *p;
  122. char _tbuf[1024 * 3], *tbuf = _tbuf, tstr[1024];
  123. int fmt_ret_hex = 0;
  124. CB_SYSCALL_INIT (&sc);
  125. if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
  126. {
  127. /* Linux syscall. */
  128. sc.func = PREG (0);
  129. sc.arg1 = args[0] = DREG (0);
  130. sc.arg2 = args[1] = DREG (1);
  131. sc.arg3 = args[2] = DREG (2);
  132. sc.arg4 = args[3] = DREG (3);
  133. /*sc.arg5 =*/ args[4] = DREG (4);
  134. /*sc.arg6 =*/ args[5] = DREG (5);
  135. }
  136. else
  137. {
  138. /* libgloss syscall. */
  139. sc.func = PREG (0);
  140. sc.arg1 = args[0] = GET_LONG (DREG (0));
  141. sc.arg2 = args[1] = GET_LONG (DREG (0) + 4);
  142. sc.arg3 = args[2] = GET_LONG (DREG (0) + 8);
  143. sc.arg4 = args[3] = GET_LONG (DREG (0) + 12);
  144. /*sc.arg5 =*/ args[4] = GET_LONG (DREG (0) + 16);
  145. /*sc.arg6 =*/ args[5] = GET_LONG (DREG (0) + 20);
  146. }
  147. sc.p1 = (PTR) sd;
  148. sc.p2 = (PTR) cpu;
  149. sc.read_mem = sim_syscall_read_mem;
  150. sc.write_mem = sim_syscall_write_mem;
  151. /* Common cb_syscall() handles most functions. */
  152. switch (cb_target_to_host_syscall (cb, sc.func))
  153. {
  154. case CB_SYS_exit:
  155. tbuf += sprintf (tbuf, "exit(%i)", args[0]);
  156. sim_engine_halt (sd, cpu, NULL, PCREG, sim_exited, sc.arg1);
  157. #ifdef CB_SYS_argc
  158. case CB_SYS_argc:
  159. tbuf += sprintf (tbuf, "argc()");
  160. sc.result = count_argc (argv);
  161. break;
  162. case CB_SYS_argnlen:
  163. {
  164. tbuf += sprintf (tbuf, "argnlen(%u)", args[0]);
  165. if (sc.arg1 < count_argc (argv))
  166. sc.result = strlen (argv[sc.arg1]);
  167. else
  168. sc.result = -1;
  169. }
  170. break;
  171. case CB_SYS_argn:
  172. {
  173. tbuf += sprintf (tbuf, "argn(%u)", args[0]);
  174. if (sc.arg1 < count_argc (argv))
  175. {
  176. const char *argn = argv[sc.arg1];
  177. int len = strlen (argn);
  178. int written = sc.write_mem (cb, &sc, sc.arg2, argn, len + 1);
  179. if (written == len + 1)
  180. sc.result = sc.arg2;
  181. else
  182. sc.result = -1;
  183. }
  184. else
  185. sc.result = -1;
  186. }
  187. break;
  188. #endif
  189. case CB_SYS_gettimeofday:
  190. {
  191. struct timeval _tv, *tv = &_tv;
  192. struct timezone _tz, *tz = &_tz;
  193. tbuf += sprintf (tbuf, "gettimeofday(%#x, %#x)", args[0], args[1]);
  194. if (sc.arg1 == 0)
  195. tv = NULL;
  196. if (sc.arg2 == 0)
  197. tz = NULL;
  198. sc.result = gettimeofday (tv, tz);
  199. if (sc.result == 0)
  200. {
  201. bu32 t;
  202. if (tv)
  203. {
  204. t = tv->tv_sec;
  205. sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
  206. t = tv->tv_usec;
  207. sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
  208. }
  209. if (sc.arg2)
  210. {
  211. t = tz->tz_minuteswest;
  212. sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
  213. t = tz->tz_dsttime;
  214. sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
  215. }
  216. }
  217. else
  218. goto sys_finish;
  219. }
  220. break;
  221. case CB_SYS_ioctl:
  222. /* XXX: hack just enough to get basic stdio w/uClibc ... */
  223. tbuf += sprintf (tbuf, "ioctl(%i, %#x, %u)", args[0], args[1], args[2]);
  224. if (sc.arg2 == 0x5401)
  225. {
  226. sc.result = !isatty (sc.arg1);
  227. sc.errcode = 0;
  228. }
  229. else
  230. {
  231. sc.result = -1;
  232. sc.errcode = TARGET_EINVAL;
  233. }
  234. break;
  235. case CB_SYS_mmap2:
  236. {
  237. static bu32 heap = BFIN_DEFAULT_MEM_SIZE / 2;
  238. fmt_ret_hex = 1;
  239. tbuf += sprintf (tbuf, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
  240. args[0], args[1], args[2], args[3], args[4], args[5]);
  241. sc.errcode = 0;
  242. if (sc.arg4 & 0x20 /*MAP_ANONYMOUS*/)
  243. /* XXX: We don't handle zeroing, but default is all zeros. */;
  244. else if (args[4] >= MAX_CALLBACK_FDS)
  245. sc.errcode = TARGET_ENOSYS;
  246. else
  247. {
  248. #ifdef HAVE_PREAD
  249. char *data = xmalloc (sc.arg2);
  250. /* XXX: Should add a cb->pread. */
  251. if (pread (cb->fdmap[args[4]], data, sc.arg2, args[5] << 12) == sc.arg2)
  252. sc.write_mem (cb, &sc, heap, data, sc.arg2);
  253. else
  254. sc.errcode = TARGET_EINVAL;
  255. free (data);
  256. #else
  257. sc.errcode = TARGET_ENOSYS;
  258. #endif
  259. }
  260. if (sc.errcode)
  261. {
  262. sc.result = -1;
  263. break;
  264. }
  265. sc.result = heap;
  266. heap += sc.arg2;
  267. /* Keep it page aligned. */
  268. heap = ALIGN (heap, 4096);
  269. break;
  270. }
  271. case CB_SYS_munmap:
  272. /* XXX: meh, just lie for mmap(). */
  273. tbuf += sprintf (tbuf, "munmap(%#x, %u)", args[0], args[1]);
  274. sc.result = 0;
  275. break;
  276. case CB_SYS_dup2:
  277. tbuf += sprintf (tbuf, "dup2(%i, %i)", args[0], args[1]);
  278. if (sc.arg1 >= MAX_CALLBACK_FDS || sc.arg2 >= MAX_CALLBACK_FDS)
  279. {
  280. sc.result = -1;
  281. sc.errcode = TARGET_EINVAL;
  282. }
  283. else
  284. {
  285. sc.result = dup2 (cb->fdmap[sc.arg1], cb->fdmap[sc.arg2]);
  286. goto sys_finish;
  287. }
  288. break;
  289. case CB_SYS__llseek:
  290. tbuf += sprintf (tbuf, "llseek(%i, %u, %u, %#x, %u)",
  291. args[0], args[1], args[2], args[3], args[4]);
  292. sc.func = TARGET_LINUX_SYS_lseek;
  293. if (sc.arg2)
  294. {
  295. sc.result = -1;
  296. sc.errcode = TARGET_EINVAL;
  297. }
  298. else
  299. {
  300. sc.arg2 = sc.arg3;
  301. sc.arg3 = args[4];
  302. cb_syscall (cb, &sc);
  303. if (sc.result != -1)
  304. {
  305. bu32 z = 0;
  306. sc.write_mem (cb, &sc, args[3], (void *)&sc.result, 4);
  307. sc.write_mem (cb, &sc, args[3] + 4, (void *)&z, 4);
  308. }
  309. }
  310. break;
  311. /* XXX: Should add a cb->pread. */
  312. case CB_SYS_pread:
  313. tbuf += sprintf (tbuf, "pread(%i, %#x, %u, %i)",
  314. args[0], args[1], args[2], args[3]);
  315. if (sc.arg1 >= MAX_CALLBACK_FDS)
  316. {
  317. sc.result = -1;
  318. sc.errcode = TARGET_EINVAL;
  319. }
  320. else
  321. {
  322. long old_pos, read_result, read_errcode;
  323. /* Get current filepos. */
  324. sc.func = TARGET_LINUX_SYS_lseek;
  325. sc.arg2 = 0;
  326. sc.arg3 = SEEK_CUR;
  327. cb_syscall (cb, &sc);
  328. if (sc.result == -1)
  329. break;
  330. old_pos = sc.result;
  331. /* Move to the new pos. */
  332. sc.func = TARGET_LINUX_SYS_lseek;
  333. sc.arg2 = args[3];
  334. sc.arg3 = SEEK_SET;
  335. cb_syscall (cb, &sc);
  336. if (sc.result == -1)
  337. break;
  338. /* Read the data. */
  339. sc.func = TARGET_LINUX_SYS_read;
  340. sc.arg2 = args[1];
  341. sc.arg3 = args[2];
  342. cb_syscall (cb, &sc);
  343. read_result = sc.result;
  344. read_errcode = sc.errcode;
  345. /* Move back to the old pos. */
  346. sc.func = TARGET_LINUX_SYS_lseek;
  347. sc.arg2 = old_pos;
  348. sc.arg3 = SEEK_SET;
  349. cb_syscall (cb, &sc);
  350. sc.result = read_result;
  351. sc.errcode = read_errcode;
  352. }
  353. break;
  354. case CB_SYS_getcwd:
  355. tbuf += sprintf (tbuf, "getcwd(%#x, %u)", args[0], args[1]);
  356. p = alloca (sc.arg2);
  357. if (getcwd (p, sc.arg2) == NULL)
  358. {
  359. sc.result = -1;
  360. sc.errcode = TARGET_EINVAL;
  361. }
  362. else
  363. {
  364. sc.write_mem (cb, &sc, sc.arg1, p, sc.arg2);
  365. sc.result = sc.arg1;
  366. }
  367. break;
  368. case CB_SYS_stat64:
  369. if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
  370. strcpy (tstr, "???");
  371. tbuf += sprintf (tbuf, "stat64(%#x:\"%s\", %u)", args[0], tstr, args[1]);
  372. cb->stat_map = stat_map_64;
  373. sc.func = TARGET_LINUX_SYS_stat;
  374. cb_syscall (cb, &sc);
  375. cb->stat_map = stat_map_32;
  376. break;
  377. case CB_SYS_lstat64:
  378. if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
  379. strcpy (tstr, "???");
  380. tbuf += sprintf (tbuf, "lstat64(%#x:\"%s\", %u)", args[0], tstr, args[1]);
  381. cb->stat_map = stat_map_64;
  382. sc.func = TARGET_LINUX_SYS_lstat;
  383. cb_syscall (cb, &sc);
  384. cb->stat_map = stat_map_32;
  385. break;
  386. case CB_SYS_fstat64:
  387. tbuf += sprintf (tbuf, "fstat64(%#x, %u)", args[0], args[1]);
  388. cb->stat_map = stat_map_64;
  389. sc.func = TARGET_LINUX_SYS_fstat;
  390. cb_syscall (cb, &sc);
  391. cb->stat_map = stat_map_32;
  392. break;
  393. case CB_SYS_ftruncate64:
  394. tbuf += sprintf (tbuf, "ftruncate64(%u, %u)", args[0], args[1]);
  395. sc.func = TARGET_LINUX_SYS_ftruncate;
  396. cb_syscall (cb, &sc);
  397. break;
  398. case CB_SYS_getuid:
  399. case CB_SYS_getuid32:
  400. tbuf += sprintf (tbuf, "getuid()");
  401. sc.result = getuid ();
  402. goto sys_finish;
  403. case CB_SYS_getgid:
  404. case CB_SYS_getgid32:
  405. tbuf += sprintf (tbuf, "getgid()");
  406. sc.result = getgid ();
  407. goto sys_finish;
  408. case CB_SYS_setuid:
  409. sc.arg1 &= 0xffff;
  410. case CB_SYS_setuid32:
  411. tbuf += sprintf (tbuf, "setuid(%u)", args[0]);
  412. sc.result = setuid (sc.arg1);
  413. goto sys_finish;
  414. case CB_SYS_setgid:
  415. sc.arg1 &= 0xffff;
  416. case CB_SYS_setgid32:
  417. tbuf += sprintf (tbuf, "setgid(%u)", args[0]);
  418. sc.result = setgid (sc.arg1);
  419. goto sys_finish;
  420. case CB_SYS_getpid:
  421. tbuf += sprintf (tbuf, "getpid()");
  422. sc.result = getpid ();
  423. goto sys_finish;
  424. case CB_SYS_kill:
  425. tbuf += sprintf (tbuf, "kill(%u, %i)", args[0], args[1]);
  426. /* Only let the app kill itself. */
  427. if (sc.arg1 != getpid ())
  428. {
  429. sc.result = -1;
  430. sc.errcode = TARGET_EPERM;
  431. }
  432. else
  433. {
  434. #ifdef HAVE_KILL
  435. sc.result = kill (sc.arg1, sc.arg2);
  436. goto sys_finish;
  437. #else
  438. sc.result = -1;
  439. sc.errcode = TARGET_ENOSYS;
  440. #endif
  441. }
  442. break;
  443. case CB_SYS_open:
  444. if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
  445. strcpy (tstr, "???");
  446. tbuf += sprintf (tbuf, "open(%#x:\"%s\", %#x, %o)",
  447. args[0], tstr, args[1], args[2]);
  448. goto case_default;
  449. case CB_SYS_close:
  450. tbuf += sprintf (tbuf, "close(%i)", args[0]);
  451. goto case_default;
  452. case CB_SYS_read:
  453. tbuf += sprintf (tbuf, "read(%i, %#x, %u)", args[0], args[1], args[2]);
  454. goto case_default;
  455. case CB_SYS_write:
  456. if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[1]))
  457. strcpy (tstr, "???");
  458. tbuf += sprintf (tbuf, "write(%i, %#x:\"%s\", %u)",
  459. args[0], args[1], tstr, args[2]);
  460. goto case_default;
  461. case CB_SYS_lseek:
  462. tbuf += sprintf (tbuf, "lseek(%i, %i, %i)", args[0], args[1], args[2]);
  463. goto case_default;
  464. case CB_SYS_unlink:
  465. if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
  466. strcpy (tstr, "???");
  467. tbuf += sprintf (tbuf, "unlink(%#x:\"%s\")", args[0], tstr);
  468. goto case_default;
  469. case CB_SYS_truncate:
  470. if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
  471. strcpy (tstr, "???");
  472. tbuf += sprintf (tbuf, "truncate(%#x:\"%s\", %i)", args[0], tstr, args[1]);
  473. goto case_default;
  474. case CB_SYS_ftruncate:
  475. tbuf += sprintf (tbuf, "ftruncate(%i, %i)", args[0], args[1]);
  476. goto case_default;
  477. case CB_SYS_rename:
  478. if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
  479. strcpy (tstr, "???");
  480. tbuf += sprintf (tbuf, "rename(%#x:\"%s\", ", args[0], tstr);
  481. if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[1]))
  482. strcpy (tstr, "???");
  483. tbuf += sprintf (tbuf, "%#x:\"%s\")", args[1], tstr);
  484. goto case_default;
  485. case CB_SYS_stat:
  486. if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
  487. strcpy (tstr, "???");
  488. tbuf += sprintf (tbuf, "stat(%#x:\"%s\", %#x)", args[0], tstr, args[1]);
  489. goto case_default;
  490. case CB_SYS_fstat:
  491. tbuf += sprintf (tbuf, "fstat(%i, %#x)", args[0], args[1]);
  492. goto case_default;
  493. case CB_SYS_lstat:
  494. if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
  495. strcpy (tstr, "???");
  496. tbuf += sprintf (tbuf, "lstat(%#x:\"%s\", %#x)", args[0], tstr, args[1]);
  497. goto case_default;
  498. case CB_SYS_pipe:
  499. tbuf += sprintf (tbuf, "pipe(%#x, %#x)", args[0], args[1]);
  500. goto case_default;
  501. default:
  502. tbuf += sprintf (tbuf, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc.func,
  503. args[0], args[1], args[2], args[3], args[4], args[5]);
  504. case_default:
  505. cb_syscall (cb, &sc);
  506. break;
  507. sys_finish:
  508. if (sc.result == -1)
  509. {
  510. cb->last_errno = errno;
  511. sc.errcode = cb->get_errno (cb);
  512. }
  513. }
  514. TRACE_EVENTS (cpu, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
  515. sc.func, args[0], args[1], args[2], args[3], args[4], args[5],
  516. sc.result, sc.errcode);
  517. tbuf += sprintf (tbuf, " = ");
  518. if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
  519. {
  520. if (sc.result == -1)
  521. {
  522. tbuf += sprintf (tbuf, "-1 (error = %i)", sc.errcode);
  523. if (sc.errcode == cb_host_to_target_errno (cb, ENOSYS))
  524. {
  525. sim_io_eprintf (sd, "bfin-sim: %#x: unimplemented syscall %i\n",
  526. PCREG, sc.func);
  527. }
  528. SET_DREG (0, -sc.errcode);
  529. }
  530. else
  531. {
  532. if (fmt_ret_hex)
  533. tbuf += sprintf (tbuf, "%#lx", sc.result);
  534. else
  535. tbuf += sprintf (tbuf, "%lu", sc.result);
  536. SET_DREG (0, sc.result);
  537. }
  538. }
  539. else
  540. {
  541. tbuf += sprintf (tbuf, "%lu (error = %i)", sc.result, sc.errcode);
  542. SET_DREG (0, sc.result);
  543. SET_DREG (1, sc.result2);
  544. SET_DREG (2, sc.errcode);
  545. }
  546. TRACE_SYSCALL (cpu, "%s", _tbuf);
  547. }
  548. /* Execute a single instruction. */
  549. static sim_cia
  550. step_once (SIM_CPU *cpu)
  551. {
  552. SIM_DESC sd = CPU_STATE (cpu);
  553. bu32 insn_len, oldpc = PCREG;
  554. int i;
  555. bool ssstep;
  556. if (TRACE_ANY_P (cpu))
  557. trace_prefix (sd, cpu, NULL_CIA, oldpc, TRACE_LINENUM_P (cpu),
  558. NULL, 0, " "); /* Use a space for gcc warnings. */
  559. /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
  560. has already had the SSSTEP bit enabled. */
  561. ssstep = false;
  562. if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT
  563. && (SYSCFGREG & SYSCFG_SSSTEP))
  564. {
  565. int ivg = cec_get_ivg (cpu);
  566. if (ivg == -1 || ivg > 3)
  567. ssstep = true;
  568. }
  569. #if 0
  570. /* XXX: Is this what happens on the hardware ? */
  571. if (cec_get_ivg (cpu) == EVT_EMU)
  572. cec_return (cpu, EVT_EMU);
  573. #endif
  574. BFIN_CPU_STATE.did_jump = false;
  575. insn_len = interp_insn_bfin (cpu, oldpc);
  576. /* If we executed this insn successfully, then we always decrement
  577. the loop counter. We don't want to update the PC though if the
  578. last insn happened to be a change in code flow (jump/etc...). */
  579. if (!BFIN_CPU_STATE.did_jump)
  580. SET_PCREG (hwloop_get_next_pc (cpu, oldpc, insn_len));
  581. for (i = 1; i >= 0; --i)
  582. if (LCREG (i) && oldpc == LBREG (i))
  583. {
  584. SET_LCREG (i, LCREG (i) - 1);
  585. if (LCREG (i))
  586. break;
  587. }
  588. ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu));
  589. /* Handle hardware single stepping only if we're still lower than EVT3.
  590. XXX: May not be entirely correct wrt EXCPT insns. */
  591. if (ssstep)
  592. {
  593. int ivg = cec_get_ivg (cpu);
  594. if (ivg == -1 || ivg > 3)
  595. {
  596. INSN_LEN = 0;
  597. cec_exception (cpu, VEC_STEP);
  598. }
  599. }
  600. return oldpc;
  601. }
  602. void
  603. sim_engine_run (SIM_DESC sd,
  604. int next_cpu_nr, /* ignore */
  605. int nr_cpus, /* ignore */
  606. int siggnal) /* ignore */
  607. {
  608. bu32 ticks;
  609. SIM_CPU *cpu;
  610. SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  611. cpu = STATE_CPU (sd, 0);
  612. while (1)
  613. {
  614. step_once (cpu);
  615. /* Process any events -- can't use tickn because it may
  616. advance right over the next event. */
  617. for (ticks = 0; ticks < CYCLE_DELAY; ++ticks)
  618. if (sim_events_tick (sd))
  619. sim_events_process (sd);
  620. }
  621. }
  622. /* Cover function of sim_state_free to free the cpu buffers as well. */
  623. static void
  624. free_state (SIM_DESC sd)
  625. {
  626. if (STATE_MODULES (sd) != NULL)
  627. sim_module_uninstall (sd);
  628. sim_cpu_free_all (sd);
  629. sim_state_free (sd);
  630. }
  631. /* Create an instance of the simulator. */
  632. static void
  633. bfin_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
  634. {
  635. memset (&cpu->state, 0, sizeof (cpu->state));
  636. PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu)) = 0;
  637. bfin_model_cpu_init (sd, cpu);
  638. /* Set default stack to top of scratch pad. */
  639. SET_SPREG (BFIN_DEFAULT_MEM_SIZE);
  640. SET_KSPREG (BFIN_DEFAULT_MEM_SIZE);
  641. SET_USPREG (BFIN_DEFAULT_MEM_SIZE);
  642. /* This is what the hardware likes. */
  643. SET_SYSCFGREG (0x30);
  644. }
  645. SIM_DESC
  646. sim_open (SIM_OPEN_KIND kind, host_callback *callback,
  647. struct bfd *abfd, char **argv)
  648. {
  649. char c;
  650. int i;
  651. SIM_DESC sd = sim_state_alloc (kind, callback);
  652. /* The cpu data is kept in a separately allocated chunk of memory. */
  653. if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
  654. {
  655. free_state (sd);
  656. return 0;
  657. }
  658. {
  659. /* XXX: Only first core gets profiled ? */
  660. SIM_CPU *cpu = STATE_CPU (sd, 0);
  661. STATE_WATCHPOINTS (sd)->pc = &PCREG;
  662. STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PCREG);
  663. }
  664. if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
  665. {
  666. free_state (sd);
  667. return 0;
  668. }
  669. /* XXX: Default to the Virtual environment. */
  670. if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
  671. STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT;
  672. /* These options override any module options.
  673. Obviously ambiguity should be avoided, however the caller may wish to
  674. augment the meaning of an option. */
  675. #define e_sim_add_option_table(sd, options) \
  676. do { \
  677. extern const OPTION options[]; \
  678. sim_add_option_table (sd, NULL, options); \
  679. } while (0)
  680. e_sim_add_option_table (sd, bfin_mmu_options);
  681. e_sim_add_option_table (sd, bfin_mach_options);
  682. /* getopt will print the error message so we just have to exit if this fails.
  683. FIXME: Hmmm... in the case of gdb we need getopt to call
  684. print_filtered. */
  685. if (sim_parse_args (sd, argv) != SIM_RC_OK)
  686. {
  687. free_state (sd);
  688. return 0;
  689. }
  690. /* Allocate external memory if none specified by user.
  691. Use address 4 here in case the user wanted address 0 unmapped. */
  692. if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
  693. {
  694. bu16 emuexcpt = 0x25;
  695. sim_do_commandf (sd, "memory-size 0x%lx", BFIN_DEFAULT_MEM_SIZE);
  696. sim_write (sd, 0, (void *)&emuexcpt, 2);
  697. }
  698. /* Check for/establish the a reference program image. */
  699. if (sim_analyze_program (sd,
  700. (STATE_PROG_ARGV (sd) != NULL
  701. ? *STATE_PROG_ARGV (sd)
  702. : NULL), abfd) != SIM_RC_OK)
  703. {
  704. free_state (sd);
  705. return 0;
  706. }
  707. /* Establish any remaining configuration options. */
  708. if (sim_config (sd) != SIM_RC_OK)
  709. {
  710. free_state (sd);
  711. return 0;
  712. }
  713. if (sim_post_argv_init (sd) != SIM_RC_OK)
  714. {
  715. free_state (sd);
  716. return 0;
  717. }
  718. /* CPU specific initialization. */
  719. for (i = 0; i < MAX_NR_PROCESSORS; ++i)
  720. {
  721. SIM_CPU *cpu = STATE_CPU (sd, i);
  722. bfin_initialize_cpu (sd, cpu);
  723. }
  724. return sd;
  725. }
  726. void
  727. sim_close (SIM_DESC sd, int quitting)
  728. {
  729. sim_module_uninstall (sd);
  730. }
  731. /* Some utils don't like having a NULL environ. */
  732. static const char * const simple_env[] = { "HOME=/", "PATH=/bin", NULL };
  733. static bu32 fdpic_load_offset;
  734. static bool
  735. bfin_fdpic_load (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd, bu32 *sp,
  736. bu32 *elf_addrs, char **ldso_path)
  737. {
  738. bool ret;
  739. int i;
  740. Elf_Internal_Ehdr *iehdr;
  741. Elf32_External_Ehdr ehdr;
  742. Elf_Internal_Phdr *phdrs;
  743. unsigned char *data;
  744. long phdr_size;
  745. int phdrc;
  746. bu32 nsegs;
  747. bu32 max_load_addr;
  748. unsigned char null[4] = { 0, 0, 0, 0 };
  749. ret = false;
  750. *ldso_path = NULL;
  751. /* See if this an FDPIC ELF. */
  752. phdrs = NULL;
  753. if (!abfd)
  754. goto skip_fdpic_init;
  755. if (bfd_seek (abfd, 0, SEEK_SET) != 0)
  756. goto skip_fdpic_init;
  757. if (bfd_bread (&ehdr, sizeof (ehdr), abfd) != sizeof (ehdr))
  758. goto skip_fdpic_init;
  759. iehdr = elf_elfheader (abfd);
  760. if (!(iehdr->e_flags & EF_BFIN_FDPIC))
  761. goto skip_fdpic_init;
  762. if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
  763. sim_io_printf (sd, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
  764. bfd_get_filename (abfd), fdpic_load_offset, elf_addrs[0]);
  765. /* Grab the Program Headers to set up the loadsegs on the stack. */
  766. phdr_size = bfd_get_elf_phdr_upper_bound (abfd);
  767. if (phdr_size == -1)
  768. goto skip_fdpic_init;
  769. phdrs = xmalloc (phdr_size);
  770. phdrc = bfd_get_elf_phdrs (abfd, phdrs);
  771. if (phdrc == -1)
  772. goto skip_fdpic_init;
  773. /* Push the Ehdr onto the stack. */
  774. *sp -= sizeof (ehdr);
  775. elf_addrs[3] = *sp;
  776. sim_write (sd, *sp, (void *)&ehdr, sizeof (ehdr));
  777. if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
  778. sim_io_printf (sd, " Elf_Ehdr: %#x\n", *sp);
  779. /* Since we're relocating things ourselves, we need to relocate
  780. the start address as well. */
  781. elf_addrs[0] = bfd_get_start_address (abfd) + fdpic_load_offset;
  782. /* And the Exec's Phdrs onto the stack. */
  783. if (STATE_PROG_BFD (sd) == abfd)
  784. {
  785. elf_addrs[4] = elf_addrs[0];
  786. phdr_size = iehdr->e_phentsize * iehdr->e_phnum;
  787. if (bfd_seek (abfd, iehdr->e_phoff, SEEK_SET) != 0)
  788. goto skip_fdpic_init;
  789. data = xmalloc (phdr_size);
  790. if (bfd_bread (data, phdr_size, abfd) != phdr_size)
  791. goto skip_fdpic_init;
  792. *sp -= phdr_size;
  793. elf_addrs[1] = *sp;
  794. elf_addrs[2] = phdrc;
  795. sim_write (sd, *sp, data, phdr_size);
  796. free (data);
  797. if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
  798. sim_io_printf (sd, " Elf_Phdrs: %#x\n", *sp);
  799. }
  800. /* Now push all the loadsegs. */
  801. nsegs = 0;
  802. max_load_addr = 0;
  803. for (i = phdrc; i >= 0; --i)
  804. if (phdrs[i].p_type == PT_LOAD)
  805. {
  806. Elf_Internal_Phdr *p = &phdrs[i];
  807. bu32 paddr, vaddr, memsz, filesz;
  808. paddr = p->p_paddr + fdpic_load_offset;
  809. vaddr = p->p_vaddr;
  810. memsz = p->p_memsz;
  811. filesz = p->p_filesz;
  812. if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
  813. sim_io_printf (sd, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
  814. i, vaddr, paddr, filesz, memsz);
  815. data = xmalloc (memsz);
  816. if (memsz != filesz)
  817. memset (data + filesz, 0, memsz - filesz);
  818. if (bfd_seek (abfd, p->p_offset, SEEK_SET) == 0
  819. && bfd_bread (data, filesz, abfd) == filesz)
  820. sim_write (sd, paddr, data, memsz);
  821. free (data);
  822. max_load_addr = MAX (paddr + memsz, max_load_addr);
  823. *sp -= 12;
  824. sim_write (sd, *sp+0, (void *)&paddr, 4); /* loadseg.addr */
  825. sim_write (sd, *sp+4, (void *)&vaddr, 4); /* loadseg.p_vaddr */
  826. sim_write (sd, *sp+8, (void *)&memsz, 4); /* loadseg.p_memsz */
  827. ++nsegs;
  828. }
  829. else if (phdrs[i].p_type == PT_DYNAMIC)
  830. {
  831. elf_addrs[5] = phdrs[i].p_paddr + fdpic_load_offset;
  832. if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
  833. sim_io_printf (sd, " PT_DYNAMIC: %#x\n", elf_addrs[5]);
  834. }
  835. else if (phdrs[i].p_type == PT_INTERP)
  836. {
  837. uint32_t off = phdrs[i].p_offset;
  838. uint32_t len = phdrs[i].p_filesz;
  839. *ldso_path = xmalloc (len);
  840. if (bfd_seek (abfd, off, SEEK_SET) != 0
  841. || bfd_bread (*ldso_path, len, abfd) != len)
  842. {
  843. free (*ldso_path);
  844. *ldso_path = NULL;
  845. }
  846. else if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
  847. sim_io_printf (sd, " PT_INTERP: %s\n", *ldso_path);
  848. }
  849. /* Update the load offset with a few extra pages. */
  850. fdpic_load_offset = ALIGN (MAX (max_load_addr, fdpic_load_offset), 0x10000);
  851. fdpic_load_offset += 0x10000;
  852. /* Push the summary loadmap info onto the stack last. */
  853. *sp -= 4;
  854. sim_write (sd, *sp+0, null, 2); /* loadmap.version */
  855. sim_write (sd, *sp+2, (void *)&nsegs, 2); /* loadmap.nsegs */
  856. ret = true;
  857. skip_fdpic_init:
  858. free (phdrs);
  859. return ret;
  860. }
  861. static void
  862. bfin_user_init (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd,
  863. const char * const *argv, const char * const *env)
  864. {
  865. /* XXX: Missing host -> target endian ... */
  866. /* Linux starts the user app with the stack:
  867. argc
  868. argv[0] -- pointers to the actual strings
  869. argv[1..N]
  870. NULL
  871. env[0]
  872. env[1..N]
  873. NULL
  874. auxvt[0].type -- ELF Auxiliary Vector Table
  875. auxvt[0].value
  876. auxvt[1..N]
  877. AT_NULL
  878. 0
  879. argv[0..N][0..M] -- actual argv/env strings
  880. env[0..N][0..M]
  881. FDPIC loadmaps -- for FDPIC apps
  882. So set things up the same way. */
  883. int i, argc, envc;
  884. bu32 argv_flat, env_flat;
  885. bu32 sp, sp_flat;
  886. /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
  887. bu32 elf_addrs[6];
  888. bu32 auxvt;
  889. bu32 exec_loadmap, ldso_loadmap;
  890. char *ldso_path;
  891. unsigned char null[4] = { 0, 0, 0, 0 };
  892. host_callback *cb = STATE_CALLBACK (sd);
  893. elf_addrs[0] = elf_addrs[4] = bfd_get_start_address (abfd);
  894. elf_addrs[1] = elf_addrs[2] = elf_addrs[3] = elf_addrs[5] = 0;
  895. /* Keep the load addresses consistent between runs. Also make sure we make
  896. space for the fixed code region (part of the Blackfin Linux ABI). */
  897. fdpic_load_offset = 0x1000;
  898. /* First try to load this as an FDPIC executable. */
  899. sp = SPREG;
  900. if (!bfin_fdpic_load (sd, cpu, STATE_PROG_BFD (sd), &sp, elf_addrs, &ldso_path))
  901. goto skip_fdpic_init;
  902. exec_loadmap = sp;
  903. /* If that worked, then load the fixed code region. We only do this for
  904. FDPIC ELFs atm because they are PIEs and let us relocate them without
  905. manual fixups. FLAT files however require location processing which
  906. we do not do ourselves, and they link with a VMA of 0. */
  907. sim_write (sd, 0x400, bfin_linux_fixed_code, sizeof (bfin_linux_fixed_code));
  908. /* If the FDPIC needs an interpreter, then load it up too. */
  909. if (ldso_path)
  910. {
  911. const char *ldso_full_path = concat (simulator_sysroot, ldso_path, NULL);
  912. struct bfd *ldso_bfd;
  913. ldso_bfd = bfd_openr (ldso_full_path, STATE_TARGET (sd));
  914. if (!ldso_bfd)
  915. {
  916. sim_io_eprintf (sd, "bfin-sim: bfd open failed: %s\n", ldso_full_path);
  917. goto static_fdpic;
  918. }
  919. if (!bfd_check_format (ldso_bfd, bfd_object))
  920. sim_io_eprintf (sd, "bfin-sim: bfd format not valid: %s\n", ldso_full_path);
  921. bfd_set_arch_info (ldso_bfd, STATE_ARCHITECTURE (sd));
  922. if (!bfin_fdpic_load (sd, cpu, ldso_bfd, &sp, elf_addrs, &ldso_path))
  923. sim_io_eprintf (sd, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path);
  924. if (ldso_path)
  925. sim_io_eprintf (sd, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
  926. ldso_full_path, ldso_path);
  927. ldso_loadmap = sp;
  928. }
  929. else
  930. static_fdpic:
  931. ldso_loadmap = 0;
  932. /* Finally setup the registers required by the FDPIC ABI. */
  933. SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
  934. SET_PREG (0, exec_loadmap); /* Exec loadmap addr. */
  935. SET_PREG (1, ldso_loadmap); /* Interp loadmap addr. */
  936. SET_PREG (2, elf_addrs[5]); /* PT_DYNAMIC map addr. */
  937. auxvt = 1;
  938. SET_SPREG (sp);
  939. skip_fdpic_init:
  940. sim_pc_set (cpu, elf_addrs[0]);
  941. /* Figure out how much storage the argv/env strings need. */
  942. argc = count_argc (argv);
  943. if (argc == -1)
  944. argc = 0;
  945. argv_flat = argc; /* NUL bytes */
  946. for (i = 0; i < argc; ++i)
  947. argv_flat += strlen (argv[i]);
  948. if (!env)
  949. env = simple_env;
  950. envc = count_argc (env);
  951. env_flat = envc; /* NUL bytes */
  952. for (i = 0; i < envc; ++i)
  953. env_flat += strlen (env[i]);
  954. /* Push the Auxiliary Vector Table between argv/env and actual strings. */
  955. sp_flat = sp = ALIGN (SPREG - argv_flat - env_flat - 4, 4);
  956. if (auxvt)
  957. {
  958. # define AT_PUSH(at, val) \
  959. auxvt_size += 8; \
  960. sp -= 4; \
  961. auxvt = (val); \
  962. sim_write (sd, sp, (void *)&auxvt, 4); \
  963. sp -= 4; \
  964. auxvt = (at); \
  965. sim_write (sd, sp, (void *)&auxvt, 4)
  966. unsigned int egid = getegid (), gid = getgid ();
  967. unsigned int euid = geteuid (), uid = getuid ();
  968. bu32 auxvt_size = 0;
  969. AT_PUSH (AT_NULL, 0);
  970. AT_PUSH (AT_SECURE, egid != gid || euid != uid);
  971. AT_PUSH (AT_EGID, egid);
  972. AT_PUSH (AT_GID, gid);
  973. AT_PUSH (AT_EUID, euid);
  974. AT_PUSH (AT_UID, uid);
  975. AT_PUSH (AT_ENTRY, elf_addrs[4]);
  976. AT_PUSH (AT_FLAGS, 0);
  977. AT_PUSH (AT_BASE, elf_addrs[3]);
  978. AT_PUSH (AT_PHNUM, elf_addrs[2]);
  979. AT_PUSH (AT_PHENT, sizeof (Elf32_External_Phdr));
  980. AT_PUSH (AT_PHDR, elf_addrs[1]);
  981. AT_PUSH (AT_CLKTCK, 100); /* XXX: This ever not 100 ? */
  982. AT_PUSH (AT_PAGESZ, 4096);
  983. AT_PUSH (AT_HWCAP, 0);
  984. #undef AT_PUSH
  985. }
  986. SET_SPREG (sp);
  987. /* Push the argc/argv/env after the auxvt. */
  988. sp -= ((1 + argc + 1 + envc + 1) * 4);
  989. SET_SPREG (sp);
  990. /* First push the argc value. */
  991. sim_write (sd, sp, (void *)&argc, 4);
  992. sp += 4;
  993. /* Then the actual argv strings so we know where to point argv[]. */
  994. for (i = 0; i < argc; ++i)
  995. {
  996. unsigned len = strlen (argv[i]) + 1;
  997. sim_write (sd, sp_flat, (void *)argv[i], len);
  998. sim_write (sd, sp, (void *)&sp_flat, 4);
  999. sp_flat += len;
  1000. sp += 4;
  1001. }
  1002. sim_write (sd, sp, null, 4);
  1003. sp += 4;
  1004. /* Then the actual env strings so we know where to point env[]. */
  1005. for (i = 0; i < envc; ++i)
  1006. {
  1007. unsigned len = strlen (env[i]) + 1;
  1008. sim_write (sd, sp_flat, (void *)env[i], len);
  1009. sim_write (sd, sp, (void *)&sp_flat, 4);
  1010. sp_flat += len;
  1011. sp += 4;
  1012. }
  1013. /* Set some callbacks. */
  1014. cb->syscall_map = cb_linux_syscall_map;
  1015. cb->errno_map = cb_linux_errno_map;
  1016. cb->open_map = cb_linux_open_map;
  1017. cb->signal_map = cb_linux_signal_map;
  1018. cb->stat_map = stat_map_32 = cb_linux_stat_map_32;
  1019. stat_map_64 = cb_linux_stat_map_64;
  1020. }
  1021. static void
  1022. bfin_os_init (SIM_DESC sd, SIM_CPU *cpu, const char * const *argv)
  1023. {
  1024. /* Pass the command line via a string in R0 like Linux expects. */
  1025. int i;
  1026. bu8 byte;
  1027. bu32 cmdline = BFIN_L1_SRAM_SCRATCH;
  1028. SET_DREG (0, cmdline);
  1029. if (argv && argv[0])
  1030. {
  1031. i = 1;
  1032. byte = ' ';
  1033. while (argv[i])
  1034. {
  1035. bu32 len = strlen (argv[i]);
  1036. sim_write (sd, cmdline, (void *)argv[i], len);
  1037. cmdline += len;
  1038. sim_write (sd, cmdline, &byte, 1);
  1039. ++cmdline;
  1040. ++i;
  1041. }
  1042. }
  1043. byte = 0;
  1044. sim_write (sd, cmdline, &byte, 1);
  1045. }
  1046. static void
  1047. bfin_virtual_init (SIM_DESC sd, SIM_CPU *cpu)
  1048. {
  1049. host_callback *cb = STATE_CALLBACK (sd);
  1050. cb->stat_map = stat_map_32 = cb_libgloss_stat_map_32;
  1051. stat_map_64 = NULL;
  1052. }
  1053. SIM_RC
  1054. sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
  1055. char **argv, char **env)
  1056. {
  1057. SIM_CPU *cpu = STATE_CPU (sd, 0);
  1058. SIM_ADDR addr;
  1059. /* Set the PC. */
  1060. if (abfd != NULL)
  1061. addr = bfd_get_start_address (abfd);
  1062. else
  1063. addr = 0;
  1064. sim_pc_set (cpu, addr);
  1065. /* Standalone mode (i.e. `bfin-...-run`) will take care of the argv
  1066. for us in sim_open() -> sim_parse_args(). But in debug mode (i.e.
  1067. 'target sim' with `bfin-...-gdb`), we need to handle it. */
  1068. if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
  1069. {
  1070. freeargv (STATE_PROG_ARGV (sd));
  1071. STATE_PROG_ARGV (sd) = dupargv (argv);
  1072. }
  1073. switch (STATE_ENVIRONMENT (sd))
  1074. {
  1075. case USER_ENVIRONMENT:
  1076. bfin_user_init (sd, cpu, abfd, (void *)argv, (void *)env);
  1077. break;
  1078. case OPERATING_ENVIRONMENT:
  1079. bfin_os_init (sd, cpu, (void *)argv);
  1080. break;
  1081. default:
  1082. bfin_virtual_init (sd, cpu);
  1083. break;
  1084. }
  1085. return SIM_RC_OK;
  1086. }