2
0

user-exec.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /*
  2. * User emulator execution
  3. *
  4. * Copyright (c) 2003-2005 Fabrice Bellard
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "config.h"
  20. #include "exec.h"
  21. #include "disas.h"
  22. #include "tcg.h"
  23. #undef EAX
  24. #undef ECX
  25. #undef EDX
  26. #undef EBX
  27. #undef ESP
  28. #undef EBP
  29. #undef ESI
  30. #undef EDI
  31. #undef EIP
  32. #include <signal.h>
  33. #ifdef __linux__
  34. #include <sys/ucontext.h>
  35. #endif
  36. //#define DEBUG_SIGNAL
  37. static void exception_action(CPUState *env1)
  38. {
  39. #if defined(TARGET_I386)
  40. raise_exception_err(env1->exception_index, env1->error_code);
  41. #else
  42. cpu_loop_exit(env1);
  43. #endif
  44. }
  45. /* exit the current TB from a signal handler. The host registers are
  46. restored in a state compatible with the CPU emulator
  47. */
  48. void cpu_resume_from_signal(CPUState *env1, void *puc)
  49. {
  50. #ifdef __linux__
  51. struct ucontext *uc = puc;
  52. #elif defined(__OpenBSD__)
  53. struct sigcontext *uc = puc;
  54. #endif
  55. env = env1;
  56. /* XXX: restore cpu registers saved in host registers */
  57. if (puc) {
  58. /* XXX: use siglongjmp ? */
  59. #ifdef __linux__
  60. #ifdef __ia64
  61. sigprocmask(SIG_SETMASK, (sigset_t *)&uc->uc_sigmask, NULL);
  62. #else
  63. sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
  64. #endif
  65. #elif defined(__OpenBSD__)
  66. sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
  67. #endif
  68. }
  69. env->exception_index = -1;
  70. longjmp(env->jmp_env, 1);
  71. }
  72. /* 'pc' is the host PC at which the exception was raised. 'address' is
  73. the effective address of the memory exception. 'is_write' is 1 if a
  74. write caused the exception and otherwise 0'. 'old_set' is the
  75. signal set which should be restored */
  76. static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
  77. int is_write, sigset_t *old_set,
  78. void *puc)
  79. {
  80. TranslationBlock *tb;
  81. int ret;
  82. if (cpu_single_env) {
  83. env = cpu_single_env; /* XXX: find a correct solution for multithread */
  84. }
  85. #if defined(DEBUG_SIGNAL)
  86. qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
  87. pc, address, is_write, *(unsigned long *)old_set);
  88. #endif
  89. /* XXX: locking issue */
  90. if (is_write && page_unprotect(h2g(address), pc, puc)) {
  91. return 1;
  92. }
  93. /* see if it is an MMU fault */
  94. ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
  95. if (ret < 0) {
  96. return 0; /* not an MMU fault */
  97. }
  98. if (ret == 0) {
  99. return 1; /* the MMU fault was handled without causing real CPU fault */
  100. }
  101. /* now we have a real cpu fault */
  102. tb = tb_find_pc(pc);
  103. if (tb) {
  104. /* the PC is inside the translated code. It means that we have
  105. a virtual CPU fault */
  106. cpu_restore_state(tb, env, pc);
  107. }
  108. /* we restore the process signal mask as the sigreturn should
  109. do it (XXX: use sigsetjmp) */
  110. sigprocmask(SIG_SETMASK, old_set, NULL);
  111. exception_action(env);
  112. /* never comes here */
  113. return 1;
  114. }
  115. #if defined(__i386__)
  116. #if defined(__APPLE__)
  117. #include <sys/ucontext.h>
  118. #define EIP_sig(context) (*((unsigned long *)&(context)->uc_mcontext->ss.eip))
  119. #define TRAP_sig(context) ((context)->uc_mcontext->es.trapno)
  120. #define ERROR_sig(context) ((context)->uc_mcontext->es.err)
  121. #define MASK_sig(context) ((context)->uc_sigmask)
  122. #elif defined(__NetBSD__)
  123. #include <ucontext.h>
  124. #define EIP_sig(context) ((context)->uc_mcontext.__gregs[_REG_EIP])
  125. #define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
  126. #define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR])
  127. #define MASK_sig(context) ((context)->uc_sigmask)
  128. #elif defined(__FreeBSD__) || defined(__DragonFly__)
  129. #include <ucontext.h>
  130. #define EIP_sig(context) (*((unsigned long *)&(context)->uc_mcontext.mc_eip))
  131. #define TRAP_sig(context) ((context)->uc_mcontext.mc_trapno)
  132. #define ERROR_sig(context) ((context)->uc_mcontext.mc_err)
  133. #define MASK_sig(context) ((context)->uc_sigmask)
  134. #elif defined(__OpenBSD__)
  135. #define EIP_sig(context) ((context)->sc_eip)
  136. #define TRAP_sig(context) ((context)->sc_trapno)
  137. #define ERROR_sig(context) ((context)->sc_err)
  138. #define MASK_sig(context) ((context)->sc_mask)
  139. #else
  140. #define EIP_sig(context) ((context)->uc_mcontext.gregs[REG_EIP])
  141. #define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO])
  142. #define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR])
  143. #define MASK_sig(context) ((context)->uc_sigmask)
  144. #endif
  145. int cpu_signal_handler(int host_signum, void *pinfo,
  146. void *puc)
  147. {
  148. siginfo_t *info = pinfo;
  149. #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
  150. ucontext_t *uc = puc;
  151. #elif defined(__OpenBSD__)
  152. struct sigcontext *uc = puc;
  153. #else
  154. struct ucontext *uc = puc;
  155. #endif
  156. unsigned long pc;
  157. int trapno;
  158. #ifndef REG_EIP
  159. /* for glibc 2.1 */
  160. #define REG_EIP EIP
  161. #define REG_ERR ERR
  162. #define REG_TRAPNO TRAPNO
  163. #endif
  164. pc = EIP_sig(uc);
  165. trapno = TRAP_sig(uc);
  166. return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  167. trapno == 0xe ?
  168. (ERROR_sig(uc) >> 1) & 1 : 0,
  169. &MASK_sig(uc), puc);
  170. }
  171. #elif defined(__x86_64__)
  172. #ifdef __NetBSD__
  173. #define PC_sig(context) _UC_MACHINE_PC(context)
  174. #define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
  175. #define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR])
  176. #define MASK_sig(context) ((context)->uc_sigmask)
  177. #elif defined(__OpenBSD__)
  178. #define PC_sig(context) ((context)->sc_rip)
  179. #define TRAP_sig(context) ((context)->sc_trapno)
  180. #define ERROR_sig(context) ((context)->sc_err)
  181. #define MASK_sig(context) ((context)->sc_mask)
  182. #elif defined(__FreeBSD__) || defined(__DragonFly__)
  183. #include <ucontext.h>
  184. #define PC_sig(context) (*((unsigned long *)&(context)->uc_mcontext.mc_rip))
  185. #define TRAP_sig(context) ((context)->uc_mcontext.mc_trapno)
  186. #define ERROR_sig(context) ((context)->uc_mcontext.mc_err)
  187. #define MASK_sig(context) ((context)->uc_sigmask)
  188. #else
  189. #define PC_sig(context) ((context)->uc_mcontext.gregs[REG_RIP])
  190. #define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO])
  191. #define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR])
  192. #define MASK_sig(context) ((context)->uc_sigmask)
  193. #endif
  194. int cpu_signal_handler(int host_signum, void *pinfo,
  195. void *puc)
  196. {
  197. siginfo_t *info = pinfo;
  198. unsigned long pc;
  199. #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
  200. ucontext_t *uc = puc;
  201. #elif defined(__OpenBSD__)
  202. struct sigcontext *uc = puc;
  203. #else
  204. struct ucontext *uc = puc;
  205. #endif
  206. pc = PC_sig(uc);
  207. return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  208. TRAP_sig(uc) == 0xe ?
  209. (ERROR_sig(uc) >> 1) & 1 : 0,
  210. &MASK_sig(uc), puc);
  211. }
  212. #elif defined(_ARCH_PPC)
  213. /***********************************************************************
  214. * signal context platform-specific definitions
  215. * From Wine
  216. */
  217. #ifdef linux
  218. /* All Registers access - only for local access */
  219. #define REG_sig(reg_name, context) \
  220. ((context)->uc_mcontext.regs->reg_name)
  221. /* Gpr Registers access */
  222. #define GPR_sig(reg_num, context) REG_sig(gpr[reg_num], context)
  223. /* Program counter */
  224. #define IAR_sig(context) REG_sig(nip, context)
  225. /* Machine State Register (Supervisor) */
  226. #define MSR_sig(context) REG_sig(msr, context)
  227. /* Count register */
  228. #define CTR_sig(context) REG_sig(ctr, context)
  229. /* User's integer exception register */
  230. #define XER_sig(context) REG_sig(xer, context)
  231. /* Link register */
  232. #define LR_sig(context) REG_sig(link, context)
  233. /* Condition register */
  234. #define CR_sig(context) REG_sig(ccr, context)
  235. /* Float Registers access */
  236. #define FLOAT_sig(reg_num, context) \
  237. (((double *)((char *)((context)->uc_mcontext.regs + 48 * 4)))[reg_num])
  238. #define FPSCR_sig(context) \
  239. (*(int *)((char *)((context)->uc_mcontext.regs + (48 + 32 * 2) * 4)))
  240. /* Exception Registers access */
  241. #define DAR_sig(context) REG_sig(dar, context)
  242. #define DSISR_sig(context) REG_sig(dsisr, context)
  243. #define TRAP_sig(context) REG_sig(trap, context)
  244. #endif /* linux */
  245. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  246. #include <ucontext.h>
  247. #define IAR_sig(context) ((context)->uc_mcontext.mc_srr0)
  248. #define MSR_sig(context) ((context)->uc_mcontext.mc_srr1)
  249. #define CTR_sig(context) ((context)->uc_mcontext.mc_ctr)
  250. #define XER_sig(context) ((context)->uc_mcontext.mc_xer)
  251. #define LR_sig(context) ((context)->uc_mcontext.mc_lr)
  252. #define CR_sig(context) ((context)->uc_mcontext.mc_cr)
  253. /* Exception Registers access */
  254. #define DAR_sig(context) ((context)->uc_mcontext.mc_dar)
  255. #define DSISR_sig(context) ((context)->uc_mcontext.mc_dsisr)
  256. #define TRAP_sig(context) ((context)->uc_mcontext.mc_exc)
  257. #endif /* __FreeBSD__|| __FreeBSD_kernel__ */
  258. #ifdef __APPLE__
  259. #include <sys/ucontext.h>
  260. typedef struct ucontext SIGCONTEXT;
  261. /* All Registers access - only for local access */
  262. #define REG_sig(reg_name, context) \
  263. ((context)->uc_mcontext->ss.reg_name)
  264. #define FLOATREG_sig(reg_name, context) \
  265. ((context)->uc_mcontext->fs.reg_name)
  266. #define EXCEPREG_sig(reg_name, context) \
  267. ((context)->uc_mcontext->es.reg_name)
  268. #define VECREG_sig(reg_name, context) \
  269. ((context)->uc_mcontext->vs.reg_name)
  270. /* Gpr Registers access */
  271. #define GPR_sig(reg_num, context) REG_sig(r##reg_num, context)
  272. /* Program counter */
  273. #define IAR_sig(context) REG_sig(srr0, context)
  274. /* Machine State Register (Supervisor) */
  275. #define MSR_sig(context) REG_sig(srr1, context)
  276. #define CTR_sig(context) REG_sig(ctr, context)
  277. /* Link register */
  278. #define XER_sig(context) REG_sig(xer, context)
  279. /* User's integer exception register */
  280. #define LR_sig(context) REG_sig(lr, context)
  281. /* Condition register */
  282. #define CR_sig(context) REG_sig(cr, context)
  283. /* Float Registers access */
  284. #define FLOAT_sig(reg_num, context) \
  285. FLOATREG_sig(fpregs[reg_num], context)
  286. #define FPSCR_sig(context) \
  287. ((double)FLOATREG_sig(fpscr, context))
  288. /* Exception Registers access */
  289. /* Fault registers for coredump */
  290. #define DAR_sig(context) EXCEPREG_sig(dar, context)
  291. #define DSISR_sig(context) EXCEPREG_sig(dsisr, context)
  292. /* number of powerpc exception taken */
  293. #define TRAP_sig(context) EXCEPREG_sig(exception, context)
  294. #endif /* __APPLE__ */
  295. int cpu_signal_handler(int host_signum, void *pinfo,
  296. void *puc)
  297. {
  298. siginfo_t *info = pinfo;
  299. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  300. ucontext_t *uc = puc;
  301. #else
  302. struct ucontext *uc = puc;
  303. #endif
  304. unsigned long pc;
  305. int is_write;
  306. pc = IAR_sig(uc);
  307. is_write = 0;
  308. #if 0
  309. /* ppc 4xx case */
  310. if (DSISR_sig(uc) & 0x00800000) {
  311. is_write = 1;
  312. }
  313. #else
  314. if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000)) {
  315. is_write = 1;
  316. }
  317. #endif
  318. return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  319. is_write, &uc->uc_sigmask, puc);
  320. }
  321. #elif defined(__alpha__)
  322. int cpu_signal_handler(int host_signum, void *pinfo,
  323. void *puc)
  324. {
  325. siginfo_t *info = pinfo;
  326. struct ucontext *uc = puc;
  327. uint32_t *pc = uc->uc_mcontext.sc_pc;
  328. uint32_t insn = *pc;
  329. int is_write = 0;
  330. /* XXX: need kernel patch to get write flag faster */
  331. switch (insn >> 26) {
  332. case 0x0d: /* stw */
  333. case 0x0e: /* stb */
  334. case 0x0f: /* stq_u */
  335. case 0x24: /* stf */
  336. case 0x25: /* stg */
  337. case 0x26: /* sts */
  338. case 0x27: /* stt */
  339. case 0x2c: /* stl */
  340. case 0x2d: /* stq */
  341. case 0x2e: /* stl_c */
  342. case 0x2f: /* stq_c */
  343. is_write = 1;
  344. }
  345. return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  346. is_write, &uc->uc_sigmask, puc);
  347. }
  348. #elif defined(__sparc__)
  349. int cpu_signal_handler(int host_signum, void *pinfo,
  350. void *puc)
  351. {
  352. siginfo_t *info = pinfo;
  353. int is_write;
  354. uint32_t insn;
  355. #if !defined(__arch64__) || defined(CONFIG_SOLARIS)
  356. uint32_t *regs = (uint32_t *)(info + 1);
  357. void *sigmask = (regs + 20);
  358. /* XXX: is there a standard glibc define ? */
  359. unsigned long pc = regs[1];
  360. #else
  361. #ifdef __linux__
  362. struct sigcontext *sc = puc;
  363. unsigned long pc = sc->sigc_regs.tpc;
  364. void *sigmask = (void *)sc->sigc_mask;
  365. #elif defined(__OpenBSD__)
  366. struct sigcontext *uc = puc;
  367. unsigned long pc = uc->sc_pc;
  368. void *sigmask = (void *)(long)uc->sc_mask;
  369. #endif
  370. #endif
  371. /* XXX: need kernel patch to get write flag faster */
  372. is_write = 0;
  373. insn = *(uint32_t *)pc;
  374. if ((insn >> 30) == 3) {
  375. switch ((insn >> 19) & 0x3f) {
  376. case 0x05: /* stb */
  377. case 0x15: /* stba */
  378. case 0x06: /* sth */
  379. case 0x16: /* stha */
  380. case 0x04: /* st */
  381. case 0x14: /* sta */
  382. case 0x07: /* std */
  383. case 0x17: /* stda */
  384. case 0x0e: /* stx */
  385. case 0x1e: /* stxa */
  386. case 0x24: /* stf */
  387. case 0x34: /* stfa */
  388. case 0x27: /* stdf */
  389. case 0x37: /* stdfa */
  390. case 0x26: /* stqf */
  391. case 0x36: /* stqfa */
  392. case 0x25: /* stfsr */
  393. case 0x3c: /* casa */
  394. case 0x3e: /* casxa */
  395. is_write = 1;
  396. break;
  397. }
  398. }
  399. return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  400. is_write, sigmask, NULL);
  401. }
  402. #elif defined(__arm__)
  403. int cpu_signal_handler(int host_signum, void *pinfo,
  404. void *puc)
  405. {
  406. siginfo_t *info = pinfo;
  407. struct ucontext *uc = puc;
  408. unsigned long pc;
  409. int is_write;
  410. #if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
  411. pc = uc->uc_mcontext.gregs[R15];
  412. #else
  413. pc = uc->uc_mcontext.arm_pc;
  414. #endif
  415. /* XXX: compute is_write */
  416. is_write = 0;
  417. return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  418. is_write,
  419. &uc->uc_sigmask, puc);
  420. }
  421. #elif defined(__mc68000)
  422. int cpu_signal_handler(int host_signum, void *pinfo,
  423. void *puc)
  424. {
  425. siginfo_t *info = pinfo;
  426. struct ucontext *uc = puc;
  427. unsigned long pc;
  428. int is_write;
  429. pc = uc->uc_mcontext.gregs[16];
  430. /* XXX: compute is_write */
  431. is_write = 0;
  432. return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  433. is_write,
  434. &uc->uc_sigmask, puc);
  435. }
  436. #elif defined(__ia64)
  437. #ifndef __ISR_VALID
  438. /* This ought to be in <bits/siginfo.h>... */
  439. # define __ISR_VALID 1
  440. #endif
  441. int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
  442. {
  443. siginfo_t *info = pinfo;
  444. struct ucontext *uc = puc;
  445. unsigned long ip;
  446. int is_write = 0;
  447. ip = uc->uc_mcontext.sc_ip;
  448. switch (host_signum) {
  449. case SIGILL:
  450. case SIGFPE:
  451. case SIGSEGV:
  452. case SIGBUS:
  453. case SIGTRAP:
  454. if (info->si_code && (info->si_segvflags & __ISR_VALID)) {
  455. /* ISR.W (write-access) is bit 33: */
  456. is_write = (info->si_isr >> 33) & 1;
  457. }
  458. break;
  459. default:
  460. break;
  461. }
  462. return handle_cpu_signal(ip, (unsigned long)info->si_addr,
  463. is_write,
  464. (sigset_t *)&uc->uc_sigmask, puc);
  465. }
  466. #elif defined(__s390__)
  467. int cpu_signal_handler(int host_signum, void *pinfo,
  468. void *puc)
  469. {
  470. siginfo_t *info = pinfo;
  471. struct ucontext *uc = puc;
  472. unsigned long pc;
  473. uint16_t *pinsn;
  474. int is_write = 0;
  475. pc = uc->uc_mcontext.psw.addr;
  476. /* ??? On linux, the non-rt signal handler has 4 (!) arguments instead
  477. of the normal 2 arguments. The 3rd argument contains the "int_code"
  478. from the hardware which does in fact contain the is_write value.
  479. The rt signal handler, as far as I can tell, does not give this value
  480. at all. Not that we could get to it from here even if it were. */
  481. /* ??? This is not even close to complete, since it ignores all
  482. of the read-modify-write instructions. */
  483. pinsn = (uint16_t *)pc;
  484. switch (pinsn[0] >> 8) {
  485. case 0x50: /* ST */
  486. case 0x42: /* STC */
  487. case 0x40: /* STH */
  488. is_write = 1;
  489. break;
  490. case 0xc4: /* RIL format insns */
  491. switch (pinsn[0] & 0xf) {
  492. case 0xf: /* STRL */
  493. case 0xb: /* STGRL */
  494. case 0x7: /* STHRL */
  495. is_write = 1;
  496. }
  497. break;
  498. case 0xe3: /* RXY format insns */
  499. switch (pinsn[2] & 0xff) {
  500. case 0x50: /* STY */
  501. case 0x24: /* STG */
  502. case 0x72: /* STCY */
  503. case 0x70: /* STHY */
  504. case 0x8e: /* STPQ */
  505. case 0x3f: /* STRVH */
  506. case 0x3e: /* STRV */
  507. case 0x2f: /* STRVG */
  508. is_write = 1;
  509. }
  510. break;
  511. }
  512. return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  513. is_write, &uc->uc_sigmask, puc);
  514. }
  515. #elif defined(__mips__)
  516. int cpu_signal_handler(int host_signum, void *pinfo,
  517. void *puc)
  518. {
  519. siginfo_t *info = pinfo;
  520. struct ucontext *uc = puc;
  521. greg_t pc = uc->uc_mcontext.pc;
  522. int is_write;
  523. /* XXX: compute is_write */
  524. is_write = 0;
  525. return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  526. is_write, &uc->uc_sigmask, puc);
  527. }
  528. #elif defined(__hppa__)
  529. int cpu_signal_handler(int host_signum, void *pinfo,
  530. void *puc)
  531. {
  532. struct siginfo *info = pinfo;
  533. struct ucontext *uc = puc;
  534. unsigned long pc = uc->uc_mcontext.sc_iaoq[0];
  535. uint32_t insn = *(uint32_t *)pc;
  536. int is_write = 0;
  537. /* XXX: need kernel patch to get write flag faster. */
  538. switch (insn >> 26) {
  539. case 0x1a: /* STW */
  540. case 0x19: /* STH */
  541. case 0x18: /* STB */
  542. case 0x1b: /* STWM */
  543. is_write = 1;
  544. break;
  545. case 0x09: /* CSTWX, FSTWX, FSTWS */
  546. case 0x0b: /* CSTDX, FSTDX, FSTDS */
  547. /* Distinguish from coprocessor load ... */
  548. is_write = (insn >> 9) & 1;
  549. break;
  550. case 0x03:
  551. switch ((insn >> 6) & 15) {
  552. case 0xa: /* STWS */
  553. case 0x9: /* STHS */
  554. case 0x8: /* STBS */
  555. case 0xe: /* STWAS */
  556. case 0xc: /* STBYS */
  557. is_write = 1;
  558. }
  559. break;
  560. }
  561. return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  562. is_write, &uc->uc_sigmask, puc);
  563. }
  564. #else
  565. #error host CPU specific signal handler needed
  566. #endif
  567. #if defined(TARGET_I386)
  568. void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
  569. {
  570. CPUX86State *saved_env;
  571. saved_env = env;
  572. env = s;
  573. if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
  574. selector &= 0xffff;
  575. cpu_x86_load_seg_cache(env, seg_reg, selector,
  576. (selector << 4), 0xffff, 0);
  577. } else {
  578. helper_load_seg(seg_reg, selector);
  579. }
  580. env = saved_env;
  581. }
  582. void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
  583. {
  584. CPUX86State *saved_env;
  585. saved_env = env;
  586. env = s;
  587. helper_fsave(ptr, data32);
  588. env = saved_env;
  589. }
  590. void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
  591. {
  592. CPUX86State *saved_env;
  593. saved_env = env;
  594. env = s;
  595. helper_frstor(ptr, data32);
  596. env = saved_env;
  597. }
  598. #endif /* TARGET_I386 */