File: linux.cc

package info (click to toggle)
bochs 2.3-2etch1
  • links: PTS
  • area: main
  • in suites: etch
  • size: 14,116 kB
  • ctags: 16,927
  • sloc: cpp: 130,524; ansic: 18,822; sh: 7,922; makefile: 3,836; yacc: 1,056; asm: 463; perl: 381; lex: 280; csh: 3
file content (158 lines) | stat: -rw-r--r-- 5,250 bytes parent folder | download | duplicates (2)
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 */