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