emul_netbsd.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569
  1. /* This file is part of the program psim.
  2. Copyright (C) 1994-1998, Andrew Cagney <cagney@highland.com.au>
  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. #ifndef _EMUL_NETBSD_C_
  15. #define _EMUL_NETBSD_C_
  16. /* Note: this module is called via a table. There is no benefit in
  17. making it inline */
  18. #include "defs.h"
  19. #include <string.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <stdio.h>
  23. #include <signal.h>
  24. #include <fcntl.h>
  25. #include <errno.h>
  26. #include <sys/param.h>
  27. #include <sys/time.h>
  28. #include "emul_generic.h"
  29. #include "emul_netbsd.h"
  30. #ifdef HAVE_GETRUSAGE
  31. #ifndef HAVE_SYS_RESOURCE_H
  32. #undef HAVE_GETRUSAGE
  33. #endif
  34. #endif
  35. #ifdef HAVE_GETRUSAGE
  36. #include <sys/resource.h>
  37. int getrusage();
  38. #endif
  39. #if HAVE_SYS_IOCTL_H
  40. #include <sys/ioctl.h>
  41. #endif
  42. #if HAVE_DIRENT_H
  43. # include <dirent.h>
  44. # define NAMLEN(dirent) strlen((dirent)->d_name)
  45. #else
  46. # define dirent direct
  47. # define NAMLEN(dirent) (dirent)->d_namlen
  48. # if HAVE_SYS_NDIR_H
  49. # include <sys/ndir.h>
  50. # endif
  51. # if HAVE_SYS_DIR_H
  52. # include <sys/dir.h>
  53. # endif
  54. # if HAVE_NDIR_H
  55. # include <ndir.h>
  56. # endif
  57. #endif
  58. #ifdef HAVE_UNISTD_H
  59. #undef MAXPATHLEN /* sys/param.h might define this also */
  60. #include <unistd.h>
  61. #endif
  62. #include <stdlib.h>
  63. #define WITH_NetBSD_HOST (NetBSD >= 199306)
  64. #if WITH_NetBSD_HOST /* here NetBSD as that is what we're emulating */
  65. #include <sys/syscall.h> /* FIXME - should not be including this one */
  66. #include <sys/sysctl.h>
  67. #include <sys/mount.h>
  68. extern int getdirentries(int fd, char *buf, int nbytes, long *basep);
  69. /* NetBSD post 2.0 has the statfs system call (if COMPAT_20), but does
  70. not have struct statfs. In this case don't implement fstatfs.
  71. FIXME: Should implement fstatvfs. */
  72. #ifndef HAVE_STRUCT_STATFS
  73. #undef HAVE_FSTATFS
  74. #endif
  75. #else
  76. /* If this is not netbsd, don't allow fstatfs or getdirentries at this time */
  77. #undef HAVE_FSTATFS
  78. #undef HAVE_GETDIRENTRIES
  79. #endif
  80. #ifndef STATIC_INLINE_EMUL_NETBSD
  81. #define STATIC_INLINE_EMUL_NETBSD STATIC_INLINE
  82. #endif
  83. #if WITH_NetBSD_HOST
  84. #define SYS(X) ASSERT(call == (SYS_##X))
  85. #else
  86. #define SYS(X)
  87. #endif
  88. #if WITH_NetBSD_HOST && (PATH_MAX != 1024)
  89. #error "PATH_MAX not 1024"
  90. #elif !defined(PATH_MAX)
  91. #define PATH_MAX 1024
  92. #endif
  93. /* EMULATION
  94. NetBSD - Emulation of user programs for NetBSD/PPC
  95. DESCRIPTION
  96. */
  97. /* NetBSD's idea of what is needed to implement emulations */
  98. struct _os_emul_data {
  99. device *vm;
  100. emul_syscall *syscalls;
  101. };
  102. STATIC_INLINE_EMUL_NETBSD void
  103. write_stat(unsigned_word addr,
  104. struct stat buf,
  105. cpu *processor,
  106. unsigned_word cia)
  107. {
  108. H2T(buf.st_dev);
  109. H2T(buf.st_ino);
  110. H2T(buf.st_mode);
  111. H2T(buf.st_nlink);
  112. H2T(buf.st_uid);
  113. H2T(buf.st_gid);
  114. H2T(buf.st_size);
  115. H2T(buf.st_atime);
  116. /* H2T(buf.st_spare1); */
  117. H2T(buf.st_mtime);
  118. /* H2T(buf.st_spare2); */
  119. H2T(buf.st_ctime);
  120. /* H2T(buf.st_spare3); */
  121. #ifdef AC_STRUCT_ST_RDEV
  122. H2T(buf.st_rdev);
  123. #endif
  124. #ifdef AC_STRUCT_ST_BLKSIZE
  125. H2T(buf.st_blksize);
  126. #endif
  127. #ifdef AC_STRUCT_ST_BLOCKS
  128. H2T(buf.st_blocks);
  129. #endif
  130. #if WITH_NetBSD_HOST
  131. H2T(buf.st_flags);
  132. H2T(buf.st_gen);
  133. #endif
  134. emul_write_buffer(&buf, addr, sizeof(buf), processor, cia);
  135. }
  136. #ifdef HAVE_FSTATFS
  137. STATIC_INLINE_EMUL_NETBSD void
  138. write_statfs(unsigned_word addr,
  139. struct statfs buf,
  140. cpu *processor,
  141. unsigned_word cia)
  142. {
  143. H2T(buf.f_type);
  144. H2T(buf.f_flags);
  145. H2T(buf.f_bsize);
  146. H2T(buf.f_iosize);
  147. H2T(buf.f_blocks);
  148. H2T(buf.f_bfree);
  149. H2T(buf.f_bavail);
  150. H2T(buf.f_files);
  151. H2T(buf.f_ffree);
  152. H2T(buf.f_fsid.val[0]);
  153. H2T(buf.f_fsid.val[1]);
  154. H2T(buf.f_owner);
  155. /* f_spare[4]; */
  156. /* f_fstypename[MFSNAMELEN]; */
  157. /* f_mntonname[MNAMELEN]; */
  158. /* f_mntfromname[MNAMELEN]; */
  159. emul_write_buffer(&buf, addr, sizeof(buf), processor, cia);
  160. }
  161. #endif
  162. STATIC_INLINE_EMUL_NETBSD void
  163. write_timeval(unsigned_word addr,
  164. struct timeval t,
  165. cpu *processor,
  166. unsigned_word cia)
  167. {
  168. H2T(t.tv_sec);
  169. H2T(t.tv_usec);
  170. emul_write_buffer(&t, addr, sizeof(t), processor, cia);
  171. }
  172. #ifdef HAVE_GETTIMEOFDAY
  173. STATIC_INLINE_EMUL_NETBSD void
  174. write_timezone(unsigned_word addr,
  175. struct timezone tz,
  176. cpu *processor,
  177. unsigned_word cia)
  178. {
  179. H2T(tz.tz_minuteswest);
  180. H2T(tz.tz_dsttime);
  181. emul_write_buffer(&tz, addr, sizeof(tz), processor, cia);
  182. }
  183. #endif
  184. #ifdef HAVE_GETDIRENTRIES
  185. STATIC_INLINE_EMUL_NETBSD void
  186. write_direntries(unsigned_word addr,
  187. char *buf,
  188. int nbytes,
  189. cpu *processor,
  190. unsigned_word cia)
  191. {
  192. while (nbytes > 0) {
  193. struct dirent *out;
  194. struct dirent *in = (struct dirent*)buf;
  195. ASSERT(in->d_reclen <= nbytes);
  196. out = (struct dirent*)zalloc(in->d_reclen);
  197. memcpy(out/*dest*/, in/*src*/, in->d_reclen);
  198. H2T(out->d_fileno);
  199. H2T(out->d_reclen);
  200. H2T(out->d_type);
  201. H2T(out->d_namlen);
  202. emul_write_buffer(out, addr, in->d_reclen, processor, cia);
  203. nbytes -= in->d_reclen;
  204. addr += in->d_reclen;
  205. buf += in->d_reclen;
  206. free(out);
  207. }
  208. }
  209. #endif
  210. #ifdef HAVE_GETRUSAGE
  211. STATIC_INLINE_EMUL_NETBSD void
  212. write_rusage(unsigned_word addr,
  213. struct rusage rusage,
  214. cpu *processor,
  215. unsigned_word cia)
  216. {
  217. H2T(rusage.ru_utime.tv_sec); /* user time used */
  218. H2T(rusage.ru_utime.tv_usec);
  219. H2T(rusage.ru_stime.tv_sec); /* system time used */
  220. H2T(rusage.ru_stime.tv_usec);
  221. H2T(rusage.ru_maxrss); /* integral max resident set size */
  222. H2T(rusage.ru_ixrss); /* integral shared text memory size */
  223. H2T(rusage.ru_idrss); /* integral unshared data size */
  224. H2T(rusage.ru_isrss); /* integral unshared stack size */
  225. H2T(rusage.ru_minflt); /* page reclaims */
  226. H2T(rusage.ru_majflt); /* page faults */
  227. H2T(rusage.ru_nswap); /* swaps */
  228. H2T(rusage.ru_inblock); /* block input operations */
  229. H2T(rusage.ru_oublock); /* block output operations */
  230. H2T(rusage.ru_msgsnd); /* messages sent */
  231. H2T(rusage.ru_msgrcv); /* messages received */
  232. H2T(rusage.ru_nsignals); /* signals received */
  233. H2T(rusage.ru_nvcsw); /* voluntary context switches */
  234. H2T(rusage.ru_nivcsw); /* involuntary context switches */
  235. emul_write_buffer(&rusage, addr, sizeof(rusage), processor, cia);
  236. }
  237. #endif
  238. /* File descriptors 0, 1, and 2 should not be closed. fd_closed[]
  239. tracks whether these descriptors have been closed in do_close()
  240. below. */
  241. static int fd_closed[3];
  242. /* Check for some occurrences of bad file descriptors. We only check
  243. whether fd 0, 1, or 2 are "closed". By "closed" we mean that these
  244. descriptors aren't actually closed, but are considered to be closed
  245. by this layer.
  246. Other checks are performed by the underlying OS call. */
  247. static int
  248. fdbad (int fd)
  249. {
  250. if (fd >=0 && fd <= 2 && fd_closed[fd])
  251. {
  252. errno = EBADF;
  253. return -1;
  254. }
  255. return 0;
  256. }
  257. static void
  258. do_exit(os_emul_data *emul,
  259. unsigned call,
  260. const int arg0,
  261. cpu *processor,
  262. unsigned_word cia)
  263. {
  264. int status = (int)cpu_registers(processor)->gpr[arg0];
  265. SYS(exit);
  266. if (WITH_TRACE && ppc_trace[trace_os_emul])
  267. printf_filtered ("%d)\n", status);
  268. cpu_halt(processor, cia, was_exited, status);
  269. }
  270. static void
  271. do_read(os_emul_data *emul,
  272. unsigned call,
  273. const int arg0,
  274. cpu *processor,
  275. unsigned_word cia)
  276. {
  277. void *scratch_buffer;
  278. int d = (int)cpu_registers(processor)->gpr[arg0];
  279. unsigned_word buf = cpu_registers(processor)->gpr[arg0+1];
  280. int nbytes = cpu_registers(processor)->gpr[arg0+2];
  281. int status;
  282. SYS(read);
  283. if (WITH_TRACE && ppc_trace[trace_os_emul])
  284. printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes);
  285. /* get a tempoary bufer */
  286. scratch_buffer = zalloc(nbytes);
  287. /* check if buffer exists by reading it */
  288. emul_read_buffer(scratch_buffer, buf, nbytes, processor, cia);
  289. /* read */
  290. #if 0
  291. if (d == 0) {
  292. status = fread (scratch_buffer, 1, nbytes, stdin);
  293. if (status == 0 && ferror (stdin))
  294. status = -1;
  295. }
  296. #endif
  297. status = fdbad (d);
  298. if (status == 0)
  299. status = read (d, scratch_buffer, nbytes);
  300. emul_write_status(processor, status, errno);
  301. if (status > 0)
  302. emul_write_buffer(scratch_buffer, buf, status, processor, cia);
  303. free(scratch_buffer);
  304. }
  305. static void
  306. do_write(os_emul_data *emul,
  307. unsigned call,
  308. const int arg0,
  309. cpu *processor,
  310. unsigned_word cia)
  311. {
  312. void *scratch_buffer = NULL;
  313. int d = (int)cpu_registers(processor)->gpr[arg0];
  314. unsigned_word buf = cpu_registers(processor)->gpr[arg0+1];
  315. int nbytes = cpu_registers(processor)->gpr[arg0+2];
  316. int status;
  317. SYS(write);
  318. if (WITH_TRACE && ppc_trace[trace_os_emul])
  319. printf_filtered ("%d, 0x%lx, %d", d, (long)buf, nbytes);
  320. /* get a tempoary bufer */
  321. scratch_buffer = zalloc(nbytes); /* FIXME - nbytes == 0 */
  322. /* copy in */
  323. emul_read_buffer(scratch_buffer, buf, nbytes,
  324. processor, cia);
  325. /* write */
  326. status = fdbad (d);
  327. if (status == 0)
  328. status = write(d, scratch_buffer, nbytes);
  329. emul_write_status(processor, status, errno);
  330. free(scratch_buffer);
  331. flush_stdoutput();
  332. }
  333. static void
  334. do_open(os_emul_data *emul,
  335. unsigned call,
  336. const int arg0,
  337. cpu *processor,
  338. unsigned_word cia)
  339. {
  340. unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
  341. char path_buf[PATH_MAX];
  342. char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
  343. int flags = (int)cpu_registers(processor)->gpr[arg0+1];
  344. int mode = (int)cpu_registers(processor)->gpr[arg0+2];
  345. int hostflags;
  346. int status;
  347. if (WITH_TRACE && ppc_trace[trace_os_emul])
  348. printf_filtered ("0x%lx [%s], 0x%x, 0x%x", (long)path_addr, path, flags, mode);
  349. SYS(open);
  350. /* Do some translation on 'flags' to match it to the host's version. */
  351. /* These flag values were taken from the NetBSD 1.4 header files. */
  352. if ((flags & 3) == 0)
  353. hostflags = O_RDONLY;
  354. else if ((flags & 3) == 1)
  355. hostflags = O_WRONLY;
  356. else
  357. hostflags = O_RDWR;
  358. if (flags & 0x00000008)
  359. hostflags |= O_APPEND;
  360. if (flags & 0x00000200)
  361. hostflags |= O_CREAT;
  362. if (flags & 0x00000400)
  363. hostflags |= O_TRUNC;
  364. if (flags & 0x00000800)
  365. hostflags |= O_EXCL;
  366. /* Can't combine these statements, cuz open sets errno. */
  367. status = open(path, hostflags, mode);
  368. emul_write_status(processor, status, errno);
  369. }
  370. static void
  371. do_close(os_emul_data *emul,
  372. unsigned call,
  373. const int arg0,
  374. cpu *processor,
  375. unsigned_word cia)
  376. {
  377. int d = (int)cpu_registers(processor)->gpr[arg0];
  378. int status;
  379. if (WITH_TRACE && ppc_trace[trace_os_emul])
  380. printf_filtered ("%d", d);
  381. SYS(close);
  382. status = fdbad (d);
  383. if (status == 0)
  384. {
  385. /* Do not close stdin, stdout, or stderr. GDB may still need access to
  386. these descriptors. */
  387. if (d == 0 || d == 1 || d == 2)
  388. {
  389. fd_closed[d] = 1;
  390. status = 0;
  391. }
  392. else
  393. status = close(d);
  394. }
  395. emul_write_status(processor, status, errno);
  396. }
  397. static void
  398. do_break(os_emul_data *emul,
  399. unsigned call,
  400. const int arg0,
  401. cpu *processor,
  402. unsigned_word cia)
  403. {
  404. /* just pass this onto the `vm' device */
  405. unsigned_word new_break = cpu_registers(processor)->gpr[arg0];
  406. int status;
  407. if (WITH_TRACE && ppc_trace[trace_os_emul])
  408. printf_filtered ("0x%lx", (long)cpu_registers(processor)->gpr[arg0]);
  409. SYS(break);
  410. status = device_ioctl(emul->vm,
  411. processor,
  412. cia,
  413. device_ioctl_break,
  414. new_break); /*ioctl-data*/
  415. emul_write_status(processor, 0, status);
  416. }
  417. #ifndef HAVE_GETPID
  418. #define do_getpid 0
  419. #else
  420. static void
  421. do_getpid(os_emul_data *emul,
  422. unsigned call,
  423. const int arg0,
  424. cpu *processor,
  425. unsigned_word cia)
  426. {
  427. SYS(getpid);
  428. emul_write_status(processor, (int)getpid(), 0);
  429. }
  430. #endif
  431. #ifndef HAVE_GETUID
  432. #define do_getuid 0
  433. #else
  434. static void
  435. do_getuid(os_emul_data *emul,
  436. unsigned call,
  437. const int arg0,
  438. cpu *processor,
  439. unsigned_word cia)
  440. {
  441. SYS(getuid);
  442. emul_write_status(processor, (int)getuid(), 0);
  443. }
  444. #endif
  445. #ifndef HAVE_GETEUID
  446. #define do_geteuid 0
  447. #else
  448. static void
  449. do_geteuid(os_emul_data *emul,
  450. unsigned call,
  451. const int arg0,
  452. cpu *processor,
  453. unsigned_word cia)
  454. {
  455. SYS(geteuid);
  456. emul_write_status(processor, (int)geteuid(), 0);
  457. }
  458. #endif
  459. #ifndef HAVE_KILL
  460. #define do_kill 0
  461. #else
  462. static void
  463. do_kill(os_emul_data *emul,
  464. unsigned call,
  465. const int arg0,
  466. cpu *processor,
  467. unsigned_word cia)
  468. {
  469. pid_t pid = cpu_registers(processor)->gpr[arg0];
  470. int sig = cpu_registers(processor)->gpr[arg0+1];
  471. if (WITH_TRACE && ppc_trace[trace_os_emul])
  472. printf_filtered ("%d, %d", (int)pid, sig);
  473. SYS(kill);
  474. printf_filtered("SYS_kill at 0x%lx - more to this than just being killed\n",
  475. (long)cia);
  476. cpu_halt(processor, cia, was_signalled, sig);
  477. }
  478. #endif
  479. #ifndef HAVE_DUP
  480. #define do_dup 0
  481. #else
  482. static void
  483. do_dup(os_emul_data *emul,
  484. unsigned call,
  485. const int arg0,
  486. cpu *processor,
  487. unsigned_word cia)
  488. {
  489. int oldd = cpu_registers(processor)->gpr[arg0];
  490. int status = (fdbad (oldd) < 0) ? -1 : dup(oldd);
  491. int err = errno;
  492. if (WITH_TRACE && ppc_trace[trace_os_emul])
  493. printf_filtered ("%d", oldd);
  494. SYS(dup);
  495. emul_write_status(processor, status, err);
  496. }
  497. #endif
  498. #ifndef HAVE_GETEGID
  499. #define do_getegid 0
  500. #else
  501. static void
  502. do_getegid(os_emul_data *emul,
  503. unsigned call,
  504. const int arg0,
  505. cpu *processor,
  506. unsigned_word cia)
  507. {
  508. SYS(getegid);
  509. emul_write_status(processor, (int)getegid(), 0);
  510. }
  511. #endif
  512. #ifndef HAVE_GETGID
  513. #define do_getgid 0
  514. #else
  515. static void
  516. do_getgid(os_emul_data *emul,
  517. unsigned call,
  518. const int arg0,
  519. cpu *processor,
  520. unsigned_word cia)
  521. {
  522. SYS(getgid);
  523. emul_write_status(processor, (int)getgid(), 0);
  524. }
  525. #endif
  526. #ifndef HAVE_SIGPROCMASK
  527. #define do_sigprocmask 0
  528. #else
  529. static void
  530. do_sigprocmask(os_emul_data *emul,
  531. unsigned call,
  532. const int arg0,
  533. cpu *processor,
  534. unsigned_word cia)
  535. {
  536. signed_word how = cpu_registers(processor)->gpr[arg0];
  537. unsigned_word set = cpu_registers(processor)->gpr[arg0+1];
  538. unsigned_word oset = cpu_registers(processor)->gpr[arg0+2];
  539. #ifdef SYS_sigprocmask
  540. SYS(sigprocmask);
  541. #endif
  542. if (WITH_TRACE && ppc_trace[trace_os_emul])
  543. printf_filtered ("%ld, 0x%lx, 0x%lx", (long)how, (long)set, (long)oset);
  544. emul_write_status(processor, 0, 0);
  545. cpu_registers(processor)->gpr[4] = set;
  546. }
  547. #endif
  548. #ifndef HAVE_IOCTL
  549. #define do_ioctl 0
  550. #else
  551. static void
  552. do_ioctl(os_emul_data *emul,
  553. unsigned call,
  554. const int arg0,
  555. cpu *processor,
  556. unsigned_word cia)
  557. {
  558. int d = cpu_registers(processor)->gpr[arg0];
  559. unsigned request = cpu_registers(processor)->gpr[arg0+1];
  560. unsigned_word argp_addr = cpu_registers(processor)->gpr[arg0+2];
  561. #if !WITH_NetBSD_HOST
  562. cpu_registers(processor)->gpr[arg0] = 0; /* just succeed */
  563. #else
  564. unsigned dir = request & IOC_DIRMASK;
  565. int status;
  566. SYS(ioctl);
  567. /* what we haven't done */
  568. if (dir & IOC_IN /* write into the io device */
  569. || dir & IOC_OUT
  570. || !(dir & IOC_VOID))
  571. error("do_ioctl() read or write of parameter not implemented\n");
  572. status = fdbad (d);
  573. if (status == 0)
  574. status = ioctl(d, request, NULL);
  575. emul_write_status(processor, status, errno);
  576. #endif
  577. if (WITH_TRACE && ppc_trace[trace_os_emul])
  578. printf_filtered ("%d, 0x%x, 0x%lx", d, request, (long)argp_addr);
  579. }
  580. #endif
  581. #ifndef HAVE_UMASK
  582. #define do_umask 0
  583. #else
  584. static void
  585. do_umask(os_emul_data *emul,
  586. unsigned call,
  587. const int arg0,
  588. cpu *processor,
  589. unsigned_word cia)
  590. {
  591. int mask = cpu_registers(processor)->gpr[arg0];
  592. if (WITH_TRACE && ppc_trace[trace_os_emul])
  593. printf_filtered ("0%o", mask);
  594. SYS(umask);
  595. emul_write_status(processor, umask(mask), 0);
  596. }
  597. #endif
  598. #ifndef HAVE_DUP2
  599. #define do_dup2 0
  600. #else
  601. static void
  602. do_dup2(os_emul_data *emul,
  603. unsigned call,
  604. const int arg0,
  605. cpu *processor,
  606. unsigned_word cia)
  607. {
  608. int oldd = cpu_registers(processor)->gpr[arg0];
  609. int newd = cpu_registers(processor)->gpr[arg0+1];
  610. int status = (fdbad (oldd) < 0) ? -1 : dup2(oldd, newd);
  611. int err = errno;
  612. if (WITH_TRACE && ppc_trace[trace_os_emul])
  613. printf_filtered ("%d, %d", oldd, newd);
  614. SYS(dup2);
  615. emul_write_status(processor, status, err);
  616. }
  617. #endif
  618. #ifndef HAVE_FCNTL
  619. #define do_fcntl 0
  620. #else
  621. static void
  622. do_fcntl(os_emul_data *emul,
  623. unsigned call,
  624. const int arg0,
  625. cpu *processor,
  626. unsigned_word cia)
  627. {
  628. int fd = cpu_registers(processor)->gpr[arg0];
  629. int cmd = cpu_registers(processor)->gpr[arg0+1];
  630. int arg = cpu_registers(processor)->gpr[arg0+2];
  631. int status;
  632. if (WITH_TRACE && ppc_trace[trace_os_emul])
  633. printf_filtered ("%d, %d, %d", fd, cmd, arg);
  634. SYS(fcntl);
  635. status = fdbad (fd);
  636. if (status == 0)
  637. status = fcntl(fd, cmd, arg);
  638. emul_write_status(processor, status, errno);
  639. }
  640. #endif
  641. #ifndef HAVE_GETTIMEOFDAY
  642. #define do_gettimeofday 0
  643. #else
  644. static void
  645. do_gettimeofday(os_emul_data *emul,
  646. unsigned call,
  647. const int arg0,
  648. cpu *processor,
  649. unsigned_word cia)
  650. {
  651. unsigned_word t_addr = cpu_registers(processor)->gpr[arg0];
  652. unsigned_word tz_addr = cpu_registers(processor)->gpr[arg0+1];
  653. struct timeval t;
  654. struct timezone tz;
  655. int status = gettimeofday(&t, (tz_addr != 0 ? &tz : NULL));
  656. int err = errno;
  657. if (WITH_TRACE && ppc_trace[trace_os_emul])
  658. printf_filtered ("0x%lx, 0x%lx", (long)t_addr, (long)tz_addr);
  659. SYS(gettimeofday);
  660. emul_write_status(processor, status, err);
  661. if (status == 0) {
  662. if (t_addr != 0)
  663. write_timeval(t_addr, t, processor, cia);
  664. if (tz_addr != 0)
  665. write_timezone(tz_addr, tz, processor, cia);
  666. }
  667. }
  668. #endif
  669. #ifndef HAVE_GETRUSAGE
  670. #define do_getrusage 0
  671. #else
  672. static void
  673. do_getrusage(os_emul_data *emul,
  674. unsigned call,
  675. const int arg0,
  676. cpu *processor,
  677. unsigned_word cia)
  678. {
  679. int who = cpu_registers(processor)->gpr[arg0];
  680. unsigned_word rusage_addr = cpu_registers(processor)->gpr[arg0+1];
  681. struct rusage rusage;
  682. int status = getrusage(who, (rusage_addr != 0 ? &rusage : NULL));
  683. int err = errno;
  684. if (WITH_TRACE && ppc_trace[trace_os_emul])
  685. printf_filtered ("%d, 0x%lx", who, (long)rusage_addr);
  686. SYS(getrusage);
  687. emul_write_status(processor, status, err);
  688. if (status == 0) {
  689. if (rusage_addr != 0)
  690. write_rusage(rusage_addr, rusage, processor, cia);
  691. }
  692. }
  693. #endif
  694. #ifndef HAVE_FSTATFS
  695. #define do_fstatfs 0
  696. #else
  697. static void
  698. do_fstatfs(os_emul_data *emul,
  699. unsigned call,
  700. const int arg0,
  701. cpu *processor,
  702. unsigned_word cia)
  703. {
  704. int fd = cpu_registers(processor)->gpr[arg0];
  705. unsigned_word buf_addr = cpu_registers(processor)->gpr[arg0+1];
  706. struct statfs buf;
  707. int status;
  708. if (WITH_TRACE && ppc_trace[trace_os_emul])
  709. printf_filtered ("%d, 0x%lx", fd, (long)buf_addr);
  710. SYS(fstatfs);
  711. status = fdbad (fd);
  712. if (status == 0)
  713. status = fstatfs(fd, (buf_addr == 0 ? NULL : &buf));
  714. emul_write_status(processor, status, errno);
  715. if (status == 0) {
  716. if (buf_addr != 0)
  717. write_statfs(buf_addr, buf, processor, cia);
  718. }
  719. }
  720. #endif
  721. #ifndef HAVE_STAT
  722. #define do_stat 0
  723. #else
  724. static void
  725. do_stat(os_emul_data *emul,
  726. unsigned call,
  727. const int arg0,
  728. cpu *processor,
  729. unsigned_word cia)
  730. {
  731. char path_buf[PATH_MAX];
  732. unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
  733. unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1];
  734. char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
  735. struct stat buf;
  736. int status;
  737. #ifdef SYS_stat
  738. SYS(stat);
  739. #endif
  740. status = stat(path, &buf);
  741. emul_write_status(processor, status, errno);
  742. if (status == 0)
  743. write_stat(stat_buf_addr, buf, processor, cia);
  744. }
  745. #endif
  746. #ifndef HAVE_FSTAT
  747. #define do_fstat 0
  748. #else
  749. static void
  750. do_fstat(os_emul_data *emul,
  751. unsigned call,
  752. const int arg0,
  753. cpu *processor,
  754. unsigned_word cia)
  755. {
  756. int fd = cpu_registers(processor)->gpr[arg0];
  757. unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1];
  758. struct stat buf;
  759. int status;
  760. #ifdef SYS_fstat
  761. SYS(fstat);
  762. #endif
  763. /* Can't combine these statements, cuz fstat sets errno. */
  764. status = fdbad (fd);
  765. if (status == 0)
  766. status = fstat(fd, &buf);
  767. emul_write_status(processor, status, errno);
  768. write_stat(stat_buf_addr, buf, processor, cia);
  769. }
  770. #endif
  771. #ifndef HAVE_LSTAT
  772. #define do_lstat 0
  773. #else
  774. static void
  775. do_lstat(os_emul_data *emul,
  776. unsigned call,
  777. const int arg0,
  778. cpu *processor,
  779. unsigned_word cia)
  780. {
  781. char path_buf[PATH_MAX];
  782. unsigned_word path_addr = cpu_registers(processor)->gpr[arg0];
  783. char *path = emul_read_string(path_buf, path_addr, PATH_MAX, processor, cia);
  784. unsigned_word stat_buf_addr = cpu_registers(processor)->gpr[arg0+1];
  785. struct stat buf;
  786. int status;
  787. #ifdef SYS_lstat
  788. SYS(lstat);
  789. #endif
  790. /* Can't combine these statements, cuz lstat sets errno. */
  791. status = lstat(path, &buf);
  792. emul_write_status(processor, status, errno);
  793. write_stat(stat_buf_addr, buf, processor, cia);
  794. }
  795. #endif
  796. #ifndef HAVE_GETDIRENTRIES
  797. #define do_getdirentries 0
  798. #else
  799. static void
  800. do_getdirentries(os_emul_data *emul,
  801. unsigned call,
  802. const int arg0,
  803. cpu *processor,
  804. unsigned_word cia)
  805. {
  806. int fd = cpu_registers(processor)->gpr[arg0];
  807. unsigned_word buf_addr = cpu_registers(processor)->gpr[arg0+1];
  808. char *buf;
  809. int nbytes = cpu_registers(processor)->gpr[arg0+2];
  810. unsigned_word basep_addr = cpu_registers(processor)->gpr[arg0+3];
  811. long basep;
  812. int status;
  813. #ifdef SYS_getdirentries
  814. SYS(getdirentries);
  815. #endif
  816. if (buf_addr != 0 && nbytes >= 0)
  817. buf = zalloc(nbytes);
  818. else
  819. buf = NULL;
  820. status = getdirentries(fd,
  821. (buf_addr == 0 ? NULL : buf),
  822. nbytes,
  823. (basep_addr == 0 ? NULL : &basep));
  824. emul_write_status(processor, status, errno);
  825. if (basep_addr != 0)
  826. emul_write_word(basep_addr, basep, processor, cia);
  827. if (status > 0)
  828. write_direntries(buf_addr, buf, status, processor, cia);
  829. if (buf != NULL)
  830. free(buf);
  831. }
  832. #endif
  833. static void
  834. do___syscall(os_emul_data *emul,
  835. unsigned call,
  836. const int arg0,
  837. cpu *processor,
  838. unsigned_word cia)
  839. {
  840. SYS(__syscall);
  841. emul_do_system_call(emul,
  842. emul->syscalls,
  843. cpu_registers(processor)->gpr[arg0],
  844. arg0 + 1,
  845. processor,
  846. cia);
  847. }
  848. #ifndef HAVE_LSEEK
  849. #define do_lseek 0
  850. #else
  851. static void
  852. do_lseek(os_emul_data *emul,
  853. unsigned call,
  854. const int arg0,
  855. cpu *processor,
  856. unsigned_word cia)
  857. {
  858. int fildes = cpu_registers(processor)->gpr[arg0];
  859. off_t offset = emul_read_gpr64(processor, arg0+2);
  860. int whence = cpu_registers(processor)->gpr[arg0+4];
  861. off_t status;
  862. SYS(lseek);
  863. status = fdbad (fildes);
  864. if (status == 0)
  865. status = lseek(fildes, offset, whence);
  866. if (status == -1)
  867. emul_write_status(processor, -1, errno);
  868. else {
  869. emul_write_status(processor, 0, 0); /* success */
  870. emul_write_gpr64(processor, 3, status);
  871. }
  872. }
  873. #endif
  874. static void
  875. do___sysctl(os_emul_data *emul,
  876. unsigned call,
  877. const int arg0,
  878. cpu *processor,
  879. unsigned_word cia)
  880. {
  881. /* call the arguments by their real name */
  882. unsigned_word name = cpu_registers(processor)->gpr[arg0];
  883. signed_word namelen = cpu_registers(processor)->gpr[arg0+1];
  884. unsigned_word oldp = cpu_registers(processor)->gpr[arg0+2];
  885. unsigned_word oldlenp = cpu_registers(processor)->gpr[arg0+3];
  886. signed_word oldlen;
  887. signed_word mib;
  888. signed_word int_val;
  889. SYS(__sysctl);
  890. /* pluck out the management information base id */
  891. if (namelen < 1)
  892. error("system_call()SYS___sysctl bad name[0]\n");
  893. mib = vm_data_map_read_word(cpu_data_map(processor),
  894. name,
  895. processor,
  896. cia);
  897. name += sizeof(mib);
  898. /* see what to do with it ... */
  899. switch ((int)mib) {
  900. case 6/*CTL_HW*/:
  901. #if WITH_NetBSD_HOST && (CTL_HW != 6)
  902. # error "CTL_HW"
  903. #endif
  904. if (namelen < 2)
  905. error("system_call()SYS___sysctl - CTL_HW - bad name[1]\n");
  906. mib = vm_data_map_read_word(cpu_data_map(processor),
  907. name,
  908. processor,
  909. cia);
  910. name += sizeof(mib);
  911. switch ((int)mib) {
  912. case 7/*HW_PAGESIZE*/:
  913. #if WITH_NetBSD_HOST && (HW_PAGESIZE != 7)
  914. # error "HW_PAGESIZE"
  915. #endif
  916. oldlen = vm_data_map_read_word(cpu_data_map(processor),
  917. oldlenp,
  918. processor,
  919. cia);
  920. if (sizeof(signed_word) > oldlen)
  921. error("system_call()sysctl - CTL_HW.HW_PAGESIZE - to small\n");
  922. int_val = 8192;
  923. oldlen = sizeof(int_val);
  924. emul_write_word(oldp, int_val, processor, cia);
  925. emul_write_word(oldlenp, oldlen, processor, cia);
  926. break;
  927. default:
  928. error("sysctl() CTL_HW.%d unknown\n", mib);
  929. break;
  930. }
  931. break;
  932. default:
  933. error("sysctl() name[0]=%d unknown\n", (int)mib);
  934. break;
  935. }
  936. emul_write_status(processor, 0, 0); /* always succeed */
  937. }
  938. static emul_syscall_descriptor netbsd_descriptors[] = {
  939. /* 0 */ { 0, "syscall" },
  940. /* 1 */ { do_exit, "exit" },
  941. /* 2 */ { 0, "fork" },
  942. /* 3 */ { do_read, "read" },
  943. /* 4 */ { do_write, "write" },
  944. /* 5 */ { do_open, "open" },
  945. /* 6 */ { do_close, "close" },
  946. /* 7 */ { 0, "wait4" },
  947. { 0, }, /* 8 is old creat */
  948. /* 9 */ { 0, "link" },
  949. /* 10 */ { 0, "unlink" },
  950. { 0, }, /* 11 is obsolete execv */
  951. /* 12 */ { 0, "chdir" },
  952. /* 13 */ { 0, "fchdir" },
  953. /* 14 */ { 0, "mknod" },
  954. /* 15 */ { 0, "chmod" },
  955. /* 16 */ { 0, "chown" },
  956. /* 17 */ { do_break, "break" },
  957. /* 18 */ { 0, "getfsstat" },
  958. { 0, }, /* 19 is old lseek */
  959. /* 20 */ { do_getpid, "getpid" },
  960. /* 21 */ { 0, "mount" },
  961. /* 22 */ { 0, "unmount" },
  962. /* 23 */ { 0, "setuid" },
  963. /* 24 */ { do_getuid, "getuid" },
  964. /* 25 */ { do_geteuid, "geteuid" },
  965. /* 26 */ { 0, "ptrace" },
  966. /* 27 */ { 0, "recvmsg" },
  967. /* 28 */ { 0, "sendmsg" },
  968. /* 29 */ { 0, "recvfrom" },
  969. /* 30 */ { 0, "accept" },
  970. /* 31 */ { 0, "getpeername" },
  971. /* 32 */ { 0, "getsockname" },
  972. /* 33 */ { 0, "access" },
  973. /* 34 */ { 0, "chflags" },
  974. /* 35 */ { 0, "fchflags" },
  975. /* 36 */ { 0, "sync" },
  976. /* 37 */ { do_kill, "kill" },
  977. { 0, }, /* 38 is old stat */
  978. /* 39 */ { 0, "getppid" },
  979. { 0, }, /* 40 is old lstat */
  980. /* 41 */ { do_dup, "dup" },
  981. /* 42 */ { 0, "pipe" },
  982. /* 43 */ { do_getegid, "getegid" },
  983. /* 44 */ { 0, "profil" },
  984. /* 45 */ { 0, "ktrace" },
  985. /* 46 */ { 0, "sigaction" },
  986. /* 47 */ { do_getgid, "getgid" },
  987. /* 48 */ { do_sigprocmask, "sigprocmask" },
  988. /* 49 */ { 0, "getlogin" },
  989. /* 50 */ { 0, "setlogin" },
  990. /* 51 */ { 0, "acct" },
  991. /* 52 */ { 0, "sigpending" },
  992. /* 53 */ { 0, "sigaltstack" },
  993. /* 54 */ { do_ioctl, "ioctl" },
  994. /* 55 */ { 0, "reboot" },
  995. /* 56 */ { 0, "revoke" },
  996. /* 57 */ { 0, "symlink" },
  997. /* 58 */ { 0, "readlink" },
  998. /* 59 */ { 0, "execve" },
  999. /* 60 */ { do_umask, "umask" },
  1000. /* 61 */ { 0, "chroot" },
  1001. { 0, }, /* 62 is old fstat */
  1002. { 0, }, /* 63 is old getkerninfo */
  1003. { 0, }, /* 64 is old getpagesize */
  1004. /* 65 */ { 0, "msync" },
  1005. /* 66 */ { 0, "vfork" },
  1006. { 0, }, /* 67 is obsolete vread */
  1007. { 0, }, /* 68 is obsolete vwrite */
  1008. /* 69 */ { 0, "sbrk" },
  1009. /* 70 */ { 0, "sstk" },
  1010. { 0, }, /* 71 is old mmap */
  1011. /* 72 */ { 0, "vadvise" },
  1012. /* 73 */ { 0, "munmap" },
  1013. /* 74 */ { 0, "mprotect" },
  1014. /* 75 */ { 0, "madvise" },
  1015. { 0, }, /* 76 is obsolete vhangup */
  1016. { 0, }, /* 77 is obsolete vlimit */
  1017. /* 78 */ { 0, "mincore" },
  1018. /* 79 */ { 0, "getgroups" },
  1019. /* 80 */ { 0, "setgroups" },
  1020. /* 81 */ { 0, "getpgrp" },
  1021. /* 82 */ { 0, "setpgid" },
  1022. /* 83 */ { 0, "setitimer" },
  1023. { 0, }, /* 84 is old wait */
  1024. /* 85 */ { 0, "swapon" },
  1025. /* 86 */ { 0, "getitimer" },
  1026. { 0, }, /* 87 is old gethostname */
  1027. { 0, }, /* 88 is old sethostname */
  1028. { 0, }, /* 89 is old getdtablesize */
  1029. { do_dup2, "dup2" },
  1030. { 0, }, /* 91 */
  1031. /* 92 */ { do_fcntl, "fcntl" },
  1032. /* 93 */ { 0, "select" },
  1033. { 0, }, /* 94 */
  1034. /* 95 */ { 0, "fsync" },
  1035. /* 96 */ { 0, "setpriority" },
  1036. /* 97 */ { 0, "socket" },
  1037. /* 98 */ { 0, "connect" },
  1038. { 0, }, /* 99 is old accept */
  1039. /* 100 */ { 0, "getpriority" },
  1040. { 0, }, /* 101 is old send */
  1041. { 0, }, /* 102 is old recv */
  1042. /* 103 */ { 0, "sigreturn" },
  1043. /* 104 */ { 0, "bind" },
  1044. /* 105 */ { 0, "setsockopt" },
  1045. /* 106 */ { 0, "listen" },
  1046. { 0, }, /* 107 is obsolete vtimes */
  1047. { 0, }, /* 108 is old sigvec */
  1048. { 0, }, /* 109 is old sigblock */
  1049. { 0, }, /* 110 is old sigsetmask */
  1050. /* 111 */ { 0, "sigsuspend" },
  1051. { 0, }, /* 112 is old sigstack */
  1052. { 0, }, /* 113 is old recvmsg */
  1053. { 0, }, /* 114 is old sendmsg */
  1054. /* - is obsolete vtrace */ { 0, "vtrace 115" },
  1055. /* 116 */ { do_gettimeofday, "gettimeofday" },
  1056. /* 117 */ { do_getrusage, "getrusage" },
  1057. /* 118 */ { 0, "getsockopt" },
  1058. /* 119 */ { 0, "resuba" },
  1059. /* 120 */ { 0, "readv" },
  1060. /* 121 */ { 0, "writev" },
  1061. /* 122 */ { 0, "settimeofday" },
  1062. /* 123 */ { 0, "fchown" },
  1063. /* 124 */ { 0, "fchmod" },
  1064. { 0, }, /* 125 is old recvfrom */
  1065. { 0, }, /* 126 is old setreuid */
  1066. { 0, }, /* 127 is old setregid */
  1067. /* 128 */ { 0, "rename" },
  1068. { 0, }, /* 129 is old truncate */
  1069. { 0, }, /* 130 is old ftruncate */
  1070. /* 131 */ { 0, "flock" },
  1071. /* 132 */ { 0, "mkfifo" },
  1072. /* 133 */ { 0, "sendto" },
  1073. /* 134 */ { 0, "shutdown" },
  1074. /* 135 */ { 0, "socketpair" },
  1075. /* 136 */ { 0, "mkdir" },
  1076. /* 137 */ { 0, "rmdir" },
  1077. /* 138 */ { 0, "utimes" },
  1078. { 0, }, /* 139 is obsolete 4.2 sigreturn */
  1079. /* 140 */ { 0, "adjtime" },
  1080. { 0, }, /* 141 is old getpeername */
  1081. { 0, }, /* 142 is old gethostid */
  1082. { 0, }, /* 143 is old sethostid */
  1083. { 0, }, /* 144 is old getrlimit */
  1084. { 0, }, /* 145 is old setrlimit */
  1085. { 0, }, /* 146 is old killpg */
  1086. /* 147 */ { 0, "setsid" },
  1087. /* 148 */ { 0, "quotactl" },
  1088. { 0, }, /* 149 is old quota */
  1089. { 0, }, /* 150 is old getsockname */
  1090. { 0, }, /* 151 */
  1091. { 0, }, /* 152 */
  1092. { 0, }, /* 153 */
  1093. { 0, }, /* 154 */
  1094. /* 155 */ { 0, "nfssvc" },
  1095. { 0, }, /* 156 is old getdirentries */
  1096. /* 157 */ { 0, "statfs" },
  1097. /* 158 */ { do_fstatfs, "fstatfs" },
  1098. { 0, }, /* 159 */
  1099. { 0, }, /* 160 */
  1100. /* 161 */ { 0, "getfh" },
  1101. { 0, }, /* 162 is old getdomainname */
  1102. { 0, }, /* 163 is old setdomainname */
  1103. { 0, }, /* 164 is old uname */
  1104. /* 165 */ { 0, "sysarch" },
  1105. { 0, }, /* 166 */
  1106. { 0, }, /* 167 */
  1107. { 0, }, /* 168 */
  1108. /* 169 */ { 0, "semsys" },
  1109. /* 170 */ { 0, "msgsys" },
  1110. /* 171 */ { 0, "shmsys" },
  1111. { 0, }, /* 172 */
  1112. { 0, }, /* 173 */
  1113. { 0, }, /* 174 */
  1114. { 0, }, /* 175 */
  1115. { 0, }, /* 176 */
  1116. { 0, }, /* 177 */
  1117. { 0, }, /* 178 */
  1118. { 0, }, /* 179 */
  1119. { 0, }, /* 180 */
  1120. /* 181 */ { 0, "setgid" },
  1121. /* 182 */ { 0, "setegid" },
  1122. /* 183 */ { 0, "seteuid" },
  1123. /* 184 */ { 0, "lfs_bmapv" },
  1124. /* 185 */ { 0, "lfs_markv" },
  1125. /* 186 */ { 0, "lfs_segclean" },
  1126. /* 187 */ { 0, "lfs_segwait" },
  1127. /* 188 */ { do_stat, "stat" },
  1128. /* 189 */ { do_fstat, "fstat" },
  1129. /* 190 */ { do_lstat, "lstat" },
  1130. /* 191 */ { 0, "pathconf" },
  1131. /* 192 */ { 0, "fpathconf" },
  1132. { 0, }, /* 193 */
  1133. /* 194 */ { 0, "getrlimit" },
  1134. /* 195 */ { 0, "setrlimit" },
  1135. /* 196 */ { do_getdirentries, "getdirentries" },
  1136. /* 197 */ { 0, "mmap" },
  1137. /* 198 */ { do___syscall, "__syscall" },
  1138. /* 199 */ { do_lseek, "lseek" },
  1139. /* 200 */ { 0, "truncate" },
  1140. /* 201 */ { 0, "ftruncate" },
  1141. /* 202 */ { do___sysctl, "__sysctl" },
  1142. /* 203 */ { 0, "mlock" },
  1143. /* 204 */ { 0, "munlock" },
  1144. };
  1145. static char *(netbsd_error_names[]) = {
  1146. /* 0 */ "ESUCCESS",
  1147. /* 1 */ "EPERM",
  1148. /* 2 */ "ENOENT",
  1149. /* 3 */ "ESRCH",
  1150. /* 4 */ "EINTR",
  1151. /* 5 */ "EIO",
  1152. /* 6 */ "ENXIO",
  1153. /* 7 */ "E2BIG",
  1154. /* 8 */ "ENOEXEC",
  1155. /* 9 */ "EBADF",
  1156. /* 10 */ "ECHILD",
  1157. /* 11 */ "EDEADLK",
  1158. /* 12 */ "ENOMEM",
  1159. /* 13 */ "EACCES",
  1160. /* 14 */ "EFAULT",
  1161. /* 15 */ "ENOTBLK",
  1162. /* 16 */ "EBUSY",
  1163. /* 17 */ "EEXIST",
  1164. /* 18 */ "EXDEV",
  1165. /* 19 */ "ENODEV",
  1166. /* 20 */ "ENOTDIR",
  1167. /* 21 */ "EISDIR",
  1168. /* 22 */ "EINVAL",
  1169. /* 23 */ "ENFILE",
  1170. /* 24 */ "EMFILE",
  1171. /* 25 */ "ENOTTY",
  1172. /* 26 */ "ETXTBSY",
  1173. /* 27 */ "EFBIG",
  1174. /* 28 */ "ENOSPC",
  1175. /* 29 */ "ESPIPE",
  1176. /* 30 */ "EROFS",
  1177. /* 31 */ "EMLINK",
  1178. /* 32 */ "EPIPE",
  1179. /* 33 */ "EDOM",
  1180. /* 34 */ "ERANGE",
  1181. /* 35 */ "EAGAIN",
  1182. /* 36 */ "EINPROGRESS",
  1183. /* 37 */ "EALREADY",
  1184. /* 38 */ "ENOTSOCK",
  1185. /* 39 */ "EDESTADDRREQ",
  1186. /* 40 */ "EMSGSIZE",
  1187. /* 41 */ "EPROTOTYPE",
  1188. /* 42 */ "ENOPROTOOPT",
  1189. /* 43 */ "EPROTONOSUPPORT",
  1190. /* 44 */ "ESOCKTNOSUPPORT",
  1191. /* 45 */ "EOPNOTSUPP",
  1192. /* 46 */ "EPFNOSUPPORT",
  1193. /* 47 */ "EAFNOSUPPORT",
  1194. /* 48 */ "EADDRINUSE",
  1195. /* 49 */ "EADDRNOTAVAIL",
  1196. /* 50 */ "ENETDOWN",
  1197. /* 51 */ "ENETUNREACH",
  1198. /* 52 */ "ENETRESET",
  1199. /* 53 */ "ECONNABORTED",
  1200. /* 54 */ "ECONNRESET",
  1201. /* 55 */ "ENOBUFS",
  1202. /* 56 */ "EISCONN",
  1203. /* 57 */ "ENOTCONN",
  1204. /* 58 */ "ESHUTDOWN",
  1205. /* 59 */ "ETOOMANYREFS",
  1206. /* 60 */ "ETIMEDOUT",
  1207. /* 61 */ "ECONNREFUSED",
  1208. /* 62 */ "ELOOP",
  1209. /* 63 */ "ENAMETOOLONG",
  1210. /* 64 */ "EHOSTDOWN",
  1211. /* 65 */ "EHOSTUNREACH",
  1212. /* 66 */ "ENOTEMPTY",
  1213. /* 67 */ "EPROCLIM",
  1214. /* 68 */ "EUSERS",
  1215. /* 69 */ "EDQUOT",
  1216. /* 70 */ "ESTALE",
  1217. /* 71 */ "EREMOTE",
  1218. /* 72 */ "EBADRPC",
  1219. /* 73 */ "ERPCMISMATCH",
  1220. /* 74 */ "EPROGUNAVAIL",
  1221. /* 75 */ "EPROGMISMATCH",
  1222. /* 76 */ "EPROCUNAVAIL",
  1223. /* 77 */ "ENOLCK",
  1224. /* 78 */ "ENOSYS",
  1225. /* 79 */ "EFTYPE",
  1226. /* 80 */ "EAUTH",
  1227. /* 81 */ "ENEEDAUTH",
  1228. /* 82 */ "EIDRM",
  1229. /* 83 */ "ENOMSG",
  1230. /* 84 */ "EOVERFLOW",
  1231. /* 85 */ "EILSEQ",
  1232. /* 86 */ "ENOTSUP",
  1233. /* 87 */ "ECANCELED",
  1234. /* 88 */ "EBADMSG",
  1235. /* 89 */ "ENODATA",
  1236. /* 90 */ "ENOSR",
  1237. /* 91 */ "ENOSTR",
  1238. /* 92 */ "ETIME",
  1239. /* 93 */ "ENOATTR",
  1240. /* 94 */ "EMULTIHOP",
  1241. /* 95 */ "ENOLINK",
  1242. /* 96 */ "EPROTO",
  1243. /* 97 */ "EOWNERDEAD",
  1244. /* 98 */ "ENOTRECOVERABLE",
  1245. /* 98 */ "ELAST",
  1246. };
  1247. static char *(netbsd_signal_names[]) = {
  1248. /* 0 */ 0,
  1249. /* 1 */ "SIGHUP",
  1250. /* 2 */ "SIGINT",
  1251. /* 3 */ "SIGQUIT",
  1252. /* 4 */ "SIGILL",
  1253. /* 5 */ "SIGTRAP",
  1254. /* 6 */ "SIGABRT",
  1255. /* 7 */ "SIGEMT",
  1256. /* 8 */ "SIGFPE",
  1257. /* 9 */ "SIGKILL",
  1258. /* 10 */ "SIGBUS",
  1259. /* 11 */ "SIGSEGV",
  1260. /* 12 */ "SIGSYS",
  1261. /* 13 */ "SIGPIPE",
  1262. /* 14 */ "SIGALRM",
  1263. /* 15 */ "SIGTERM",
  1264. /* 16 */ "SIGURG",
  1265. /* 17 */ "SIGSTOP",
  1266. /* 18 */ "SIGTSTP",
  1267. /* 19 */ "SIGCONT",
  1268. /* 20 */ "SIGCHLD",
  1269. /* 21 */ "SIGTTIN",
  1270. /* 22 */ "SIGTTOU",
  1271. /* 23 */ "SIGIO",
  1272. /* 24 */ "SIGXCPU",
  1273. /* 25 */ "SIGXFSZ",
  1274. /* 26 */ "SIGVTALRM",
  1275. /* 27 */ "SIGPROF",
  1276. /* 28 */ "SIGWINCH",
  1277. /* 29 */ "SIGINFO",
  1278. /* 30 */ "SIGUSR1",
  1279. /* 31 */ "SIGUSR2",
  1280. /* 32 */ "SIGPWR",
  1281. /* 33 */ "SIGRTMIN",
  1282. /* 34 */ "SIGRTMIN+1",
  1283. /* 35 */ "SIGRTMIN+2",
  1284. /* 36 */ "SIGRTMIN+3",
  1285. /* 37 */ "SIGRTMIN+4",
  1286. /* 38 */ "SIGRTMIN+5",
  1287. /* 39 */ "SIGRTMIN+6",
  1288. /* 40 */ "SIGRTMIN+7",
  1289. /* 41 */ "SIGRTMIN+8",
  1290. /* 42 */ "SIGRTMIN+9",
  1291. /* 43 */ "SIGRTMIN+10",
  1292. /* 44 */ "SIGRTMIN+11",
  1293. /* 45 */ "SIGRTMIN+12",
  1294. /* 46 */ "SIGRTMIN+13",
  1295. /* 47 */ "SIGRTMIN+14",
  1296. /* 48 */ "SIGRTMIN+15",
  1297. /* 49 */ "SIGRTMIN+16",
  1298. /* 50 */ "SIGRTMIN+17",
  1299. /* 51 */ "SIGRTMIN+18",
  1300. /* 52 */ "SIGRTMIN+19",
  1301. /* 53 */ "SIGRTMIN+20",
  1302. /* 54 */ "SIGRTMIN+21",
  1303. /* 55 */ "SIGRTMIN+22",
  1304. /* 56 */ "SIGRTMIN+23",
  1305. /* 57 */ "SIGRTMIN+24",
  1306. /* 58 */ "SIGRTMIN+25",
  1307. /* 59 */ "SIGRTMIN+26",
  1308. /* 60 */ "SIGRTMIN+27",
  1309. /* 61 */ "SIGRTMIN+28",
  1310. /* 62 */ "SIGRTMIN+29",
  1311. /* 63 */ "SIGRTMAX",
  1312. };
  1313. static emul_syscall emul_netbsd_syscalls = {
  1314. netbsd_descriptors,
  1315. ARRAY_SIZE (netbsd_descriptors),
  1316. netbsd_error_names,
  1317. ARRAY_SIZE (netbsd_error_names),
  1318. netbsd_signal_names,
  1319. ARRAY_SIZE (netbsd_signal_names),
  1320. };
  1321. /* NetBSD's os_emul interface, most are just passed on to the generic
  1322. syscall stuff */
  1323. static os_emul_data *
  1324. emul_netbsd_create(device *root,
  1325. bfd *image,
  1326. const char *name)
  1327. {
  1328. unsigned_word top_of_stack;
  1329. unsigned stack_size;
  1330. int elf_binary;
  1331. os_emul_data *bsd_data;
  1332. device *vm;
  1333. char *filename;
  1334. /* check that this emulation is really for us */
  1335. if (name != NULL && strcmp(name, "netbsd") != 0)
  1336. return NULL;
  1337. if (image == NULL)
  1338. return NULL;
  1339. /* merge any emulation specific entries into the device tree */
  1340. /* establish a few defaults */
  1341. if (image->xvec->flavour == bfd_target_elf_flavour) {
  1342. elf_binary = 1;
  1343. top_of_stack = 0xe0000000;
  1344. stack_size = 0x00100000;
  1345. }
  1346. else {
  1347. elf_binary = 0;
  1348. top_of_stack = 0x20000000;
  1349. stack_size = 0x00100000;
  1350. }
  1351. /* options */
  1352. emul_add_tree_options(root, image, "netbsd",
  1353. (WITH_ENVIRONMENT == USER_ENVIRONMENT
  1354. ? "user" : "virtual"),
  1355. 0 /*oea-interrupt-prefix*/);
  1356. /* virtual memory - handles growth of stack/heap */
  1357. vm = tree_parse(root, "/openprom/vm");
  1358. tree_parse(vm, "./stack-base 0x%lx",
  1359. (unsigned long)(top_of_stack - stack_size));
  1360. tree_parse(vm, "./nr-bytes 0x%x", stack_size);
  1361. filename = tree_quote_property (bfd_get_filename(image));
  1362. tree_parse(root, "/openprom/vm/map-binary/file-name %s",
  1363. filename);
  1364. free (filename);
  1365. /* finish the init */
  1366. tree_parse(root, "/openprom/init/register/pc 0x%lx",
  1367. (unsigned long)bfd_get_start_address(image));
  1368. tree_parse(root, "/openprom/init/register/sp 0x%lx",
  1369. (unsigned long)top_of_stack);
  1370. tree_parse(root, "/openprom/init/register/msr 0x%x",
  1371. ((tree_find_boolean_property(root, "/options/little-endian?")
  1372. ? msr_little_endian_mode
  1373. : 0)
  1374. | (tree_find_boolean_property(root, "/openprom/options/floating-point?")
  1375. ? (msr_floating_point_available
  1376. | msr_floating_point_exception_mode_0
  1377. | msr_floating_point_exception_mode_1)
  1378. : 0)));
  1379. tree_parse(root, "/openprom/init/stack/stack-type %s",
  1380. (elf_binary ? "ppc-elf" : "ppc-xcoff"));
  1381. /* finally our emulation data */
  1382. bsd_data = ZALLOC(os_emul_data);
  1383. bsd_data->vm = vm;
  1384. bsd_data->syscalls = &emul_netbsd_syscalls;
  1385. return bsd_data;
  1386. }
  1387. static void
  1388. emul_netbsd_init(os_emul_data *emul_data,
  1389. int nr_cpus)
  1390. {
  1391. fd_closed[0] = 0;
  1392. fd_closed[1] = 0;
  1393. fd_closed[2] = 0;
  1394. }
  1395. static void
  1396. emul_netbsd_system_call(cpu *processor,
  1397. unsigned_word cia,
  1398. os_emul_data *emul_data)
  1399. {
  1400. emul_do_system_call(emul_data,
  1401. emul_data->syscalls,
  1402. cpu_registers(processor)->gpr[0],
  1403. 3, /*r3 contains arg0*/
  1404. processor,
  1405. cia);
  1406. }
  1407. const os_emul emul_netbsd = {
  1408. "netbsd",
  1409. emul_netbsd_create,
  1410. emul_netbsd_init,
  1411. emul_netbsd_system_call,
  1412. 0, /*instruction_call*/
  1413. 0 /*data*/
  1414. };
  1415. #endif /* _EMUL_NETBSD_C_ */