mgorny created this revision. mgorny added reviewers: labath, krytarowski, emaste. Herald added a subscriber: pengfei. mgorny requested review of this revision.
The FXSAVE/XSAVE data can have two different layouts on x86_64. When called as FXSAVE/XSAVE..., the Instruction Pointer and Address Pointer registers are reported using a 16-bit segment identifier and a 32-bit offset. When called as FXSAVE64/XSAVE64..., they are reported using a complete 64-bit offsets instead. LLDB has historically followed GDB and unconditionally used to assume the 32-bit layout, with the slight modification of possibly using a 32-bit segment register (i.e. extending the register into the reserved 16 upper bits). When the underlying operating system used FXSAVE64/XSAVE64..., the pointer was split into two halves, with the upper half repored as the segment registers. While reconstructing the full address was possible on the user end (and e.g. the FPU register tests did that), it certainly was not the most convenient option. Introduce a two additional 'fip' and 'fdp' registers that overlap with 'fiseg'/'fioff' and 'foseg'/'foff' respectively, and report the complete 64-bit address. https://reviews.llvm.org/D91497 Files: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h lldb/test/Shell/Register/x86-64-fp-read.test lldb/test/Shell/Register/x86-fp-read.test lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp
Index: lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp =================================================================== --- lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp +++ lldb/unittests/Process/Utility/RegisterContextFreeBSDTest.cpp @@ -83,8 +83,10 @@ // are reserved. However, we use them to access/recombine 64-bit FIP/FDP. EXPECT_OFF(fioff_x86_64, 0x08, 4); EXPECT_OFF(fiseg_x86_64, 0x0C, 4); + EXPECT_OFF(fip_x86_64, 0x08, 8); EXPECT_OFF(fooff_x86_64, 0x10, 4); EXPECT_OFF(foseg_x86_64, 0x14, 4); + EXPECT_OFF(fdp_x86_64, 0x10, 8); EXPECT_OFF(mxcsr_x86_64, 0x18, 4); EXPECT_OFF(mxcsrmask_x86_64, 0x1C, 4); EXPECT_OFF(st0_x86_64, 0x20, 10); Index: lldb/test/Shell/Register/x86-fp-read.test =================================================================== --- lldb/test/Shell/Register/x86-fp-read.test +++ lldb/test/Shell/Register/x86-fp-read.test @@ -1,5 +1,5 @@ # XFAIL: system-windows -# REQUIRES: native && (target-x86 || target-x86_64) +# REQUIRES: native && target-x86 # RUN: %clangxx_host -g %p/Inputs/x86-fp-read.cpp -o %t # RUN: %lldb -b -s %s %t | FileCheck %s process launch Index: lldb/test/Shell/Register/x86-64-fp-read.test =================================================================== --- /dev/null +++ lldb/test/Shell/Register/x86-64-fp-read.test @@ -0,0 +1,38 @@ +# XFAIL: system-windows +# REQUIRES: native && target-x86_64 +# RUN: %clangxx_host -g %p/Inputs/x86-fp-read.cpp -o %t +# RUN: %lldb -b -s %s %t | FileCheck %s +process launch +# CHECK: Process {{.*}} stopped + +# fdiv (%rbx) gets encoded into 2 bytes, int3 into 1 byte +print (void*)($pc-3) +# CHECK: (void *) $0 = [[FDIV:0x[0-9a-f]*]] +print (void*)($fiseg*0x100000000 + $fioff) +# CHECK: (void *) $1 = [[FDIV]] +print &zero +# CHECK: (uint32_t *) $2 = [[ZERO:0x[0-9a-f]*]] +print (uint32_t*)($foseg * 0x100000000 + $fooff) +# CHECK: (uint32_t *) $3 = [[ZERO]] + +register read --all +# CHECK-DAG: fctrl = 0x037b +# CHECK-DAG: fstat = 0x8084 +# TODO: the following value is incorrect, it's a bug in the way +# FXSAVE/XSAVE is interpreted +# CHECK-DAG: ftag = 0x007f +# CHECK-DAG: fop = 0x0033 +# CHECK-DAG: fip = [[FDIV]] +# CHECK-DAG: fdp = [[ZERO]] + +# CHECK-DAG: st{{(mm)?}}0 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0x00 0x40} +# CHECK-DAG: st{{(mm)?}}1 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x3f 0x00 0x00} +# CHECK-DAG: st{{(mm)?}}2 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00} +# CHECK-DAG: st{{(mm)?}}3 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80} +# CHECK-DAG: st{{(mm)?}}4 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0xff 0x7f} +# CHECK-DAG: st{{(mm)?}}5 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x80 0xff 0xff} +# CHECK-DAG: st{{(mm)?}}6 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xc0 0xff 0xff} +# CHECK-DAG: st{{(mm)?}}7 = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00} + +process continue +# CHECK: Process {{[0-9]+}} exited with status = 0 Index: lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h =================================================================== --- lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h +++ lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h @@ -228,8 +228,10 @@ lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64, + lldb_fip_x86_64, lldb_foseg_x86_64, lldb_fooff_x86_64, + lldb_fdp_x86_64, lldb_mxcsr_x86_64, lldb_mxcsrmask_x86_64, lldb_st0_x86_64, Index: lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h =================================================================== --- lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h +++ lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h @@ -259,8 +259,10 @@ DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_FPR(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_FPR(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(fip, ptr.x86_64.fip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_FPR(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_FPR(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(fdp, ptr.x86_64.fdp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), Index: lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp =================================================================== --- lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp +++ lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp @@ -120,8 +120,8 @@ static const uint32_t g_lldb_regnums_x86_64[] = { lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64, - lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64, - lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64, + lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64, lldb_fip_x86_64, + lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_fdp_x86_64, lldb_mxcsr_x86_64, lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64, lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64, lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64, Index: lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp =================================================================== --- lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp +++ lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp @@ -84,8 +84,8 @@ // x86 64-bit registers available via XState. static const uint32_t g_xstate_regnums_x86_64[] = { lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64, - lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64, - lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64, + lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64, lldb_fip_x86_64, + lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_fdp_x86_64, lldb_mxcsr_x86_64, lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64, lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64, lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64, @@ -621,12 +621,18 @@ case lldb_fioff_x86_64: reg_value = (uint32_t)m_xstate.xs_fxsave.fx_ip.fa_32.fa_off; break; + case lldb_fip_x86_64: + reg_value = (uint64_t)m_xstate.xs_fxsave.fx_ip.fa_64; + break; case lldb_foseg_x86_64: reg_value = (uint32_t)m_xstate.xs_fxsave.fx_dp.fa_32.fa_seg; break; case lldb_fooff_x86_64: reg_value = (uint32_t)m_xstate.xs_fxsave.fx_dp.fa_32.fa_off; break; + case lldb_fdp_x86_64: + reg_value = (uint64_t)m_xstate.xs_fxsave.fx_dp.fa_64; + break; case lldb_mxcsr_x86_64: reg_value = (uint32_t)m_xstate.xs_fxsave.fx_mxcsr; break; @@ -912,12 +918,18 @@ case lldb_fioff_x86_64: m_xstate.xs_fxsave.fx_ip.fa_32.fa_off = reg_value.GetAsUInt32(); break; + case lldb_fip_x86_64: + m_xstate.xs_fxsave.fx_ip.fa_64 = reg_value.GetAsUInt64(); + break; case lldb_foseg_x86_64: m_xstate.xs_fxsave.fx_dp.fa_32.fa_seg = reg_value.GetAsUInt32(); break; case lldb_fooff_x86_64: m_xstate.xs_fxsave.fx_dp.fa_32.fa_off = reg_value.GetAsUInt32(); break; + case lldb_fdp_x86_64: + m_xstate.xs_fxsave.fx_dp.fa_64 = reg_value.GetAsUInt64(); + break; case lldb_mxcsr_x86_64: m_xstate.xs_fxsave.fx_mxcsr = reg_value.GetAsUInt32(); new_xstate_bv = XCR0_SSE; Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp =================================================================== --- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp +++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp @@ -150,8 +150,8 @@ // x86 64-bit floating point registers. static const uint32_t g_fpu_regnums_x86_64[] = { lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64, - lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64, - lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64, + lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64, lldb_fip_x86_64, + lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_fdp_x86_64, lldb_mxcsr_x86_64, lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64, lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64, lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64, Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp +++ lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp @@ -81,8 +81,8 @@ // x86 64-bit floating point registers. static const uint32_t g_fpu_regnums_x86_64[] = { lldb_fctrl_x86_64, lldb_fstat_x86_64, lldb_ftag_x86_64, - lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64, - lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_mxcsr_x86_64, + lldb_fop_x86_64, lldb_fiseg_x86_64, lldb_fioff_x86_64, lldb_fip_x86_64, + lldb_foseg_x86_64, lldb_fooff_x86_64, lldb_fdp_x86_64, lldb_mxcsr_x86_64, lldb_mxcsrmask_x86_64, lldb_st0_x86_64, lldb_st1_x86_64, lldb_st2_x86_64, lldb_st3_x86_64, lldb_st4_x86_64, lldb_st5_x86_64, lldb_st6_x86_64, lldb_st7_x86_64,
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits