* ld-spu/icache1.s: New file.
[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
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
de584861
PA
114struct cpms_data
115{
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;
124
125 char *module_name;
126 size_t module_name_size;
127 CORE_ADDR base_addr;
128
129 char *buf = NULL;
130
131 if (strncmp (sect->name, ".module", 7) != 0)
132 return;
133
134 buf = xmalloc (bfd_get_section_size (sect) + 1);
135 if (!buf)
136 {
137 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
138 goto out;
139 }
140 if (!bfd_get_section_contents (abfd, sect,
141 buf, 0, bfd_get_section_size (sect)))
142 goto out;
143
144
145
146 /* A DWORD (data_type) followed by struct win32_core_module_info. */
147
148 base_addr =
149 extract_unsigned_integer (buf + 4, 4);
150
151 module_name_size =
152 extract_unsigned_integer (buf + 8, 4);
153
154 module_name = buf + 12;
155 if (module_name - buf + module_name_size > bfd_get_section_size (sect))
156 goto out;
157
158 /* The first module is the .exe itself. */
159 if (data->module_count != 0)
160 win32_xfer_shared_library (module_name, base_addr, data->obstack);
161 data->module_count++;
162
163out:
164 if (buf)
165 xfree (buf);
166 return;
167}
168
169static LONGEST
170win32_core_xfer_shared_libraries (struct gdbarch *gdbarch,
171 gdb_byte *readbuf,
172 ULONGEST offset, LONGEST len)
173{
174 struct obstack obstack;
175 const char *buf;
176 LONGEST len_avail;
177 struct cpms_data data = { &obstack, 0 };
178
179 obstack_init (&obstack);
180 obstack_grow_str (&obstack, "<library-list>\n");
181 bfd_map_over_sections (core_bfd,
182 core_process_module_section,
183 &data);
184 obstack_grow_str0 (&obstack, "</library-list>\n");
185
186 buf = obstack_finish (&obstack);
187 len_avail = strlen (buf);
188 if (offset >= len_avail)
189 return 0;
190
191 if (len > len_avail - offset)
192 len = len_avail - offset;
193 memcpy (readbuf, buf + offset, len);
194
195 obstack_free (&obstack, NULL);
196 return len;
197}
1762d96d 198
f7948b5f 199static CORE_ADDR
52f729a7 200i386_cygwin_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
f7948b5f
JB
201{
202 return i386_pe_skip_trampoline_code (pc, NULL);
203}
204
1762d96d
CV
205static void
206i386_cygwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
207{
208 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
209
f7948b5f
JB
210 set_gdbarch_skip_trampoline_code (gdbarch, i386_cygwin_skip_trampoline_code);
211
4309257c
PM
212 set_gdbarch_skip_main_prologue (gdbarch, i386_skip_main_prologue);
213
1762d96d 214 tdep->struct_return = reg_struct_return;
de584861
PA
215
216 tdep->gregset_reg_offset = i386_win32_gregset_reg_offset;
217 tdep->gregset_num_regs = ARRAY_SIZE (i386_win32_gregset_reg_offset);
218 tdep->sizeof_gregset = I386_WIN32_SIZEOF_GREGSET;
219
8d465389
UW
220 set_solib_ops (gdbarch, &solib_target_so_ops);
221
de584861
PA
222 /* Core file support. */
223 set_gdbarch_regset_from_core_section
224 (gdbarch, i386_win32_regset_from_core_section);
225 set_gdbarch_core_xfer_shared_libraries
226 (gdbarch, win32_core_xfer_shared_libraries);
1762d96d
CV
227}
228
229static enum gdb_osabi
de584861
PA
230i386_cygwin_osabi_sniffer (bfd *abfd)
231{
1762d96d
CV
232 char *target_name = bfd_get_target (abfd);
233
de584861 234 /* Interix also uses pei-i386.
1762d96d
CV
235 We need a way to distinguish between the two. */
236 if (strcmp (target_name, "pei-i386") == 0)
237 return GDB_OSABI_CYGWIN;
238
c0993dbe
UW
239 /* Cygwin uses elf core dumps. Do not claim all ELF executables,
240 check whether there is a .reg section of proper size. */
de584861 241 if (strcmp (target_name, "elf32-i386") == 0)
c0993dbe
UW
242 {
243 asection *section = bfd_get_section_by_name (abfd, ".reg");
244 if (section
245 && bfd_section_size (abfd, section) == I386_WIN32_SIZEOF_GREGSET)
246 return GDB_OSABI_CYGWIN;
247 }
de584861 248
1762d96d
CV
249 return GDB_OSABI_UNKNOWN;
250}
251
acd5c798
MK
252/* Provide a prototype to silence -Wmissing-prototypes. */
253void _initialize_i386_cygwin_tdep (void);
254
1762d96d
CV
255void
256_initialize_i386_cygwin_tdep (void)
257{
258 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
259 i386_cygwin_osabi_sniffer);
260
de584861
PA
261 /* Cygwin uses elf core dumps. */
262 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
263 i386_cygwin_osabi_sniffer);
264
1762d96d
CV
265 gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_CYGWIN,
266 i386_cygwin_init_abi);
267}
This page took 0.423779 seconds and 4 git commands to generate.