Search code examples
x86gdbx86-64memory-segmentationmsr

Using GDB to read MSRs


Is there some way to read the x86-64 model-specific registers, specifically IA32_FS_BASE and IA32_GS_BASE, while debugging a program using GDB?

Less preferable would be a solution using a dynamic instrumentation package like Intel's Pintool, but it would be appreciated all the same.


Solution

  • If you prefer not changing your code (or if the code is not available) you could do something similar to amdn's answer in the following way. The call to arch_prctl requires a pointer to a uint64_t, for which I use the address to an empty portion of the stack (8 bytes below the current stack pointer). After the call returns, read the 8 byte value stored at the location.

    Constants used: ARCH_GET_FS = 0x1003, ARCH_GET_GS = 0x1004

    (gdb) p $rsp
    $1 = (void *)0x7fffffffe6f0
    
    (gdb) call arch_prctl(0x1003, $rsp - 0x8)    
    $2 = 0 
    (gdb) x /gx $rsp - 0x8
    0x7fffffffe6e8: 0x00007ffff7fe0700   => IA32_FS_BASE
    
    (gdb) call arch_prctl(0x1004, $rsp - 0x8)
    $3 = 0 
    (gdb) x /gx $rsp - 0x8
    0x7fffffffe6e8: 0x0000000000000000   => IA32_GS_BASE