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