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…
	
	Add table
		
		Reference in a new issue