]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/sun3-dep.c
gdb-3.5
[thirdparty/binutils-gdb.git] / gdb / sun3-dep.c
CommitLineData
e91b87a3 1/* Machine-dependent code which would otherwise be in inflow.c and core.c,
2 for GDB, the GNU debugger.
4187119d 3 Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
e91b87a3 4
4187119d 5This file is part of GDB.
e91b87a3 6
4187119d 7GDB is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 1, or (at your option)
10any later version.
e91b87a3 11
4187119d 12GDB is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GDB; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
e91b87a3 20
7a67dd45 21#include <stdio.h>
e91b87a3 22#include "defs.h"
23#include "param.h"
24#include "frame.h"
25#include "inferior.h"
26
e91b87a3 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 <machine/reg.h>
36
37#include <a.out.h>
38#include <sys/file.h>
39#include <sys/stat.h>
40#include <sys/core.h>
41
42extern int errno;
43extern int attach_flag;
44\f
45/* This function simply calls ptrace with the given arguments.
46 It exists so that all calls to ptrace are isolated in this
47 machine-dependent file. */
48int
49call_ptrace (request, pid, arg3, arg4)
50 int request, pid, arg3, arg4;
51{
52 return ptrace (request, pid, arg3, arg4);
53}
54
55kill_inferior ()
56{
57 if (remote_debugging)
58 return;
59 if (inferior_pid == 0)
60 return;
61 ptrace (8, inferior_pid, 0, 0);
62 wait (0);
63 inferior_died ();
64}
65
66/* This is used when GDB is exiting. It gives less chance of error.*/
67
68kill_inferior_fast ()
69{
70 if (remote_debugging)
71 return;
72 if (inferior_pid == 0)
73 return;
74 ptrace (8, inferior_pid, 0, 0);
75 wait (0);
76}
77
78/* Resume execution of the inferior process.
79 If STEP is nonzero, single-step it.
80 If SIGNAL is nonzero, give it that signal. */
81
82void
83resume (step, signal)
84 int step;
85 int signal;
86{
87 errno = 0;
88 if (remote_debugging)
89 remote_resume (step, signal);
90 else
91 {
92 ptrace (step ? 9 : 7, inferior_pid, 1, signal);
93 if (errno)
94 perror_with_name ("ptrace");
95 }
96}
97\f
98#ifdef ATTACH_DETACH
99
100/* Start debugging the process whose number is PID. */
101
102attach (pid)
103 int pid;
104{
105 errno = 0;
106 ptrace (PTRACE_ATTACH, pid, 0, 0);
107 if (errno)
108 perror_with_name ("ptrace");
109 attach_flag = 1;
110 return pid;
111}
112
113/* Stop debugging the process whose number is PID
114 and continue it with signal number SIGNAL.
115 SIGNAL = 0 means just continue it. */
116
117void
118detach (signal)
119 int signal;
120{
121 errno = 0;
122 ptrace (PTRACE_DETACH, inferior_pid, 1, signal);
123 if (errno)
124 perror_with_name ("ptrace");
125 attach_flag = 0;
126}
127#endif /* ATTACH_DETACH */
128\f
129void
130fetch_inferior_registers ()
131{
132 struct regs inferior_registers;
4187119d 133#ifdef FP0_REGNUM
e91b87a3 134 struct fp_status inferior_fp_registers;
4187119d 135#endif
e91b87a3 136 extern char registers[];
137
138 if (remote_debugging)
139 remote_fetch_registers (registers);
140 else
141 {
142 ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
4187119d 143#ifdef FP0_REGNUM
e91b87a3 144 ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
4187119d 145#endif
e91b87a3 146
147 bcopy (&inferior_registers, registers, 16 * 4);
4187119d 148#ifdef FP0_REGNUM
e91b87a3 149 bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
150 sizeof inferior_fp_registers.fps_regs);
4187119d 151#endif
e91b87a3 152 *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
153 *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
4187119d 154#ifdef FP0_REGNUM
e91b87a3 155 bcopy (&inferior_fp_registers.fps_control,
156 &registers[REGISTER_BYTE (FPC_REGNUM)],
157 sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
4187119d 158#endif
e91b87a3 159 }
160}
161
162/* Store our register values back into the inferior.
163 If REGNO is -1, do this for all registers.
164 Otherwise, REGNO specifies which register (so we can save time). */
165
166store_inferior_registers (regno)
167 int regno;
168{
169 struct regs inferior_registers;
170 struct fp_status inferior_fp_registers;
171 extern char registers[];
172
173 if (remote_debugging)
174 remote_store_registers (registers);
175 else
176 {
177 bcopy (registers, &inferior_registers, 16 * 4);
7a67dd45 178#ifdef FP0_REGNUM
e91b87a3 179 bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
180 sizeof inferior_fp_registers.fps_regs);
7a67dd45 181#endif
e91b87a3 182 inferior_registers.r_ps = *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
183 inferior_registers.r_pc = *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
7a67dd45 184
185#ifdef FP0_REGNUM
e91b87a3 186 bcopy (&registers[REGISTER_BYTE (FPC_REGNUM)],
187 &inferior_fp_registers.fps_control,
188 sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
7a67dd45 189#endif
e91b87a3 190
191 ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
7a67dd45 192#if FP0_REGNUM
e91b87a3 193 ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
7a67dd45 194#endif
e91b87a3 195 }
196}
197\f
198/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
199 in the NEW_SUN_PTRACE case.
200 It ought to be straightforward. But it appears that writing did
201 not write the data that I specified. I cannot understand where
202 it got the data that it actually did write. */
203
204/* Copy LEN bytes from inferior's memory starting at MEMADDR
205 to debugger memory starting at MYADDR.
206 On failure (cannot read from inferior, usually because address is out
207 of bounds) returns the value of errno. */
208
209int
210read_inferior_memory (memaddr, myaddr, len)
211 CORE_ADDR memaddr;
212 char *myaddr;
213 int len;
214{
215 register int i;
216 /* Round starting address down to longword boundary. */
217 register CORE_ADDR addr = memaddr & - sizeof (int);
218 /* Round ending address up; get number of longwords that makes. */
219 register int count
220 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
221 /* Allocate buffer of that many longwords. */
222 register int *buffer = (int *) alloca (count * sizeof (int));
223 extern int errno;
224
225 /* Read all the longwords */
226 for (i = 0; i < count; i++, addr += sizeof (int))
227 {
228 errno = 0;
229 if (remote_debugging)
230 buffer[i] = remote_fetch_word (addr);
231 else
232 buffer[i] = ptrace (1, inferior_pid, addr, 0);
233 if (errno)
234 return errno;
235 }
236
237 /* Copy appropriate bytes out of the buffer. */
238 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
239 return 0;
240}
241
242/* Copy LEN bytes of data from debugger memory at MYADDR
243 to inferior's memory at MEMADDR.
244 On failure (cannot write the inferior)
245 returns the value of errno. */
246
247int
248write_inferior_memory (memaddr, myaddr, len)
249 CORE_ADDR memaddr;
250 char *myaddr;
251 int len;
252{
253 register int i;
254 /* Round starting address down to longword boundary. */
255 register CORE_ADDR addr = memaddr & - sizeof (int);
256 /* Round ending address up; get number of longwords that makes. */
257 register int count
258 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
259 /* Allocate buffer of that many longwords. */
260 register int *buffer = (int *) alloca (count * sizeof (int));
261 extern int errno;
262
263 /* Fill start and end extra bytes of buffer with existing memory data. */
264
265 if (remote_debugging)
266 buffer[0] = remote_fetch_word (addr);
267 else
268 buffer[0] = ptrace (1, inferior_pid, addr, 0);
269
270 if (count > 1)
271 {
272 if (remote_debugging)
273 buffer[count - 1]
274 = remote_fetch_word (addr + (count - 1) * sizeof (int));
275 else
276 buffer[count - 1]
277 = ptrace (1, inferior_pid,
278 addr + (count - 1) * sizeof (int), 0);
279 }
280
281 /* Copy data to be written over corresponding part of buffer */
282
283 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
284
285 /* Write the entire buffer. */
286
287 for (i = 0; i < count; i++, addr += sizeof (int))
288 {
289 errno = 0;
290 if (remote_debugging)
291 remote_store_word (addr, buffer[i]);
292 else
293 ptrace (4, inferior_pid, addr, buffer[i]);
294 if (errno)
295 return errno;
296 }
297
298 return 0;
299}
300
301\f
302/* Machine-dependent code which would otherwise be in core.c */
303/* Work with core dump and executable files, for GDB. */
304
e91b87a3 305#ifndef N_TXTADDR
306#define N_TXTADDR(hdr) 0
307#endif /* no N_TXTADDR */
308
309#ifndef N_DATADDR
310#define N_DATADDR(hdr) hdr.a_text
311#endif /* no N_DATADDR */
312
4187119d 313/* Non-zero if this is an object (.o) file, rather than an executable.
314 Distinguishing between the two is rarely necessary (and seems like
315 a hack, but there is no other way to get the text and data
316 addresses--N_TXTADDR should probably take care of
317 this, but it doesn't). */
318/* This definition will not work
319 if someone decides to make ld preserve relocation info. */
320#define IS_OBJECT_FILE(hdr) (hdr.a_trsize != 0)
321
e91b87a3 322/* Make COFF and non-COFF names for things a little more compatible
323 to reduce conditionals later. */
324
325#ifdef COFF_FORMAT
326#define a_magic magic
327#endif
328
329#ifndef COFF_FORMAT
4187119d 330#ifndef AOUTHDR
e91b87a3 331#define AOUTHDR struct exec
332#endif
4187119d 333#endif
e91b87a3 334
335extern char *sys_siglist[];
336
337/* Hook for `exec_file_command' command to call. */
338
339extern void (*exec_file_display_hook) ();
340
341/* File names of core file and executable file. */
342
343extern char *corefile;
344extern char *execfile;
345
346/* Descriptors on which core file and executable file are open.
347 Note that the execchan is closed when an inferior is created
348 and reopened if the inferior dies or is killed. */
349
350extern int corechan;
351extern int execchan;
352
353/* Last modification time of executable file.
354 Also used in source.c to compare against mtime of a source file. */
355
356extern int exec_mtime;
357
358/* Virtual addresses of bounds of the two areas of memory in the core file. */
359
360extern CORE_ADDR data_start;
361extern CORE_ADDR data_end;
362extern CORE_ADDR stack_start;
363extern CORE_ADDR stack_end;
364
365/* Virtual addresses of bounds of two areas of memory in the exec file.
366 Note that the data area in the exec file is used only when there is no core file. */
367
368extern CORE_ADDR text_start;
369extern CORE_ADDR text_end;
370
371extern CORE_ADDR exec_data_start;
372extern CORE_ADDR exec_data_end;
373
374/* Address in executable file of start of text area data. */
375
376extern int text_offset;
377
378/* Address in executable file of start of data area data. */
379
380extern int exec_data_offset;
381
382/* Address in core file of start of data area data. */
383
384extern int data_offset;
385
386/* Address in core file of start of stack area data. */
387
388extern int stack_offset;
389
390#ifdef COFF_FORMAT
391/* various coff data structures */
392
393extern FILHDR file_hdr;
394extern SCNHDR text_hdr;
395extern SCNHDR data_hdr;
396
397#endif /* not COFF_FORMAT */
398
399/* a.out header saved in core file. */
400
401extern AOUTHDR core_aouthdr;
402
403/* a.out header of exec file. */
404
405extern AOUTHDR exec_aouthdr;
406
407extern void validate_files ();
408\f
409core_file_command (filename, from_tty)
410 char *filename;
411 int from_tty;
412{
413 int val;
414 extern char registers[];
415
416 /* Discard all vestiges of any previous core file
417 and mark data and stack spaces as empty. */
418
419 if (corefile)
420 free (corefile);
421 corefile = 0;
422
423 if (corechan >= 0)
424 close (corechan);
425 corechan = -1;
426
427 data_start = 0;
428 data_end = 0;
429 stack_start = STACK_END_ADDR;
430 stack_end = STACK_END_ADDR;
431
432 /* Now, if a new core file was specified, open it and digest it. */
433
434 if (filename)
435 {
4187119d 436 filename = tilde_expand (filename);
437 make_cleanup (free, filename);
438
e91b87a3 439 if (have_inferior_p ())
440 error ("To look at a core file, you must kill the inferior with \"kill\".");
441 corechan = open (filename, O_RDONLY, 0);
442 if (corechan < 0)
443 perror_with_name (filename);
444
445 {
446 struct core corestr;
447
448 val = myread (corechan, &corestr, sizeof corestr);
449 if (val < 0)
450 perror_with_name (filename);
451 if (corestr.c_magic != CORE_MAGIC)
452 error ("\"%s\" does not appear to be a core dump file (magic 0x%x, expected 0x%x)",
453 filename, corestr.c_magic, (int) CORE_MAGIC);
454 else if (sizeof (struct core) != corestr.c_len)
455 error ("\"%s\" has an invalid struct core length (%d, expected %d)",
456 filename, corestr.c_len, (int) sizeof (struct core));
457
458 data_start = exec_data_start;
459 data_end = data_start + corestr.c_dsize;
460 stack_start = stack_end - corestr.c_ssize;
461 data_offset = sizeof corestr;
462 stack_offset = sizeof corestr + corestr.c_dsize;
463
464 bcopy (&corestr.c_regs, registers, 16 * 4);
465 *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = corestr.c_regs.r_ps;
466 *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = corestr.c_regs.r_pc;
4187119d 467#ifdef FP0_REGNUM
e91b87a3 468#ifdef FPU
469 bcopy (corestr.c_fpu.f_fpstatus.fps_regs,
470 &registers[REGISTER_BYTE (FP0_REGNUM)],
471 sizeof corestr.c_fpu.f_fpstatus.fps_regs);
472 bcopy (&corestr.c_fpu.f_fpstatus.fps_control,
473 &registers[REGISTER_BYTE (FPC_REGNUM)],
474 sizeof corestr.c_fpu.f_fpstatus - sizeof corestr.c_fpu.f_fpstatus.fps_regs);
475#else
476 bcopy (corestr.c_fpstatus.fps_regs,
477 &registers[REGISTER_BYTE (FP0_REGNUM)],
478 sizeof corestr.c_fpstatus.fps_regs);
479 bcopy (&corestr.c_fpstatus.fps_control,
480 &registers[REGISTER_BYTE (FPC_REGNUM)],
481 sizeof corestr.c_fpstatus - sizeof corestr.c_fpstatus.fps_regs);
4187119d 482#endif
e91b87a3 483#endif
484 bcopy (&corestr.c_aouthdr, &core_aouthdr, sizeof (struct exec));
485
486 printf ("Core file is from \"%s\".\n", corestr.c_cmdname);
487 if (corestr.c_signo > 0)
488 printf ("Program terminated with signal %d, %s.\n",
489 corestr.c_signo,
490 corestr.c_signo < NSIG
491 ? sys_siglist[corestr.c_signo]
492 : "(undocumented)");
493 }
494 if (filename[0] == '/')
495 corefile = savestring (filename, strlen (filename));
496 else
497 {
498 corefile = concat (current_directory, "/", filename);
499 }
500
501 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
502 read_pc ()));
503 select_frame (get_current_frame (), 0);
504 validate_files ();
505 }
506 else if (from_tty)
507 printf ("No core file now.\n");
508}
509\f
510exec_file_command (filename, from_tty)
511 char *filename;
512 int from_tty;
513{
514 int val;
515
516 /* Eliminate all traces of old exec file.
517 Mark text segment as empty. */
518
519 if (execfile)
520 free (execfile);
521 execfile = 0;
522 data_start = 0;
523 data_end -= exec_data_start;
524 text_start = 0;
525 text_end = 0;
526 exec_data_start = 0;
527 exec_data_end = 0;
528 if (execchan >= 0)
529 close (execchan);
530 execchan = -1;
531
532 /* Now open and digest the file the user requested, if any. */
533
534 if (filename)
535 {
4187119d 536 filename = tilde_expand (filename);
537 make_cleanup (free, filename);
538
e91b87a3 539 execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
540 &execfile);
541 if (execchan < 0)
542 perror_with_name (filename);
543
544#ifdef COFF_FORMAT
545 {
546 int aout_hdrsize;
547 int num_sections;
548
549 if (read_file_hdr (execchan, &file_hdr) < 0)
550 error ("\"%s\": not in executable format.", execfile);
551
552 aout_hdrsize = file_hdr.f_opthdr;
553 num_sections = file_hdr.f_nscns;
554
555 if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0)
556 error ("\"%s\": can't read optional aouthdr", execfile);
557
7a67dd45 558 if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
559 aout_hdrsize) < 0)
e91b87a3 560 error ("\"%s\": can't read text section header", execfile);
561
7a67dd45 562 if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
563 aout_hdrsize) < 0)
e91b87a3 564 error ("\"%s\": can't read data section header", execfile);
565
566 text_start = exec_aouthdr.text_start;
567 text_end = text_start + exec_aouthdr.tsize;
568 text_offset = text_hdr.s_scnptr;
569 exec_data_start = exec_aouthdr.data_start;
570 exec_data_end = exec_data_start + exec_aouthdr.dsize;
571 exec_data_offset = data_hdr.s_scnptr;
572 data_start = exec_data_start;
573 data_end += exec_data_start;
574 exec_mtime = file_hdr.f_timdat;
575 }
576#else /* not COFF_FORMAT */
577 {
578 struct stat st_exec;
579 val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
580
581 if (val < 0)
582 perror_with_name (filename);
583
4187119d 584 text_start =
585 IS_OBJECT_FILE (exec_aouthdr) ? 0 : N_TXTADDR (exec_aouthdr);
586 exec_data_start = IS_OBJECT_FILE (exec_aouthdr)
587 ? exec_aouthdr.a_text : N_DATADDR (exec_aouthdr);
e91b87a3 588 text_offset = N_TXTOFF (exec_aouthdr);
589 exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
590
591 text_end = text_start + exec_aouthdr.a_text;
592 exec_data_end = exec_data_start + exec_aouthdr.a_data;
593 data_start = exec_data_start;
594 data_end += exec_data_start;
595
596 fstat (execchan, &st_exec);
597 exec_mtime = st_exec.st_mtime;
598 }
599#endif /* not COFF_FORMAT */
600
601 validate_files ();
602 }
603 else if (from_tty)
604 printf ("No exec file now.\n");
605
606 /* Tell display code (if any) about the changed file name. */
607 if (exec_file_display_hook)
608 (*exec_file_display_hook) (filename);
609}
610