* disasm.h (gdb_disassembly): 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
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{
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
dc05df57 146 /* A DWORD (data_type) followed by struct windows_core_module_info. */
de584861
PA
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)
dc05df57 160 windows_xfer_shared_library (module_name, base_addr, data->obstack);
de584861
PA
161 data->module_count++;
162
163out:
164 if (buf)
165 xfree (buf);
166 return;
167}
168
169static LONGEST
dc05df57 170windows_core_xfer_shared_libraries (struct gdbarch *gdbarch,
de584861
PA
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 215
dc05df57
CF
216 tdep->gregset_reg_offset = i386_windows_gregset_reg_offset;
217 tdep->gregset_num_regs = ARRAY_SIZE (i386_windows_gregset_reg_offset);
218 tdep->sizeof_gregset = I386_WINDOWS_SIZEOF_GREGSET;
de584861 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
dc05df57 224 (gdbarch, i386_windows_regset_from_core_section);
de584861 225 set_gdbarch_core_xfer_shared_libraries
dc05df57 226 (gdbarch, windows_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
dc05df57 245 && bfd_section_size (abfd, section) == I386_WINDOWS_SIZEOF_GREGSET)
c0993dbe
UW
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.715327 seconds and 4 git commands to generate.