win32-i386-low.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. /* Copyright (C) 2007-2022 Free Software Foundation, Inc.
  2. This file is part of GDB.
  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. #include "server.h"
  14. #include "win32-low.h"
  15. #include "x86-low.h"
  16. #include "gdbsupport/x86-xstate.h"
  17. #ifdef __x86_64__
  18. #include "arch/amd64.h"
  19. #endif
  20. #include "arch/i386.h"
  21. #include "tdesc.h"
  22. #include "x86-tdesc.h"
  23. using namespace windows_nat;
  24. #ifndef CONTEXT_EXTENDED_REGISTERS
  25. #define CONTEXT_EXTENDED_REGISTERS 0
  26. #endif
  27. #define FCS_REGNUM 27
  28. #define FOP_REGNUM 31
  29. #define FLAG_TRACE_BIT 0x100
  30. static struct x86_debug_reg_state debug_reg_state;
  31. static void
  32. update_debug_registers (thread_info *thread)
  33. {
  34. windows_thread_info *th = (windows_thread_info *) thread_target_data (thread);
  35. /* The actual update is done later just before resuming the lwp,
  36. we just mark that the registers need updating. */
  37. th->debug_registers_changed = true;
  38. }
  39. /* Update the inferior's debug register REGNUM from STATE. */
  40. static void
  41. x86_dr_low_set_addr (int regnum, CORE_ADDR addr)
  42. {
  43. gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
  44. /* Only update the threads of this process. */
  45. for_each_thread (current_thread->id.pid (), update_debug_registers);
  46. }
  47. /* Update the inferior's DR7 debug control register from STATE. */
  48. static void
  49. x86_dr_low_set_control (unsigned long control)
  50. {
  51. /* Only update the threads of this process. */
  52. for_each_thread (current_thread->id.pid (), update_debug_registers);
  53. }
  54. /* Return the current value of a DR register of the current thread's
  55. context. */
  56. static DWORD64
  57. win32_get_current_dr (int dr)
  58. {
  59. windows_thread_info *th
  60. = (windows_thread_info *) thread_target_data (current_thread);
  61. win32_require_context (th);
  62. #ifdef __x86_64__
  63. #define RET_DR(DR) \
  64. case DR: \
  65. return th->wow64_context.Dr ## DR
  66. if (wow64_process)
  67. {
  68. switch (dr)
  69. {
  70. RET_DR (0);
  71. RET_DR (1);
  72. RET_DR (2);
  73. RET_DR (3);
  74. RET_DR (6);
  75. RET_DR (7);
  76. }
  77. }
  78. else
  79. #undef RET_DR
  80. #endif
  81. #define RET_DR(DR) \
  82. case DR: \
  83. return th->context.Dr ## DR
  84. {
  85. switch (dr)
  86. {
  87. RET_DR (0);
  88. RET_DR (1);
  89. RET_DR (2);
  90. RET_DR (3);
  91. RET_DR (6);
  92. RET_DR (7);
  93. }
  94. }
  95. #undef RET_DR
  96. gdb_assert_not_reached ("unhandled dr");
  97. }
  98. static CORE_ADDR
  99. x86_dr_low_get_addr (int regnum)
  100. {
  101. gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);
  102. return win32_get_current_dr (regnum - DR_FIRSTADDR);
  103. }
  104. static unsigned long
  105. x86_dr_low_get_control (void)
  106. {
  107. return win32_get_current_dr (7);
  108. }
  109. /* Get the value of the DR6 debug status register from the inferior
  110. and record it in STATE. */
  111. static unsigned long
  112. x86_dr_low_get_status (void)
  113. {
  114. return win32_get_current_dr (6);
  115. }
  116. /* Low-level function vector. */
  117. struct x86_dr_low_type x86_dr_low =
  118. {
  119. x86_dr_low_set_control,
  120. x86_dr_low_set_addr,
  121. x86_dr_low_get_addr,
  122. x86_dr_low_get_status,
  123. x86_dr_low_get_control,
  124. sizeof (void *),
  125. };
  126. /* Breakpoint/watchpoint support. */
  127. static int
  128. i386_supports_z_point_type (char z_type)
  129. {
  130. switch (z_type)
  131. {
  132. case Z_PACKET_HW_BP:
  133. case Z_PACKET_WRITE_WP:
  134. case Z_PACKET_ACCESS_WP:
  135. return 1;
  136. default:
  137. return 0;
  138. }
  139. }
  140. static int
  141. i386_insert_point (enum raw_bkpt_type type, CORE_ADDR addr,
  142. int size, struct raw_breakpoint *bp)
  143. {
  144. switch (type)
  145. {
  146. case raw_bkpt_type_hw:
  147. case raw_bkpt_type_write_wp:
  148. case raw_bkpt_type_access_wp:
  149. {
  150. enum target_hw_bp_type hw_type
  151. = raw_bkpt_type_to_target_hw_bp_type (type);
  152. return x86_dr_insert_watchpoint (&debug_reg_state,
  153. hw_type, addr, size);
  154. }
  155. default:
  156. /* Unsupported. */
  157. return 1;
  158. }
  159. }
  160. static int
  161. i386_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
  162. int size, struct raw_breakpoint *bp)
  163. {
  164. switch (type)
  165. {
  166. case raw_bkpt_type_hw:
  167. case raw_bkpt_type_write_wp:
  168. case raw_bkpt_type_access_wp:
  169. {
  170. enum target_hw_bp_type hw_type
  171. = raw_bkpt_type_to_target_hw_bp_type (type);
  172. return x86_dr_remove_watchpoint (&debug_reg_state,
  173. hw_type, addr, size);
  174. }
  175. default:
  176. /* Unsupported. */
  177. return 1;
  178. }
  179. }
  180. static int
  181. x86_stopped_by_watchpoint (void)
  182. {
  183. return x86_dr_stopped_by_watchpoint (&debug_reg_state);
  184. }
  185. static CORE_ADDR
  186. x86_stopped_data_address (void)
  187. {
  188. CORE_ADDR addr;
  189. if (x86_dr_stopped_data_address (&debug_reg_state, &addr))
  190. return addr;
  191. return 0;
  192. }
  193. static void
  194. i386_initial_stuff (void)
  195. {
  196. x86_low_init_dregs (&debug_reg_state);
  197. }
  198. static void
  199. i386_get_thread_context (windows_thread_info *th)
  200. {
  201. /* Requesting the CONTEXT_EXTENDED_REGISTERS register set fails if
  202. the system doesn't support extended registers. */
  203. static DWORD extended_registers = CONTEXT_EXTENDED_REGISTERS;
  204. again:
  205. #ifdef __x86_64__
  206. if (wow64_process)
  207. th->wow64_context.ContextFlags = (CONTEXT_FULL
  208. | CONTEXT_FLOATING_POINT
  209. | CONTEXT_DEBUG_REGISTERS
  210. | extended_registers);
  211. else
  212. #endif
  213. th->context.ContextFlags = (CONTEXT_FULL
  214. | CONTEXT_FLOATING_POINT
  215. | CONTEXT_DEBUG_REGISTERS
  216. | extended_registers);
  217. BOOL ret;
  218. #ifdef __x86_64__
  219. if (wow64_process)
  220. ret = Wow64GetThreadContext (th->h, &th->wow64_context);
  221. else
  222. #endif
  223. ret = GetThreadContext (th->h, &th->context);
  224. if (!ret)
  225. {
  226. DWORD e = GetLastError ();
  227. if (extended_registers && e == ERROR_INVALID_PARAMETER)
  228. {
  229. extended_registers = 0;
  230. goto again;
  231. }
  232. error ("GetThreadContext failure %ld\n", (long) e);
  233. }
  234. }
  235. static void
  236. i386_prepare_to_resume (windows_thread_info *th)
  237. {
  238. if (th->debug_registers_changed)
  239. {
  240. struct x86_debug_reg_state *dr = &debug_reg_state;
  241. win32_require_context (th);
  242. #ifdef __x86_64__
  243. if (wow64_process)
  244. {
  245. th->wow64_context.Dr0 = dr->dr_mirror[0];
  246. th->wow64_context.Dr1 = dr->dr_mirror[1];
  247. th->wow64_context.Dr2 = dr->dr_mirror[2];
  248. th->wow64_context.Dr3 = dr->dr_mirror[3];
  249. /* th->wow64_context.Dr6 = dr->dr_status_mirror;
  250. FIXME: should we set dr6 also ?? */
  251. th->wow64_context.Dr7 = dr->dr_control_mirror;
  252. }
  253. else
  254. #endif
  255. {
  256. th->context.Dr0 = dr->dr_mirror[0];
  257. th->context.Dr1 = dr->dr_mirror[1];
  258. th->context.Dr2 = dr->dr_mirror[2];
  259. th->context.Dr3 = dr->dr_mirror[3];
  260. /* th->context.Dr6 = dr->dr_status_mirror;
  261. FIXME: should we set dr6 also ?? */
  262. th->context.Dr7 = dr->dr_control_mirror;
  263. }
  264. th->debug_registers_changed = false;
  265. }
  266. }
  267. static void
  268. i386_thread_added (windows_thread_info *th)
  269. {
  270. th->debug_registers_changed = true;
  271. }
  272. static void
  273. i386_single_step (windows_thread_info *th)
  274. {
  275. #ifdef __x86_64__
  276. if (wow64_process)
  277. th->wow64_context.EFlags |= FLAG_TRACE_BIT;
  278. else
  279. #endif
  280. th->context.EFlags |= FLAG_TRACE_BIT;
  281. }
  282. /* An array of offset mappings into a Win32 Context structure.
  283. This is a one-to-one mapping which is indexed by gdb's register
  284. numbers. It retrieves an offset into the context structure where
  285. the 4 byte register is located.
  286. An offset value of -1 indicates that Win32 does not provide this
  287. register in it's CONTEXT structure. In this case regptr will return
  288. a pointer into a dummy register. */
  289. #ifdef __x86_64__
  290. #define context_offset(x) (offsetof (WOW64_CONTEXT, x))
  291. #else
  292. #define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
  293. #endif
  294. static const int i386_mappings[] = {
  295. context_offset (Eax),
  296. context_offset (Ecx),
  297. context_offset (Edx),
  298. context_offset (Ebx),
  299. context_offset (Esp),
  300. context_offset (Ebp),
  301. context_offset (Esi),
  302. context_offset (Edi),
  303. context_offset (Eip),
  304. context_offset (EFlags),
  305. context_offset (SegCs),
  306. context_offset (SegSs),
  307. context_offset (SegDs),
  308. context_offset (SegEs),
  309. context_offset (SegFs),
  310. context_offset (SegGs),
  311. context_offset (FloatSave.RegisterArea[0 * 10]),
  312. context_offset (FloatSave.RegisterArea[1 * 10]),
  313. context_offset (FloatSave.RegisterArea[2 * 10]),
  314. context_offset (FloatSave.RegisterArea[3 * 10]),
  315. context_offset (FloatSave.RegisterArea[4 * 10]),
  316. context_offset (FloatSave.RegisterArea[5 * 10]),
  317. context_offset (FloatSave.RegisterArea[6 * 10]),
  318. context_offset (FloatSave.RegisterArea[7 * 10]),
  319. context_offset (FloatSave.ControlWord),
  320. context_offset (FloatSave.StatusWord),
  321. context_offset (FloatSave.TagWord),
  322. context_offset (FloatSave.ErrorSelector),
  323. context_offset (FloatSave.ErrorOffset),
  324. context_offset (FloatSave.DataSelector),
  325. context_offset (FloatSave.DataOffset),
  326. context_offset (FloatSave.ErrorSelector),
  327. /* XMM0-7 */
  328. context_offset (ExtendedRegisters[10 * 16]),
  329. context_offset (ExtendedRegisters[11 * 16]),
  330. context_offset (ExtendedRegisters[12 * 16]),
  331. context_offset (ExtendedRegisters[13 * 16]),
  332. context_offset (ExtendedRegisters[14 * 16]),
  333. context_offset (ExtendedRegisters[15 * 16]),
  334. context_offset (ExtendedRegisters[16 * 16]),
  335. context_offset (ExtendedRegisters[17 * 16]),
  336. /* MXCSR */
  337. context_offset (ExtendedRegisters[24])
  338. };
  339. #undef context_offset
  340. #ifdef __x86_64__
  341. #define context_offset(x) (offsetof (CONTEXT, x))
  342. static const int amd64_mappings[] =
  343. {
  344. context_offset (Rax),
  345. context_offset (Rbx),
  346. context_offset (Rcx),
  347. context_offset (Rdx),
  348. context_offset (Rsi),
  349. context_offset (Rdi),
  350. context_offset (Rbp),
  351. context_offset (Rsp),
  352. context_offset (R8),
  353. context_offset (R9),
  354. context_offset (R10),
  355. context_offset (R11),
  356. context_offset (R12),
  357. context_offset (R13),
  358. context_offset (R14),
  359. context_offset (R15),
  360. context_offset (Rip),
  361. context_offset (EFlags),
  362. context_offset (SegCs),
  363. context_offset (SegSs),
  364. context_offset (SegDs),
  365. context_offset (SegEs),
  366. context_offset (SegFs),
  367. context_offset (SegGs),
  368. context_offset (FloatSave.FloatRegisters[0]),
  369. context_offset (FloatSave.FloatRegisters[1]),
  370. context_offset (FloatSave.FloatRegisters[2]),
  371. context_offset (FloatSave.FloatRegisters[3]),
  372. context_offset (FloatSave.FloatRegisters[4]),
  373. context_offset (FloatSave.FloatRegisters[5]),
  374. context_offset (FloatSave.FloatRegisters[6]),
  375. context_offset (FloatSave.FloatRegisters[7]),
  376. context_offset (FloatSave.ControlWord),
  377. context_offset (FloatSave.StatusWord),
  378. context_offset (FloatSave.TagWord),
  379. context_offset (FloatSave.ErrorSelector),
  380. context_offset (FloatSave.ErrorOffset),
  381. context_offset (FloatSave.DataSelector),
  382. context_offset (FloatSave.DataOffset),
  383. context_offset (FloatSave.ErrorSelector)
  384. /* XMM0-7 */ ,
  385. context_offset (Xmm0),
  386. context_offset (Xmm1),
  387. context_offset (Xmm2),
  388. context_offset (Xmm3),
  389. context_offset (Xmm4),
  390. context_offset (Xmm5),
  391. context_offset (Xmm6),
  392. context_offset (Xmm7),
  393. context_offset (Xmm8),
  394. context_offset (Xmm9),
  395. context_offset (Xmm10),
  396. context_offset (Xmm11),
  397. context_offset (Xmm12),
  398. context_offset (Xmm13),
  399. context_offset (Xmm14),
  400. context_offset (Xmm15),
  401. /* MXCSR */
  402. context_offset (FloatSave.MxCsr)
  403. };
  404. #undef context_offset
  405. #endif /* __x86_64__ */
  406. /* Fetch register from gdbserver regcache data. */
  407. static void
  408. i386_fetch_inferior_register (struct regcache *regcache,
  409. windows_thread_info *th, int r)
  410. {
  411. const int *mappings;
  412. #ifdef __x86_64__
  413. if (!wow64_process)
  414. mappings = amd64_mappings;
  415. else
  416. #endif
  417. mappings = i386_mappings;
  418. char *context_offset;
  419. #ifdef __x86_64__
  420. if (wow64_process)
  421. context_offset = (char *) &th->wow64_context + mappings[r];
  422. else
  423. #endif
  424. context_offset = (char *) &th->context + mappings[r];
  425. long l;
  426. if (r == FCS_REGNUM)
  427. {
  428. l = *((long *) context_offset) & 0xffff;
  429. supply_register (regcache, r, (char *) &l);
  430. }
  431. else if (r == FOP_REGNUM)
  432. {
  433. l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
  434. supply_register (regcache, r, (char *) &l);
  435. }
  436. else
  437. supply_register (regcache, r, context_offset);
  438. }
  439. /* Store a new register value into the thread context of TH. */
  440. static void
  441. i386_store_inferior_register (struct regcache *regcache,
  442. windows_thread_info *th, int r)
  443. {
  444. const int *mappings;
  445. #ifdef __x86_64__
  446. if (!wow64_process)
  447. mappings = amd64_mappings;
  448. else
  449. #endif
  450. mappings = i386_mappings;
  451. char *context_offset;
  452. #ifdef __x86_64__
  453. if (wow64_process)
  454. context_offset = (char *) &th->wow64_context + mappings[r];
  455. else
  456. #endif
  457. context_offset = (char *) &th->context + mappings[r];
  458. collect_register (regcache, r, context_offset);
  459. }
  460. static const unsigned char i386_win32_breakpoint = 0xcc;
  461. #define i386_win32_breakpoint_len 1
  462. static void
  463. i386_arch_setup (void)
  464. {
  465. struct target_desc *tdesc;
  466. #ifdef __x86_64__
  467. tdesc = amd64_create_target_description (X86_XSTATE_SSE_MASK, false,
  468. false, false);
  469. init_target_desc (tdesc, amd64_expedite_regs);
  470. win32_tdesc = tdesc;
  471. #endif
  472. tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false);
  473. init_target_desc (tdesc, i386_expedite_regs);
  474. #ifdef __x86_64__
  475. wow64_win32_tdesc = tdesc;
  476. #else
  477. win32_tdesc = tdesc;
  478. #endif
  479. }
  480. /* Implement win32_target_ops "num_regs" method. */
  481. static int
  482. i386_win32_num_regs (void)
  483. {
  484. int num_regs;
  485. #ifdef __x86_64__
  486. if (!wow64_process)
  487. num_regs = sizeof (amd64_mappings) / sizeof (amd64_mappings[0]);
  488. else
  489. #endif
  490. num_regs = sizeof (i386_mappings) / sizeof (i386_mappings[0]);
  491. return num_regs;
  492. }
  493. /* Implement win32_target_ops "get_pc" method. */
  494. static CORE_ADDR
  495. i386_win32_get_pc (struct regcache *regcache)
  496. {
  497. bool use_64bit = register_size (regcache->tdesc, 0) == 8;
  498. if (use_64bit)
  499. {
  500. uint64_t pc;
  501. collect_register_by_name (regcache, "rip", &pc);
  502. return (CORE_ADDR) pc;
  503. }
  504. else
  505. {
  506. uint32_t pc;
  507. collect_register_by_name (regcache, "eip", &pc);
  508. return (CORE_ADDR) pc;
  509. }
  510. }
  511. /* Implement win32_target_ops "set_pc" method. */
  512. static void
  513. i386_win32_set_pc (struct regcache *regcache, CORE_ADDR pc)
  514. {
  515. bool use_64bit = register_size (regcache->tdesc, 0) == 8;
  516. if (use_64bit)
  517. {
  518. uint64_t newpc = pc;
  519. supply_register_by_name (regcache, "rip", &newpc);
  520. }
  521. else
  522. {
  523. uint32_t newpc = pc;
  524. supply_register_by_name (regcache, "eip", &newpc);
  525. }
  526. }
  527. struct win32_target_ops the_low_target = {
  528. i386_arch_setup,
  529. i386_win32_num_regs,
  530. i386_initial_stuff,
  531. i386_get_thread_context,
  532. i386_prepare_to_resume,
  533. i386_thread_added,
  534. i386_fetch_inferior_register,
  535. i386_store_inferior_register,
  536. i386_single_step,
  537. &i386_win32_breakpoint,
  538. i386_win32_breakpoint_len,
  539. 1,
  540. i386_win32_get_pc,
  541. i386_win32_set_pc,
  542. i386_supports_z_point_type,
  543. i386_insert_point,
  544. i386_remove_point,
  545. x86_stopped_by_watchpoint,
  546. x86_stopped_data_address
  547. };