added base src
[xv6-db.git] / gdbutil
blobe0c362fbdb7d5acd8b774e7256a2aec2aeba4e89
1 # -*- gdb-script -*-
3 # Utility functions to pretty-print x86 segment/interrupt descriptors.
4 # To load this file, run "source gdbutil" in gdb.
5 # printdesc and printdescs are the main entry points.
7 # IA32 2007, Volume 3A, Table 3-2
8 set $STS_T16A = 0x1
9 set $STS_LDT  = 0x2
10 set $STS_T16B = 0x3
11 set $STS_CG16 = 0x4
12 set $STS_TG   = 0x5
13 set $STS_IG16 = 0x6
14 set $STS_TG16 = 0x7
15 set $STS_T32A = 0x9
16 set $STS_T32B = 0xB
17 set $STS_CG32 = 0xC
18 set $STS_IG32 = 0xE
19 set $STS_TG32 = 0xF
21 define outputsts
22   while 1
23     if $arg0 == $STS_T16A
24       echo STS_T16A
25       loop_break
26     end
27     if $arg0 == $STS_LDT
28       echo STS_LDT\ 
29       loop_break
30     end
31     if $arg0 == $STS_T16B
32       echo STS_T16B
33       loop_break
34     end
35     if $arg0 == $STS_CG16
36       echo STS_CG16
37       loop_break
38     end
39     if $arg0 == $STS_TG
40       echo STS_TG\ \ 
41       loop_break
42     end
43     if $arg0 == $STS_IG16
44       echo STS_IG16
45       loop_break
46     end
47     if $arg0 == $STS_TG16
48       echo STS_TG16
49       loop_break
50     end
51     if $arg0 == $STS_T32A
52       echo STS_T32A
53       loop_break
54     end
55     if $arg0 == $STS_T32B
56       echo STS_T32B
57       loop_break
58     end
59     if $arg0 == $STS_CG32
60       echo STS_CG32
61       loop_break
62     end
63     if $arg0 == $STS_IG32
64       echo STS_IG32
65       loop_break
66     end
67     if $arg0 == $STS_TG32
68       echo STS_TG32
69       loop_break
70     end
71     echo Reserved
72     loop_break
73   end
74 end  
76 # IA32 2007, Volume 3A, Table 3-1
77 set $STA_X = 0x8
78 set $STA_E = 0x4
79 set $STA_C = 0x4
80 set $STA_W = 0x2
81 set $STA_R = 0x2
82 set $STA_A = 0x1
84 define outputsta
85   if $arg0 & $STA_X
86     # Code segment
87     echo code
88     if $arg0 & $STA_C
89       echo |STA_C
90     end
91     if $arg0 & $STA_R
92       echo |STA_R
93     end
94   else
95     # Data segment
96     echo data
97     if $arg0 & $STA_E
98       echo |STA_E
99     end
100     if $arg0 & $STA_W
101       echo |STA_W
102     end
103   end
104   if $arg0 & $STA_A
105     echo |STA_A
106   else
107     printf "      "
108   end
111 # xv6-specific
112 set $SEG_KCODE = 1
113 set $SEG_KDATA = 2
114 set $SEG_KCPU  = 3
115 set $SEG_UCODE = 4
116 set $SEG_UDATA = 5
117 set $SEG_TSS   = 6
119 define outputcs
120   if ($arg0 & 4) == 0
121     if $arg0 >> 3 == $SEG_KCODE
122       printf "SEG_KCODE<<3"
123     end
124     if $arg0 >> 3 == $SEG_KDATA
125       printf "SEG_KDATA<<3"
126     end
127     if $arg0 >> 3 == $SEG_KCPU
128       printf "SEG_KCPU<<3"
129     end
130     if $arg0 >> 3 == $SEG_UCODE
131       printf "SEG_UCODE<<3"
132     end
133     if $arg0 >> 3 == $SEG_UDATA
134       printf "SEG_UDATA<<3"
135     end
136     if $arg0 >> 3 == $SEG_TSS
137       printf "SEG_TSS<<3"
138     end
139     if ($arg0 >> 3 < 1) + ($arg0 >> 3 > 6)
140       printf "GDT[%d]", $arg0 >> 3
141     end
142   else
143     printf "LDT[%d]", $arg0 >> 3
144   end
145   if ($arg0 & 3) > 0
146     printf "|"
147     outputdpl ($arg0&3)
148   end
151 define outputdpl
152   if $arg0 == 0
153     printf "DPL_KERN"
154   else
155     if $arg0 == 3
156       printf "DPL_USER"
157     else
158       printf "DPL%d", $arg0
159     end
160   end
163 define printdesc
164   if $argc != 1
165     echo Usage: printdesc expr
166   else
167     _printdesc ((uint*)&($arg0))[0] ((uint*)&($arg0))[1]
168     printf "\n"
169   end
172 document printdesc
173 Print an x86 segment or gate descriptor.
174 printdesc EXPR
175 EXPR must evaluate to a descriptor value.  It can be of any C type.
178 define _printdesc
179   _printdesc1 $arg0 $arg1 ($arg1>>15&1) ($arg1>>13&3) ($arg1>>12&1) ($arg1>>8&15)
182 define _printdesc1
183   # 2:P 3:DPL 4:S 5:Type
184   if $arg2 == 0
185     printf "P = 0 (Not present)"
186   else
187     printf "type = "
188     if $arg4 == 0
189       # System segment
190       outputsts $arg5
191       printf " (0x%x)    ", $arg5
192       _printsysdesc $arg0 $arg1 $arg5
193     else
194       # Code/data segment
195       outputsta $arg5
196       printf "  "
197       _printsegdesc $arg0 $arg1
198     end
200     printf "  DPL = "
201     outputdpl $arg3
202     printf " (%d)", $arg3
203   end
206 define _printsysdesc
207   # 2:Type
208   # GDB's || is buggy
209   if ($arg2 == $STS_TG) + (($arg2&7) == $STS_IG16) + (($arg2&7) == $STS_TG16)
210     # Gate descriptor
211     _printgate $arg2 ($arg0>>16) ($arg0&0xFFFF) ($arg1>>16)
212   else
213     # System segment descriptor
214     _printsegdesc $arg0 $arg1
215   end
218 define _printgate
219   # IA32 2007, Voume 3A, Figure 5-2
220   # 0:Type 1:CS 2:Offset 15..0 3:Offset 31..16
221   printf "CS = "
222   outputcs $arg1
223   printf " (%d)", $arg1
225   if (($arg0&7) == $STS_IG16) + (($arg0&7) == $STS_TG16)
226     printf "  Offset = "
227     output/a $arg3 << 16 | $arg2
228   end
231 define _printsegdesc
232   # IA32 20007, Volume 3A, Figure 3-8 and Figure 4-1
233   _printsegdesc1 ($arg0>>16) ($arg1&0xFF) ($arg1>>24) ($arg0&0xFFFF) ($arg1>>16&15) ($arg1>>23&1)
234   if ($arg1>>12&1) == 1
235     printf "  AVL = %d", $arg1>>20&1
236     if ($arg1>>11&1) == 0
237       # Data segment
238       if ($arg1>>22&1) == 0
239         printf "  B = small (0) "
240       else
241         printf "  B = big (1)   "
242       end
243     else
244       # Code segment
245       printf "  D = "
246       if ($arg1>>22&1) == 0
247         printf "16-bit (0)"
248       else
249         printf "32-bit (1)"
250       end
251     end
252   end
255 define _printsegdesc1
256   # 0:Base 0..15  1:Base 16..23  2:Base 24..32  3:Limit 0..15  4:Limit 16..19  5:G
257   printf "base = 0x%08x", $arg0 | ($arg1<<16) | ($arg2<<24)
258   printf "  limit = 0x"
259   if $arg5 == 0
260     printf "%08x", $arg3 | ($arg4<<16)
261   else
262     printf "%08x", (($arg3 | ($arg4<<16)) << 12) | 0xFFF
263   end
266 define printdescs
267   if $argc < 1 || $argc > 2
268     echo Usage: printdescs expr [count]
269   else
270     if $argc == 1
271       _printdescs ($arg0) (sizeof($arg0)/sizeof(($arg0)[0]))
272     else
273       _printdescs ($arg0) ($arg1)
274     end
275   end
278 document printdescs
279 Print an array of x86 segment or gate descriptors.
280 printdescs EXPR [COUNT]
281 EXPR must evaluate to an array of descriptors.
284 define _printdescs
285   set $i = 0
286   while $i < $arg1
287     printf "[%d] ", $i
288     printdesc $arg0[$i]
289     set $i = $i + 1
290   end