* Makefile.in (strerror.o): Add rule so that broken Sun make can
[deliverable/binutils-gdb.git] / gdb / rs6000-xdep.c
CommitLineData
41abdfbd
JG
1/* IBM RS/6000 host-dependent code for GDB, the GNU debugger.
2 Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include <stdio.h>
21#include "defs.h"
41abdfbd
JG
22#include "frame.h"
23#include "inferior.h"
24#include "symtab.h"
25#include "target.h"
26
27#include <sys/param.h>
28#include <sys/dir.h>
29#include <sys/user.h>
30#include <signal.h>
31#include <sys/ioctl.h>
32#include <fcntl.h>
33
34#include <sys/ptrace.h>
35#include <sys/reg.h>
36
37#include <a.out.h>
38#include <sys/file.h>
39#include <sys/stat.h>
40#include <sys/core.h>
41#include <sys/ldr.h>
818de002 42#include <sys/utsname.h>
41abdfbd
JG
43
44extern int errno;
45extern int attach_flag;
46
47/* Conversion from gdb-to-system special purpose register numbers.. */
48
49static int special_regs[] = {
50 IAR, /* PC_REGNUM */
51 MSR, /* PS_REGNUM */
52 CR, /* CR_REGNUM */
53 LR, /* LR_REGNUM */
54 CTR, /* CTR_REGNUM */
55 XER, /* XER_REGNUM */
56 MQ /* MQ_REGNUM */
57};
58
59
60/* Nonzero if we just simulated a single step break. */
61extern int one_stepped;
62
63\f
818de002 64void
1ab3bf1b
JG
65fetch_inferior_registers (regno)
66 int regno;
41abdfbd
JG
67{
68 int ii;
69 extern char registers[];
70
71 /* read 32 general purpose registers. */
72
73 for (ii=0; ii < 32; ++ii)
74 *(int*)&registers[REGISTER_BYTE (ii)] =
75 ptrace (PT_READ_GPR, inferior_pid, ii, 0, 0);
76
77 /* read general purpose floating point registers. */
78
79 for (ii=0; ii < 32; ++ii)
80 ptrace (PT_READ_FPR, inferior_pid,
81 (int*)&registers [REGISTER_BYTE (FP0_REGNUM+ii)], FPR0+ii, 0);
82
83 /* read special registers. */
84 for (ii=0; ii <= LAST_SP_REGNUM-FIRST_SP_REGNUM; ++ii)
85 *(int*)&registers[REGISTER_BYTE (FIRST_SP_REGNUM+ii)] =
86 ptrace (PT_READ_GPR, inferior_pid, special_regs[ii], 0, 0);
87}
88
89/* Store our register values back into the inferior.
90 If REGNO is -1, do this for all registers.
91 Otherwise, REGNO specifies which register (so we can save time). */
92
1ab3bf1b 93void
41abdfbd
JG
94store_inferior_registers (regno)
95 int regno;
96{
97 extern char registers[];
98
99 errno = 0;
100
101 if (regno == -1) { /* for all registers.. */
102 int ii;
103
104 /* execute one dummy instruction (which is a breakpoint) in inferior
105 process. So give kernel a chance to do internal house keeping.
106 Otherwise the following ptrace(2) calls will mess up user stack
107 since kernel will get confused about the bottom of the stack (%sp) */
108
109 exec_one_dummy_insn ();
110
111 /* write general purpose registers first! */
112 for ( ii=GPR0; ii<=GPR31; ++ii) {
113 ptrace (PT_WRITE_GPR, inferior_pid, ii,
114 *(int*)&registers[REGISTER_BYTE (ii)], 0);
115 if ( errno ) {
116 perror ("ptrace write_gpr"); errno = 0;
117 }
118 }
119
120 /* write floating point registers now. */
121 for ( ii=0; ii < 32; ++ii) {
122 ptrace (PT_WRITE_FPR, inferior_pid,
123 (int*)&registers[REGISTER_BYTE (FP0_REGNUM+ii)], FPR0+ii, 0);
124 if ( errno ) {
125 perror ("ptrace write_fpr"); errno = 0;
126 }
127 }
128
129 /* write special registers. */
130 for (ii=0; ii <= LAST_SP_REGNUM-FIRST_SP_REGNUM; ++ii) {
131 ptrace (PT_WRITE_GPR, inferior_pid, special_regs[ii],
132 *(int*)&registers[REGISTER_BYTE (FIRST_SP_REGNUM+ii)], 0);
133 if ( errno ) {
134 perror ("ptrace write_gpr"); errno = 0;
135 }
136 }
137 }
138
139 /* else, a specific register number is given... */
140
141 else if (regno < FP0_REGNUM) { /* a GPR */
142
143 ptrace (PT_WRITE_GPR, inferior_pid, regno,
144 *(int*)&registers[REGISTER_BYTE (regno)], 0);
145 }
146
147 else if (regno <= FPLAST_REGNUM) { /* a FPR */
148 ptrace (PT_WRITE_FPR, inferior_pid,
149 (int*)&registers[REGISTER_BYTE (regno)], regno-FP0_REGNUM+FPR0, 0);
150 }
151
152 else if (regno <= LAST_SP_REGNUM) { /* a special register */
153
154 ptrace (PT_WRITE_GPR, inferior_pid, special_regs [regno-FIRST_SP_REGNUM],
155 *(int*)&registers[REGISTER_BYTE (regno)], 0);
156 }
157
158 else
159 fprintf (stderr, "Gdb error: register no %d not implemented.\n", regno);
160
161 if ( errno ) {
162 perror ("ptrace write"); errno = 0;
41abdfbd 163 }
41abdfbd
JG
164}
165
166void
1ab3bf1b 167fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
41abdfbd
JG
168 char *core_reg_sect;
169 unsigned core_reg_size;
170 int which;
1ab3bf1b 171 unsigned int reg_addr; /* Unused in this version */
41abdfbd
JG
172{
173 /* fetch GPRs and special registers from the first register section
174 in core bfd. */
175 if (which == 0) {
176
177 /* copy GPRs first. */
178 bcopy (core_reg_sect, registers, 32 * 4);
179
180 /* gdb's internal register template and bfd's register section layout
181 should share a common include file. FIXMEmgo */
182 /* then comes special registes. They are supposed to be in the same
183 order in gdb template and bfd `.reg' section. */
184 core_reg_sect += (32 * 4);
185 bcopy (core_reg_sect, &registers [REGISTER_BYTE (FIRST_SP_REGNUM)],
186 (LAST_SP_REGNUM - FIRST_SP_REGNUM + 1) * 4);
187 }
188
189 /* fetch floating point registers from register section 2 in core bfd. */
190 else if (which == 2)
191 bcopy (core_reg_sect, &registers [REGISTER_BYTE (FP0_REGNUM)], 32 * 8);
192
193 else
194 fprintf (stderr, "Gdb error: unknown parameter to fetch_core_registers().\n");
195}
196
197
198frameless_function_invocation (fi)
199struct frame_info *fi;
200{
818de002
PB
201 CORE_ADDR func_start;
202 int frameless, dummy;
41abdfbd 203
41abdfbd 204 func_start = get_pc_function_start (fi->pc) + FUNCTION_START_OFFSET;
41abdfbd 205
818de002
PB
206 /* If we failed to find the start of the function, it is a mistake
207 to inspect the instructions. */
208
209 if (!func_start)
210 return 0;
211
212 function_frame_info (func_start, &frameless, &dummy, &dummy, &dummy);
213 return frameless;
41abdfbd
JG
214}
215
216
217/* aixcoff_relocate_symtab - hook for symbol table relocation.
218 also reads shared libraries.. */
219
220aixcoff_relocate_symtab (pid)
221unsigned int pid;
222{
223#define MAX_LOAD_SEGS 64 /* maximum number of load segments */
224
41abdfbd
JG
225 struct ld_info *ldi;
226 int temp;
227
228 ldi = (void *) alloca(MAX_LOAD_SEGS * sizeof (*ldi));
229
230 /* According to my humble theory, aixcoff has some timing problems and
231 when the user stack grows, kernel doesn't update stack info in time
232 and ptrace calls step on user stack. That is why we sleep here a little,
233 and give kernel to update its internals. */
234
235 usleep (36000);
236
237 errno = 0;
238 ptrace(PT_LDINFO, pid, ldi, MAX_LOAD_SEGS * sizeof(*ldi), ldi);
818de002 239 if (errno) {
41abdfbd 240 perror_with_name ("ptrace ldinfo");
818de002
PB
241 return 0;
242 }
41abdfbd
JG
243
244 vmap_ldinfo(ldi);
245
246 do {
247 add_text_to_loadinfo (ldi->ldinfo_textorg, ldi->ldinfo_dataorg);
248 } while (ldi->ldinfo_next
249 && (ldi = (void *) (ldi->ldinfo_next + (char *) ldi)));
250
818de002 251#if 0
41abdfbd 252 /* Now that we've jumbled things around, re-sort them. */
1ab3bf1b 253 sort_minimal_symbols ();
818de002 254#endif
41abdfbd
JG
255
256 /* relocate the exec and core sections as well. */
257 vmap_exec ();
258}
259
260
261/* Keep an array of load segment information and their TOC table addresses.
262 This info will be useful when calling a shared library function by hand. */
263
264typedef struct {
265 unsigned long textorg, dataorg, toc_offset;
266} LoadInfo;
267
268#define LOADINFOLEN 10
269
270static LoadInfo *loadInfo = NULL;
271static int loadInfoLen = 0;
272static int loadInfoTocIndex = 0;
818de002 273int aix_loadInfoTextIndex = 0;
41abdfbd
JG
274
275
276xcoff_init_loadinfo ()
277{
278 loadInfoTocIndex = 0;
818de002 279 aix_loadInfoTextIndex = 0;
41abdfbd
JG
280
281 if (loadInfoLen == 0) {
282 loadInfo = (void*) xmalloc (sizeof (LoadInfo) * LOADINFOLEN);
283 loadInfoLen = LOADINFOLEN;
284 }
285}
286
287
288free_loadinfo ()
289{
290 if (loadInfo)
291 free (loadInfo);
292 loadInfo = NULL;
293 loadInfoLen = 0;
294 loadInfoTocIndex = 0;
818de002 295 aix_loadInfoTextIndex = 0;
41abdfbd
JG
296}
297
298
299xcoff_add_toc_to_loadinfo (unsigned long tocaddr)
300{
301 while (loadInfoTocIndex >= loadInfoLen) {
302 loadInfoLen += LOADINFOLEN;
303 loadInfo = (void*) xrealloc (loadInfo, sizeof(LoadInfo) * loadInfoLen);
304 }
305 loadInfo [loadInfoTocIndex++].toc_offset = tocaddr;
306}
307
308
309add_text_to_loadinfo (unsigned long textaddr, unsigned long dataaddr)
310{
818de002 311 while (aix_loadInfoTextIndex >= loadInfoLen) {
41abdfbd
JG
312 loadInfoLen += LOADINFOLEN;
313 loadInfo = (void*) xrealloc (loadInfo, sizeof(LoadInfo) * loadInfoLen);
314 }
818de002
PB
315 loadInfo [aix_loadInfoTextIndex].textorg = textaddr;
316 loadInfo [aix_loadInfoTextIndex].dataorg = dataaddr;
317 ++aix_loadInfoTextIndex;
41abdfbd
JG
318}
319
320
321unsigned long
322find_toc_address (unsigned long pc)
323{
818de002 324 int ii, toc_entry, tocbase = 0;
41abdfbd 325
818de002
PB
326 for (ii=0; ii < aix_loadInfoTextIndex; ++ii)
327 if (pc > loadInfo [ii].textorg && loadInfo [ii].textorg > tocbase) {
41abdfbd 328 toc_entry = ii;
818de002
PB
329 tocbase = loadInfo [ii].textorg;
330 }
41abdfbd
JG
331
332 return loadInfo [toc_entry].dataorg + loadInfo [toc_entry].toc_offset;
333}
334
335
336/* execute one dummy breakpoint instruction. This way we give kernel
337 a chance to do some housekeeping and update inferior's internal data,
338 including u_area. */
339
340exec_one_dummy_insn ()
341{
818de002 342#define DUMMY_INSN_ADDR (TEXT_SEGMENT_BASE)+0x200
41abdfbd
JG
343
344 unsigned long shadow;
345 unsigned int status, pid;
346
818de002
PB
347 /* We plant one dummy breakpoint into DUMMY_INSN_ADDR address. We assume that
348 this address will never be executed again by the real code. */
349
41abdfbd
JG
350 target_insert_breakpoint (DUMMY_INSN_ADDR, &shadow);
351
352 errno = 0;
353 ptrace (PT_CONTINUE, inferior_pid, DUMMY_INSN_ADDR, 0, 0);
354 if (errno)
355 perror ("pt_continue");
356
357 do {
358 pid = wait (&status);
359 } while (pid != inferior_pid);
360
361 target_remove_breakpoint (DUMMY_INSN_ADDR, &shadow);
362}
363
818de002
PB
364
365/* Return the number of initial trap signals we need to ignore once the inferior
366 process starts running. This will be `2' for aix-3.1, `3' for aix-3.2 */
367
368int
369aix_starting_inferior_traps ()
370{
371 struct utsname unamebuf;
372
373 if (uname (&unamebuf) == -1)
374 fatal ("uname(3) failed.");
375
376 /* Assume the future versions will behave like 3.2 and return '3' for
377 anything other than 3.1x. The extra trap in 3.2 is the "trap after the
378 program is loaded" signal. */
379
380 if (unamebuf.version[0] == '3' && unamebuf.release[0] == '1')
381 return 2;
382 else
383 return 3;
384}
This page took 0.048357 seconds and 4 git commands to generate.