forked from mit-pdos/xv6-public
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Austin Clements
committed
Nov 23, 2009
1 parent
f4c12f1
commit b0170c4
Showing
1 changed file
with
291 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,291 @@ | ||
# -*- gdb-script -*- | ||
|
||
# Utility functions to pretty-print x86 segment/interrupt descriptors. | ||
# To load this file, run "source gdbutil" in gdb. | ||
# printdesc and printdescs are the main entry points. | ||
|
||
# IA32 2007, Volume 3A, Table 3-2 | ||
set $STS_T16A = 0x1 | ||
set $STS_LDT = 0x2 | ||
set $STS_T16B = 0x3 | ||
set $STS_CG16 = 0x4 | ||
set $STS_TG = 0x5 | ||
set $STS_IG16 = 0x6 | ||
set $STS_TG16 = 0x7 | ||
set $STS_T32A = 0x9 | ||
set $STS_T32B = 0xB | ||
set $STS_CG32 = 0xC | ||
set $STS_IG32 = 0xE | ||
set $STS_TG32 = 0xF | ||
|
||
define outputsts | ||
while 1 | ||
if $arg0 == $STS_T16A | ||
echo STS_T16A | ||
loop_break | ||
end | ||
if $arg0 == $STS_LDT | ||
echo STS_LDT\ | ||
loop_break | ||
end | ||
if $arg0 == $STS_T16B | ||
echo STS_T16B | ||
loop_break | ||
end | ||
if $arg0 == $STS_CG16 | ||
echo STS_CG16 | ||
loop_break | ||
end | ||
if $arg0 == $STS_TG | ||
echo STS_TG\ \ | ||
loop_break | ||
end | ||
if $arg0 == $STS_IG16 | ||
echo STS_IG16 | ||
loop_break | ||
end | ||
if $arg0 == $STS_TG16 | ||
echo STS_TG16 | ||
loop_break | ||
end | ||
if $arg0 == $STS_T32A | ||
echo STS_T32A | ||
loop_break | ||
end | ||
if $arg0 == $STS_T32B | ||
echo STS_T32B | ||
loop_break | ||
end | ||
if $arg0 == $STS_CG32 | ||
echo STS_CG32 | ||
loop_break | ||
end | ||
if $arg0 == $STS_IG32 | ||
echo STS_IG32 | ||
loop_break | ||
end | ||
if $arg0 == $STS_TG32 | ||
echo STS_TG32 | ||
loop_break | ||
end | ||
echo Reserved | ||
loop_break | ||
end | ||
end | ||
|
||
# IA32 2007, Volume 3A, Table 3-1 | ||
set $STA_X = 0x8 | ||
set $STA_E = 0x4 | ||
set $STA_C = 0x4 | ||
set $STA_W = 0x2 | ||
set $STA_R = 0x2 | ||
set $STA_A = 0x1 | ||
|
||
define outputsta | ||
if $arg0 & $STA_X | ||
# Code segment | ||
echo code | ||
if $arg0 & $STA_C | ||
echo |STA_C | ||
end | ||
if $arg0 & $STA_R | ||
echo |STA_R | ||
end | ||
else | ||
# Data segment | ||
echo data | ||
if $arg0 & $STA_E | ||
echo |STA_E | ||
end | ||
if $arg0 & $STA_W | ||
echo |STA_W | ||
end | ||
end | ||
if $arg0 & $STA_A | ||
echo |STA_A | ||
else | ||
printf " " | ||
end | ||
end | ||
|
||
# xv6-specific | ||
set $SEG_KCODE = 1 | ||
set $SEG_KDATA = 2 | ||
set $SEG_KCPU = 3 | ||
set $SEG_UCODE = 4 | ||
set $SEG_UDATA = 5 | ||
set $SEG_TSS = 6 | ||
|
||
define outputcs | ||
if ($arg0 & 4) == 0 | ||
if $arg0 >> 3 == $SEG_KCODE | ||
printf "SEG_KCODE<<3" | ||
end | ||
if $arg0 >> 3 == $SEG_KDATA | ||
printf "SEG_KDATA<<3" | ||
end | ||
if $arg0 >> 3 == $SEG_KCPU | ||
printf "SEG_KCPU<<3" | ||
end | ||
if $arg0 >> 3 == $SEG_UCODE | ||
printf "SEG_UCODE<<3" | ||
end | ||
if $arg0 >> 3 == $SEG_UDATA | ||
printf "SEG_UDATA<<3" | ||
end | ||
if $arg0 >> 3 == $SEG_TSS | ||
printf "SEG_TSS<<3" | ||
end | ||
if ($arg0 >> 3 < 1) + ($arg0 >> 3 > 6) | ||
printf "GDT[%d]", $arg0 >> 3 | ||
end | ||
else | ||
printf "LDT[%d]", $arg0 >> 3 | ||
end | ||
if ($arg0 & 3) > 0 | ||
printf "|" | ||
outputdpl ($arg0&3) | ||
end | ||
end | ||
|
||
define outputdpl | ||
if $arg0 == 0 | ||
printf "DPL_KERN" | ||
else | ||
if $arg0 == 3 | ||
printf "DPL_USER" | ||
else | ||
printf "DPL%d", $arg0 | ||
end | ||
end | ||
end | ||
|
||
define printdesc | ||
if $argc != 1 | ||
echo Usage: printdesc expr | ||
else | ||
_printdesc ((uint*)&($arg0))[0] ((uint*)&($arg0))[1] | ||
printf "\n" | ||
end | ||
end | ||
|
||
document printdesc | ||
Print an x86 segment or gate descriptor. | ||
printdesc EXPR | ||
EXPR must evaluate to a descriptor value. It can be of any C type. | ||
end | ||
|
||
define _printdesc | ||
_printdesc1 $arg0 $arg1 ($arg1>>15&1) ($arg1>>13&3) ($arg1>>12&1) ($arg1>>8&15) | ||
end | ||
|
||
define _printdesc1 | ||
# 2:P 3:DPL 4:S 5:Type | ||
if $arg2 == 0 | ||
printf "P = 0 (Not present)" | ||
else | ||
printf "type = " | ||
if $arg4 == 0 | ||
# System segment | ||
outputsts $arg5 | ||
printf " (0x%x) ", $arg5 | ||
_printsysdesc $arg0 $arg1 $arg5 | ||
else | ||
# Code/data segment | ||
outputsta $arg5 | ||
printf " " | ||
_printsegdesc $arg0 $arg1 | ||
end | ||
|
||
printf " DPL = " | ||
outputdpl $arg3 | ||
printf " (%d)", $arg3 | ||
end | ||
end | ||
|
||
define _printsysdesc | ||
# 2:Type | ||
# GDB's || is buggy | ||
if ($arg2 == $STS_TG) + (($arg2&7) == $STS_IG16) + (($arg2&7) == $STS_TG16) | ||
# Gate descriptor | ||
_printgate $arg2 ($arg0>>16) ($arg0&0xFFFF) ($arg1>>16) | ||
else | ||
# System segment descriptor | ||
_printsegdesc $arg0 $arg1 | ||
end | ||
end | ||
|
||
define _printgate | ||
# IA32 2007, Voume 3A, Figure 5-2 | ||
# 0:Type 1:CS 2:Offset 15..0 3:Offset 31..16 | ||
printf "CS = " | ||
outputcs $arg1 | ||
printf " (%d)", $arg1 | ||
|
||
if (($arg0&7) == $STS_IG16) + (($arg0&7) == $STS_TG16) | ||
printf " Offset = " | ||
output/a $arg3 << 16 | $arg2 | ||
end | ||
end | ||
|
||
define _printsegdesc | ||
# IA32 20007, Volume 3A, Figure 3-8 and Figure 4-1 | ||
_printsegdesc1 ($arg0>>16) ($arg1&0xFF) ($arg1>>24) ($arg0&0xFFFF) ($arg1>>16&15) ($arg1>>23&1) | ||
if ($arg1>>12&1) == 1 | ||
printf " AVL = %d", $arg1>>20&1 | ||
if ($arg1>>11&1) == 0 | ||
# Data segment | ||
if ($arg1>>22&1) == 0 | ||
printf " B = small (0) " | ||
else | ||
printf " B = big (1) " | ||
end | ||
else | ||
# Code segment | ||
printf " D = " | ||
if ($arg1>>22&1) == 0 | ||
printf "16-bit (0)" | ||
else | ||
printf "32-bit (1)" | ||
end | ||
end | ||
end | ||
end | ||
|
||
define _printsegdesc1 | ||
# 0:Base 0..15 1:Base 16..23 2:Base 24..32 3:Limit 0..15 4:Limit 16..19 5:G | ||
printf "base = 0x%08x", $arg0 | ($arg1<<16) | ($arg2<<24) | ||
printf " limit = 0x" | ||
if $arg5 == 0 | ||
printf "%08x", $arg3 | ($arg4<<16) | ||
else | ||
printf "%08x", (($arg3 | ($arg4<<16)) << 12) | 0xFFF | ||
end | ||
end | ||
|
||
define printdescs | ||
if $argc < 1 || $argc > 2 | ||
echo Usage: printdescs expr [count] | ||
else | ||
if $argc == 1 | ||
_printdescs ($arg0) (sizeof($arg0)/sizeof(($arg0)[0])) | ||
else | ||
_printdescs ($arg0) ($arg1) | ||
end | ||
end | ||
end | ||
|
||
document printdescs | ||
Print an array of x86 segment or gate descriptors. | ||
printdescs EXPR [COUNT] | ||
EXPR must evaluate to an array of descriptors. | ||
end | ||
|
||
define _printdescs | ||
set $i = 0 | ||
while $i < $arg1 | ||
printf "[%d] ", $i | ||
printdesc $arg0[$i] | ||
set $i = $i + 1 | ||
end | ||
end |