gdb smob cleanups
[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
ecd75fc8 3 Copyright (C) 2003-2014 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"
0e9f083f 22#include <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"
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
PA
91
92/* Return the appropriate register set for the core section identified
93 by SECT_NAME and SECT_SIZE. */
94
95static const struct regset *
dc05df57 96i386_windows_regset_from_core_section (struct gdbarch *gdbarch,
de584861
PA
97 const char *sect_name, size_t sect_size)
98{
de584861 99 if (strcmp (sect_name, ".reg") == 0
dc05df57 100 && sect_size == I386_WINDOWS_SIZEOF_GREGSET)
ecc37a5a 101 return &i386_gregset;
de584861
PA
102
103 return NULL;
104}
105
de584861
PA
106struct cpms_data
107{
5af949e3 108 struct gdbarch *gdbarch;
de584861
PA
109 struct obstack *obstack;
110 int module_count;
111};
112
113static void
114core_process_module_section (bfd *abfd, asection *sect, void *obj)
115{
116 struct cpms_data *data = obj;
e17a4113 117 enum bfd_endian byte_order = gdbarch_byte_order (data->gdbarch);
de584861
PA
118
119 char *module_name;
120 size_t module_name_size;
121 CORE_ADDR base_addr;
122
001f13d8 123 gdb_byte *buf = NULL;
de584861
PA
124
125 if (strncmp (sect->name, ".module", 7) != 0)
126 return;
127
128 buf = xmalloc (bfd_get_section_size (sect) + 1);
129 if (!buf)
130 {
131 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
132 goto out;
133 }
134 if (!bfd_get_section_contents (abfd, sect,
135 buf, 0, bfd_get_section_size (sect)))
136 goto out;
137
138
139
dc05df57 140 /* A DWORD (data_type) followed by struct windows_core_module_info. */
de584861
PA
141
142 base_addr =
e17a4113 143 extract_unsigned_integer (buf + 4, 4, byte_order);
de584861
PA
144
145 module_name_size =
e17a4113 146 extract_unsigned_integer (buf + 8, 4, byte_order);
de584861 147
001f13d8 148 if (12 + module_name_size > bfd_get_section_size (sect))
de584861 149 goto out;
001f13d8 150 module_name = (char *) buf + 12;
de584861
PA
151
152 /* The first module is the .exe itself. */
153 if (data->module_count != 0)
5af949e3
UW
154 windows_xfer_shared_library (module_name, base_addr,
155 data->gdbarch, data->obstack);
de584861
PA
156 data->module_count++;
157
158out:
159 if (buf)
160 xfree (buf);
161 return;
162}
163
c09f20e4 164static ULONGEST
dc05df57 165windows_core_xfer_shared_libraries (struct gdbarch *gdbarch,
de584861 166 gdb_byte *readbuf,
7ec1862d 167 ULONGEST offset, ULONGEST len)
de584861
PA
168{
169 struct obstack obstack;
170 const char *buf;
c09f20e4 171 ULONGEST len_avail;
5af949e3 172 struct cpms_data data = { gdbarch, &obstack, 0 };
de584861
PA
173
174 obstack_init (&obstack);
175 obstack_grow_str (&obstack, "<library-list>\n");
176 bfd_map_over_sections (core_bfd,
177 core_process_module_section,
178 &data);
179 obstack_grow_str0 (&obstack, "</library-list>\n");
180
181 buf = obstack_finish (&obstack);
182 len_avail = strlen (buf);
183 if (offset >= len_avail)
184 return 0;
185
186 if (len > len_avail - offset)
187 len = len_avail - offset;
188 memcpy (readbuf, buf + offset, len);
189
190 obstack_free (&obstack, NULL);
191 return len;
192}
1762d96d 193
a5ee0f0c
PA
194/* This is how we want PTIDs from core files to be printed. */
195
196static char *
197i386_windows_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid)
198{
199 static char buf[80];
200
201 if (ptid_get_lwp (ptid) != 0)
202 {
203 snprintf (buf, sizeof (buf), "Thread 0x%lx", ptid_get_lwp (ptid));
204 return buf;
205 }
206
207 return normal_pid_to_str (ptid);
208}
209
f7948b5f 210static CORE_ADDR
52f729a7 211i386_cygwin_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
f7948b5f 212{
e17a4113 213 return i386_pe_skip_trampoline_code (frame, pc, NULL);
f7948b5f
JB
214}
215
f870a310
TT
216static const char *
217i386_cygwin_auto_wide_charset (void)
218{
219 return "UTF-16";
220}
221
1762d96d
CV
222static void
223i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
224{
225 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
226
64870a42
YQ
227 windows_init_abi (info, gdbarch);
228
f7948b5f
JB
229 set_gdbarch_skip_trampoline_code (gdbarch, i386_cygwin_skip_trampoline_code);
230
4309257c
PM
231 set_gdbarch_skip_main_prologue (gdbarch, i386_skip_main_prologue);
232
1762d96d 233 tdep->struct_return = reg_struct_return;
de584861 234
dc05df57
CF
235 tdep->gregset_reg_offset = i386_windows_gregset_reg_offset;
236 tdep->gregset_num_regs = ARRAY_SIZE (i386_windows_gregset_reg_offset);
237 tdep->sizeof_gregset = I386_WINDOWS_SIZEOF_GREGSET;
de584861
PA
238
239 /* Core file support. */
240 set_gdbarch_regset_from_core_section
dc05df57 241 (gdbarch, i386_windows_regset_from_core_section);
de584861 242 set_gdbarch_core_xfer_shared_libraries
dc05df57 243 (gdbarch, windows_core_xfer_shared_libraries);
a5ee0f0c 244 set_gdbarch_core_pid_to_str (gdbarch, i386_windows_core_pid_to_str);
f870a310
TT
245
246 set_gdbarch_auto_wide_charset (gdbarch, i386_cygwin_auto_wide_charset);
1762d96d
CV
247}
248
249static enum gdb_osabi
de584861
PA
250i386_cygwin_osabi_sniffer (bfd *abfd)
251{
1762d96d
CV
252 char *target_name = bfd_get_target (abfd);
253
1762d96d
CV
254 if (strcmp (target_name, "pei-i386") == 0)
255 return GDB_OSABI_CYGWIN;
256
c0993dbe
UW
257 /* Cygwin uses elf core dumps. Do not claim all ELF executables,
258 check whether there is a .reg section of proper size. */
de584861 259 if (strcmp (target_name, "elf32-i386") == 0)
c0993dbe
UW
260 {
261 asection *section = bfd_get_section_by_name (abfd, ".reg");
262 if (section
dc05df57 263 && bfd_section_size (abfd, section) == I386_WINDOWS_SIZEOF_GREGSET)
c0993dbe
UW
264 return GDB_OSABI_CYGWIN;
265 }
de584861 266
1762d96d
CV
267 return GDB_OSABI_UNKNOWN;
268}
269
acd5c798
MK
270/* Provide a prototype to silence -Wmissing-prototypes. */
271void _initialize_i386_cygwin_tdep (void);
272
1762d96d
CV
273void
274_initialize_i386_cygwin_tdep (void)
275{
276 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
277 i386_cygwin_osabi_sniffer);
278
de584861
PA
279 /* Cygwin uses elf core dumps. */
280 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
281 i386_cygwin_osabi_sniffer);
282
1762d96d
CV
283 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN,
284 i386_cygwin_init_abi);
285}
This page took 0.883522 seconds and 4 git commands to generate.