f693a30a0452c45cc727cd287a0b11b2ea4efa21
[deliverable/binutils-gdb.git] / gdb / cxux-nat.c
1 /* Native support for Motorola 88k running Harris CX/UX.
2 Copyright 1988, 1990, 1991, 1992, 1993, 1994 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 "frame.h"
22 #include "inferior.h"
23
24 #include <sys/types.h>
25 #include <sys/param.h>
26 #include <sys/dir.h>
27 #include <signal.h>
28 #include "gdbcore.h"
29 #include <sys/user.h>
30
31 #include "bfd.h"
32 #include "symfile.h"
33 #include "objfiles.h"
34 #include "symtab.h"
35
36 #ifndef USER /* added to support BCS ptrace_user */
37 #define USER ptrace_user
38 #endif
39 #include <sys/ioctl.h>
40 #include <fcntl.h>
41 #include <sys/file.h>
42 #include "gdb_stat.h"
43
44 #include "symtab.h"
45 #include "setjmp.h"
46 #include "value.h"
47
48 #include <sys/ptrace.h>
49
50 /* CX/UX provides them already, but as word offsets instead of char offsets */
51 #define SXIP_OFFSET (PT_SXIP * 4)
52 #define SNIP_OFFSET (PT_SNIP * 4)
53 #define SFIP_OFFSET (PT_SFIP * 4)
54 #define PSR_OFFSET (PT_PSR * sizeof(int))
55 #define FPSR_OFFSET (PT_FPSR * sizeof(int))
56 #define FPCR_OFFSET (PT_FPCR * sizeof(int))
57
58 #define XREGADDR(r) (((char *)&u.pt_x0-(char *)&u) + \
59 ((r)-X0_REGNUM)*sizeof(X_REGISTER_RAW_TYPE))
60
61 extern int have_symbol_file_p();
62
63 extern jmp_buf stack_jmp;
64
65 extern int errno;
66
67 void
68 fetch_inferior_registers (regno)
69 int regno; /* Original value discarded */
70 {
71 register unsigned int regaddr;
72 char buf[MAX_REGISTER_RAW_SIZE];
73 register int i;
74
75 struct USER u;
76 unsigned int offset;
77
78 offset = (char *) &u.pt_r0 - (char *) &u;
79 regaddr = offset; /* byte offset to r0;*/
80
81 /* offset = ptrace (3, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0) - KERNEL_U_ADDR; */
82 for (regno = 0; regno < PC_REGNUM; regno++)
83 {
84 /*regaddr = register_addr (regno, offset);*/
85 /* 88k enhancement */
86
87 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
88 {
89 *(int *) &buf[i] = ptrace (3, inferior_pid,
90 (PTRACE_ARG3_TYPE) regaddr, 0);
91 regaddr += sizeof (int);
92 }
93 supply_register (regno, buf);
94 }
95 /* now load up registers 32-37; special pc registers */
96 *(int *) &buf[0] = ptrace (3, inferior_pid,
97 (PTRACE_ARG3_TYPE) PSR_OFFSET,0);
98 supply_register (PSR_REGNUM, buf);
99 *(int *) &buf[0] = ptrace (3, inferior_pid,
100 (PTRACE_ARG3_TYPE) FPSR_OFFSET,0);
101 supply_register (FPSR_REGNUM, buf);
102 *(int *) &buf[0] = ptrace (3, inferior_pid,
103 (PTRACE_ARG3_TYPE) FPCR_OFFSET,0);
104 supply_register (FPCR_REGNUM, buf);
105 *(int *) &buf[0] = ptrace (3,inferior_pid,
106 (PTRACE_ARG3_TYPE) SXIP_OFFSET ,0);
107 supply_register (SXIP_REGNUM, buf);
108 *(int *) &buf[0] = ptrace (3, inferior_pid,
109 (PTRACE_ARG3_TYPE) SNIP_OFFSET,0);
110 supply_register (SNIP_REGNUM, buf);
111 *(int *) &buf[0] = ptrace (3, inferior_pid,
112 (PTRACE_ARG3_TYPE) SFIP_OFFSET,0);
113 supply_register (SFIP_REGNUM, buf);
114
115 if (target_is_m88110)
116 {
117 for (regaddr = XREGADDR(X0_REGNUM), regno = X0_REGNUM;
118 regno < NUM_REGS;
119 regno++, regaddr += 16)
120 {
121 X_REGISTER_RAW_TYPE xval;
122
123 *(int *) &xval.w1 = ptrace (3, inferior_pid,
124 (PTRACE_ARG3_TYPE) regaddr, 0);
125 *(int *) &xval.w2 = ptrace (3, inferior_pid,
126 (PTRACE_ARG3_TYPE) (regaddr+4), 0);
127 *(int *) &xval.w3 = ptrace (3, inferior_pid,
128 (PTRACE_ARG3_TYPE) (regaddr+8), 0);
129 *(int *) &xval.w4 = ptrace (3, inferior_pid,
130 (PTRACE_ARG3_TYPE) (regaddr+12), 0);
131 supply_register(regno, (void *)&xval);
132 }
133 }
134 }
135
136 /* Store our register values back into the inferior.
137 If REGNO is -1, do this for all registers.
138 Otherwise, REGNO specifies which register (so we can save time). */
139
140 void
141 store_inferior_registers (regno)
142 int regno;
143 {
144 register unsigned int regaddr;
145 char buf[80];
146
147 struct USER u;
148
149 unsigned int offset = (char *) &u.pt_r0 - (char *) &u;
150
151 regaddr = offset;
152
153 /* Don't try to deal with EXIP_REGNUM or ENIP_REGNUM, because I think either
154 svr3 doesn't run on an 88110, or the kernel isolates the different (not
155 completely sure this is true, but seems to be. */
156 if (regno >= 0)
157 {
158 /* regaddr = register_addr (regno, offset); */
159 if (regno < PC_REGNUM)
160 {
161 regaddr = offset + regno * sizeof (int);
162 errno = 0;
163 ptrace (6, inferior_pid,
164 (PTRACE_ARG3_TYPE) regaddr, read_register (regno));
165 if (errno != 0)
166 {
167 sprintf (buf, "writing register number %d", regno);
168 perror_with_name (buf);
169 }
170 }
171 else if (regno == PSR_REGNUM)
172 ptrace (6, inferior_pid,
173 (PTRACE_ARG3_TYPE) PSR_OFFSET, read_register(regno));
174 else if (regno == FPSR_REGNUM)
175 ptrace (6, inferior_pid,
176 (PTRACE_ARG3_TYPE) FPSR_OFFSET, read_register(regno));
177 else if (regno == FPCR_REGNUM)
178 ptrace (6, inferior_pid,
179 (PTRACE_ARG3_TYPE) FPCR_OFFSET, read_register(regno));
180 else if (regno == SXIP_REGNUM)
181 ptrace (6, inferior_pid,
182 (PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register(regno));
183 else if (regno == SNIP_REGNUM)
184 ptrace (6, inferior_pid,
185 (PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register(regno));
186 else if (regno == SFIP_REGNUM)
187 ptrace (6, inferior_pid,
188 (PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register(regno));
189 else if (target_is_m88110 && regno < NUM_REGS)
190 {
191 X_REGISTER_RAW_TYPE xval;
192
193 read_register_bytes(REGISTER_BYTE(regno), (char *)&xval,
194 sizeof(X_REGISTER_RAW_TYPE));
195 regaddr = XREGADDR(regno);
196 ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, xval.w1);
197 ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr+4, xval.w2);
198 ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr+8, xval.w3);
199 ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr+12, xval.w4);
200 }
201 else
202 printf_unfiltered ("Bad register number for store_inferior routine\n");
203 }
204 else
205 {
206 for (regno = 0; regno < PC_REGNUM; regno++)
207 {
208 /* regaddr = register_addr (regno, offset); */
209 errno = 0;
210 regaddr = offset + regno * sizeof (int);
211 ptrace (6, inferior_pid,
212 (PTRACE_ARG3_TYPE) regaddr, read_register (regno));
213 if (errno != 0)
214 {
215 sprintf (buf, "writing register number %d", regno);
216 perror_with_name (buf);
217 }
218 }
219 ptrace (6, inferior_pid,
220 (PTRACE_ARG3_TYPE) PSR_OFFSET, read_register(regno));
221 ptrace (6, inferior_pid,
222 (PTRACE_ARG3_TYPE) FPSR_OFFSET,read_register(regno));
223 ptrace (6, inferior_pid,
224 (PTRACE_ARG3_TYPE) FPCR_OFFSET,read_register(regno));
225 ptrace (6,inferior_pid,
226 (PTRACE_ARG3_TYPE) SXIP_OFFSET,read_register(SXIP_REGNUM));
227 ptrace (6,inferior_pid,
228 (PTRACE_ARG3_TYPE) SNIP_OFFSET,read_register(SNIP_REGNUM));
229 ptrace (6,inferior_pid,
230 (PTRACE_ARG3_TYPE) SFIP_OFFSET,read_register(SFIP_REGNUM));
231 if (target_is_m88110)
232 {
233 for (regno = X0_REGNUM; regno < NUM_REGS; regno++)
234 {
235 X_REGISTER_RAW_TYPE xval;
236
237 read_register_bytes(REGISTER_BYTE(regno), (char *)&xval,
238 sizeof(X_REGISTER_RAW_TYPE));
239 regaddr = XREGADDR(regno);
240 ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, xval.w1);
241 ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) (regaddr+4), xval.w2);
242 ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) (regaddr+8), xval.w3);
243 ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) (regaddr+12), xval.w4);
244 }
245 }
246 }
247 }
248
249 /* blockend is the address of the end of the user structure */
250
251 m88k_register_u_addr (blockend, regnum)
252 int blockend, regnum;
253 {
254 struct USER u;
255 int ustart = blockend - sizeof (struct USER);
256
257 if (regnum < PSR_REGNUM)
258 return (ustart + ((int) &u.pt_r0 - (int) &u) +
259 REGISTER_SIZE * regnum);
260 else if (regnum == PSR_REGNUM)
261 return (ustart + ((int) &u.pt_psr) - (int) &u);
262 else if (regnum == FPSR_REGNUM)
263 return (ustart + ((int) &u.pt_fpsr) - (int) &u);
264 else if (regnum == FPCR_REGNUM)
265 return (ustart + ((int) &u.pt_fpcr) - (int) &u);
266 else if (regnum == SXIP_REGNUM)
267 return (ustart + SXIP_OFFSET);
268 else if (regnum == SNIP_REGNUM)
269 return (ustart + SNIP_OFFSET);
270 else if (regnum == SFIP_REGNUM)
271 return (ustart + SFIP_OFFSET);
272 else if (target_is_m88110)
273 return (ustart + ((int) &u.pt_x0 - (int) &u) + /* Must be X register */
274 sizeof(u.pt_x0) * (regnum - X0_REGNUM));
275 else
276 return (blockend + REGISTER_SIZE * regnum);
277 }
278
279 #ifdef USE_PROC_FS
280
281 #include <sys/procfs.h>
282
283 /* Given a pointer to a general register set in /proc format (gregset_t *),
284 unpack the register contents and supply them as gdb's idea of the current
285 register values. */
286
287 void
288 supply_gregset (gregsetp)
289 gregset_t *gregsetp;
290 {
291 register int regi;
292 register greg_t *regp = (greg_t *) gregsetp;
293
294 for (regi=0; regi <= SP_REGNUM; regi++)
295 supply_register (regi, (char *) (regp + regi));
296
297 supply_register (SXIP_REGNUM, (char *) (regp + R_XIP));
298 supply_register (SNIP_REGNUM, (char *) (regp + R_NIP));
299 supply_register (SFIP_REGNUM, (char *) (regp + R_FIP));
300 supply_register (PSR_REGNUM, (char *) (regp + R_PSR));
301 supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR));
302 supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR));
303 }
304
305 void
306 fill_gregset (gregsetp, regno)
307 gregset_t *gregsetp;
308 int regno;
309 {
310 int regi;
311 register greg_t *regp = (greg_t *) gregsetp;
312
313 for (regi = 0 ; regi <= R_R31 ; regi++)
314 if ((regno == -1) || (regno == regi))
315 *(regp + regi) = *(int *) &registers[REGISTER_BYTE(regi)];
316
317 if ((regno == -1) || (regno == SXIP_REGNUM))
318 *(regp + R_XIP) = *(int *) &registers[REGISTER_BYTE(SXIP_REGNUM)];
319 if ((regno == -1) || (regno == SNIP_REGNUM))
320 *(regp + R_NIP) = *(int *) &registers[REGISTER_BYTE(SNIP_REGNUM)];
321 if ((regno == -1) || (regno == SFIP_REGNUM))
322 *(regp + R_FIP) = *(int *) &registers[REGISTER_BYTE(SFIP_REGNUM)];
323 if ((regno == -1) || (regno == PSR_REGNUM))
324 *(regp + R_PSR) = *(int *) &registers[REGISTER_BYTE(PSR_REGNUM)];
325 if ((regno == -1) || (regno == FPSR_REGNUM))
326 *(regp + R_FPSR) = *(int *) &registers[REGISTER_BYTE(FPSR_REGNUM)];
327 if ((regno == -1) || (regno == FPCR_REGNUM))
328 *(regp + R_FPCR) = *(int *) &registers[REGISTER_BYTE(FPCR_REGNUM)];
329 }
330
331 #endif /* USE_PROC_FS */
332
333 /* This support adds the equivalent of adb's % command. When
334 the `add-shared-symbol-files' command is given, this routine scans
335 the dynamic linker's link map and reads the minimal symbols
336 from each shared object file listed in the map. */
337
338 struct link_map {
339 unsigned long l_addr; /* address at which object is mapped */
340 char *l_name; /* full name of loaded object */
341 void *l_ld; /* dynamic structure of object */
342 struct link_map *l_next; /* next link object */
343 struct link_map *l_prev; /* previous link object */
344 };
345
346 #define LINKS_MAP_POINTER "_ld_tail"
347 #define LIBC_FILE "/usr/lib/libc.so.1"
348 #define SHARED_OFFSET 0xf0001000
349
350 #ifndef PATH_MAX
351 #define PATH_MAX 1023 /* maximum size of path name on OS */
352 #endif
353
354 void
355 add_shared_symbol_files ()
356 {
357 void *desc;
358 struct link_map *ld_map, *lm, lms;
359 struct minimal_symbol *minsym;
360 struct objfile *objfile;
361 char *path_name;
362
363 if (! inferior_pid)
364 {
365 warning ("The program has not yet been started.");
366 return;
367 }
368
369 objfile = symbol_file_add (LIBC_FILE, 0, 0, 0, 0, 1, 0, 0);
370 minsym = lookup_minimal_symbol (LINKS_MAP_POINTER, objfile);
371
372 ld_map = (struct link_map *)
373 read_memory_integer (((int)SYMBOL_VALUE_ADDRESS(minsym) + SHARED_OFFSET), 4);
374 lm = ld_map;
375 while (lm)
376 {
377 int local_errno = 0;
378
379 read_memory ((CORE_ADDR)lm, (char*)&lms, sizeof (struct link_map));
380 if (lms.l_name)
381 {
382 if (target_read_string ((CORE_ADDR)lms.l_name, &path_name,
383 PATH_MAX, &local_errno))
384 {
385 symbol_file_add (path_name, 1, lms.l_addr, 0, 0, 0, 0, 0);
386 free(path_name);
387 }
388 }
389 /* traverse links in reverse order so that we get the
390 the symbols the user actually gets. */
391 lm = lms.l_prev;
392 }
393
394 /* Getting new symbols may change our opinion about what is
395 frameless. */
396 reinit_frame_cache ();
397 }
398
399 #if defined(_ES_MP)
400
401 #include <sys/regset.h>
402
403 unsigned int
404 m88k_harris_core_register_addr (regno, reg_ptr)
405 int regno, reg_ptr;
406 {
407 unsigned int word_offset;
408
409 switch (regno)
410 {
411 case PSR_REGNUM:
412 word_offset = R_EPSR;
413 break;
414 case FPSR_REGNUM:
415 word_offset = R_FPSR;
416 break;
417 case FPCR_REGNUM:
418 word_offset = R_FPCR;
419 break;
420 case SXIP_REGNUM:
421 word_offset = R_EXIP;
422 break;
423 case SNIP_REGNUM:
424 word_offset = R_ENIP;
425 break;
426 case SFIP_REGNUM:
427 word_offset = R_EFIP;
428 break;
429 default:
430 if (regno <= FP_REGNUM)
431 word_offset = regno;
432 else
433 word_offset = ((regno - X0_REGNUM) * 4);
434 }
435 return (word_offset * 4);
436 }
437
438 #endif /* _ES_MP */
439
440 void
441 _initialize_m88k_nat()
442 {
443 #ifdef _ES_MP
444 /* Enable 88110 support, as we don't support the 88100 under ES/MP. */
445
446 target_is_m88110 = 1;
447 #elif defined(_CX_UX)
448 /* Determine whether we're running on an 88100 or an 88110. */
449 target_is_m88110 = (sinfo(SYSMACHINE,0) == SYS5800);
450 #endif /* _CX_UX */
451 }
452
453 #ifdef _ES_MP
454 /* Given a pointer to a general register set in /proc format (gregset_t *),
455 unpack the register contents and supply them as gdb's idea of the current
456 register values. */
457
458 void
459 supply_gregset (gregsetp)
460 gregset_t *gregsetp;
461 {
462 register int regi;
463 register greg_t *regp = (greg_t *) gregsetp;
464
465 for (regi = 0 ; regi < R_R31 ; regi++)
466 {
467 supply_register (regi, (char *) (regp + regi));
468 }
469 supply_register (PSR_REGNUM, (char *) (regp + R_EPSR));
470 supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR));
471 supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR));
472 supply_register (SXIP_REGNUM, (char *) (regp + R_EXIP));
473 supply_register (SNIP_REGNUM, (char *) (regp + R_ENIP));
474 supply_register (SFIP_REGNUM, (char *) (regp + R_EFIP));
475 }
476
477 /* Given a pointer to a floating point register set in /proc format
478 (fpregset_t *), unpack the register contents and supply them as gdb's
479 idea of the current floating point register values. */
480
481 void
482 supply_fpregset (fpregsetp)
483 fpregset_t *fpregsetp;
484 {
485 register int regi;
486 char *from;
487
488 for (regi = FP0_REGNUM ; regi <= FPLAST_REGNUM ; regi++)
489 {
490 from = (char *) &((*fpregsetp)[regi-FP0_REGNUM]);
491 supply_register (regi, from);
492 }
493 }
494
495 #endif /* _ES_MP */
496
497 #ifdef _CX_UX
498
499 #include <sys/regset.h>
500
501 unsigned int m88k_harris_core_register_addr(int regno, int reg_ptr)
502 {
503 unsigned int word_offset;
504
505 switch (regno) {
506 case PSR_REGNUM : word_offset = R_PSR; break;
507 case FPSR_REGNUM : word_offset = R_FPSR; break;
508 case FPCR_REGNUM : word_offset = R_FPCR; break;
509 case SXIP_REGNUM : word_offset = R_XIP; break;
510 case SNIP_REGNUM : word_offset = R_NIP; break;
511 case SFIP_REGNUM : word_offset = R_FIP; break;
512 default :
513 if (regno <= FP_REGNUM)
514 word_offset = regno;
515 else
516 word_offset = ((regno - X0_REGNUM) * 4) + R_X0;
517 }
518 return (word_offset * 4);
519 }
520
521 #endif /* _CX_UX */
This page took 0.040729 seconds and 4 git commands to generate.