* tm-hppa.h: New file, architectural definition of HP PA.
[deliverable/binutils-gdb.git] / gdb / hppahpux-tdep.c
CommitLineData
7da1e27d
SG
1/* Machine-dependent code which would otherwise be in inflow.c and 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 (pa-gdb-bugs@cs.utah.edu).
7
8This file is part of GDB.
9
5140562f 10This program is free software; you can redistribute it and/or modify
7da1e27d 11it under the terms of the GNU General Public License as published by
5140562f
JG
12the Free Software Foundation; either version 2 of the License, or
13(at your option) any later version.
7da1e27d 14
5140562f 15This program is distributed in the hope that it will be useful,
7da1e27d
SG
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
5140562f
JG
21along with this program; if not, write to the Free Software
22Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
7da1e27d 23
7da1e27d
SG
24#include "defs.h"
25#include "frame.h"
26#include "inferior.h"
27#include "value.h"
28
29/* For argument passing to the inferior */
30#include "symtab.h"
31
32#ifdef USG
33#include <sys/types.h>
34#endif
35
36#include <sys/param.h>
37#include <sys/dir.h>
38#include <signal.h>
39#include <sys/ioctl.h>
7da1e27d
SG
40
41#ifdef COFF_ENCAPSULATE
42#include "a.out.encap.h"
43#else
44#include <a.out.h>
45#endif
46#ifndef N_SET_MAGIC
47#define N_SET_MAGIC(exec, val) ((exec).a_magic = (val))
48#endif
49
50/*#include <sys/user.h> After a.out.h */
51#include <sys/file.h>
52#include <sys/stat.h>
53#include <sys/ptrace.h>
54#include <machine/psl.h>
55
56#ifdef KERNELDEBUG
57#include <sys/vmmac.h>
58#include <machine/machparam.h>
59#include <machine/vmparam.h>
60#include <machine/pde.h>
61#include <machine/cpu.h>
62#include <machine/iomod.h>
63#include <machine/pcb.h>
64#include <machine/rpb.h>
65#include <ctype.h>
66
67extern int kernel_debugging;
68extern CORE_ADDR startup_file_start;
69extern CORE_ADDR startup_file_end;
70
71#define KERNOFF ((unsigned)KERNBASE)
72#define INKERNEL(x) ((x) >= KERNOFF && (x) < KERNOFF + ctob(slr))
73
74static int ok_to_cache();
75static void set_kernel_boundaries();
76
77int devmem = 0;
78int vtophys_ready = 0;
79int kerneltype;
80#define OS_BSD 1
81#define OS_MACH 2
82#endif
83
84#include "gdbcore.h"
85#include "gdbcmd.h"
86
87extern int errno;
88\f
89
90
91
92
93
94/* Last modification time of executable file.
95 Also used in source.c to compare against mtime of a source file. */
96
97extern int exec_mtime;
98
99/* Virtual addresses of bounds of the two areas of memory in the core file. */
100
101/* extern CORE_ADDR data_start; */
102extern CORE_ADDR data_end;
103extern CORE_ADDR stack_start;
104extern CORE_ADDR stack_end;
105
106/* Virtual addresses of bounds of two areas of memory in the exec file.
107 Note that the data area in the exec file is used only when there is no core file. */
108
109extern CORE_ADDR text_start;
110extern CORE_ADDR text_end;
111
112extern CORE_ADDR exec_data_start;
113extern CORE_ADDR exec_data_end;
114
115/* Address in executable file of start of text area data. */
116
117extern int text_offset;
118
119/* Address in executable file of start of data area data. */
120
121extern int exec_data_offset;
122
123/* Address in core file of start of data area data. */
124
125extern int data_offset;
126
127/* Address in core file of start of stack area data. */
128
129extern int stack_offset;
130
131struct header file_hdr;
132struct som_exec_auxhdr exec_hdr;
133\f
134#ifdef KERNELDEBUG
135/*
136 * Kernel debugging routines.
137 */
138
139static struct pcb pcb;
140static struct pde *pdir;
141static struct hte *htbl;
142static u_int npdir, nhtbl;
143
144static CORE_ADDR
145ksym_lookup(name)
146 char *name;
147{
148 struct symbol *sym;
149 int i;
150
151 if ((i = lookup_misc_func(name)) < 0)
152 error("kernel symbol `%s' not found.", name);
153
154 return (misc_function_vector[i].address);
155}
156
157/*
158 * (re-)set the variables that tell "inside_entry_file" where to end
159 * a stack backtrace.
160 */
161void
162set_kernel_boundaries()
163{
164 switch (kerneltype) {
165 case OS_MACH:
166 startup_file_start = ksym_lookup("$syscall");
167 startup_file_end = ksym_lookup("trap");
168 break;
169 case OS_BSD:
170 startup_file_start = ksym_lookup("syscallinit");
171 startup_file_end = ksym_lookup("$syscallexit");
172 break;
173 }
174}
175
176/*
177 * return true if 'len' bytes starting at 'addr' can be read out as
178 * longwords and/or locally cached (this is mostly for memory mapped
179 * i/o register access when debugging remote kernels).
180 */
181static int
182ok_to_cache(addr, len)
183{
184 static CORE_ADDR ioptr;
185
186 if (! ioptr)
187 ioptr = ksym_lookup("ioptr");
188
189 if (addr >= ioptr && addr < SPA_HIGH)
190 return (0);
191
192 return (1);
193}
194
195static
196physrd(addr, dat, len)
197 u_int addr;
198 char *dat;
199{
200 if (lseek(corechan, addr, L_SET) == -1)
201 return (-1);
202 if (read(corechan, dat, len) != len)
203 return (-1);
204
205 return (0);
206}
207
208/*
209 * When looking at kernel data space through /dev/mem or with a core file, do
210 * virtual memory mapping.
211 */
212static CORE_ADDR
213vtophys(space, addr)
214 unsigned space;
215 CORE_ADDR addr;
216{
217 struct pde *pptr;
218 u_int hindx, vpageno, ppageno;
219 CORE_ADDR phys = ~0;
220
221 if (!vtophys_ready) {
222 phys = addr; /* XXX for kvread */
223 } else if (kerneltype == OS_BSD) {
224 /* make offset into a virtual page no */
225 vpageno = btop(addr);
226 /*
227 * Determine index into hash table, initialize pptr to this
228 * entry (since first word of pte & hte are same), and set
229 * physical page number for first entry in chain.
230 */
231 hindx = pdirhash(space, addr) & (nhtbl-1);
232 pptr = (struct pde *) &htbl[hindx];
233 ppageno = pptr->pde_next;
234 while (1) {
235 if (pptr->pde_end)
236 break;
237 pptr = &pdir[ppageno];
238 /*
239 * If space id & virtual page number match, return
240 * "next PDIR entry of previous PDIR entry" as the
241 * physical page or'd with offset into page.
242 */
243 if (pptr->pde_space == space &&
244 pptr->pde_page == vpageno) {
245 phys = (CORE_ADDR) ((u_int)ptob(ppageno) |
246 (addr & PGOFSET));
247 break;
248 }
249 ppageno = pptr->pde_next;
250 }
251 }
252#ifdef MACHKERNELDEBUG
253 else if (kerneltype == OS_MACH) {
254 (void) mach_vtophys(space, addr, &phys);
255 }
256#endif
257#if 0
258 printf("vtophys(%x.%x) -> %x\n", space, addr, phys);
259#endif
260 return (phys);
261}
262
263static
264kvread(addr)
265 CORE_ADDR addr;
266{
267 CORE_ADDR paddr;
268
269 paddr = vtophys(0, addr);
270 if (paddr != ~0)
271 if (physrd(paddr, (char *)&addr, sizeof(addr)) == 0)
272 return (addr);
273
274 return (~0);
275}
276
277static void
278read_pcb(addr)
279 u_int addr;
280{
281 int i, off;
282 extern char registers[];
283 static int reg2pcb[] = {
284 /* RPB */
285 -1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
286 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
287 45, 52, 51, 75, 74, 49, 53, 54, 55, 56, -1, 70, 66, 67, 68, 69,
288 71, 72, 73, 34, 42, 43, 44, 46, 47, 58, 59, 60, -1, -1, -1, -1,
289 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
290 -1, -1, -1, -1,
291 /* BSD */
292 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
293 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
294 43, 64, 67, 68, 67, 47, 51, 52, 53, 54, -1, 35, 31, 32, 33, 34,
295 36, 37, 38, 39, 40, 41, 42, 44, 45, 56, 57, 58,102,103,104, -1,
296 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 82, 84, 86, 88, 90, 92,
297 94, 96, 98, 100,
298 /* Mach */
299 -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
300 14, 15, 16, -1, -1, -1, -1, -1, -1, -1, -1, 17, -1, -1, 18, -1,
301 25, -1, -1, -1, -1, 30, -1, -1, -1, -1, -1, 20, -1, -1, -1, 19,
302 21, 22, 23, 24, 26, 27, -1, 28, 29, -1, -1, -1, -1, -1, -1, -1,
303 34, 35, 36, 37, 38, 39, 40, 41, -1, -1, -1, -1, -1, -1, -1, -1,
304 42, 44, 46, 48
305 };
306 static struct rpb *rpbaddr = (struct rpb *) 0;
307 static u_int rpbpcbaddr = 0;
308
309 if (!remote_debugging) {
310 /*
311 * If we are debugging a post-mortem and this is the first
312 * call of read_pcb, read the RPB. Also assoicate the
313 * thread/proc running at the time with the RPB.
314 */
315 if (!devmem && rpbpcbaddr == 0) {
316 CORE_ADDR raddr = ksym_lookup("rpb");
317 int usepcb = 1;
318
319 if (raddr != ~0) {
320 rpbaddr = (struct rpb *) malloc(sizeof *rpbaddr);
321 if (!physrd(raddr, (char *)rpbaddr, sizeof *rpbaddr)) {
322 rpbpcbaddr = addr;
323 usepcb = 0;
324 }
325 }
326 if (usepcb) {
327 error("cannot read rpb, using pcb for registers\n");
328 if (rpbaddr)
329 free((char *)rpbaddr);
330 rpbpcbaddr = ~0;
331 }
332 }
333 if (physrd (addr, (char *)&pcb, sizeof pcb))
334 error ("cannot read pcb at %x.\n", addr);
335 } else {
336 if (remote_read_inferior_memory(addr, (char *)&pcb, sizeof pcb))
337 error ("cannot read pcb at %x.\n", addr);
338 }
339
340 if (kerneltype == OS_BSD) {
341 printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",
342 pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr);
343 off = NUM_REGS;
344 } else {
345 printf("pcb %lx psw %lx ksp %lx\n",
346 addr, ((int *)&pcb)[31], ((int *)&pcb)[32]);
347 off = NUM_REGS * 2;
348 }
349 /*
350 * get the register values out of the sys pcb and
351 * store them where `read_register' will find them.
352 */
353 bzero(registers, REGISTER_BYTES);
354 for (i = 0; i < NUM_REGS; ++i)
355 if (reg2pcb[i+off] != -1)
356 supply_register(i, &((int *)&pcb)[reg2pcb[i+off]]);
357 /*
358 * If the RPB is valid for this thread/proc use the register values
359 * contained there.
360 */
361 if (addr == rpbpcbaddr) {
362 off = 0;
363 for (i = 0; i < NUM_REGS; ++i)
364 if (reg2pcb[i+off] != -1)
365 supply_register(i, &((int *)rpbaddr)[reg2pcb[i+off]]);
366 }
367}
368
369void
370setup_kernel_debugging()
371{
372 struct stat stb;
373 CORE_ADDR addr;
374
375 fstat(corechan, &stb);
376 devmem = 0;
377 if ((stb.st_mode & S_IFMT) == S_IFCHR && stb.st_rdev == makedev(2, 0))
378 devmem = 1;
379
380 /* XXX */
381 if (lookup_misc_func("Sysmap") < 0)
382 kerneltype = OS_MACH;
383 else
384 kerneltype = OS_BSD;
385
386 if (kerneltype == OS_BSD) {
387 int len, err = 0;
388
389 /*
390 * Hash table and PDIR are equivalently mapped
391 */
392 nhtbl = kvread(ksym_lookup("nhtbl"));
393 if (nhtbl != ~0) {
394 len = nhtbl * sizeof(*htbl);
395 htbl = (struct hte *) malloc(len);
396 if (htbl) {
397 addr = kvread(ksym_lookup("htbl"));
398 if (physrd(addr, (char *)htbl, len))
399 err++;
400 } else
401 err++;
402 } else
403 err++;
404 npdir = kvread(ksym_lookup("npdir"));
405 if (npdir != ~0) {
406 len = npdir * sizeof(*pdir);
407 pdir = (struct pde *) malloc(len);
408 if (pdir) {
409 addr = kvread(ksym_lookup("pdir"));
410 if (physrd(addr, (char *)pdir, len))
411 err++;
412 } else
413 err++;
414 } else
415 err++;
416 if (err) {
417 error("cannot read PDIR/HTBL");
418 return;
419 }
420 vtophys_ready = 1;
421
422 /*
423 * pcb where "panic" saved registers in first thing in
424 * current u-area. The current u-area is pointed to by
425 * "uptr".
426 */
427 addr = kvread(ksym_lookup("uptr"));
428 if (addr == ~0) {
429 error("cannot read current u-area address");
430 return;
431 }
432 read_pcb(vtophys(0, addr)); /* XXX space */
433 if (!devmem) {
434 /* find stack frame */
435 CORE_ADDR panicstr;
436 char buf[256];
437 register char *cp;
438
439 panicstr = kvread(ksym_lookup("panicstr"));
440 if (panicstr == ~0)
441 return;
442 (void) kernel_core_file_hook(panicstr, buf, sizeof(buf));
443 for (cp = buf; cp < &buf[sizeof(buf)] && *cp; cp++)
444 if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp)))
445 *cp = '?';
446 if (*cp)
447 *cp = '\0';
448 printf("panic: %s\n", buf);
449 }
450 }
451#ifdef MACHKERNELDEBUG
452 else {
453 int *thread;
454
455 /*
456 * Set up address translation
457 */
458 if (mach_vtophys_init() == 0) {
459 error("cannot initialize vtophys for Mach");
460 return;
461 }
462 vtophys_ready = 1;
463
464 /*
465 * Locate active thread and read PCB
466 * XXX MAJOR HACK
467 * - assumes uni-processor
468 * - assumes position of pcb to avoid mach includes
469 */
470 thread = (int *)kvread(ksym_lookup("active_threads"));
471 addr = kvread(&thread[9]); /* XXX: pcb addr */
472 read_pcb(vtophys(0, addr));
473 }
474#endif
475}
476
477vtop_command(arg)
478 char *arg;
479{
480 u_int sp, off, pa;
481
482 if (!arg)
483 error_no_arg("kernel virtual address");
484 if (!kernel_debugging)
485 error("not debugging kernel");
486
487 sp = 0; /* XXX */
488 off = (u_int) parse_and_eval_address(arg);
489 pa = vtophys(sp, off);
490 printf("%lx.%lx -> ", sp, off);
491 if (pa == ~0)
492 printf("<invalid>\n");
493 else
494 printf("%lx\n", pa);
495}
496
497set_paddr_command(arg)
498 char *arg;
499{
500 u_int addr;
501
502 if (!arg) {
503 if (kerneltype == OS_BSD)
504 error_no_arg("ps-style address for new process");
505 else
506 error_no_arg("thread structure virtual address");
507 }
508 if (!kernel_debugging)
509 error("not debugging kernel");
510
511 addr = (u_int) parse_and_eval_address(arg);
512 if (kerneltype == OS_BSD)
513 addr = ctob(addr);
514 else {
515 addr = kvread(&(((int *)addr)[9])); /* XXX: pcb addr */
516 addr = vtophys(0, addr); /* XXX space */
517 }
518 read_pcb(addr);
519
520 flush_cached_frames();
521 set_current_frame(create_new_frame(read_register(FP_REGNUM), read_pc()));
522 select_frame(get_current_frame(), 0);
523}
524
525/*
526 * read len bytes from kernel virtual address 'addr' into local
527 * buffer 'buf'. Return 0 if read ok, 1 otherwise. On read
528 * errors, portion of buffer not read is zeroed.
529 */
530kernel_core_file_hook(addr, buf, len)
531 CORE_ADDR addr;
532 char *buf;
533 int len;
534{
535 int i;
536 CORE_ADDR paddr;
537
538 while (len > 0) {
539 paddr = vtophys(0, addr); /* XXX space */
540 if (paddr == ~0) {
541 bzero(buf, len);
542 return (1);
543 }
544 /* we can't read across a page boundary */
545 i = min(len, NBPG - (addr & PGOFSET));
546 if (physrd(paddr, buf, i)) {
547 bzero(buf, len);
548 return (1);
549 }
550 buf += i;
551 addr += i;
552 len -= i;
553 }
554 return (0);
555}
556#endif
557
558
559\f
560
561
562
563/* Routines to extract various sized constants out of hppa
564 instructions. */
565
566/* This assumes that no garbage lies outside of the lower bits of
567 value. */
568
569int
570sign_extend (val, bits)
571 unsigned val, bits;
572{
573 return (int)(val >> bits - 1 ? (-1 << bits) | val : val);
574}
575
576/* For many immediate values the sign bit is the low bit! */
577
578int
579low_sign_extend (val, bits)
580 unsigned val, bits;
581{
582 return (int)((val & 0x1 ? (-1 << (bits - 1)) : 0) | val >> 1);
583}
584/* extract the immediate field from a ld{bhw}s instruction */
585
586
587
588unsigned
589get_field (val, from, to)
590 unsigned val, from, to;
591{
592 val = val >> 31 - to;
593 return val & ((1 << 32 - from) - 1);
594}
595
596unsigned
597set_field (val, from, to, new_val)
598 unsigned *val, from, to;
599{
600 unsigned mask = ~((1 << (to - from + 1)) << (31 - from));
601 return *val = *val & mask | (new_val << (31 - from));
602}
603
604/* extract a 3-bit space register number from a be, ble, mtsp or mfsp */
605
606extract_3 (word)
607 unsigned word;
608{
609 return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
610}
611
612extract_5_load (word)
613 unsigned word;
614{
615 return low_sign_extend (word >> 16 & MASK_5, 5);
616}
617
618/* extract the immediate field from a st{bhw}s instruction */
619
620int
621extract_5_store (word)
622 unsigned word;
623{
624 return low_sign_extend (word & MASK_5, 5);
625}
626
627/* extract an 11 bit immediate field */
628
629int
630extract_11 (word)
631 unsigned word;
632{
633 return low_sign_extend (word & MASK_11, 11);
634}
635
636/* extract a 14 bit immediate field */
637
638int
639extract_14 (word)
640 unsigned word;
641{
642 return low_sign_extend (word & MASK_14, 14);
643}
644
645/* deposit a 14 bit constant in a word */
646
647unsigned
648deposit_14 (opnd, word)
649 int opnd;
650 unsigned word;
651{
652 unsigned sign = (opnd < 0 ? 1 : 0);
653
654 return word | ((unsigned)opnd << 1 & MASK_14) | sign;
655}
656
657/* extract a 21 bit constant */
658
659int
660extract_21 (word)
661 unsigned word;
662{
663 int val;
664
665 word &= MASK_21;
666 word <<= 11;
667 val = GET_FIELD (word, 20, 20);
668 val <<= 11;
669 val |= GET_FIELD (word, 9, 19);
670 val <<= 2;
671 val |= GET_FIELD (word, 5, 6);
672 val <<= 5;
673 val |= GET_FIELD (word, 0, 4);
674 val <<= 2;
675 val |= GET_FIELD (word, 7, 8);
676 return sign_extend (val, 21) << 11;
677}
678
679/* deposit a 21 bit constant in a word. Although 21 bit constants are
680 usually the top 21 bits of a 32 bit constant, we assume that only
681 the low 21 bits of opnd are relevant */
682
683unsigned
684deposit_21 (opnd, word)
685 unsigned opnd, word;
686{
687 unsigned val = 0;
688
689 val |= GET_FIELD (opnd, 11 + 14, 11 + 18);
690 val <<= 2;
691 val |= GET_FIELD (opnd, 11 + 12, 11 + 13);
692 val <<= 2;
693 val |= GET_FIELD (opnd, 11 + 19, 11 + 20);
694 val <<= 11;
695 val |= GET_FIELD (opnd, 11 + 1, 11 + 11);
696 val <<= 1;
697 val |= GET_FIELD (opnd, 11 + 0, 11 + 0);
698 return word | val;
699}
700
701/* extract a 12 bit constant from branch instructions */
702
703int
704extract_12 (word)
705 unsigned word;
706{
707 return sign_extend (GET_FIELD (word, 19, 28) |
708 GET_FIELD (word, 29, 29) << 10 |
709 (word & 0x1) << 11, 12) << 2;
710}
711
712/* extract a 17 bit constant from branch instructions, returning the
713 19 bit signed value. */
714
715int
716extract_17 (word)
717 unsigned word;
718{
719 return sign_extend (GET_FIELD (word, 19, 28) |
720 GET_FIELD (word, 29, 29) << 10 |
721 GET_FIELD (word, 11, 15) << 11 |
722 (word & 0x1) << 16, 17) << 2;
723}
724
725
726CORE_ADDR
727frame_saved_pc (frame)
728 FRAME frame;
729{
730 if (get_current_frame () == frame)
731 {
732 struct frame_saved_regs saved_regs;
733 CORE_ADDR pc = get_frame_pc (frame);
734
735 get_frame_saved_regs (frame, &saved_regs);
736 if (pc >= millicode_start && pc < millicode_end)
737 return read_register (31);
738 else if (saved_regs.regs[RP_REGNUM])
739 return read_memory_integer (saved_regs.regs[RP_REGNUM], 4);
740 else
741 return read_register (RP_REGNUM);
742 }
743 return read_memory_integer (frame->frame - 20, 4) & ~0x3;
744}
745
746
747/* To see if a frame chain is valid, see if the caller looks like it
748 was compiled with gcc. */
749
750int frame_chain_valid (chain, thisframe)
751 FRAME_ADDR chain;
752 FRAME thisframe;
753{
754 if (chain && (chain > 0x60000000
755 /* || remote_debugging -this is no longer used */
756#ifdef KERNELDEBUG
757 || kernel_debugging
758#endif
759 ))
760 {
761 CORE_ADDR pc = get_pc_function_start (FRAME_SAVED_PC (thisframe));
762
763 if (!inside_entry_file (pc))
764 return 0;
765 /* look for stw rp, -20(0,sp); copy 4,1; copy sp, 4 */
766 if (read_memory_integer (pc, 4) == 0x6BC23FD9)
767 pc = pc + 4;
768
769 if (read_memory_integer (pc, 4) == 0x8040241 &&
770 read_memory_integer (pc + 4, 4) == 0x81E0244)
771 return 1;
772 else
773 return 0;
774 }
775 else
776 return 0;
777}
778
779/* Some helper functions. gcc_p returns 1 if the function beginning at
780 pc appears to have been compiled with gcc. hpux_cc_p returns 1 if
781 fn was compiled with hpux cc. gcc functions look like :
782
783 stw rp,-0x14(sp) ; optional
784 or r4,r0,r1
785 or sp,r0,r4
786 stwm r1,framesize(sp)
787
788 hpux cc functions look like:
789
790 stw rp,-0x14(sp) ; optional.
791 stwm r3,framesiz(sp)
792 */
793
794gcc_p (pc)
795 CORE_ADDR pc;
796{
797 if (read_memory_integer (pc, 4) == 0x6BC23FD9)
798 pc = pc + 4;
799
800 if (read_memory_integer (pc, 4) == 0x8040241 &&
801 read_memory_integer (pc + 4, 4) == 0x81E0244)
802 return 1;
803 return 0;
804}
805
806
807find_dummy_frame_regs (frame, frame_saved_regs)
808 struct frame_info *frame;
809 struct frame_saved_regs *frame_saved_regs;
810{
811 CORE_ADDR fp = frame->frame;
812 int i;
813
814 frame_saved_regs->regs[RP_REGNUM] = fp - 20 & ~0x3;
815 frame_saved_regs->regs[FP_REGNUM] = fp;
816 frame_saved_regs->regs[1] = fp + 8;
817 frame_saved_regs->regs[3] = fp + 12;
818 for (fp += 16, i = 3; i < 30; fp += 4, i++)
819 frame_saved_regs->regs[i] = fp;
820 frame_saved_regs->regs[31] = fp;
821 fp += 4;
822 for (i = FP0_REGNUM; i < NUM_REGS; i++, fp += 8)
823 frame_saved_regs->regs[i] = fp;
824 /* depend on last increment of fp */
825 frame_saved_regs->regs[IPSW_REGNUM] = fp - 4;
826 frame_saved_regs->regs[SAR_REGNUM] = fp;
827 fp += 4;
828 frame_saved_regs->regs[PCOQ_TAIL_REGNUM] = fp;
829 frame_saved_regs->regs[PCSQ_TAIL_REGNUM] = fp;
830}
831
832CORE_ADDR
833hp_push_arguments (nargs, args, sp, struct_return, struct_addr)
834 int nargs;
835 value *args;
836 CORE_ADDR sp;
837 int struct_return;
838 CORE_ADDR struct_addr;
839{
840 /* array of arguments' offsets */
841 int *offset = (int *)alloca(nargs);
842 int cum = 0;
843 int i, alignment;
844
845 for (i = 0; i < nargs; i++)
846 {
847 cum += TYPE_LENGTH (VALUE_TYPE (args[i]));
848 /* value must go at proper alignment. Assume alignment is a
849 power of two.*/
850 alignment = hp_alignof (VALUE_TYPE (args[i]));
851 if (cum % alignment)
852 cum = (cum + alignment) & -alignment;
853 offset[i] = -cum;
854 }
855 for (i == 0; i < nargs; i++)
856 {
857 write_memory (sp + offset[i], VALUE_CONTENTS (args[i]), sizeof(int));
858 }
859 sp += min ((cum + 7) & -8, 48);
860 if (struct_return)
861 write_register (28, struct_addr);
862 return sp + 48;
863}
864
865/* return the alignment of a type in bytes. Structures have the maximum
866 alignment required by their fields. */
867
868int
869hp_alignof (arg)
870 struct type *arg;
871{
872 int max_align, align, i;
873 switch (TYPE_CODE (arg))
874 {
875 case TYPE_CODE_PTR:
876 case TYPE_CODE_INT:
877 case TYPE_CODE_FLT:
878 return TYPE_LENGTH (arg);
879 case TYPE_CODE_ARRAY:
880 return hp_alignof (TYPE_FIELD_TYPE (arg, 0));
881 case TYPE_CODE_STRUCT:
882 case TYPE_CODE_UNION:
883 max_align = 2;
884 for (i = 0; i < TYPE_NFIELDS (arg); i++)
885 {
886 /* Bit fields have no real alignment. */
887 if (!TYPE_FIELD_BITPOS (arg, i))
888 {
889 align = hp_alignof (TYPE_FIELD_TYPE (arg, i));
890 max_align = max (max_align, align);
891 }
892 }
893 return max_align;
894 default:
895 return 4;
896 }
897}
898
899/* Print the register regnum, or all registers if regnum is -1 */
900
901pa_do_registers_info (regnum, fpregs)
902 int regnum;
903 int fpregs;
904{
905 char raw_regs [REGISTER_BYTES];
906 int i;
907
908 for (i = 0; i < NUM_REGS; i++)
909 read_relative_register_raw_bytes (i, raw_regs + REGISTER_BYTE (i));
910 if (regnum = -1)
911 pa_print_registers (raw_regs, regnum);
912 else if (regnum < FP0_REGNUM)
913 {
914 printf ("%s %x\n", reg_names[regnum], *(long *)(raw_regs +
915 REGISTER_BYTE (regnum)));
916 }
917 else
918 pa_print_fp_reg (regnum);
919}
920
921pa_print_registers (raw_regs, regnum)
922 char *raw_regs;
923 int regnum;
924{
925 int i;
926
927 for (i = 0; i < 18; i++)
928 printf ("%8.8s: %8x %8.8s: %8x %8.8s: %8x %8.8s: %8x\n",
929 reg_names[i],
930 *(int *)(raw_regs + REGISTER_BYTE (i)),
931 reg_names[i + 18],
932 *(int *)(raw_regs + REGISTER_BYTE (i + 18)),
933 reg_names[i + 36],
934 *(int *)(raw_regs + REGISTER_BYTE (i + 36)),
935 reg_names[i + 54],
936 *(int *)(raw_regs + REGISTER_BYTE (i + 54)));
937 for (i = 72; i < NUM_REGS; i++)
938 pa_print_fp_reg (i);
939}
940
941pa_print_fp_reg (i)
942 int i;
943{
944 unsigned char raw_buffer[MAX_REGISTER_RAW_SIZE];
945 unsigned char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
946 REGISTER_TYPE val;
947
948 /* Get the data in raw format, then convert also to virtual format. */
949 read_relative_register_raw_bytes (i, raw_buffer);
950 REGISTER_CONVERT_TO_VIRTUAL (i, raw_buffer, virtual_buffer);
951
952 fputs_filtered (reg_names[i], stdout);
953 print_spaces_filtered (15 - strlen (reg_names[i]), stdout);
954
955 val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, stdout, 0,
956 1, 0, Val_pretty_default);
957 printf_filtered ("\n");
958
959}
960
961/*
962 * Virtual to physical translation routines for Utah's Mach 3.0
963 */
964#ifdef MACHKERNELDEBUG
965
966#define STATIC
967
968#if 0 /* too many includes to resolve, too much crap */
969#include <kern/queue.h>
970#include <vm/pmap.h>
971#include <mach/vm_prot.h>
972#else
973/* queue.h */
974struct queue_entry {
975 struct queue_entry *next; /* next element */
976 struct queue_entry *prev; /* previous element */
977};
978
979typedef struct queue_entry *queue_t;
980typedef struct queue_entry queue_head_t;
981typedef struct queue_entry queue_chain_t;
982typedef struct queue_entry *queue_entry_t;
983
984/* pmap.h */
985#define HP800_HASHSIZE 1024
986#define HP800_HASHSIZE_LOG2 10
987
988#define pmap_hash(space, offset) \
989 (((unsigned) (space) << 5 ^ \
990 ((unsigned) (offset) >> 19 | (unsigned) (space) << 13) ^ \
991 (unsigned) (offset) >> 11) & (HP800_HASHSIZE-1))
992
993struct mapping {
994 queue_head_t hash_link; /* hash table links */
995 queue_head_t phys_link; /* for mappings of a given PA */
996 space_t space; /* virtual space */
997 unsigned offset; /* virtual page number */
998 unsigned tlbpage; /* physical page (for TLB load) */
999 unsigned tlbprot; /* prot/access rights (for TLB load) */
1000 struct pmap *pmap; /* pmap mapping belongs to */
1001};
1002
1003struct phys_entry {
1004 queue_head_t phys_link; /* head of mappings of a given PA */
1005 struct mapping *writer; /* mapping with R/W access */
1006 unsigned tlbprot; /* TLB format protection */
1007};
1008
1009#endif
1010
1011#define atop(a) ((unsigned)(a) >> 11)
1012#define ptoa(p) ((unsigned)(p) << 11)
1013#define trunc_page(a) ((unsigned)(a) & ~2047)
1014
1015STATIC long equiv_end;
1016STATIC queue_head_t *Ovtop_table, *vtop_table, *Ofree_mapping, free_mapping;
1017STATIC struct phys_entry *Ophys_table, *phys_table;
1018STATIC long vm_last_phys, vm_first_phys;
1019STATIC struct mapping *firstmap, *lastmap, *Omap_table, *map_table;
1020STATIC unsigned Omlow, Omhigh, Omhead, Ovlow, Ovhigh, Oplow, Ophigh;
1021STATIC unsigned mlow, mhigh, mhead, vlow, vhigh, plow, phigh;
1022STATIC int vtopsize, physsize, mapsize;
1023STATIC int kmemfd;
1024
1025#define IS_OVTOPPTR(p) ((unsigned)(p) >= Ovlow && (unsigned)(p) < Ovhigh)
1026#define IS_OMAPPTR(p) ((unsigned)(p) >= Omlow && (unsigned)(p) < Omhigh)
1027#define IS_OPHYSPTR(p) ((unsigned)(p) >= Oplow && (unsigned)(p) < Ophigh)
1028#define IS_VTOPPTR(p) ((unsigned)(p) >= vlow && (unsigned)(p) < vhigh)
1029#define IS_MAPPTR(p) ((unsigned)(p) >= mlow && (unsigned)(p) < mhigh)
1030#define IS_PHYSPTR(p) ((unsigned)(p) >= plow && (unsigned)(p) < phigh)
1031
1032struct mapstate {
1033 char unused;
1034 char flags;
1035 short hashix;
1036 short physix;
1037} *mapstate;
1038
1039/* flags */
1040#define M_ISFREE 1
1041#define M_ISHASH 2
1042#define M_ISPHYS 4
1043
1044mach_vtophys_init()
1045{
1046 int errors = 0;
1047
1048 if (!readdata())
1049 errors++;
1050 if (!verifydata())
1051 errors++;
1052 if (!errors)
1053 return(1);
1054 fflush(stdout);
1055 fprintf(stderr,
1056 "translate: may not be able to translate all addresses\n");
1057 return(0);
1058}
1059
1060mach_vtophys(space, off, pa)
1061 unsigned space, off, *pa;
1062{
1063 register int i;
1064 register queue_t qp;
1065 register struct mapping *mp;
1066 int poff;
1067
1068 /*
1069 * Kernel IO or equivilently mapped, one to one.
1070 */
1071 if (space == 0 && (long)off < equiv_end) {
1072 *pa = off;
1073 return(1);
1074 }
1075 /*
1076 * Else look it up in specified space
1077 */
1078 poff = off - trunc_page(off);
1079 off = trunc_page(off);
1080 qp = &vtop_table[pmap_hash(space, off)];
1081 for (mp = (struct mapping *)qp->next;
1082 qp != (queue_entry_t)mp;
1083 mp = (struct mapping *)mp->hash_link.next) {
1084 if (mp->space == space && mp->offset == off) {
1085 *pa = (mp->tlbpage << 7) | poff;
1086 return(1);
1087 }
1088 }
1089 return(0);
1090}
1091
1092STATIC
1093readdata()
1094{
1095 char *tmp, *mach_malloc();
1096 long size;
1097
1098 /* easy scalars */
1099 mach_read("equiv_end", ~0, (char *)&equiv_end, sizeof equiv_end);
1100 mach_read("vm_first_phys", ~0,
1101 (char *)&vm_first_phys, sizeof vm_first_phys);
1102 mach_read("vm_last_phys", ~0,
1103 (char *)&vm_last_phys, sizeof vm_last_phys);
1104 mach_read("firstmap", ~0, (char *)&firstmap, sizeof firstmap);
1105 mach_read("lastmap", ~0, (char *)&lastmap, sizeof lastmap);
1106
1107 /* virtual to physical hash table */
1108 vtopsize = HP800_HASHSIZE;
1109 size = vtopsize * sizeof(queue_head_t);
1110 tmp = mach_malloc("vtop table", size);
1111 mach_read("vtop_table", ~0, (char *)&Ovtop_table, sizeof Ovtop_table);
1112 mach_read("vtop table", (CORE_ADDR)Ovtop_table, tmp, size);
1113 vtop_table = (queue_head_t *) tmp;
1114
1115 /* inverted page table */
1116 physsize = atop(vm_last_phys - vm_first_phys);
1117 size = physsize * sizeof(struct phys_entry);
1118 tmp = mach_malloc("phys table", size);
1119 mach_read("phys_table", ~0, (char *)&Ophys_table, sizeof Ophys_table);
1120 mach_read("phys table", (CORE_ADDR)Ophys_table, tmp, size);
1121 phys_table = (struct phys_entry *) tmp;
1122
1123 /* mapping structures */
1124 Ofree_mapping = (queue_head_t *) ksym_lookup("free_mapping");
1125 mach_read("free mapping", (CORE_ADDR)Ofree_mapping,
1126 (char *) &free_mapping, sizeof free_mapping);
1127 Omap_table = firstmap;
1128 mapsize = lastmap - firstmap;
1129 size = mapsize * sizeof(struct mapping);
1130 tmp = mach_malloc("mapping table", size);
1131 mach_read("mapping table", (CORE_ADDR)Omap_table, tmp, size);
1132 map_table = (struct mapping *) tmp;
1133
1134 /* set limits */
1135 Ovlow = (unsigned) Ovtop_table;
1136 Ovhigh = (unsigned) &Ovtop_table[vtopsize];
1137 Oplow = (unsigned) Ophys_table;
1138 Ophigh = (unsigned) &Ophys_table[physsize];
1139 Omhead = (unsigned) Ofree_mapping;
1140 Omlow = (unsigned) firstmap;
1141 Omhigh = (unsigned) lastmap;
1142 mlow = (unsigned) map_table;
1143 mhigh = (unsigned) &map_table[mapsize];
1144 mhead = (unsigned) &free_mapping;
1145 vlow = (unsigned) vtop_table;
1146 vhigh = (unsigned) &vtop_table[vtopsize];
1147 plow = (unsigned) phys_table;
1148 phigh = (unsigned) &phys_table[physsize];
1149
1150#if 0
1151 fprintf(stderr, "Ovtop [%#x-%#x) Ophys [%#x-%#x) Omap %#x [%#x-%#x)\n",
1152 Ovlow, Ovhigh, Oplow, Ophigh, Omhead, Omlow, Omhigh);
1153 fprintf(stderr, "vtop [%#x-%#x) phys [%#x-%#x) map %#x [%#x-%#x)\n",
1154 vlow, vhigh, plow, phigh, mhead, mlow, mhigh);
1155#endif
1156 return(adjustdata());
1157}
1158
1159STATIC unsigned
1160ptrcvt(ptr)
1161 unsigned ptr;
1162{
1163 unsigned ret;
1164 char *str;
1165
1166 if (ptr == 0) {
1167 ret = ptr;
1168 str = "null";
1169 } else if (IS_OVTOPPTR(ptr)) {
1170 ret = vlow + (ptr - Ovlow);
1171 str = "vtop";
1172 } else if (IS_OPHYSPTR(ptr)) {
1173 ret = plow + (ptr - Oplow);
1174 str = "phys";
1175 } else if (IS_OMAPPTR(ptr)) {
1176 ret = mlow + (ptr - Omlow);
1177 str = "map";
1178 } else if (ptr == Omhead) {
1179 ret = mhead;
1180 str = "maphead";
1181 } else {
1182 error("bogus pointer %#x", ptr);
1183 str = "wild";
1184 ret = ptr;
1185 }
1186#if 0
1187 fprintf(stderr, "%x (%s) -> %x\n", ptr, str, ret);
1188#endif
1189 return(ret);
1190}
1191
1192STATIC int
1193adjustdata()
1194{
1195 register int i, lim;
1196 queue_head_t *nq;
1197 struct phys_entry *np;
1198 struct mapping *nm;
1199
1200 /* hash table */
1201 lim = vtopsize;
1202 for (nq = vtop_table; nq < &vtop_table[lim]; nq++) {
1203 nq->next = (queue_entry_t) ptrcvt((unsigned)nq->next);
1204 nq->prev = (queue_entry_t) ptrcvt((unsigned)nq->prev);
1205 }
1206
1207 /* IPT */
1208 lim = physsize;
1209 for (np = phys_table; np < &phys_table[lim]; np++) {
1210 np->phys_link.next = (queue_entry_t)
1211 ptrcvt((unsigned)np->phys_link.next);
1212 np->phys_link.prev = (queue_entry_t)
1213 ptrcvt((unsigned)np->phys_link.prev);
1214 np->writer = (struct mapping *) ptrcvt((unsigned)np->writer);
1215 }
1216
1217 /* mapping table */
1218 free_mapping.next = (queue_entry_t)ptrcvt((unsigned)free_mapping.next);
1219 free_mapping.prev = (queue_entry_t)ptrcvt((unsigned)free_mapping.prev);
1220 lim = mapsize;
1221 for (nm = map_table; nm < &map_table[lim]; nm++) {
1222 nm->hash_link.next = (queue_entry_t)
1223 ptrcvt((unsigned)nm->hash_link.next);
1224 nm->hash_link.prev = (queue_entry_t)
1225 ptrcvt((unsigned)nm->hash_link.prev);
1226 nm->phys_link.next = (queue_entry_t)
1227 ptrcvt((unsigned)nm->phys_link.next);
1228 nm->phys_link.prev = (queue_entry_t)
1229 ptrcvt((unsigned)nm->phys_link.prev);
1230 }
1231 return(1);
1232}
1233
1234/*
1235 * Consistency checks, make sure:
1236 *
1237 * 1. all mappings are accounted for
1238 * 2. no cycles
1239 * 3. no wild pointers
1240 * 4. consisent TLB state
1241 */
1242STATIC int
1243verifydata()
1244{
1245 register struct mapstate *ms;
1246 register int i;
1247 int errors = 0;
1248
1249 mapstate = (struct mapstate *)
1250 mach_malloc("map state", mapsize * sizeof(struct mapstate));
1251 for (ms = mapstate; ms < &mapstate[mapsize]; ms++) {
1252 ms->flags = 0;
1253 ms->hashix = ms->physix = -2;
1254 }
1255
1256 /*
1257 * Check the free list
1258 */
1259 checkhashchain(&free_mapping, M_ISFREE, -1);
1260 /*
1261 * Check every hash chain
1262 */
1263 for (i = 0; i < vtopsize; i++)
1264 checkhashchain(&vtop_table[i], M_ISHASH, i);
1265 /*
1266 * Check every phys chain
1267 */
1268 for (i = 0; i < physsize; i++)
1269 checkphyschain(&phys_table[i].phys_link, M_ISPHYS, i);
1270 /*
1271 * Cycle through mapstate looking for anomolies
1272 */
1273 ms = mapstate;
1274 for (i = 0; i < mapsize; i++) {
1275 switch (ms->flags) {
1276 case M_ISFREE:
1277 case M_ISHASH|M_ISPHYS:
1278 break;
1279 case 0:
1280 merror(ms, "not found");
1281 errors++;
1282 break;
1283 case M_ISHASH:
1284 merror(ms, "in vtop but not phys");
1285 errors++;
1286 break;
1287 case M_ISPHYS:
1288 merror(ms, "in phys but not vtop");
1289 errors++;
1290 break;
1291 default:
1292 merror(ms, "totally bogus");
1293 errors++;
1294 break;
1295 }
1296 ms++;
1297 }
1298 return(errors ? 0 : 1);
1299}
1300
1301STATIC void
1302checkhashchain(qhp, flag, ix)
1303 queue_entry_t qhp;
1304{
1305 register queue_entry_t qp, pqp;
1306 register struct mapping *mp;
1307 struct mapstate *ms;
1308
1309 qp = qhp->next;
1310 /*
1311 * First element is not a mapping structure,
1312 * chain must be empty.
1313 */
1314 if (!IS_MAPPTR(qp)) {
1315 if (qp != qhp || qp != qhp->prev)
1316 fatal("bad vtop_table header pointer");
1317 } else {
1318 pqp = qhp;
1319 do {
1320 mp = (struct mapping *) qp;
1321 qp = &mp->hash_link;
1322 if (qp->prev != pqp)
1323 fatal("bad hash_link prev pointer");
1324 ms = &mapstate[mp-map_table];
1325 ms->flags |= flag;
1326 ms->hashix = ix;
1327 pqp = (queue_entry_t) mp;
1328 qp = qp->next;
1329 } while (IS_MAPPTR(qp));
1330 if (qp != qhp)
1331 fatal("bad hash_link next pointer");
1332 }
1333}
1334
1335STATIC void
1336checkphyschain(qhp, flag, ix)
1337 queue_entry_t qhp;
1338{
1339 register queue_entry_t qp, pqp;
1340 register struct mapping *mp;
1341 struct mapstate *ms;
1342
1343 qp = qhp->next;
1344 /*
1345 * First element is not a mapping structure,
1346 * chain must be empty.
1347 */
1348 if (!IS_MAPPTR(qp)) {
1349 if (qp != qhp || qp != qhp->prev)
1350 fatal("bad phys_table header pointer");
1351 } else {
1352 pqp = qhp;
1353 do {
1354 mp = (struct mapping *) qp;
1355 qp = &mp->phys_link;
1356 if (qp->prev != pqp)
1357 fatal("bad phys_link prev pointer");
1358 ms = &mapstate[mp-map_table];
1359 ms->flags |= flag;
1360 ms->physix = ix;
1361 pqp = (queue_entry_t) mp;
1362 qp = qp->next;
1363 } while (IS_MAPPTR(qp));
1364 if (qp != qhp)
1365 fatal("bad phys_link next pointer");
1366 }
1367}
1368
1369STATIC void
1370merror(ms, str)
1371 struct mapstate *ms;
1372 char *str;
1373{
1374 terminal_ours();
1375 fflush(stdout);
1376 fprintf(stderr,
1377 "vtophys: %s: %c%c%c, hashix %d, physix %d, mapping %x\n",
1378 str,
1379 (ms->flags & M_ISFREE) ? 'F' : '-',
1380 (ms->flags & M_ISHASH) ? 'H' : '-',
1381 (ms->flags & M_ISPHYS) ? 'P' : '-',
1382 ms->hashix, ms->physix, &map_table[ms-mapstate]);
1383 return_to_top_level();
1384}
1385
1386STATIC int
1387mach_read(str, from, top, size)
1388 char *str;
1389 CORE_ADDR from;
1390 char *top;
1391 int size;
1392{
1393 CORE_ADDR paddr;
1394
1395 if (from == ~0)
1396 from = ksym_lookup(str);
1397 paddr = vtophys(0, from);
1398 if (paddr == ~0 || physrd(paddr, top, size) != 0)
1399 fatal("cannot read %s", str);
1400}
1401
1402STATIC char *
1403mach_malloc(str, size)
1404 char *str;
1405 int size;
1406{
1407 char *ptr = (char *) malloc(size);
1408
1409 if (ptr == 0)
1410 fatal("no memory for %s", str);
1411 return(ptr);
1412}
1413#endif
1414
1415#ifdef KERNELDEBUG
1416void
1417_initialize_hp9k8_dep()
1418{
1419 add_com ("process-address", class_obscure, set_paddr_command,
1420"The process identified by (ps-style) ADDR becomes the\n\
1421\"current\" process context for kernel debugging.");
1422 add_com_alias ("paddr", "process-address", class_obscure, 0);
1423 add_com ("virtual-to-physical", class_obscure, vtop_command,
1424"Translates the kernel virtual address ADDR into a physical address.");
1425 add_com_alias ("vtop", "virtual-to-physical", class_obscure, 0);
1426}
1427#endif
This page took 0.106963 seconds and 4 git commands to generate.