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