1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
/////////////////////////////////////////////////////////////////////////
// $Id: linux.cc,v 1.5 2006/03/06 22:02:50 sshwarts Exp $
/////////////////////////////////////////////////////////////////////////
//
#include <stdio.h>
#include "bochs.h"
#include "cpu/cpu.h"
#if BX_DEBUGGER
#define LOG_THIS genlog->
// for Linux segment numbers
// these numbers are from <asm/segment.h>
#define KERNEL_CS 0x10
#define USER_CS 0x18
void bx_dbg_info_linux_command (void)
{
BX_INFO (("Info linux"));
bx_dbg_cpu_t cpu;
BX_CPU(dbg_cpu)->dbg_get_cpu(&cpu);
int mode;
if (cpu.cr0 & 1) {
// protected mode
if (cpu.cs.sel == KERNEL_CS) {
mode = 'k';
fprintf (stderr, "Processor mode: kernel\n");
} else if (cpu.cs.sel == USER_CS) {
fprintf (stderr, "Processor mode: user\n");
mode = 'u';
} else {
mode = '?';
fprintf (stderr, "Processor mode: ??? protected=1 but unrecognized CS\n");
}
} else {
mode = 'r';
fprintf (stderr, "Processor mode: real-address mode, maybe during boot sequence\n");
}
if (mode != 'u') return;
/* user mode, look through registers and memory to find our process ID */
#if 0
fprintf(stderr, "eax:0x%x\n", (unsigned) cpu.eax);
fprintf(stderr, "ebx:0x%x\n", (unsigned) cpu.ebx);
fprintf(stderr, "ecx:0x%x\n", (unsigned) cpu.ecx);
fprintf(stderr, "edx:0x%x\n", (unsigned) cpu.edx);
fprintf(stderr, "ebp:0x%x\n", (unsigned) cpu.ebp);
fprintf(stderr, "esi:0x%x\n", (unsigned) cpu.esi);
fprintf(stderr, "edi:0x%x\n", (unsigned) cpu.edi);
fprintf(stderr, "esp:0x%x\n", (unsigned) cpu.esp);
fprintf(stderr, "eflags:0x%x\n", (unsigned) cpu.eflags);
fprintf(stderr, "eip:0x%x\n", (unsigned) cpu.eip);
fprintf(stderr, "cs:s=0x%x, dl=0x%x, dh=0x%x, valid=%u\n",
(unsigned) cpu.cs.sel, (unsigned) cpu.cs.des_l,
(unsigned) cpu.cs.des_h, (unsigned) cpu.cs.valid);
fprintf(stderr, "ss:s=0x%x, dl=0x%x, dh=0x%x, valid=%u\n",
(unsigned) cpu.ss.sel, (unsigned) cpu.ss.des_l,
(unsigned) cpu.ss.des_h, (unsigned) cpu.ss.valid);
fprintf(stderr, "ds:s=0x%x, dl=0x%x, dh=0x%x, valid=%u\n",
(unsigned) cpu.ds.sel, (unsigned) cpu.ds.des_l,
(unsigned) cpu.ds.des_h, (unsigned) cpu.ds.valid);
fprintf(stderr, "es:s=0x%x, dl=0x%x, dh=0x%x, valid=%u\n",
(unsigned) cpu.es.sel, (unsigned) cpu.es.des_l,
(unsigned) cpu.es.des_h, (unsigned) cpu.es.valid);
fprintf(stderr, "fs:s=0x%x, dl=0x%x, dh=0x%x, valid=%u\n",
(unsigned) cpu.fs.sel, (unsigned) cpu.fs.des_l,
(unsigned) cpu.fs.des_h, (unsigned) cpu.fs.valid);
fprintf(stderr, "gs:s=0x%x, dl=0x%x, dh=0x%x, valid=%u\n",
(unsigned) cpu.gs.sel, (unsigned) cpu.gs.des_l,
(unsigned) cpu.gs.des_h, (unsigned) cpu.gs.valid);
fprintf(stderr, "ldtr:s=0x%x, dl=0x%x, dh=0x%x, valid=%u\n",
(unsigned) cpu.ldtr.sel, (unsigned) cpu.ldtr.des_l,
(unsigned) cpu.ldtr.des_h, (unsigned) cpu.ldtr.valid);
fprintf(stderr, "tr:s=0x%x, dl=0x%x, dh=0x%x, valid=%u\n",
(unsigned) cpu.tr.sel, (unsigned) cpu.tr.des_l,
(unsigned) cpu.tr.des_h, (unsigned) cpu.tr.valid);
fprintf(stderr, "gdtr:base=0x%x, limit=0x%x\n",
(unsigned) cpu.gdtr.base, (unsigned) cpu.gdtr.limit);
fprintf(stderr, "idtr:base=0x%x, limit=0x%x\n",
(unsigned) cpu.idtr.base, (unsigned) cpu.idtr.limit);
fprintf(stderr, "dr0:0x%x\n", (unsigned) cpu.dr0);
fprintf(stderr, "dr1:0x%x\n", (unsigned) cpu.dr1);
fprintf(stderr, "dr2:0x%x\n", (unsigned) cpu.dr2);
fprintf(stderr, "dr3:0x%x\n", (unsigned) cpu.dr3);
fprintf(stderr, "dr6:0x%x\n", (unsigned) cpu.dr6);
fprintf(stderr, "dr7:0x%x\n", (unsigned) cpu.dr7);
fprintf(stderr, "cr0:0x%x\n", (unsigned) cpu.cr0);
fprintf(stderr, "cr1:0x%x\n", (unsigned) cpu.cr1);
fprintf(stderr, "cr2:0x%x\n", (unsigned) cpu.cr2);
fprintf(stderr, "cr3:0x%x\n", (unsigned) cpu.cr3);
fprintf(stderr, "cr4:0x%x\n", (unsigned) cpu.cr4);
fprintf(stderr, "inhibit_mask:%u\n", cpu.inhibit_mask);
#endif
}
class syscall_names_t {
#define MAX_SYSCALLS 200
char *syscall_names_linux[MAX_SYSCALLS];
public:
syscall_names_t () { init (); }
void init ();
char *get_name (int num);
};
void syscall_names_t::init ()
{
for (int i=0; i<MAX_SYSCALLS; i++) {
syscall_names_linux[i] = "<unknown syscall>";
}
#define DEF_SYSCALL(num,name) syscall_names_linux[num] = name;
/* basically every line in the included file is a call to DEF_SYSCALL.
The preprocessor will turn each DEF_SYSCALL into an assignment
to syscall_names_linux[num]. */
#include "syscalls-linux.h"
/* now almost all the name entries have been initialized. If there
are any gaps, they still point to "<unknown syscall>". */
#if (N_SYSCALLS > MAX_SYSCALLS)
#error MAX_SYSCALLS must exceed N_SYSCALLS from syscalls-linux.h
#endif
}
char *syscall_names_t::get_name (int n)
{
static char buf[64];
if (n < 0 || n > N_SYSCALLS) {
sprintf (buf, "syscall %d out of range", n);
return buf;
}
return syscall_names_linux[n];
}
syscall_names_t syscall_names;
void bx_dbg_linux_syscall (unsigned which_cpu)
{
Bit32u eax = BX_CPU(which_cpu)->get_reg32(BX_32BIT_REG_EAX);
char *name = syscall_names.get_name (eax);
fprintf (stderr, "linux system call %s (#%d)\n", name, eax);
}
#endif /* if BX_DEBUGGER */
|