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