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