* ia64-linux-nat.c (ia64_register_addr): Add gdbarch parameter,
[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
6aba47ca 3 Copyright (C) 2003, 2007 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"
de1b3c3d 24#include "i386-cygwin-tdep.h"
de584861
PA
25#include "regset.h"
26#include "gdb_obstack.h"
27#include "xml-support.h"
28#include "gdbcore.h"
29
30/* Core file support. */
31
32/* This vector maps GDB's idea of a register's number into an address
33 in the win32 exception context vector. */
34
35static int i386_win32_gregset_reg_offset[] =
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
89#define I386_WIN32_SIZEOF_GREGSET 716
90
91/* Return the appropriate register set for the core section identified
92 by SECT_NAME and SECT_SIZE. */
93
94static const struct regset *
95i386_win32_regset_from_core_section (struct gdbarch *gdbarch,
96 const char *sect_name, size_t sect_size)
97{
98 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
99
100 if (strcmp (sect_name, ".reg") == 0
101 && sect_size == I386_WIN32_SIZEOF_GREGSET)
102 {
103 if (tdep->gregset == NULL)
104 tdep->gregset = regset_alloc (gdbarch, i386_supply_gregset,
105 i386_collect_gregset);
106 return tdep->gregset;
107 }
108
109 return NULL;
110}
111
de1b3c3d 112void
de584861
PA
113win32_xfer_shared_library (const char* so_name, CORE_ADDR load_addr,
114 struct obstack *obstack)
115{
116 char *p;
117 obstack_grow_str (obstack, "<library name=\"");
118 p = xml_escape_text (so_name);
119 obstack_grow_str (obstack, p);
120 xfree (p);
121 obstack_grow_str (obstack, "\"><segment address=\"0x");
122 /* The symbols in a dll are offset by 0x1000, which is the the
123 offset from 0 of the first byte in an image - because of the file
124 header and the section alignment. */
125 p = paddr_nz (load_addr + 0x1000);
126 obstack_grow_str (obstack, p);
127 obstack_grow_str (obstack, "\"/></library>");
128}
129
130struct cpms_data
131{
132 struct obstack *obstack;
133 int module_count;
134};
135
136static void
137core_process_module_section (bfd *abfd, asection *sect, void *obj)
138{
139 struct cpms_data *data = obj;
140
141 char *module_name;
142 size_t module_name_size;
143 CORE_ADDR base_addr;
144
145 char *buf = NULL;
146
147 if (strncmp (sect->name, ".module", 7) != 0)
148 return;
149
150 buf = xmalloc (bfd_get_section_size (sect) + 1);
151 if (!buf)
152 {
153 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
154 goto out;
155 }
156 if (!bfd_get_section_contents (abfd, sect,
157 buf, 0, bfd_get_section_size (sect)))
158 goto out;
159
160
161
162 /* A DWORD (data_type) followed by struct win32_core_module_info. */
163
164 base_addr =
165 extract_unsigned_integer (buf + 4, 4);
166
167 module_name_size =
168 extract_unsigned_integer (buf + 8, 4);
169
170 module_name = buf + 12;
171 if (module_name - buf + module_name_size > bfd_get_section_size (sect))
172 goto out;
173
174 /* The first module is the .exe itself. */
175 if (data->module_count != 0)
176 win32_xfer_shared_library (module_name, base_addr, data->obstack);
177 data->module_count++;
178
179out:
180 if (buf)
181 xfree (buf);
182 return;
183}
184
185static LONGEST
186win32_core_xfer_shared_libraries (struct gdbarch *gdbarch,
187 gdb_byte *readbuf,
188 ULONGEST offset, LONGEST len)
189{
190 struct obstack obstack;
191 const char *buf;
192 LONGEST len_avail;
193 struct cpms_data data = { &obstack, 0 };
194
195 obstack_init (&obstack);
196 obstack_grow_str (&obstack, "<library-list>\n");
197 bfd_map_over_sections (core_bfd,
198 core_process_module_section,
199 &data);
200 obstack_grow_str0 (&obstack, "</library-list>\n");
201
202 buf = obstack_finish (&obstack);
203 len_avail = strlen (buf);
204 if (offset >= len_avail)
205 return 0;
206
207 if (len > len_avail - offset)
208 len = len_avail - offset;
209 memcpy (readbuf, buf + offset, len);
210
211 obstack_free (&obstack, NULL);
212 return len;
213}
1762d96d 214
f7948b5f 215static CORE_ADDR
52f729a7 216i386_cygwin_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
f7948b5f
JB
217{
218 return i386_pe_skip_trampoline_code (pc, NULL);
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
f7948b5f
JB
226 set_gdbarch_skip_trampoline_code (gdbarch, i386_cygwin_skip_trampoline_code);
227
1762d96d 228 tdep->struct_return = reg_struct_return;
de584861
PA
229
230 tdep->gregset_reg_offset = i386_win32_gregset_reg_offset;
231 tdep->gregset_num_regs = ARRAY_SIZE (i386_win32_gregset_reg_offset);
232 tdep->sizeof_gregset = I386_WIN32_SIZEOF_GREGSET;
233
234 /* Core file support. */
235 set_gdbarch_regset_from_core_section
236 (gdbarch, i386_win32_regset_from_core_section);
237 set_gdbarch_core_xfer_shared_libraries
238 (gdbarch, win32_core_xfer_shared_libraries);
1762d96d
CV
239}
240
241static enum gdb_osabi
de584861
PA
242i386_cygwin_osabi_sniffer (bfd *abfd)
243{
1762d96d
CV
244 char *target_name = bfd_get_target (abfd);
245
de584861 246 /* Interix also uses pei-i386.
1762d96d
CV
247 We need a way to distinguish between the two. */
248 if (strcmp (target_name, "pei-i386") == 0)
249 return GDB_OSABI_CYGWIN;
250
de584861
PA
251 /* Cygwin uses elf core dumps. */
252 if (strcmp (target_name, "elf32-i386") == 0)
253 return GDB_OSABI_CYGWIN;
254
1762d96d
CV
255 return GDB_OSABI_UNKNOWN;
256}
257
acd5c798
MK
258/* Provide a prototype to silence -Wmissing-prototypes. */
259void _initialize_i386_cygwin_tdep (void);
260
1762d96d
CV
261void
262_initialize_i386_cygwin_tdep (void)
263{
264 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
265 i386_cygwin_osabi_sniffer);
266
de584861
PA
267 /* Cygwin uses elf core dumps. */
268 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
269 i386_cygwin_osabi_sniffer);
270
1762d96d
CV
271 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN,
272 i386_cygwin_init_abi);
273}
This page took 0.411466 seconds and 4 git commands to generate.