xv6

port of xv6 to x86-64
git clone http://frotz.net/git/xv6.git
Log | Files | Refs | README | LICENSE

gdbutil (5690B)


      1 # -*- gdb-script -*-
      2 
      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.
      6 
      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
     20 
     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  
     75 
     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
     83 
     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
    109 end
    110 
    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
    118 
    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
    149 end
    150 
    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
    161 end
    162 
    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
    170 end
    171 
    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.
    176 end
    177 
    178 define _printdesc
    179   _printdesc1 $arg0 $arg1 ($arg1>>15&1) ($arg1>>13&3) ($arg1>>12&1) ($arg1>>8&15)
    180 end
    181 
    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
    199 
    200     printf "  DPL = "
    201     outputdpl $arg3
    202     printf " (%d)", $arg3
    203   end
    204 end
    205 
    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
    216 end
    217 
    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
    224 
    225   if (($arg0&7) == $STS_IG16) + (($arg0&7) == $STS_TG16)
    226     printf "  Offset = "
    227     output/a $arg3 << 16 | $arg2
    228   end
    229 end
    230 
    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
    253 end
    254 
    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
    264 end
    265 
    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
    276 end
    277 
    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.
    282 end
    283 
    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
    291 end