i386-windows-tdep.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /* Target-dependent code for Windows (including Cygwin) running on i386's,
  2. for GDB.
  3. Copyright (C) 2003-2022 Free Software Foundation, Inc.
  4. This file is part of GDB.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  15. #include "defs.h"
  16. #include "osabi.h"
  17. #include "i386-tdep.h"
  18. #include "windows-tdep.h"
  19. #include "regset.h"
  20. #include "gdbsupport/gdb_obstack.h"
  21. #include "xml-support.h"
  22. #include "gdbcore.h"
  23. #include "inferior.h"
  24. /* Core file support. */
  25. /* This vector maps GDB's idea of a register's number into an address
  26. in the windows exception context vector. */
  27. static int i386_windows_gregset_reg_offset[] =
  28. {
  29. 176, /* eax */
  30. 172, /* ecx */
  31. 168, /* edx */
  32. 164, /* ebx */
  33. 196, /* esp */
  34. 180, /* ebp */
  35. 160, /* esi */
  36. 156, /* edi */
  37. 184, /* eip */
  38. 192, /* eflags */
  39. 188, /* cs */
  40. 200, /* ss */
  41. 152, /* ds */
  42. 148, /* es */
  43. 144, /* fs */
  44. 140, /* gs */
  45. 56, /* FloatSave.RegisterArea[0 * 10] */
  46. 66, /* FloatSave.RegisterArea[1 * 10] */
  47. 76, /* FloatSave.RegisterArea[2 * 10] */
  48. 86, /* FloatSave.RegisterArea[3 * 10] */
  49. 96, /* FloatSave.RegisterArea[4 * 10] */
  50. 106, /* FloatSave.RegisterArea[5 * 10] */
  51. 116, /* FloatSave.RegisterArea[6 * 10] */
  52. 126, /* FloatSave.RegisterArea[7 * 10] */
  53. 28, /* FloatSave.ControlWord */
  54. 32, /* FloatSave.StatusWord */
  55. 36, /* FloatSave.TagWord */
  56. 44, /* FloatSave.ErrorSelector */
  57. 40, /* FloatSave.ErrorOffset */
  58. 52, /* FloatSave.DataSelector */
  59. 48, /* FloatSave.DataOffset */
  60. 44, /* FloatSave.ErrorSelector */
  61. /* XMM0-7 */
  62. 364, /* ExtendedRegisters[10*16] */
  63. 380, /* ExtendedRegisters[11*16] */
  64. 396, /* ExtendedRegisters[12*16] */
  65. 412, /* ExtendedRegisters[13*16] */
  66. 428, /* ExtendedRegisters[14*16] */
  67. 444, /* ExtendedRegisters[15*16] */
  68. 460, /* ExtendedRegisters[16*16] */
  69. 476, /* ExtendedRegisters[17*16] */
  70. /* MXCSR */
  71. 228 /* ExtendedRegisters[24] */
  72. };
  73. #define I386_WINDOWS_SIZEOF_GREGSET 716
  74. static CORE_ADDR
  75. i386_windows_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
  76. {
  77. return i386_pe_skip_trampoline_code (frame, pc, NULL);
  78. }
  79. static const char *
  80. i386_windows_auto_wide_charset (void)
  81. {
  82. return "UTF-16";
  83. }
  84. /* Implement the "push_dummy_call" gdbarch method. */
  85. static CORE_ADDR
  86. i386_windows_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
  87. struct regcache *regcache, CORE_ADDR bp_addr,
  88. int nargs, struct value **args, CORE_ADDR sp,
  89. function_call_return_method return_method,
  90. CORE_ADDR struct_addr)
  91. {
  92. /* For non-static member functions of 32bit Windows programs, the thiscall
  93. calling convention is used, so the 'this' pointer is passed in ECX. */
  94. bool thiscall = false;
  95. struct type *type = check_typedef (value_type (function));
  96. if (type->code () == TYPE_CODE_PTR)
  97. type = check_typedef (TYPE_TARGET_TYPE (type));
  98. /* read_subroutine_type sets for non-static member functions the
  99. artificial flag of the first parameter ('this' pointer). */
  100. if (type->code () == TYPE_CODE_METHOD
  101. && type->num_fields () > 0
  102. && TYPE_FIELD_ARTIFICIAL (type, 0)
  103. && type->field (0).type ()->code () == TYPE_CODE_PTR)
  104. thiscall = 1;
  105. return i386_thiscall_push_dummy_call (gdbarch, function, regcache, bp_addr,
  106. nargs, args, sp, return_method,
  107. struct_addr, thiscall);
  108. }
  109. /* Common parts for gdbarch initialization for Windows and Cygwin on i386. */
  110. static void
  111. i386_windows_init_abi_common (struct gdbarch_info info, struct gdbarch *gdbarch)
  112. {
  113. i386_gdbarch_tdep *tdep = (i386_gdbarch_tdep *) gdbarch_tdep (gdbarch);
  114. set_gdbarch_skip_trampoline_code (gdbarch, i386_windows_skip_trampoline_code);
  115. set_gdbarch_skip_main_prologue (gdbarch, i386_skip_main_prologue);
  116. tdep->struct_return = reg_struct_return;
  117. tdep->gregset_reg_offset = i386_windows_gregset_reg_offset;
  118. tdep->gregset_num_regs = ARRAY_SIZE (i386_windows_gregset_reg_offset);
  119. tdep->sizeof_gregset = I386_WINDOWS_SIZEOF_GREGSET;
  120. tdep->sizeof_fpregset = 0;
  121. /* Core file support. */
  122. set_gdbarch_core_xfer_shared_libraries
  123. (gdbarch, windows_core_xfer_shared_libraries);
  124. set_gdbarch_core_pid_to_str (gdbarch, windows_core_pid_to_str);
  125. set_gdbarch_auto_wide_charset (gdbarch, i386_windows_auto_wide_charset);
  126. }
  127. /* gdbarch initialization for Windows on i386. */
  128. static void
  129. i386_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
  130. {
  131. i386_windows_init_abi_common (info, gdbarch);
  132. windows_init_abi (info, gdbarch);
  133. set_gdbarch_push_dummy_call (gdbarch, i386_windows_push_dummy_call);
  134. }
  135. /* gdbarch initialization for Cygwin on i386. */
  136. static void
  137. i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
  138. {
  139. i386_windows_init_abi_common (info, gdbarch);
  140. cygwin_init_abi (info, gdbarch);
  141. }
  142. static gdb_osabi
  143. i386_windows_osabi_sniffer (bfd *abfd)
  144. {
  145. const char *target_name = bfd_get_target (abfd);
  146. if (!streq (target_name, "pei-i386"))
  147. return GDB_OSABI_UNKNOWN;
  148. if (is_linked_with_cygwin_dll (abfd))
  149. return GDB_OSABI_CYGWIN;
  150. return GDB_OSABI_WINDOWS;
  151. }
  152. static enum gdb_osabi
  153. i386_cygwin_core_osabi_sniffer (bfd *abfd)
  154. {
  155. const char *target_name = bfd_get_target (abfd);
  156. /* Cygwin uses elf core dumps. Do not claim all ELF executables,
  157. check whether there is a .reg section of proper size. */
  158. if (strcmp (target_name, "elf32-i386") == 0)
  159. {
  160. asection *section = bfd_get_section_by_name (abfd, ".reg");
  161. if (section != nullptr
  162. && bfd_section_size (section) == I386_WINDOWS_SIZEOF_GREGSET)
  163. return GDB_OSABI_CYGWIN;
  164. }
  165. return GDB_OSABI_UNKNOWN;
  166. }
  167. void _initialize_i386_windows_tdep ();
  168. void
  169. _initialize_i386_windows_tdep ()
  170. {
  171. gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
  172. i386_windows_osabi_sniffer);
  173. /* Cygwin uses elf core dumps. */
  174. gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
  175. i386_cygwin_core_osabi_sniffer);
  176. gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_WINDOWS,
  177. i386_windows_init_abi);
  178. gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN,
  179. i386_cygwin_init_abi);
  180. }