* tm-hppa.h: New file, architectural definition of HP PA.
[binutils-gdb.git] / gdb / hppabsd-core.c
1 /* Machine-dependent code which would otherwise be in core.c
2 for GDB, the GNU debugger. This code is for the HP PA-RISC cpu.
3 Copyright 1986, 1987, 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
4
5 Contributed by the Center for Software Science at the
6 University of Utah (pa-gdb-bugs@cs.utah.edu).
7
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23
24 #include "defs.h"
25 #include "param.h"
26 #include "frame.h"
27 #include "inferior.h"
28
29 #ifdef USG
30 #include <sys/types.h>
31 #endif
32
33 #include <sys/param.h>
34 #include <sys/dir.h>
35 #include <signal.h>
36 #include <sys/ioctl.h>
37 /* #include <fcntl.h> Can we live without this? */
38
39 #ifndef hpux
40 #include <a.out.h>
41 #include <machine/pcb.h>
42 #include <sys/time.h>
43 #include "/usr/src/sys/hpux/hpux.h"
44 #define USRSTACK 0x68FF3000
45 #else
46 #include <sys/user.h> /* After a.out.h */
47 #endif
48
49 #include <sys/file.h>
50 #include <sys/stat.h>
51 #include <sys/ptrace.h>
52
53 #ifndef hpux
54 #undef USIZE
55 #undef UPAGES
56
57 #define USIZE 3
58 #define UPAGES 7
59 #endif
60
61 extern int errno;
62
63 /* File names of core file and executable file. */
64
65 extern char *corefile;
66 extern char *execfile;
67
68 /* Descriptors on which core file and executable file are open.
69 Note that the execchan is closed when an inferior is created
70 and reopened if the inferior dies or is killed. */
71
72 extern int corechan;
73 extern int execchan;
74
75 /* Last modification time of executable file.
76 Also used in source.c to compare against mtime of a source file. */
77
78 extern int exec_mtime;
79
80 /* Virtual addresses of bounds of the two areas of memory in the core file. */
81
82 extern CORE_ADDR data_start;
83 extern CORE_ADDR data_end;
84 extern CORE_ADDR stack_start;
85 extern CORE_ADDR stack_end;
86
87 /* Virtual addresses of bounds of two areas of memory in the exec file.
88 Note that the data area in the exec file is used only when there is no core file. */
89
90 extern CORE_ADDR text_start;
91 extern CORE_ADDR text_end;
92
93 extern CORE_ADDR exec_data_start;
94 extern CORE_ADDR exec_data_end;
95
96 /* Address in executable file of start of text area data. */
97
98 extern int text_offset;
99
100 /* Address in executable file of start of data area data. */
101
102 extern int exec_data_offset;
103
104 /* Address in core file of start of data area data. */
105
106 extern int data_offset;
107
108 /* Address in core file of start of stack area data. */
109
110 extern int stack_offset;
111
112 extern struct header file_hdr;
113 extern struct som_exec_auxhdr exec_hdr;
114
115 extern int (*core_file_hook)();
116
117 #ifdef KERNELDEBUG
118
119 extern int kernel_debugging;
120 extern int kernel_core_file_hook();
121
122 #endif
123
124 core_file_command (filename, from_tty)
125 char *filename;
126 int from_tty;
127 {
128 int val;
129 extern char registers[];
130 #ifdef KERNELDEBUG
131 struct stat stb;
132 #endif
133
134 /* Discard all vestiges of any previous core file
135 and mark data and stack spaces as empty. */
136
137 if (corefile)
138 free (corefile);
139 corefile = 0;
140 core_file_hook = 0;
141
142 if (corechan >= 0)
143 close (corechan);
144 corechan = -1;
145
146 data_start = 0;
147 data_end = 0;
148 stack_start = STACK_END_ADDR;
149 stack_end = STACK_END_ADDR;
150
151 /* Now, if a new core file was specified, open it and digest it. */
152
153 if (filename)
154 {
155 filename = tilde_expand (filename);
156 make_cleanup (free, filename);
157
158 if (have_inferior_p ())
159 error ("To look at a core file, you must kill the inferior with \"kill\".");
160 corechan = open (filename, O_RDONLY, 0);
161 if (corechan < 0)
162 perror_with_name (filename);
163
164 #ifdef KERNELDEBUG
165 fstat(corechan, &stb);
166
167 if (kernel_debugging) {
168 setup_kernel_debugging();
169 core_file_hook = kernel_core_file_hook;
170 set_kernel_boundaries();
171 } else if ((stb.st_mode & S_IFMT) == S_IFCHR &&
172 stb.st_rdev == makedev(2, 1)) {
173 /* looking at /dev/kmem */
174 data_offset = data_start = KERNBASE;
175 data_end = ~0; /* XXX */
176 stack_end = stack_start = data_end;
177 set_kernel_boundaries();
178 } else
179 #endif
180 {
181 /* HP PA-RISC style corefile. */
182 #ifndef hpux
183 struct hpuxuser u;
184 #else
185 struct user u;
186 #endif
187
188 unsigned int reg_offset;
189
190 val = myread (corechan, &u, sizeof u);
191 if (val < 0)
192 perror_with_name ("Not a core file: reading upage");
193 if (val != sizeof u)
194 error ("Not a core file: could only read %d bytes", val);
195
196 /* We are depending on exec_file_command having been called
197 previously to set exec_data_start. Since the executable
198 and the core file share the same text segment, the address
199 of the data segment will be the same in both. */
200 data_start = exec_data_start;
201
202 data_end = data_start + NBPG * u.u_dsize;
203 stack_start = USRSTACK; /* from sys/param.h */
204 stack_end = stack_start + NBPG * u.u_ssize;
205 data_offset = NBPG * UPAGES;
206 stack_offset = NBPG * (UPAGES + u.u_dsize);
207
208 /* Some machines put an absolute address in here and some put
209 the offset in the upage of the regs. */
210 reg_offset = NBPG * USIZE;
211 /* Read the register values out of the core file and store
212 them where `read_register' will find them. */
213
214 {
215 register int regno;
216
217 for (regno = 0; regno < NUM_REGS; regno++)
218 {
219 unsigned char buf[MAX_REGISTER_RAW_SIZE];
220
221 val = lseek (corechan, register_addr (regno, reg_offset), 0);
222 if (val < 0
223 || (val = myread (corechan, buf, sizeof buf)) < 0)
224 {
225 char * buffer = (char *) alloca (strlen (reg_names[regno])
226 + 30);
227 strcpy (buffer, "Reading register ");
228 strcat (buffer, reg_names[regno]);
229
230 perror_with_name (buffer);
231 }
232 if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
233 buf[3] &= ~0x3;
234 supply_register (regno, buf);
235 }
236 }
237 }
238 if (filename[0] == '/')
239 corefile = savestring (filename, strlen (filename));
240 else
241 {
242 corefile = concat (current_directory, "/", filename);
243 }
244
245 set_current_frame ( create_new_frame (read_register (FP_REGNUM),
246 read_pc ()));
247 select_frame (get_current_frame (), 0);
248 validate_files ();
249 }
250 else if (from_tty)
251 printf ("No core file now.\n");
252 }