2008-08-21 Sterling Augustine <sterling@tensilica.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
9b254dd1 3 Copyright (C) 2003, 2007, 2008 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
4309257c
PM
230 set_gdbarch_skip_main_prologue (gdbarch, i386_skip_main_prologue);
231
1762d96d 232 tdep->struct_return = reg_struct_return;
de584861
PA
233
234 tdep->gregset_reg_offset = i386_win32_gregset_reg_offset;
235 tdep->gregset_num_regs = ARRAY_SIZE (i386_win32_gregset_reg_offset);
236 tdep->sizeof_gregset = I386_WIN32_SIZEOF_GREGSET;
237
8d465389
UW
238 set_solib_ops (gdbarch, &solib_target_so_ops);
239
de584861
PA
240 /* Core file support. */
241 set_gdbarch_regset_from_core_section
242 (gdbarch, i386_win32_regset_from_core_section);
243 set_gdbarch_core_xfer_shared_libraries
244 (gdbarch, win32_core_xfer_shared_libraries);
1762d96d
CV
245}
246
247static enum gdb_osabi
de584861
PA
248i386_cygwin_osabi_sniffer (bfd *abfd)
249{
1762d96d
CV
250 char *target_name = bfd_get_target (abfd);
251
de584861 252 /* Interix also uses pei-i386.
1762d96d
CV
253 We need a way to distinguish between the two. */
254 if (strcmp (target_name, "pei-i386") == 0)
255 return GDB_OSABI_CYGWIN;
256
c0993dbe
UW
257 /* Cygwin uses elf core dumps. Do not claim all ELF executables,
258 check whether there is a .reg section of proper size. */
de584861 259 if (strcmp (target_name, "elf32-i386") == 0)
c0993dbe
UW
260 {
261 asection *section = bfd_get_section_by_name (abfd, ".reg");
262 if (section
263 && bfd_section_size (abfd, section) == I386_WIN32_SIZEOF_GREGSET)
264 return GDB_OSABI_CYGWIN;
265 }
de584861 266
1762d96d
CV
267 return GDB_OSABI_UNKNOWN;
268}
269
acd5c798
MK
270/* Provide a prototype to silence -Wmissing-prototypes. */
271void _initialize_i386_cygwin_tdep (void);
272
1762d96d
CV
273void
274_initialize_i386_cygwin_tdep (void)
275{
276 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
277 i386_cygwin_osabi_sniffer);
278
de584861
PA
279 /* Cygwin uses elf core dumps. */
280 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
281 i386_cygwin_osabi_sniffer);
282
1762d96d
CV
283 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN,
284 i386_cygwin_init_abi);
285}
This page took 0.58378 seconds and 4 git commands to generate.