gdb-3.1
[deliverable/binutils-gdb.git] / gdb / RCS / default-dep.c,v
1 head 1.4;
2 access ;
3 symbols ;
4 locks ; strict;
5 comment @ * @;
6
7
8 1.4
9 date 89.03.27.20.08.50; author gnu; state Exp;
10 branches ;
11 next 1.3;
12
13 1.3
14 date 89.03.27.20.07.47; author gnu; state Exp;
15 branches ;
16 next 1.2;
17
18 1.2
19 date 89.03.27.18.49.06; author gnu; state Exp;
20 branches ;
21 next 1.1;
22
23 1.1
24 date 89.03.20.19.47.11; author gnu; state Exp;
25 branches ;
26 next ;
27
28
29 desc
30 @@
31
32
33 1.4
34 log
35 @Restore A/UX-specific changes.
36 @
37 text
38 @/* Low level interface to ptrace, for GDB when running under Unix.
39 Copyright (C) 1988 Free Software Foundation, Inc.
40
41 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
42 WARRANTY. No author or distributor accepts responsibility to anyone
43 for the consequences of using it or for whether it serves any
44 particular purpose or works at all, unless he says so in writing.
45 Refer to the GDB General Public License for full details.
46
47 Everyone is granted permission to copy, modify and redistribute GDB,
48 but only under the conditions described in the GDB General Public
49 License. A copy of this license is supposed to have been given to you
50 along with GDB so you can know your rights and responsibilities. It
51 should be in a file named COPYING. Among other things, the copyright
52 notice and this notice must be preserved on all copies.
53
54 In other words, go ahead and share GDB, but don't try to stop
55 anyone else from sharing it farther. Help stamp out software hoarding!
56 */
57
58 #include "defs.h"
59 #include "param.h"
60 #include "frame.h"
61 #include "inferior.h"
62
63 #ifdef USG
64 #include <sys/types.h>
65 #endif
66
67 #ifdef UNISOFT_ASSHOLES
68 #define PMMU
69 #define NEW_PMMU
70 #define mc68881 /* Needed to get float in user.h!!! */
71 #include <sys/seg.h> /* For user.h */
72 #include <sys/mmu.h>
73 #include <sys/time.h>
74 /* Things Unisoft defined differently from every other Unix system */
75 #define NBPG PAGESIZE
76 #define UPAGES USIZE
77 #define KERNEL_U_ADDR UDOT
78 #endif
79
80 #include <stdio.h>
81 #include <sys/param.h>
82 #include <sys/dir.h>
83 #include <signal.h>
84 #include <sys/ioctl.h>
85 #include <fcntl.h>
86
87 #ifdef COFF_ENCAPSULATE
88 #include "a.out.encap.h"
89 #else
90 #include <a.out.h>
91 #endif
92 #ifndef N_SET_MAGIC
93 #define N_SET_MAGIC(exec, val) ((exec).a_magic = (val))
94 #endif
95
96 #include <sys/user.h> /* After a.out.h */
97 #include <sys/file.h>
98 #include <sys/stat.h>
99
100 extern int errno;
101 \f
102 /* This function simply calls ptrace with the given arguments.
103 It exists so that all calls to ptrace are isolated in this
104 machine-dependent file.
105
106 If you are having trouble debugging ptrace calls, turn on DEBUG
107 and every call to ptrace, in this module or elsewhere, will be
108 logged to stderr. */
109 int
110 call_ptrace (request, pid, arg3, arg4)
111 int request, pid, arg3, arg4;
112 {
113 #ifdef DEBUG
114 int result;
115
116 fprintf(stderr, "ptrace(%x,,%x, %x) = ", request, arg3, arg4);
117 result=ptrace (request, pid, arg3, arg4);
118 fprintf(stderr, "%x\n", result);
119 return result;
120
121 #define ptrace call_ptrace
122
123 #else
124 return ptrace (request, pid, arg3, arg4);
125 #endif
126 }
127
128 kill_inferior ()
129 {
130 if (remote_debugging)
131 return;
132 if (inferior_pid == 0)
133 return;
134 ptrace (8, inferior_pid, 0, 0);
135 wait (0);
136 inferior_died ();
137 }
138
139 /* This is used when GDB is exiting. It gives less chance of error.*/
140
141 kill_inferior_fast ()
142 {
143 if (remote_debugging)
144 return;
145 if (inferior_pid == 0)
146 return;
147 ptrace (8, inferior_pid, 0, 0);
148 wait (0);
149 }
150
151 /* Resume execution of the inferior process.
152 If STEP is nonzero, single-step it.
153 If SIGNAL is nonzero, give it that signal. */
154
155 void
156 resume (step, signal)
157 int step;
158 int signal;
159 {
160 errno = 0;
161 if (remote_debugging)
162 remote_resume (step, signal);
163 else
164 {
165 ptrace (step ? 9 : 7, inferior_pid, 1, signal);
166 if (errno)
167 perror_with_name ("ptrace");
168 }
169 }
170 \f
171 void
172 fetch_inferior_registers ()
173 {
174 register int regno;
175 register unsigned int regaddr;
176 char buf[MAX_REGISTER_RAW_SIZE];
177 register int i;
178
179 struct user u;
180 unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
181 offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR;
182
183 for (regno = 0; regno < NUM_REGS; regno++)
184 {
185 regaddr = register_addr (regno, offset);
186 for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
187 {
188 *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0);
189 regaddr += sizeof (int);
190 }
191 supply_register (regno, buf);
192 }
193 }
194
195 /* Store our register values back into the inferior.
196 If REGNO is -1, do this for all registers.
197 Otherwise, REGNO specifies which register (so we can save time). */
198
199 store_inferior_registers (regno)
200 int regno;
201 {
202 register unsigned int regaddr;
203 char buf[80];
204
205 struct user u;
206 unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
207 offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR;
208
209 if (regno >= 0)
210 {
211 regaddr = register_addr (regno, offset);
212 errno = 0;
213 #ifdef UNISOFT_ASSHOLES
214 /* You can't write the PC with ptrace 6, only with ptrace 11! */
215 if (regno == PC_REGNUM)
216 ptrace(11, inferior_pid, 16, read_register(regno));
217 else
218 #endif
219 ptrace (6, inferior_pid, regaddr, read_register (regno));
220 if (errno != 0)
221 {
222 sprintf (buf, "writing register number %d", regno);
223 perror_with_name (buf);
224 }
225 }
226 else for (regno = 0; regno < NUM_REGS; regno++)
227 {
228 regaddr = register_addr (regno, offset);
229 errno = 0;
230 #ifdef UNISOFT_ASSHOLES
231 if (regno == PC_REGNUM)
232 ptrace(11, inferior_pid, 16, read_register(regno));
233 else
234 #endif
235 ptrace (6, inferior_pid, regaddr, read_register (regno));
236 if (errno != 0)
237 {
238 sprintf (buf, "writing all regs, number %d", regno);
239 perror_with_name (buf);
240 }
241 }
242 }
243 \f
244 /* Copy LEN bytes from inferior's memory starting at MEMADDR
245 to debugger memory starting at MYADDR.
246 On failure (cannot read from inferior, usually because address is out
247 of bounds) returns the value of errno. */
248
249 int
250 read_inferior_memory (memaddr, myaddr, len)
251 CORE_ADDR memaddr;
252 char *myaddr;
253 int len;
254 {
255 register int i;
256 /* Round starting address down to longword boundary. */
257 register CORE_ADDR addr = memaddr & - sizeof (int);
258 /* Round ending address up; get number of longwords that makes. */
259 register int count
260 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
261 /* Allocate buffer of that many longwords. */
262 register int *buffer = (int *) alloca (count * sizeof (int));
263 extern int errno;
264
265 /* Read all the longwords */
266 for (i = 0; i < count; i++, addr += sizeof (int))
267 {
268 errno = 0;
269 if (remote_debugging)
270 buffer[i] = remote_fetch_word (addr);
271 else
272 buffer[i] = ptrace (1, inferior_pid, addr, 0);
273 if (errno)
274 return errno;
275 }
276
277 /* Copy appropriate bytes out of the buffer. */
278 bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
279 return 0;
280 }
281
282 /* Copy LEN bytes of data from debugger memory at MYADDR
283 to inferior's memory at MEMADDR.
284 On failure (cannot write the inferior)
285 returns the value of errno. */
286
287 int
288 write_inferior_memory (memaddr, myaddr, len)
289 CORE_ADDR memaddr;
290 char *myaddr;
291 int len;
292 {
293 register int i;
294 /* Round starting address down to longword boundary. */
295 register CORE_ADDR addr = memaddr & - sizeof (int);
296 /* Round ending address up; get number of longwords that makes. */
297 register int count
298 = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
299 /* Allocate buffer of that many longwords. */
300 register int *buffer = (int *) alloca (count * sizeof (int));
301 extern int errno;
302
303 /* Fill start and end extra bytes of buffer with existing memory data. */
304
305 if (remote_debugging)
306 buffer[0] = remote_fetch_word (addr);
307 else
308 buffer[0] = ptrace (1, inferior_pid, addr, 0);
309
310 if (count > 1)
311 {
312 if (remote_debugging)
313 buffer[count - 1]
314 = remote_fetch_word (addr + (count - 1) * sizeof (int));
315 else
316 buffer[count - 1]
317 = ptrace (1, inferior_pid,
318 addr + (count - 1) * sizeof (int), 0);
319 }
320
321 /* Copy data to be written over corresponding part of buffer */
322
323 bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
324
325 /* Write the entire buffer. */
326
327 for (i = 0; i < count; i++, addr += sizeof (int))
328 {
329 errno = 0;
330 if (remote_debugging)
331 remote_store_word (addr, buffer[i]);
332 else
333 ptrace (4, inferior_pid, addr, buffer[i]);
334 if (errno)
335 return errno;
336 }
337
338 return 0;
339 }
340 \f
341 /* Work with core dump and executable files, for GDB.
342 This code would be in core.c if it weren't machine-dependent. */
343
344 /* Recognize COFF format systems because a.out.h defines AOUTHDR. */
345 #ifdef AOUTHDR
346 #define COFF_FORMAT
347 #endif
348
349 #ifndef N_TXTADDR
350 #define N_TXTADDR(hdr) 0
351 #endif /* no N_TXTADDR */
352
353 #ifndef N_DATADDR
354 #define N_DATADDR(hdr) hdr.a_text
355 #endif /* no N_DATADDR */
356
357 /* Make COFF and non-COFF names for things a little more compatible
358 to reduce conditionals later. */
359
360 #ifdef COFF_FORMAT
361 #define a_magic magic
362 #endif
363
364 #ifndef COFF_FORMAT
365 #define AOUTHDR struct exec
366 #endif
367
368 extern char *sys_siglist[];
369
370
371 /* Hook for `exec_file_command' command to call. */
372
373 extern void (*exec_file_display_hook) ();
374
375 /* File names of core file and executable file. */
376
377 extern char *corefile;
378 extern char *execfile;
379
380 /* Descriptors on which core file and executable file are open.
381 Note that the execchan is closed when an inferior is created
382 and reopened if the inferior dies or is killed. */
383
384 extern int corechan;
385 extern int execchan;
386
387 /* Last modification time of executable file.
388 Also used in source.c to compare against mtime of a source file. */
389
390 extern int exec_mtime;
391
392 /* Virtual addresses of bounds of the two areas of memory in the core file. */
393
394 extern CORE_ADDR data_start;
395 extern CORE_ADDR data_end;
396 extern CORE_ADDR stack_start;
397 extern CORE_ADDR stack_end;
398
399 /* Virtual addresses of bounds of two areas of memory in the exec file.
400 Note that the data area in the exec file is used only when there is no core file. */
401
402 extern CORE_ADDR text_start;
403 extern CORE_ADDR text_end;
404
405 extern CORE_ADDR exec_data_start;
406 extern CORE_ADDR exec_data_end;
407
408 /* Address in executable file of start of text area data. */
409
410 extern int text_offset;
411
412 /* Address in executable file of start of data area data. */
413
414 extern int exec_data_offset;
415
416 /* Address in core file of start of data area data. */
417
418 extern int data_offset;
419
420 /* Address in core file of start of stack area data. */
421
422 extern int stack_offset;
423
424 #ifdef COFF_FORMAT
425 /* various coff data structures */
426
427 extern FILHDR file_hdr;
428 extern SCNHDR text_hdr;
429 extern SCNHDR data_hdr;
430
431 #endif /* not COFF_FORMAT */
432
433 /* a.out header saved in core file. */
434
435 extern AOUTHDR core_aouthdr;
436
437 /* a.out header of exec file. */
438
439 extern AOUTHDR exec_aouthdr;
440
441 extern void validate_files ();
442 \f
443 core_file_command (filename, from_tty)
444 char *filename;
445 int from_tty;
446 {
447 int val;
448 extern char registers[];
449
450 /* Discard all vestiges of any previous core file
451 and mark data and stack spaces as empty. */
452
453 if (corefile)
454 free (corefile);
455 corefile = 0;
456
457 if (corechan >= 0)
458 close (corechan);
459 corechan = -1;
460
461 data_start = 0;
462 data_end = 0;
463 stack_start = STACK_END_ADDR;
464 stack_end = STACK_END_ADDR;
465
466 /* Now, if a new core file was specified, open it and digest it. */
467
468 if (filename)
469 {
470 if (have_inferior_p ())
471 error ("To look at a core file, you must kill the inferior with \"kill\".");
472 corechan = open (filename, O_RDONLY, 0);
473 if (corechan < 0)
474 perror_with_name (filename);
475 /* 4.2-style (and perhaps also sysV-style) core dump file. */
476 {
477 struct user u;
478
479 int reg_offset;
480
481 val = myread (corechan, &u, sizeof u);
482 if (val < 0)
483 perror_with_name ("Not a core file: reading upage");
484 if (val != sizeof u)
485 error ("Not a core file: could only read %d bytes", val);
486 data_start = exec_data_start;
487
488 data_end = data_start + NBPG * u.u_dsize;
489 stack_start = stack_end - NBPG * u.u_ssize;
490 data_offset = NBPG * UPAGES;
491 stack_offset = NBPG * (UPAGES + u.u_dsize);
492
493 /* Some machines put an absolute address in here; Unisoft
494 seems to put the offset in the upage of the regs. Sigh. */
495 reg_offset = (int) u.u_ar0;
496 if (reg_offset > NBPG * UPAGES)
497 reg_offset -= KERNEL_U_ADDR;
498
499 /* I don't know where to find this info.
500 So, for now, mark it as not available. */
501 N_SET_MAGIC (core_aouthdr, 0);
502
503 /* Read the register values out of the core file and store
504 them where `read_register' will find them. */
505
506 {
507 register int regno;
508
509 for (regno = 0; regno < NUM_REGS; regno++)
510 {
511 char buf[MAX_REGISTER_RAW_SIZE];
512
513 val = lseek (corechan, register_addr (regno, reg_offset), 0);
514 if (val < 0)
515 perror_with_name (reg_names[regno]);
516
517 val = myread (corechan, buf, sizeof buf);
518 if (val < 0)
519 perror_with_name (reg_names[regno]);
520 supply_register (regno, buf);
521 }
522 }
523 }
524 if (filename[0] == '/')
525 corefile = savestring (filename, strlen (filename));
526 else
527 {
528 corefile = concat (current_directory, "/", filename);
529 }
530
531 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
532 read_pc ()));
533 select_frame (get_current_frame (), 0);
534 validate_files ();
535 }
536 else if (from_tty)
537 printf ("No core file now.\n");
538 }
539 \f
540 exec_file_command (filename, from_tty)
541 char *filename;
542 int from_tty;
543 {
544 int val;
545
546 /* Eliminate all traces of old exec file.
547 Mark text segment as empty. */
548
549 if (execfile)
550 free (execfile);
551 execfile = 0;
552 data_start = 0;
553 data_end -= exec_data_start;
554 text_start = 0;
555 text_end = 0;
556 exec_data_start = 0;
557 exec_data_end = 0;
558 if (execchan >= 0)
559 close (execchan);
560 execchan = -1;
561
562 /* Now open and digest the file the user requested, if any. */
563
564 if (filename)
565 {
566 execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
567 &execfile);
568 if (execchan < 0)
569 perror_with_name (filename);
570
571 #ifdef COFF_FORMAT
572 {
573 int aout_hdrsize;
574 int num_sections;
575
576 if (read_file_hdr (execchan, &file_hdr) < 0)
577 error ("\"%s\": not in executable format.", execfile);
578
579 aout_hdrsize = file_hdr.f_opthdr;
580 num_sections = file_hdr.f_nscns;
581
582 if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0)
583 error ("\"%s\": can't read optional aouthdr", execfile);
584
585 if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections) < 0)
586 error ("\"%s\": can't read text section header", execfile);
587
588 if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
589 error ("\"%s\": can't read data section header", execfile);
590
591 text_start = exec_aouthdr.text_start;
592 text_end = text_start + exec_aouthdr.tsize;
593 text_offset = text_hdr.s_scnptr;
594 exec_data_start = exec_aouthdr.data_start;
595 exec_data_end = exec_data_start + exec_aouthdr.dsize;
596 exec_data_offset = data_hdr.s_scnptr;
597 data_start = exec_data_start;
598 data_end += exec_data_start;
599 exec_mtime = file_hdr.f_timdat;
600 }
601 #else /* not COFF_FORMAT */
602 {
603 struct stat st_exec;
604
605 #ifdef HEADER_SEEK_FD
606 HEADER_SEEK_FD (execchan);
607 #endif
608
609 val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
610
611 if (val < 0)
612 perror_with_name (filename);
613
614 text_start = N_TXTADDR (exec_aouthdr);
615 exec_data_start = N_DATADDR (exec_aouthdr);
616
617 text_offset = N_TXTOFF (exec_aouthdr);
618 exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
619
620 text_end = text_start + exec_aouthdr.a_text;
621 exec_data_end = exec_data_start + exec_aouthdr.a_data;
622 data_start = exec_data_start;
623 data_end += exec_data_start;
624
625 fstat (execchan, &st_exec);
626 exec_mtime = st_exec.st_mtime;
627 }
628 #endif /* not COFF_FORMAT */
629
630 validate_files ();
631 }
632 else if (from_tty)
633 printf ("No exec file now.\n");
634
635 /* Tell display code (if any) about the changed file name. */
636 if (exec_file_display_hook)
637 (*exec_file_display_hook) (filename);
638 }
639 @
640
641
642 1.3
643 log
644 @Remove A/UX-specific changes for shipping to FSF.
645 @
646 text
647 @d30 13
648 d176 7
649 a182 1
650 ptrace (6, inferior_pid, regaddr, read_register (regno));
651 d193 6
652 a198 1
653 ptrace (6, inferior_pid, regaddr, read_register (regno));
654 @
655
656
657 1.2
658 log
659 @A/UX and USG changes, and a little better error reporting.
660 @
661 text
662 @a29 13
663 #ifdef UNISOFT_ASSHOLES
664 #define PMMU
665 #define NEW_PMMU
666 #define mc68881 /* Needed to get float in user.h!!! */
667 #include <sys/seg.h> /* For user.h */
668 #include <sys/mmu.h>
669 #include <sys/time.h>
670 /* Things Unisoft defined differently from every other Unix system */
671 #define NBPG PAGESIZE
672 #define UPAGES USIZE
673 #define KERNEL_U_ADDR UDOT
674 #endif
675
676 d163 1
677 a163 7
678 #ifdef UNISOFT_ASSHOLES
679 /* You can't write the PC with ptrace 6, only with ptrace 11! */
680 if (regno == PC_REGNUM)
681 ptrace(11, inferior_pid, 16, read_register(regno));
682 else
683 #endif
684 ptrace (6, inferior_pid, regaddr, read_register (regno));
685 d174 1
686 a174 6
687 #ifdef UNISOFT_ASSHOLES
688 if (regno == PC_REGNUM)
689 ptrace(11, inferior_pid, 16, read_register(regno));
690 else
691 #endif
692 ptrace (6, inferior_pid, regaddr, read_register (regno));
693 @
694
695
696 1.1
697 log
698 @Initial revision
699 @
700 text
701 @d30 13
702 a46 1
703 #include <sys/user.h>
704 d58 2
705 d67 5
706 a71 1
707 machine-dependent file. */
708 d76 11
709 d88 1
710 d176 7
711 a182 1
712 ptrace (6, inferior_pid, regaddr, read_register (regno));
713 d193 6
714 a198 1
715 ptrace (6, inferior_pid, regaddr, read_register (regno));
716 d201 1
717 a201 1
718 sprintf (buf, "writing register number %d", regno);
719 d446 3
720 a448 1
721 perror_with_name (filename);
722 d455 6
723 a460 1
724 reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
725 d478 1
726 a478 1
727 perror_with_name (filename);
728 d482 1
729 a482 1
730 perror_with_name (filename);
731 @
This page took 0.060653 seconds and 4 git commands to generate.