GDB utilities
This commit is contained in:
parent
f4c12f116d
commit
b0170c4b82
1 changed files with 291 additions and 0 deletions
291
gdbutil
Normal file
291
gdbutil
Normal file
|
@ -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
|
Loading…
Reference in a new issue