]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/i386-windows-tdep.c
Move scoped_ignore_sigttou to gdbsupport/
[thirdparty/binutils-gdb.git] / gdb / i386-windows-tdep.c
CommitLineData
5982a56a
SM
1/* Target-dependent code for Windows (including Cygwin) running on i386's,
2 for GDB.
acd5c798 3
3666a048 4 Copyright (C) 2003-2021 Free Software Foundation, Inc.
1762d96d 5
acd5c798 6 This file is part of GDB.
1762d96d 7
acd5c798
MK
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
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
acd5c798 11 (at your option) any later version.
1762d96d 12
acd5c798
MK
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.
1762d96d 17
acd5c798 18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
1762d96d
CV
20
21#include "defs.h"
1762d96d 22#include "osabi.h"
acd5c798 23#include "i386-tdep.h"
31b060a2 24#include "windows-tdep.h"
de584861
PA
25#include "regset.h"
26#include "gdb_obstack.h"
27#include "xml-support.h"
28#include "gdbcore.h"
a5ee0f0c 29#include "inferior.h"
de584861
PA
30
31/* Core file support. */
32
33/* This vector maps GDB's idea of a register's number into an address
dc05df57 34 in the windows exception context vector. */
de584861 35
dc05df57 36static int i386_windows_gregset_reg_offset[] =
de584861
PA
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
dc05df57 90#define I386_WINDOWS_SIZEOF_GREGSET 716
de584861 91
f7948b5f 92static CORE_ADDR
5982a56a 93i386_windows_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
f7948b5f 94{
e17a4113 95 return i386_pe_skip_trampoline_code (frame, pc, NULL);
f7948b5f
JB
96}
97
f870a310 98static const char *
5982a56a 99i386_windows_auto_wide_charset (void)
f870a310
TT
100{
101 return "UTF-16";
102}
103
627c7fb8
HD
104/* Implement the "push_dummy_call" gdbarch method. */
105
106static CORE_ADDR
107i386_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));
78134374 118 if (type->code () == TYPE_CODE_PTR)
627c7fb8
HD
119 type = check_typedef (TYPE_TARGET_TYPE (type));
120
121 /* read_subroutine_type sets for non-static member functions the
122 artificial flag of the first parameter ('this' pointer). */
78134374 123 if (type->code () == TYPE_CODE_METHOD
1f704f76 124 && type->num_fields () > 0
627c7fb8 125 && TYPE_FIELD_ARTIFICIAL (type, 0)
940da03e 126 && type->field (0).type ()->code () == TYPE_CODE_PTR)
627c7fb8
HD
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
0f2265e2
SM
134/* Common parts for gdbarch initialization for Windows and Cygwin on i386. */
135
1762d96d 136static void
0f2265e2 137i386_windows_init_abi_common (struct gdbarch_info info, struct gdbarch *gdbarch)
1762d96d
CV
138{
139 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
140
5982a56a 141 set_gdbarch_skip_trampoline_code (gdbarch, i386_windows_skip_trampoline_code);
f7948b5f 142
4309257c
PM
143 set_gdbarch_skip_main_prologue (gdbarch, i386_skip_main_prologue);
144
1762d96d 145 tdep->struct_return = reg_struct_return;
de584861 146
dc05df57
CF
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;
de584861 150
490496c3
AA
151 tdep->sizeof_fpregset = 0;
152
de584861 153 /* Core file support. */
de584861 154 set_gdbarch_core_xfer_shared_libraries
dc05df57 155 (gdbarch, windows_core_xfer_shared_libraries);
62a5151b 156 set_gdbarch_core_pid_to_str (gdbarch, windows_core_pid_to_str);
f870a310 157
5982a56a 158 set_gdbarch_auto_wide_charset (gdbarch, i386_windows_auto_wide_charset);
1762d96d
CV
159}
160
0f2265e2
SM
161/* gdbarch initialization for Windows on i386. */
162
163static void
164i386_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);
627c7fb8
HD
168
169 set_gdbarch_push_dummy_call (gdbarch, i386_windows_push_dummy_call);
0f2265e2
SM
170}
171
172/* gdbarch initialization for Cygwin on i386. */
173
174static void
175i386_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
5982a56a
SM
181static gdb_osabi
182i386_windows_osabi_sniffer (bfd *abfd)
de584861 183{
1d38e9d1 184 const char *target_name = bfd_get_target (abfd);
1762d96d 185
8db52437
SM
186 if (!streq (target_name, "pei-i386"))
187 return GDB_OSABI_UNKNOWN;
053205cc 188
8db52437
SM
189 if (is_linked_with_cygwin_dll (abfd))
190 return GDB_OSABI_CYGWIN;
191
192 return GDB_OSABI_WINDOWS;
053205cc
SM
193}
194
195static enum gdb_osabi
196i386_cygwin_core_osabi_sniffer (bfd *abfd)
197{
198 const char *target_name = bfd_get_target (abfd);
1762d96d 199
c0993dbe
UW
200 /* Cygwin uses elf core dumps. Do not claim all ELF executables,
201 check whether there is a .reg section of proper size. */
de584861 202 if (strcmp (target_name, "elf32-i386") == 0)
c0993dbe
UW
203 {
204 asection *section = bfd_get_section_by_name (abfd, ".reg");
053205cc 205 if (section != nullptr
fd361982 206 && bfd_section_size (section) == I386_WINDOWS_SIZEOF_GREGSET)
c0993dbe
UW
207 return GDB_OSABI_CYGWIN;
208 }
de584861 209
1762d96d
CV
210 return GDB_OSABI_UNKNOWN;
211}
212
5982a56a 213void _initialize_i386_windows_tdep ();
1762d96d 214void
5982a56a 215_initialize_i386_windows_tdep ()
1762d96d
CV
216{
217 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
dda83cd7 218 i386_windows_osabi_sniffer);
1762d96d 219
de584861
PA
220 /* Cygwin uses elf core dumps. */
221 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
dda83cd7 222 i386_cygwin_core_osabi_sniffer);
de584861 223
053205cc 224 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_WINDOWS,
dda83cd7 225 i386_windows_init_abi);
5982a56a 226 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN,
0f2265e2 227 i386_cygwin_init_abi);
1762d96d 228}