Add DT_MIPS_RLD_MAP case for 64-bit targets.
[deliverable/binutils-gdb.git] / gdb / i386-interix-tdep.c
1 /* Target-dependent code for Interix running on i386's, for GDB.
2 Copyright 2002 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #include "defs.h"
21 #include "arch-utils.h"
22
23 #include "frame.h"
24 #include "gdb_string.h"
25 #include "gdb-stabs.h"
26 #include "gdbcore.h"
27 #include "gdbtypes.h"
28 #include "i386-tdep.h"
29 #include "inferior.h"
30 #include "libbfd.h"
31 #include "objfiles.h"
32 #include "osabi.h"
33 #include "regcache.h"
34
35 /* offsetof (mcontext_t, gregs.gregs[EBP]) */
36 static const int mcontext_EBP_greg_offset = 180;
37
38 /* offsetof (mcontext_t, gregs.gregs[EIP]) */
39 static const int mcontext_EIP_greg_offset = 184;
40
41 /* offsetof (mcontext_t, gregs.gregs[UESP]) */
42 static const int mcontext_UESP_greg_offset = 196;
43
44 /* offsetof (mcontext_t, gregs.reserved[1]) */
45 static const int mcontext_syscall_greg_offset = 4;
46
47 /* offsetof (_JUMP_BUFFER, Eip) */
48 static const int jump_buffer_Eip_offset = 20;
49
50 /* See procfs.c and *interix*.h in config/[alpha,i386]. */
51 /* ??? These should be static, but this needs a bit of work before this
52 can be done. */
53 CORE_ADDR tramp_start;
54 CORE_ADDR tramp_end;
55 CORE_ADDR null_start;
56 CORE_ADDR null_end;
57 int winver; /* Windows NT version number */
58
59 /* Forward declarations. */
60 extern void _initialize_i386_interix_tdep (void);
61 extern initialize_file_ftype _initialize_i386_interix_tdep;
62
63 /* Adjust the section offsets in an objfile structure so that it's correct
64 for the type of symbols being read (or undo it with the _restore
65 arguments).
66
67 If main programs ever start showing up at other than the default Image
68 Base, this is where that would likely be applied. */
69
70 void
71 pei_adjust_objfile_offsets (struct objfile *objfile,
72 enum objfile_adjusts type)
73 {
74 int i;
75 CORE_ADDR symbols_offset;
76
77 switch (type)
78 {
79 case adjust_for_symtab:
80 symbols_offset = NONZERO_LINK_BASE (objfile->obfd);
81 break;
82 case adjust_for_symtab_restore:
83 symbols_offset = -NONZERO_LINK_BASE (objfile->obfd);
84 break;
85 case adjust_for_stabs:
86 case adjust_for_stabs_restore:
87 case adjust_for_dwarf:
88 case adjust_for_dwarf_restore:
89 default:
90 return;
91 }
92
93 for (i = 0; i < SECT_OFF_MAX; i++)
94 {
95 (objfile->section_offsets)->offsets[i] += symbols_offset;
96 }
97 }
98
99 static int
100 i386_interix_pc_in_sigtramp (CORE_ADDR pc, char *name)
101 {
102 /* This is sufficient, where used, but is NOT a complete test; There
103 is more in INIT_EXTRA_FRAME_INFO (a.k.a. interix_back_one_frame). */
104 return ((pc >= tramp_start && pc < tramp_end)
105 || (pc >= null_start && pc < null_end));
106 }
107
108 static int
109 i386_interix_in_solib_call_trampoline (CORE_ADDR pc, char *name)
110 {
111 return i386_pe_skip_trampoline_code (pc, name);
112 }
113
114 static CORE_ADDR
115 i386_interix_skip_trampoline_code (CORE_ADDR pc)
116 {
117 return i386_pe_skip_trampoline_code (pc, 0);
118 }
119
120 static int
121 i386_interix_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
122 {
123 /* In the context where this is used, we get the saved PC before we've
124 successfully unwound far enough to be sure what we've got (it may
125 be a signal handler caller). If we're dealing with a signal
126 handler caller, this will return valid, which is fine. If not,
127 it'll make the correct test. */
128 return ((get_frame_type (thisframe) == SIGTRAMP_FRAME)
129 || (chain != 0
130 && !inside_entry_file (read_memory_integer
131 (thisframe->frame + 4, 4))));
132 }
133
134 /* We want to find the previous frame, which on Interix is tricky when
135 signals are involved; set frame->frame appropriately, and also get
136 the pc and tweak tye frame's type; this replaces a boatload of
137 nested macros, as well. */
138 static void
139 i386_interix_back_one_frame (int fromleaf, struct frame_info *frame)
140 {
141 CORE_ADDR ra;
142 CORE_ADDR fm;
143 CORE_ADDR context;
144 long t;
145
146 if (frame == NULL)
147 internal_error (__FILE__, __LINE__, "unexpected NULL frame");
148
149 if (fromleaf)
150 {
151 frame->pc = SAVED_PC_AFTER_CALL (frame->next);
152 return;
153 }
154
155 if (!frame->next)
156 {
157 frame->pc = read_pc ();
158
159 /* Part of the signal stuff... See below. */
160 if (stopped_by_random_signal)
161 {
162 /* We know we're in a system call mini-frame; was it
163 NullApi or something else? */
164 ra = SAVED_PC_AFTER_CALL (frame);
165 if (ra >= null_start && ra < null_end)
166 deprecated_set_frame_type (frame, SIGTRAMP_FRAME);
167 /* There might also be an indirect call to the mini-frame,
168 putting one more return address on the stack. (XP only,
169 I think?) This can't (reasonably) return the address of the
170 signal handler caller unless it's that situation, so this
171 is safe. */
172 ra = read_memory_unsigned_integer (read_register (SP_REGNUM) + 4, 4);
173 if (ra >= null_start && ra < null_end)
174 deprecated_set_frame_type (frame, SIGTRAMP_FRAME);
175 }
176 return;
177 }
178
179 if (!(get_frame_type (frame->next) == SIGTRAMP_FRAME))
180 {
181 frame->pc = read_memory_integer (frame->next->frame + 4, 4);
182 return;
183 }
184
185 /* This is messy (actually AWFUL)... The "trampoline" might be 2, 3
186 or all 5 entities on the frame.
187
188 Chunk 1 will be present when we're actually in a signal handler.
189 Chunk 2 will be present when an asynchronous signal (one that
190 didn't come in with a system call) is present.
191 We may not (yet) be in the handler, if we're just returning
192 from the call.
193 When we're actually in a handler taken from an asynchronous
194 signal, both will be present.
195
196 Chunk 1:
197 PdxSignalDeliverer's frame
198 + Context struct -- not accounted for in any frame
199
200 Chunk 2:
201 + PdxNullPosixApi's frame
202 + PdxNullApiCaller's frame
203 + Context struct = 0x230 not accounted for in any frame
204
205 The symbol names come from examining objdumps of psxdll.dll;
206 they don't appear in the runtime image.
207
208 For gdb's purposes, we can pile all this into one frame. */
209
210 ra = frame->next->pc;
211 /* Are we already pointing at PdxNullPosixApi? We are if
212 this is a signal frame, we're at next-to-top, and were stopped
213 by a random signal (if it wasn't the right address under
214 these circumstances, we wouldn't be here at all by tests above
215 on the prior frame). */
216 if (frame->next->next == NULL && stopped_by_random_signal)
217 {
218 /* We're pointing at the frame FOR PdxNullApi. */
219 fm = frame->frame;
220 }
221 else
222 {
223 /* No... We must be pointing at the frame that was called
224 by PdxSignalDeliverer; back up across the whole mess. */
225
226 /* Extract the frame for PdxSignalDeliverer.
227 Note: FRAME_CHAIN used the "old" frame pointer because we were
228 a deliverer. Get the address of the context record that's on
229 here frameless. */
230 context = read_memory_integer (frame->frame, 4); /* an Arg */
231
232 /* Now extract the frame pointer contained in the context. */
233 fm = read_memory_integer (context + mcontext_EBP_greg_offset, 4);
234
235 ra = read_memory_integer (context + mcontext_EIP_greg_offset, 4);
236
237 /* We need to know if we're in a system call because we'll be
238 in a syscall mini-frame, if so, and the rules are different. */
239 t = (long) read_memory_integer (context + mcontext_syscall_greg_offset,
240 4);
241 /* t contains 0 if running free, 1 if blocked on a system call,
242 and 2 if blocked on an exception message (e.g. a trap);
243 we don't expect to get here with a 2. */
244 if (t != 1)
245 {
246 /* Not at a system call, therefore it can't be NullApi. */
247 frame->pc = ra;
248 frame->frame = fm;
249 return;
250 }
251
252 /* It's a system call... Mini frame, then look for NullApi. */
253 /* Get the RA (on the stack) associated with this... It's
254 a system call mini-frame. */
255 ra = read_memory_integer (context + mcontext_UESP_greg_offset, 4);
256
257 if (winver >= 51)
258 {
259 /* Newer versions of Windows NT interpose another return
260 address (but no other "stack frame" stuff) that we need
261 to simply ignore here. */
262 ra += 4;
263 }
264
265 ra = read_memory_integer (ra, 4);
266
267 if (!(ra >= null_start && ra < null_end))
268 {
269 /* No Null API present; we're done. */
270 frame->pc = ra;
271 frame->frame = fm;
272 return;
273 }
274 }
275
276 /* At this point, we're looking at the frame for PdxNullPosixApi,
277 in either case.
278
279 PdxNullPosixApi is called by PdxNullApiCaller (which in turn
280 is called by _PdxNullApiCaller (note the _).)
281 PdxNullPosixApiCaller (no _) is a frameless function.
282
283 The saved frame pointer is as fm, but it's not of interest
284 to us because it skips us over the saved context, which is
285 the wrong thing to do, because it skips the interrrupted
286 routine! PdxNullApiCaller takes as its only argument the
287 address of the context of the interrupded function (which
288 is really in no frame, but jammed on the stack by the system)
289
290 So: fm+0: saved bp
291 fm+4: return address to _PdxNullApiCaller
292 fm+8: arg to PdxNullApiCaller pushed by _Pdx... */
293
294 fm = read_memory_integer (fm + 0x8, 4);
295
296 /* Extract the second context record. */
297
298 ra = read_memory_integer (fm + mcontext_EIP_greg_offset, 4);
299 fm = read_memory_integer (fm + mcontext_EBP_greg_offset, 4);
300
301 frame->frame = fm;
302 frame->pc = ra;
303
304 return;
305 }
306
307 static CORE_ADDR
308 i386_interix_frame_saved_pc (struct frame_info *fi)
309 {
310 /* Assume that we've already unwound enough to have the caller's address
311 if we're dealing with a signal handler caller (And if that fails,
312 return 0). */
313 if ((get_frame_type (fi) == SIGTRAMP_FRAME))
314 return fi->next ? fi->next->pc : 0;
315 else
316 return read_memory_integer (fi->frame + 4, 4);
317 }
318
319 static void
320 i386_interix_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
321 {
322 struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
323
324 tdep->struct_return = reg_struct_return;
325 tdep->jb_pc_offset = jump_buffer_Eip_offset;
326
327 set_gdbarch_decr_pc_after_break (gdbarch, 0);
328 set_gdbarch_pc_in_sigtramp (gdbarch, i386_interix_pc_in_sigtramp);
329 set_gdbarch_in_solib_call_trampoline (gdbarch,
330 i386_interix_in_solib_call_trampoline);
331 set_gdbarch_skip_trampoline_code (gdbarch,
332 i386_interix_skip_trampoline_code);
333 set_gdbarch_init_extra_frame_info (gdbarch, i386_interix_back_one_frame);
334 set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_noop);
335 set_gdbarch_frame_chain_valid (gdbarch, i386_interix_frame_chain_valid);
336 set_gdbarch_frame_saved_pc (gdbarch, i386_interix_frame_saved_pc);
337 set_gdbarch_name_of_malloc (gdbarch, "_malloc");
338 }
339
340 static enum gdb_osabi
341 i386_interix_osabi_sniffer (bfd * abfd)
342 {
343 char *target_name = bfd_get_target (abfd);
344
345 if (strcmp (target_name, "pei-i386") == 0)
346 return GDB_OSABI_INTERIX;
347
348 return GDB_OSABI_UNKNOWN;
349 }
350
351 void
352 _initialize_i386_interix_tdep (void)
353 {
354 gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_coff_flavour,
355 i386_interix_osabi_sniffer);
356
357 gdbarch_register_osabi (bfd_arch_i386, GDB_OSABI_INTERIX,
358 i386_interix_init_abi);
359 }
This page took 0.037286 seconds and 4 git commands to generate.