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 | This code is for the sparc cpu. |
5 | |
4187119d |
6 | This file is part of GDB. |
e91b87a3 |
7 | |
4187119d |
8 | GDB is free software; you can redistribute it and/or modify |
9 | it under the terms of the GNU General Public License as published by |
10 | the Free Software Foundation; either version 1, or (at your option) |
11 | any later version. |
e91b87a3 |
12 | |
4187119d |
13 | GDB is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with GDB; see the file COPYING. If not, write to |
20 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ |
e91b87a3 |
21 | |
7a67dd45 |
22 | #include <stdio.h> |
e91b87a3 |
23 | #include "defs.h" |
24 | #include "param.h" |
25 | #include "frame.h" |
26 | #include "inferior.h" |
27 | #include "obstack.h" |
e91b87a3 |
28 | |
e91b87a3 |
29 | #include <sys/param.h> |
30 | #include <sys/dir.h> |
31 | #include <sys/user.h> |
32 | #include <signal.h> |
33 | #include <sys/ioctl.h> |
34 | #include <fcntl.h> |
35 | |
36 | #include <sys/ptrace.h> |
37 | #include <machine/reg.h> |
38 | |
39 | #include <a.out.h> |
40 | #include <sys/file.h> |
41 | #include <sys/stat.h> |
42 | #include <sys/core.h> |
43 | |
44 | extern int errno; |
45 | extern int attach_flag; |
4187119d |
46 | |
47 | typedef enum |
48 | { |
49 | Error, not_branch, bicc, bicca, ba, baa, ticc, ta, |
50 | } branch_type; |
e91b87a3 |
51 | \f |
52 | /* This function simply calls ptrace with the given arguments. |
53 | It exists so that all calls to ptrace are isolated in this |
54 | machine-dependent file. */ |
55 | int |
56 | call_ptrace (request, pid, arg3, arg4) |
57 | int request, pid, arg3, arg4; |
58 | { |
59 | return ptrace (request, pid, arg3, arg4); |
60 | } |
61 | |
62 | void |
63 | kill_inferior () |
64 | { |
65 | if (remote_debugging) |
66 | return; |
67 | if (inferior_pid == 0) |
68 | return; |
69 | ptrace (8, inferior_pid, 0, 0); |
70 | wait (0); |
71 | inferior_died (); |
72 | } |
73 | |
74 | /* This is used when GDB is exiting. It gives less chance of error.*/ |
75 | |
76 | void |
77 | kill_inferior_fast () |
78 | { |
79 | if (remote_debugging) |
80 | return; |
81 | if (inferior_pid == 0) |
82 | return; |
83 | ptrace (8, inferior_pid, 0, 0); |
84 | wait (0); |
85 | } |
86 | |
87 | /* Simulate single-step ptrace call for sun4. Code written by Gary |
88 | Beihl (beihl@mcc.com). */ |
89 | |
90 | /* |
91 | * Duplicated from breakpoint.c because (at least for now) this is a |
92 | * machine dependent routine. |
93 | */ |
94 | static char break_insn[] = BREAKPOINT; |
95 | |
96 | /* From infrun.c */ |
97 | extern int stop_after_trap, stop_after_attach; |
98 | |
99 | static CORE_ADDR next_pc, npc4, target; |
100 | static int brknpc4, brktrg; |
101 | typedef char binsn_quantum[sizeof break_insn]; |
102 | static binsn_quantum break_mem[3]; |
103 | |
104 | /* Non-zero if we just simulated a single-step ptrace call. This is |
105 | needed because we cannot remove the breakpoints in the inferior |
106 | process until after the `wait' in `wait_for_inferior'. Used for |
107 | sun4. */ |
108 | |
109 | int one_stepped; |
110 | |
111 | void |
112 | single_step (signal) |
113 | int signal; |
114 | { |
115 | branch_type br, isannulled(); |
116 | CORE_ADDR pc; |
117 | |
118 | next_pc = read_register (NPC_REGNUM); |
119 | npc4 = next_pc + 4; /* branch not taken */ |
120 | |
121 | if (!one_stepped) |
122 | { |
123 | /* Always set breakpoint for NPC. */ |
124 | read_memory (next_pc, break_mem[0], sizeof break_insn); |
125 | write_memory (next_pc, break_insn, sizeof break_insn); |
126 | /* printf ("set break at %x\n",next_pc); */ |
127 | |
128 | pc = read_register (PC_REGNUM); |
129 | br = isannulled (pc, &target); |
130 | brknpc4 = brktrg = 0; |
131 | |
132 | if (br == bicca) |
133 | { |
134 | /* Conditional annulled branch will either end up at |
4187119d |
135 | npc (if taken) or at npc+4 (if not taken). |
136 | Trap npc+4. */ |
e91b87a3 |
137 | brknpc4 = 1; |
138 | read_memory (npc4, break_mem[1], sizeof break_insn); |
139 | write_memory (npc4, break_insn, sizeof break_insn); |
140 | } |
141 | else if (br == baa && target != next_pc) |
4187119d |
142 | { |
e91b87a3 |
143 | /* Unconditional annulled branch will always end up at |
4187119d |
144 | the target. */ |
e91b87a3 |
145 | brktrg = 1; |
146 | read_memory (target, break_mem[2], sizeof break_insn); |
147 | write_memory (target, break_insn, sizeof break_insn); |
148 | } |
149 | |
150 | /* Let it go */ |
151 | ptrace (7, inferior_pid, 1, signal); |
152 | one_stepped = 1; |
153 | return; |
154 | } |
155 | else |
156 | { |
157 | /* Remove breakpoints */ |
158 | write_memory (next_pc, break_mem[0], sizeof break_insn); |
159 | |
160 | if (brknpc4) |
161 | { |
162 | write_memory (npc4, break_mem[1], sizeof break_insn); |
163 | } |
164 | if (brktrg) |
165 | { |
166 | write_memory (target, break_mem[2], sizeof break_insn); |
167 | } |
168 | one_stepped = 0; |
169 | } |
170 | } |
171 | |
172 | /* Resume execution of the inferior process. |
173 | If STEP is nonzero, single-step it. |
174 | If SIGNAL is nonzero, give it that signal. */ |
175 | |
176 | void |
177 | resume (step, signal) |
178 | int step; |
179 | int signal; |
180 | { |
181 | errno = 0; |
182 | if (remote_debugging) |
183 | remote_resume (step, signal); |
184 | else |
185 | { |
186 | /* Sparc doesn't have single step on ptrace */ |
187 | if (step) |
188 | single_step (signal); |
189 | else |
190 | ptrace (7, inferior_pid, 1, signal); |
191 | if (errno) |
192 | perror_with_name ("ptrace"); |
193 | } |
194 | } |
195 | \f |
196 | #ifdef ATTACH_DETACH |
197 | |
198 | /* Start debugging the process whose number is PID. */ |
199 | |
200 | int |
201 | attach (pid) |
202 | int pid; |
203 | { |
204 | errno = 0; |
205 | ptrace (PTRACE_ATTACH, pid, 0, 0); |
206 | if (errno) |
207 | perror_with_name ("ptrace"); |
208 | attach_flag = 1; |
209 | return pid; |
210 | } |
211 | |
212 | /* Stop debugging the process whose number is PID |
213 | and continue it with signal number SIGNAL. |
214 | SIGNAL = 0 means just continue it. */ |
215 | |
216 | void |
217 | detach (signal) |
218 | int signal; |
219 | { |
220 | errno = 0; |
221 | ptrace (PTRACE_DETACH, inferior_pid, 1, signal); |
222 | if (errno) |
223 | perror_with_name ("ptrace"); |
224 | attach_flag = 0; |
225 | } |
226 | #endif /* ATTACH_DETACH */ |
227 | \f |
228 | void |
229 | fetch_inferior_registers () |
230 | { |
231 | struct regs inferior_registers; |
232 | struct fp_status inferior_fp_registers; |
233 | extern char registers[]; |
234 | int cwp; |
235 | struct rwindow local_and_ins; |
236 | |
237 | if (remote_debugging) |
238 | remote_fetch_registers (registers); |
239 | else |
240 | { |
241 | ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers); |
242 | ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers); |
243 | |
244 | registers[REGISTER_BYTE (0)] = 0; |
245 | bcopy (&inferior_registers.r_g1, ®isters[REGISTER_BYTE (1)], 15 * 4); |
246 | bcopy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)], |
247 | sizeof inferior_fp_registers.fpu_fr); |
248 | *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; |
249 | *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; |
250 | *(int *)®isters[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc; |
251 | *(int *)®isters[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y; |
252 | /* *(int *)®isters[REGISTER_BYTE (RP_REGNUM)] = |
253 | inferior_registers.r_o7 + 8; |
254 | bcopy (&inferior_fp_registers.Fpu_fsr, |
255 | ®isters[REGISTER_BYTE (FPS_REGNUM)], |
256 | sizeof (FPU_FSR_TYPE)); */ |
257 | |
258 | read_inferior_memory (inferior_registers.r_sp, |
259 | ®isters[REGISTER_BYTE (16)], |
260 | 16*4); |
261 | } |
262 | } |
263 | |
264 | /* Store our register values back into the inferior. |
265 | If REGNO is -1, do this for all registers. |
266 | Otherwise, REGNO specifies which register (so we can save time). */ |
267 | |
268 | void |
269 | store_inferior_registers (regno) |
270 | int regno; |
271 | { |
272 | struct regs inferior_registers; |
273 | struct fp_status inferior_fp_registers; |
274 | extern char registers[]; |
275 | |
276 | if (remote_debugging) |
277 | remote_store_registers (registers); |
278 | else |
279 | { |
280 | int in_regs = 1, in_fpregs = 1, in_fparegs, in_cpregs = 1; |
281 | |
282 | if (regno >= 0) |
283 | if (FP0_REGNUM <= regno && regno <= FP0_REGNUM + 32) |
284 | in_regs = 0; |
285 | else |
286 | in_fpregs = 0; |
287 | |
288 | if (in_regs) |
289 | { |
290 | bcopy (®isters[REGISTER_BYTE (1)], |
291 | &inferior_registers.r_g1, 15 * 4); |
292 | |
293 | inferior_registers.r_ps = |
294 | *(int *)®isters[REGISTER_BYTE (PS_REGNUM)]; |
295 | inferior_registers.r_pc = |
296 | *(int *)®isters[REGISTER_BYTE (PC_REGNUM)]; |
297 | inferior_registers.r_npc = |
298 | *(int *)®isters[REGISTER_BYTE (NPC_REGNUM)]; |
299 | inferior_registers.r_y = |
300 | *(int *)®isters[REGISTER_BYTE (Y_REGNUM)]; |
301 | |
302 | write_inferior_memory (*(int *)®isters[REGISTER_BYTE (SP_REGNUM)], |
303 | ®isters[REGISTER_BYTE (16)], |
304 | 16*4); |
305 | } |
306 | if (in_fpregs) |
307 | { |
308 | bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], |
309 | &inferior_fp_registers, |
310 | sizeof inferior_fp_registers.fpu_fr); |
311 | |
312 | /* bcopy (®isters[REGISTER_BYTE (FPS_REGNUM)], |
313 | &inferior_fp_registers.Fpu_fsr, |
314 | sizeof (FPU_FSR_TYPE)); |
315 | ****/ |
316 | } |
317 | |
318 | if (in_regs) |
319 | ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers); |
320 | if (in_fpregs) |
321 | ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers); |
322 | } |
323 | } |
324 | \f |
325 | /* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory |
326 | in the NEW_SUN_PTRACE case. |
327 | It ought to be straightforward. But it appears that writing did |
328 | not write the data that I specified. I cannot understand where |
329 | it got the data that it actually did write. */ |
330 | |
331 | /* Copy LEN bytes from inferior's memory starting at MEMADDR |
332 | to debugger memory starting at MYADDR. |
333 | On failure (cannot read from inferior, usually because address is out |
334 | of bounds) returns the value of errno. */ |
335 | |
336 | int |
337 | read_inferior_memory (memaddr, myaddr, len) |
338 | CORE_ADDR memaddr; |
339 | char *myaddr; |
340 | int len; |
341 | { |
342 | register int i; |
343 | /* Round starting address down to longword boundary. */ |
344 | register CORE_ADDR addr = memaddr & - sizeof (int); |
345 | /* Round ending address up; get number of longwords that makes. */ |
346 | register int count |
347 | = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); |
348 | /* Allocate buffer of that many longwords. */ |
349 | register int *buffer = (int *) alloca (count * sizeof (int)); |
350 | extern int errno; |
351 | |
352 | /* Read all the longwords */ |
353 | for (i = 0; i < count; i++, addr += sizeof (int)) |
354 | { |
355 | errno = 0; |
356 | if (remote_debugging) |
357 | buffer[i] = remote_fetch_word (addr); |
358 | else |
359 | buffer[i] = ptrace (1, inferior_pid, addr, 0); |
360 | if (errno) |
361 | return errno; |
362 | } |
363 | |
364 | /* Copy appropriate bytes out of the buffer. */ |
365 | bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len); |
366 | return 0; |
367 | } |
368 | |
369 | /* Copy LEN bytes of data from debugger memory at MYADDR |
370 | to inferior's memory at MEMADDR. |
371 | On failure (cannot write the inferior) |
372 | returns the value of errno. */ |
373 | |
374 | int |
375 | write_inferior_memory (memaddr, myaddr, len) |
376 | CORE_ADDR memaddr; |
377 | char *myaddr; |
378 | int len; |
379 | { |
380 | register int i; |
381 | /* Round starting address down to longword boundary. */ |
382 | register CORE_ADDR addr = memaddr & - sizeof (int); |
383 | /* Round ending address up; get number of longwords that makes. */ |
384 | register int count |
385 | = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); |
386 | /* Allocate buffer of that many longwords. */ |
387 | register int *buffer = (int *) alloca (count * sizeof (int)); |
388 | extern int errno; |
389 | |
390 | /* Fill start and end extra bytes of buffer with existing memory data. */ |
391 | |
392 | if (remote_debugging) |
393 | buffer[0] = remote_fetch_word (addr); |
394 | else |
395 | buffer[0] = ptrace (1, inferior_pid, addr, 0); |
396 | |
397 | if (count > 1) |
398 | { |
399 | if (remote_debugging) |
400 | buffer[count - 1] |
401 | = remote_fetch_word (addr + (count - 1) * sizeof (int)); |
402 | else |
403 | buffer[count - 1] |
404 | = ptrace (1, inferior_pid, |
405 | addr + (count - 1) * sizeof (int), 0); |
406 | } |
407 | |
408 | /* Copy data to be written over corresponding part of buffer */ |
409 | |
410 | bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len); |
411 | |
412 | /* Write the entire buffer. */ |
413 | |
414 | for (i = 0; i < count; i++, addr += sizeof (int)) |
415 | { |
416 | errno = 0; |
417 | if (remote_debugging) |
418 | remote_store_word (addr, buffer[i]); |
419 | else |
420 | ptrace (4, inferior_pid, addr, buffer[i]); |
421 | if (errno) |
422 | return errno; |
423 | } |
424 | |
425 | return 0; |
426 | } |
427 | |
428 | \f |
429 | /* Machine-dependent code which would otherwise be in core.c */ |
430 | /* Work with core dump and executable files, for GDB. */ |
431 | |
e91b87a3 |
432 | #ifndef N_TXTADDR |
433 | #define N_TXTADDR(hdr) 0 |
434 | #endif /* no N_TXTADDR */ |
435 | |
436 | #ifndef N_DATADDR |
437 | #define N_DATADDR(hdr) hdr.a_text |
438 | #endif /* no N_DATADDR */ |
439 | |
4187119d |
440 | /* Non-zero if this is an object (.o) file, rather than an executable. |
441 | Distinguishing between the two is rarely necessary (and seems like |
442 | a hack, but there is no other way to get the text and data |
443 | addresses--N_TXTADDR should probably take care of |
444 | this, but it doesn't). */ |
445 | /* This definition will not work |
446 | if someone decides to make ld preserve relocation info. */ |
447 | #define IS_OBJECT_FILE(hdr) (hdr.a_trsize != 0) |
448 | |
e91b87a3 |
449 | /* Make COFF and non-COFF names for things a little more compatible |
450 | to reduce conditionals later. */ |
451 | |
452 | #ifdef COFF_FORMAT |
453 | #define a_magic magic |
454 | #endif |
455 | |
456 | #ifndef COFF_FORMAT |
4187119d |
457 | #ifndef AOUTHDR |
e91b87a3 |
458 | #define AOUTHDR struct exec |
459 | #endif |
4187119d |
460 | #endif |
e91b87a3 |
461 | |
462 | extern char *sys_siglist[]; |
463 | |
464 | /* Hook for `exec_file_command' command to call. */ |
465 | |
466 | extern void (*exec_file_display_hook) (); |
467 | |
4187119d |
468 | /* File names of core file and executable file. */ |
469 | |
470 | extern char *corefile; |
471 | extern char *execfile; |
472 | |
473 | /* Descriptors on which core file and executable file are open. |
474 | Note that the execchan is closed when an inferior is created |
475 | and reopened if the inferior dies or is killed. */ |
476 | |
477 | extern int corechan; |
478 | extern int execchan; |
479 | |
480 | /* Last modification time of executable file. |
481 | Also used in source.c to compare against mtime of a source file. */ |
482 | |
483 | extern int exec_mtime; |
484 | |
485 | /* Virtual addresses of bounds of the two areas of memory in the core file. */ |
486 | |
487 | extern CORE_ADDR data_start; |
488 | extern CORE_ADDR data_end; |
489 | extern CORE_ADDR stack_start; |
490 | extern CORE_ADDR stack_end; |
491 | |
492 | /* Virtual addresses of bounds of two areas of memory in the exec file. |
493 | Note that the data area in the exec file is used only when there is no core file. */ |
494 | |
495 | extern CORE_ADDR text_start; |
496 | extern CORE_ADDR text_end; |
497 | |
498 | extern CORE_ADDR exec_data_start; |
499 | extern CORE_ADDR exec_data_end; |
500 | |
501 | /* Address in executable file of start of text area data. */ |
502 | |
503 | extern int text_offset; |
504 | |
505 | /* Address in executable file of start of data area data. */ |
506 | |
507 | extern int exec_data_offset; |
508 | |
509 | /* Address in core file of start of data area data. */ |
510 | |
511 | extern int data_offset; |
512 | |
513 | /* Address in core file of start of stack area data. */ |
514 | |
515 | extern int stack_offset; |
516 | |
e91b87a3 |
517 | #ifdef COFF_FORMAT |
518 | /* various coff data structures */ |
519 | |
520 | extern FILHDR file_hdr; |
521 | extern SCNHDR text_hdr; |
522 | extern SCNHDR data_hdr; |
523 | |
524 | #endif /* not COFF_FORMAT */ |
525 | |
526 | /* a.out header saved in core file. */ |
527 | |
528 | extern AOUTHDR core_aouthdr; |
529 | |
530 | /* a.out header of exec file. */ |
531 | |
532 | extern AOUTHDR exec_aouthdr; |
533 | |
534 | extern void validate_files (); |
535 | \f |
536 | void |
537 | core_file_command (filename, from_tty) |
538 | char *filename; |
539 | int from_tty; |
540 | { |
541 | int val; |
542 | extern char registers[]; |
543 | |
544 | /* Discard all vestiges of any previous core file |
545 | and mark data and stack spaces as empty. */ |
546 | |
547 | if (corefile) |
548 | free (corefile); |
549 | corefile = 0; |
550 | |
551 | if (corechan >= 0) |
552 | close (corechan); |
553 | corechan = -1; |
554 | |
555 | data_start = 0; |
556 | data_end = 0; |
557 | stack_start = STACK_END_ADDR; |
558 | stack_end = STACK_END_ADDR; |
559 | |
560 | /* Now, if a new core file was specified, open it and digest it. */ |
561 | |
562 | if (filename) |
563 | { |
4187119d |
564 | filename = tilde_expand (filename); |
565 | make_cleanup (free, filename); |
566 | |
e91b87a3 |
567 | if (have_inferior_p ()) |
568 | error ("To look at a core file, you must kill the inferior with \"kill\"."); |
569 | corechan = open (filename, O_RDONLY, 0); |
570 | if (corechan < 0) |
571 | perror_with_name (filename); |
572 | |
573 | { |
574 | struct core corestr; |
575 | |
576 | val = myread (corechan, &corestr, sizeof corestr); |
577 | if (val < 0) |
578 | perror_with_name (filename); |
579 | if (corestr.c_magic != CORE_MAGIC) |
580 | error ("\"%s\" does not appear to be a core dump file (magic 0x%x, expected 0x%x)", |
581 | filename, corestr.c_magic, (int) CORE_MAGIC); |
582 | else if (sizeof (struct core) != corestr.c_len) |
583 | error ("\"%s\" has an invalid struct core length (%d, expected %d)", |
584 | filename, corestr.c_len, (int) sizeof (struct core)); |
585 | |
4187119d |
586 | data_start = exec_data_start; |
e91b87a3 |
587 | data_end = data_start + corestr.c_dsize; |
588 | stack_start = stack_end - corestr.c_ssize; |
589 | data_offset = sizeof corestr; |
590 | stack_offset = sizeof corestr + corestr.c_dsize; |
591 | |
592 | /* G0 *always* holds 0. */ |
593 | *(int *)®isters[REGISTER_BYTE (0)] = 0; |
594 | /* The globals and output registers. */ |
595 | |
596 | bcopy (&corestr.c_regs.r_g1, ((int *) registers) + 1, 15 * 4); |
597 | *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = corestr.c_regs.r_ps; |
598 | *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = corestr.c_regs.r_pc; |
599 | *(int *)®isters[REGISTER_BYTE (NPC_REGNUM)] = corestr.c_regs.r_npc; |
600 | *(int *)®isters[REGISTER_BYTE (Y_REGNUM)] = corestr.c_regs.r_y; |
601 | |
602 | /* My best guess at where to get the locals and input |
603 | registers is exactly where they usually are, right above |
604 | the stack pointer. If the core dump was caused by a bus |
605 | writing off the stack pointer (as is possible) then this |
606 | won't work, but it's worth the try. */ |
607 | { |
608 | int sp; |
609 | |
610 | sp = *(int *)®isters[REGISTER_BYTE (SP_REGNUM)]; |
611 | lseek (corechan, sp - stack_start + stack_offset, L_SET); |
612 | if (16 * 4 != myread (corechan, |
613 | ®isters[REGISTER_BYTE (16)], |
614 | 16 * 4)) |
615 | /* fprintf so user can still use gdb */ |
616 | fprintf (stderr, "Couldn't read input and local registers from core file\n"); |
617 | } |
618 | |
619 | bcopy (corestr.c_fpu.fpu_regs, |
620 | ®isters[REGISTER_BYTE (FP0_REGNUM)], |
621 | sizeof corestr.c_fpu.fpu_regs); |
622 | #ifdef FPU |
623 | bcopy (&corestr.c_fpu.fpu_fsr, |
624 | ®isters[REGISTER_BYTE (FPS_REGNUM)], |
625 | sizeof (FPU_FSR_TYPE)); |
626 | #endif |
627 | |
628 | bcopy (&corestr.c_aouthdr, &core_aouthdr, sizeof (struct exec)); |
629 | |
630 | printf ("Core file is from \"%s\".\n", corestr.c_cmdname); |
631 | if (corestr.c_signo > 0) |
632 | printf ("Program terminated with signal %d, %s.\n", |
633 | corestr.c_signo, |
634 | corestr.c_signo < NSIG |
635 | ? sys_siglist[corestr.c_signo] |
636 | : "(undocumented)"); |
637 | } |
638 | if (filename[0] == '/') |
639 | corefile = savestring (filename, strlen (filename)); |
640 | else |
641 | { |
642 | corefile = concat (current_directory, "/", filename); |
643 | } |
644 | |
645 | set_current_frame ( create_new_frame (read_register (FP_REGNUM), |
646 | read_pc ())); |
647 | select_frame (get_current_frame (), 0); |
648 | validate_files (); |
649 | } |
650 | else if (from_tty) |
651 | printf ("No core file now.\n"); |
652 | } |
653 | \f |
654 | void |
655 | exec_file_command (filename, from_tty) |
656 | char *filename; |
657 | int from_tty; |
658 | { |
659 | int val; |
660 | |
661 | /* Eliminate all traces of old exec file. |
662 | Mark text segment as empty. */ |
663 | |
664 | if (execfile) |
665 | free (execfile); |
666 | execfile = 0; |
4187119d |
667 | data_start = 0; |
668 | data_end -= exec_data_start; |
e91b87a3 |
669 | text_start = 0; |
670 | text_end = 0; |
671 | exec_data_start = 0; |
672 | exec_data_end = 0; |
673 | if (execchan >= 0) |
674 | close (execchan); |
675 | execchan = -1; |
676 | |
677 | /* Now open and digest the file the user requested, if any. */ |
678 | |
679 | if (filename) |
680 | { |
4187119d |
681 | filename = tilde_expand (filename); |
682 | make_cleanup (free, filename); |
683 | |
e91b87a3 |
684 | execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0, |
685 | &execfile); |
686 | if (execchan < 0) |
687 | perror_with_name (filename); |
688 | |
689 | #ifdef COFF_FORMAT |
690 | { |
691 | int aout_hdrsize; |
692 | int num_sections; |
693 | |
694 | if (read_file_hdr (execchan, &file_hdr) < 0) |
695 | error ("\"%s\": not in executable format.", execfile); |
696 | |
697 | aout_hdrsize = file_hdr.f_opthdr; |
698 | num_sections = file_hdr.f_nscns; |
699 | |
700 | if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0) |
701 | error ("\"%s\": can't read optional aouthdr", execfile); |
702 | |
7a67dd45 |
703 | if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections, |
704 | aout_hdrsize) < 0) |
e91b87a3 |
705 | error ("\"%s\": can't read text section header", execfile); |
706 | |
7a67dd45 |
707 | if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections, |
708 | aout_hdrsize) < 0) |
e91b87a3 |
709 | error ("\"%s\": can't read data section header", execfile); |
710 | |
711 | text_start = exec_aouthdr.text_start; |
712 | text_end = text_start + exec_aouthdr.tsize; |
713 | text_offset = text_hdr.s_scnptr; |
714 | exec_data_start = exec_aouthdr.data_start; |
715 | exec_data_end = exec_data_start + exec_aouthdr.dsize; |
716 | exec_data_offset = data_hdr.s_scnptr; |
4187119d |
717 | data_start = exec_data_start; |
718 | data_end += exec_data_start; |
e91b87a3 |
719 | exec_mtime = file_hdr.f_timdat; |
720 | } |
721 | #else /* not COFF_FORMAT */ |
722 | { |
723 | struct stat st_exec; |
724 | val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR)); |
725 | |
726 | if (val < 0) |
727 | perror_with_name (filename); |
728 | |
4187119d |
729 | text_start = |
730 | IS_OBJECT_FILE (exec_aouthdr) ? 0 : N_TXTADDR (exec_aouthdr); |
731 | exec_data_start = IS_OBJECT_FILE (exec_aouthdr) |
732 | ? exec_aouthdr.a_text : N_DATADDR (exec_aouthdr); |
e91b87a3 |
733 | text_offset = N_TXTOFF (exec_aouthdr); |
734 | exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text; |
735 | |
736 | text_end = text_start + exec_aouthdr.a_text; |
737 | exec_data_end = exec_data_start + exec_aouthdr.a_data; |
4187119d |
738 | data_start = exec_data_start; |
739 | data_end += exec_data_start; |
e91b87a3 |
740 | |
741 | fstat (execchan, &st_exec); |
742 | exec_mtime = st_exec.st_mtime; |
743 | } |
744 | #endif /* not COFF_FORMAT */ |
745 | |
746 | validate_files (); |
747 | } |
748 | else if (from_tty) |
749 | printf ("No exec file now.\n"); |
750 | |
751 | /* Tell display code (if any) about the changed file name. */ |
752 | if (exec_file_display_hook) |
753 | (*exec_file_display_hook) (filename); |
754 | } |
755 | |
756 | /* |
757 | * Find the pc saved in frame FRAME. |
758 | */ |
759 | CORE_ADDR |
760 | frame_saved_pc (frame) |
761 | FRAME frame; |
762 | { |
763 | CORE_ADDR prev_pc; |
764 | |
765 | /* If it's at the bottom, the return value's stored in i7/rp */ |
766 | if (get_current_frame () == frame) |
767 | prev_pc = GET_RWINDOW_REG (read_register (SP_REGNUM), rw_in[7]); |
768 | else |
769 | /* Wouldn't this always work? This would allow this routine to |
770 | be completely a macro. */ |
771 | prev_pc = GET_RWINDOW_REG (frame->bottom, rw_in[7]); |
772 | |
773 | return PC_ADJUST (prev_pc); |
774 | } |
775 | |
776 | /* |
777 | * Since an individual frame in the frame cache is defined by two |
778 | * arguments (a frame pointer and a stack pointer), we need two |
779 | * arguments to get info for an arbitrary stack frame. This routine |
780 | * takes two arguments and makes the cached frames look as if these |
781 | * two arguments defined a frame on the cache. This allows the rest |
782 | * of info frame to extract the important arguments without |
783 | * difficulty. |
784 | */ |
785 | FRAME |
786 | setup_arbitrary_frame (frame, stack) |
787 | FRAME_ADDR frame, stack; |
788 | { |
789 | struct frame_info *fci; |
790 | FRAME fid = create_new_frame (frame, 0); |
791 | |
792 | if (!fid) |
793 | fatal ("internal: create_new_frame returned invalid frame id"); |
794 | |
795 | fid->bottom = stack; |
796 | |
797 | return fid; |
798 | } |
799 | |
800 | /* This code was written by Gary Beihl (beihl@mcc.com). |
801 | It was modified by Michael Tiemann (tiemann@corto.inria.fr). */ |
802 | |
803 | struct command_line *get_breakpoint_commands (); |
804 | |
805 | /* |
806 | * This routine appears to be passed a size by which to increase the |
807 | * stack. It then executes a save instruction in the inferior to |
808 | * increase the stack by this amount. Only the register window system |
809 | * should be affected by this; the program counter & etc. will not be. |
810 | * |
811 | * This instructions used for this purpose are: |
812 | * |
813 | * sethi %hi(0x0),g1 * |
814 | * add g1,0x1ee0,g1 * |
815 | * save sp,g1,sp |
816 | * sethi %hi(0x0),g1 * |
817 | * add g1,0x1ee0,g1 * |
818 | * t g0,0x1,o0 |
819 | * sethi %hi(0x0),g0 (nop) |
820 | * |
821 | * I presume that these set g1 to be the negative of the size, do a |
822 | * save (putting the stack pointer at sp - size) and restore the |
823 | * original contents of g1. A * indicates that the actual value of |
824 | * the instruction is modified below. |
825 | */ |
826 | static int save_insn_opcodes[] = { |
827 | 0x03000000, 0x82007ee0, 0x9de38001, 0x03000000, |
828 | 0x82007ee0, 0x91d02001, 0x01000000 }; |
829 | |
830 | /* Neither do_save_insn or do_restore_insn save stack configuration |
831 | (since the stack is in an indeterminate state through the call to |
832 | each of them); that responsibility of the routine which calls them. */ |
833 | |
834 | void |
835 | do_save_insn (size) |
836 | int size; |
837 | { |
838 | int g1 = read_register (1); |
839 | CORE_ADDR sp = read_register (SP_REGNUM); |
840 | CORE_ADDR pc = read_register (PC_REGNUM); |
841 | CORE_ADDR npc = read_register (NPC_REGNUM); |
842 | CORE_ADDR fake_pc = sp - sizeof (save_insn_opcodes); |
843 | struct inferior_status inf_status; |
844 | |
845 | save_inferior_status (&inf_status, 0); /* Don't restore stack info */ |
846 | /* |
847 | * See above. |
848 | */ |
849 | save_insn_opcodes[0] = 0x03000000 | ((-size >> 10) & 0x3fffff); |
850 | save_insn_opcodes[1] = 0x82006000 | (-size & 0x3ff); |
851 | save_insn_opcodes[3] = 0x03000000 | ((g1 >> 10) & 0x3fffff); |
852 | save_insn_opcodes[4] = 0x82006000 | (g1 & 0x3ff); |
853 | write_memory (fake_pc, save_insn_opcodes, sizeof (save_insn_opcodes)); |
854 | |
855 | clear_proceed_status (); |
856 | stop_after_trap = 1; |
857 | proceed (fake_pc, 0, 0); |
858 | |
859 | write_register (PC_REGNUM, pc); |
860 | write_register (NPC_REGNUM, npc); |
861 | restore_inferior_status (&inf_status); |
862 | } |
863 | |
864 | /* |
865 | * This routine takes a program counter value. It restores the |
866 | * register window system to the frame above the current one, and sets |
867 | * the pc and npc to the correct values. |
868 | */ |
869 | |
870 | /* The following insns translate to: |
871 | |
872 | restore |
873 | t g0,0x1,o0 |
874 | sethi %hi(0x0), g0 */ |
875 | |
876 | static int restore_insn_opcodes[] = { 0x81e80000, 0x91d02001, 0x01000000 }; |
877 | |
878 | void |
879 | do_restore_insn (pc) |
880 | CORE_ADDR pc; |
881 | { |
882 | CORE_ADDR sp = read_register (SP_REGNUM); |
883 | CORE_ADDR npc = pc + 4; |
884 | CORE_ADDR fake_pc = sp - sizeof (restore_insn_opcodes); |
885 | struct inferior_status inf_status; |
886 | |
887 | save_inferior_status (&inf_status, 0); /* Don't restore stack info */ |
888 | |
889 | if (!pc) |
890 | abort(); |
891 | |
892 | write_memory (fake_pc, restore_insn_opcodes, sizeof (restore_insn_opcodes)); |
893 | |
894 | clear_proceed_status (); |
895 | stop_after_trap = 1; |
896 | proceed (fake_pc, 0, 0); |
897 | |
898 | write_register (PC_REGNUM, pc); |
899 | write_register (NPC_REGNUM, npc); |
900 | restore_inferior_status (&inf_status); |
901 | } |
902 | |
903 | /* |
904 | * This routine should be more specific in it's actions; making sure |
905 | * that it uses the same register in the initial prologue section. |
906 | */ |
907 | CORE_ADDR |
908 | skip_prologue (pc) |
909 | CORE_ADDR pc; |
910 | { |
911 | union |
912 | { |
4187119d |
913 | unsigned long int code; |
914 | struct |
915 | { |
916 | unsigned int op:2; |
917 | unsigned int rd:5; |
918 | unsigned int op2:3; |
919 | unsigned int imm22:22; |
920 | } sethi; |
921 | struct |
922 | { |
923 | unsigned int op:2; |
924 | unsigned int rd:5; |
925 | unsigned int op3:6; |
926 | unsigned int rs1:5; |
927 | unsigned int i:1; |
928 | unsigned int simm13:13; |
929 | } add; |
e91b87a3 |
930 | int i; |
931 | } x; |
932 | int dest = -1; |
933 | |
934 | x.i = read_memory_integer (pc, 4); |
935 | |
4187119d |
936 | /* Recognize the `sethi' insn and record its destination. */ |
937 | if (x.sethi.op == 0 && x.sethi.op2 == 4) |
e91b87a3 |
938 | { |
4187119d |
939 | dest = x.sethi.rd; |
e91b87a3 |
940 | pc += 4; |
941 | x.i = read_memory_integer (pc, 4); |
942 | } |
943 | |
4187119d |
944 | /* Recognize an add immediate value to register to either %g1 or |
e91b87a3 |
945 | the destination register recorded above. Actually, this might |
4187119d |
946 | well recognize several different arithmetic operations. */ |
947 | if (x.add.op == 2 && x.add.i && (x.add.rd == 1 || x.add.rd == dest)) |
e91b87a3 |
948 | { |
949 | pc += 4; |
950 | x.i = read_memory_integer (pc, 4); |
951 | } |
952 | |
953 | /* This recognizes any SAVE insn. But why do the XOR and then |
954 | the compare? That's identical to comparing against 60 (as long |
955 | as there isn't any sign extension). */ |
4187119d |
956 | if (x.add.op == 2 && (x.add.op3 ^ 32) == 28) |
e91b87a3 |
957 | { |
958 | pc += 4; |
959 | x.i = read_memory_integer (pc, 4); |
960 | } |
961 | |
962 | /* Now we need to recognize stores into the frame from the input |
963 | registers. This recognizes all non alternate stores of input |
4187119d |
964 | register, into a location offset from the frame pointer. */ |
965 | while (x.add.op == 3 |
966 | && (x.add.op3 & 0x3c) == 4 /* Store, non-alternate. */ |
967 | && (x.add.rd & 0x18) == 0x18 /* Input register. */ |
968 | && x.add.i /* Immediate mode. */ |
969 | && x.add.rs1 == 30 /* Off of frame pointer. */ |
970 | /* Into reserved stack space. */ |
971 | && x.add.simm13 >= 0x44 |
972 | && x.add.simm13 < 0x5b) |
e91b87a3 |
973 | { |
974 | pc += 4; |
975 | x.i = read_memory_integer (pc, 4); |
976 | } |
977 | return pc; |
978 | } |
979 | |
4187119d |
980 | /* Check instruction at ADDR to see if it is an annulled branch. |
981 | All other instructions will go to NPC or will trap. |
982 | Set *TARGET if we find a canidate branch; set to zero if not. */ |
983 | |
e91b87a3 |
984 | branch_type |
985 | isannulled (addr, target) |
986 | CORE_ADDR addr, *target; |
987 | { |
e91b87a3 |
988 | branch_type val = not_branch; |
4187119d |
989 | long int offset; /* Must be signed for sign-extend. */ |
990 | union |
991 | { |
992 | unsigned long int code; |
993 | struct |
994 | { |
995 | unsigned int op:2; |
996 | unsigned int a:1; |
997 | unsigned int cond:4; |
998 | unsigned int op2:3; |
999 | unsigned int disp22:22; |
1000 | } b; |
1001 | } insn; |
e91b87a3 |
1002 | |
1003 | *target = 0; |
4187119d |
1004 | insn.code = read_memory_integer (addr, 4); |
1005 | |
1006 | if (insn.b.op == 0 |
1007 | && (insn.b.op2 == 2 || insn.b.op2 == 6 || insn.b.op2 == 7)) |
e91b87a3 |
1008 | { |
4187119d |
1009 | if (insn.b.cond == 8) |
1010 | val = insn.b.a ? baa : ba; |
1011 | else |
1012 | val = insn.b.a ? bicca : bicc; |
1013 | offset = 4 * ((int) (insn.b.disp22 << 10) >> 10); |
1014 | *target = addr + offset; |
e91b87a3 |
1015 | } |
4187119d |
1016 | |
e91b87a3 |
1017 | return val; |
1018 | } |
4187119d |
1019 | |