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