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