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