-Wpointer-sign: char -> gdb_byte.
[deliverable/binutils-gdb.git] / gdb / i386-cygwin-tdep.c
CommitLineData
1762d96d 1/* Target-dependent code for Cygwin running on i386's, for GDB.
acd5c798 2
28e7fd62 3 Copyright (C) 2003-2013 Free Software Foundation, Inc.
1762d96d 4
acd5c798 5 This file is part of GDB.
1762d96d 6
acd5c798
MK
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
acd5c798 10 (at your option) any later version.
1762d96d 11
acd5c798
MK
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
1762d96d 16
acd5c798 17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
1762d96d
CV
19
20#include "defs.h"
1762d96d 21#include "osabi.h"
acd5c798 22#include "gdb_string.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"
8d465389
UW
29#include "solib.h"
30#include "solib-target.h"
a5ee0f0c 31#include "inferior.h"
de584861
PA
32
33/* Core file support. */
34
35/* This vector maps GDB's idea of a register's number into an address
dc05df57 36 in the windows exception context vector. */
de584861 37
dc05df57 38static int i386_windows_gregset_reg_offset[] =
de584861
PA
39{
40 176, /* eax */
41 172, /* ecx */
42 168, /* edx */
43 164, /* ebx */
44
45 196, /* esp */
46 180, /* ebp */
47 160, /* esi */
48 156, /* edi */
49
50 184, /* eip */
51 192, /* eflags */
52 188, /* cs */
53 200, /* ss */
54
55 152, /* ds */
56 148, /* es */
57 144, /* fs */
58 140, /* gs */
59
60 56, /* FloatSave.RegisterArea[0 * 10] */
61 66, /* FloatSave.RegisterArea[1 * 10] */
62 76, /* FloatSave.RegisterArea[2 * 10] */
63 86, /* FloatSave.RegisterArea[3 * 10] */
64 96, /* FloatSave.RegisterArea[4 * 10] */
65 106, /* FloatSave.RegisterArea[5 * 10] */
66 116, /* FloatSave.RegisterArea[6 * 10] */
67 126, /* FloatSave.RegisterArea[7 * 10] */
68
69 28, /* FloatSave.ControlWord */
70 32, /* FloatSave.StatusWord */
71 36, /* FloatSave.TagWord */
72 44, /* FloatSave.ErrorSelector */
73 40, /* FloatSave.ErrorOffset */
74 52, /* FloatSave.DataSelector */
75 48, /* FloatSave.DataOffset */
76 44, /* FloatSave.ErrorSelector */
77
78 /* XMM0-7 */
79 364, /* ExtendedRegisters[10*16] */
80 380, /* ExtendedRegisters[11*16] */
81 396, /* ExtendedRegisters[12*16] */
82 412, /* ExtendedRegisters[13*16] */
83 428, /* ExtendedRegisters[14*16] */
84 444, /* ExtendedRegisters[15*16] */
85 460, /* ExtendedRegisters[16*16] */
86 476, /* ExtendedRegisters[17*16] */
87
88 /* MXCSR */
89 228 /* ExtendedRegisters[24] */
90};
91
dc05df57 92#define I386_WINDOWS_SIZEOF_GREGSET 716
de584861
PA
93
94/* Return the appropriate register set for the core section identified
95 by SECT_NAME and SECT_SIZE. */
96
97static const struct regset *
dc05df57 98i386_windows_regset_from_core_section (struct gdbarch *gdbarch,
de584861
PA
99 const char *sect_name, size_t sect_size)
100{
101 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
102
103 if (strcmp (sect_name, ".reg") == 0
dc05df57 104 && sect_size == I386_WINDOWS_SIZEOF_GREGSET)
de584861
PA
105 {
106 if (tdep->gregset == NULL)
107 tdep->gregset = regset_alloc (gdbarch, i386_supply_gregset,
108 i386_collect_gregset);
109 return tdep->gregset;
110 }
111
112 return NULL;
113}
114
de584861
PA
115struct cpms_data
116{
5af949e3 117 struct gdbarch *gdbarch;
de584861
PA
118 struct obstack *obstack;
119 int module_count;
120};
121
122static void
123core_process_module_section (bfd *abfd, asection *sect, void *obj)
124{
125 struct cpms_data *data = obj;
e17a4113 126 enum bfd_endian byte_order = gdbarch_byte_order (data->gdbarch);
de584861
PA
127
128 char *module_name;
129 size_t module_name_size;
130 CORE_ADDR base_addr;
131
132 char *buf = NULL;
133
134 if (strncmp (sect->name, ".module", 7) != 0)
135 return;
136
137 buf = xmalloc (bfd_get_section_size (sect) + 1);
138 if (!buf)
139 {
140 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
141 goto out;
142 }
143 if (!bfd_get_section_contents (abfd, sect,
144 buf, 0, bfd_get_section_size (sect)))
145 goto out;
146
147
148
dc05df57 149 /* A DWORD (data_type) followed by struct windows_core_module_info. */
de584861
PA
150
151 base_addr =
e17a4113 152 extract_unsigned_integer (buf + 4, 4, byte_order);
de584861
PA
153
154 module_name_size =
e17a4113 155 extract_unsigned_integer (buf + 8, 4, byte_order);
de584861
PA
156
157 module_name = buf + 12;
158 if (module_name - buf + module_name_size > bfd_get_section_size (sect))
159 goto out;
160
161 /* The first module is the .exe itself. */
162 if (data->module_count != 0)
5af949e3
UW
163 windows_xfer_shared_library (module_name, base_addr,
164 data->gdbarch, data->obstack);
de584861
PA
165 data->module_count++;
166
167out:
168 if (buf)
169 xfree (buf);
170 return;
171}
172
173static LONGEST
dc05df57 174windows_core_xfer_shared_libraries (struct gdbarch *gdbarch,
de584861
PA
175 gdb_byte *readbuf,
176 ULONGEST offset, LONGEST len)
177{
178 struct obstack obstack;
179 const char *buf;
180 LONGEST len_avail;
5af949e3 181 struct cpms_data data = { gdbarch, &obstack, 0 };
de584861
PA
182
183 obstack_init (&obstack);
184 obstack_grow_str (&obstack, "<library-list>\n");
185 bfd_map_over_sections (core_bfd,
186 core_process_module_section,
187 &data);
188 obstack_grow_str0 (&obstack, "</library-list>\n");
189
190 buf = obstack_finish (&obstack);
191 len_avail = strlen (buf);
192 if (offset >= len_avail)
193 return 0;
194
195 if (len > len_avail - offset)
196 len = len_avail - offset;
197 memcpy (readbuf, buf + offset, len);
198
199 obstack_free (&obstack, NULL);
200 return len;
201}
1762d96d 202
a5ee0f0c
PA
203/* This is how we want PTIDs from core files to be printed. */
204
205static char *
206i386_windows_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
207{
208 static char buf[80];
209
210 if (ptid_get_lwp (ptid) != 0)
211 {
212 snprintf (buf, sizeof (buf), "Thread 0x%lx", ptid_get_lwp (ptid));
213 return buf;
214 }
215
216 return normal_pid_to_str (ptid);
217}
218
f7948b5f 219static CORE_ADDR
52f729a7 220i386_cygwin_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
f7948b5f 221{
e17a4113 222 return i386_pe_skip_trampoline_code (frame, pc, NULL);
f7948b5f
JB
223}
224
f870a310
TT
225static const char *
226i386_cygwin_auto_wide_charset (void)
227{
228 return "UTF-16";
229}
230
1762d96d
CV
231static void
232i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
233{
234 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
235
f7948b5f
JB
236 set_gdbarch_skip_trampoline_code (gdbarch, i386_cygwin_skip_trampoline_code);
237
4309257c
PM
238 set_gdbarch_skip_main_prologue (gdbarch, i386_skip_main_prologue);
239
1762d96d 240 tdep->struct_return = reg_struct_return;
de584861 241
dc05df57
CF
242 tdep->gregset_reg_offset = i386_windows_gregset_reg_offset;
243 tdep->gregset_num_regs = ARRAY_SIZE (i386_windows_gregset_reg_offset);
244 tdep->sizeof_gregset = I386_WINDOWS_SIZEOF_GREGSET;
de584861 245
8d465389
UW
246 set_solib_ops (gdbarch, &solib_target_so_ops);
247
de584861
PA
248 /* Core file support. */
249 set_gdbarch_regset_from_core_section
dc05df57 250 (gdbarch, i386_windows_regset_from_core_section);
de584861 251 set_gdbarch_core_xfer_shared_libraries
dc05df57 252 (gdbarch, windows_core_xfer_shared_libraries);
a5ee0f0c 253 set_gdbarch_core_pid_to_str (gdbarch, i386_windows_core_pid_to_str);
f870a310
TT
254
255 set_gdbarch_auto_wide_charset (gdbarch, i386_cygwin_auto_wide_charset);
ab38a727
PA
256
257 /* Canonical paths on this target look like
258 `c:\Program Files\Foo App\mydll.dll', for example. */
259 set_gdbarch_has_dos_based_file_system (gdbarch, 1);
a8e1bb34
JB
260
261 set_gdbarch_iterate_over_objfiles_in_search_order
262 (gdbarch, windows_iterate_over_objfiles_in_search_order);
1762d96d
CV
263}
264
265static enum gdb_osabi
de584861
PA
266i386_cygwin_osabi_sniffer (bfd *abfd)
267{
1762d96d
CV
268 char *target_name = bfd_get_target (abfd);
269
de584861 270 /* Interix also uses pei-i386.
1777feb0 271 We need a way to distinguish between the two. */
1762d96d
CV
272 if (strcmp (target_name, "pei-i386") == 0)
273 return GDB_OSABI_CYGWIN;
274
c0993dbe
UW
275 /* Cygwin uses elf core dumps. Do not claim all ELF executables,
276 check whether there is a .reg section of proper size. */
de584861 277 if (strcmp (target_name, "elf32-i386") == 0)
c0993dbe
UW
278 {
279 asection *section = bfd_get_section_by_name (abfd, ".reg");
280 if (section
dc05df57 281 && bfd_section_size (abfd, section) == I386_WINDOWS_SIZEOF_GREGSET)
c0993dbe
UW
282 return GDB_OSABI_CYGWIN;
283 }
de584861 284
1762d96d
CV
285 return GDB_OSABI_UNKNOWN;
286}
287
acd5c798
MK
288/* Provide a prototype to silence -Wmissing-prototypes. */
289void _initialize_i386_cygwin_tdep (void);
290
1762d96d
CV
291void
292_initialize_i386_cygwin_tdep (void)
293{
294 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
295 i386_cygwin_osabi_sniffer);
296
de584861
PA
297 /* Cygwin uses elf core dumps. */
298 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
299 i386_cygwin_osabi_sniffer);
300
1762d96d
CV
301 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN,
302 i386_cygwin_init_abi);
303}
This page took 0.760273 seconds and 4 git commands to generate.