Skip to content

[lldb] [debugserver] Use "full" x86_64 GPR state when available. #108663

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 53 additions & 14 deletions lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,22 +182,39 @@ kern_return_t DNBArchImplX86_64::GetGPRState(bool force) {
m_state.context.gpr.__gs = ('g' << 8) + 's';
m_state.SetError(e_regSetGPR, Read, 0);
#else
mach_msg_type_number_t count = e_regSetWordSizeGPR;
mach_msg_type_number_t count = e_regSetWordSizeGPRFull;
int flavor = __x86_64_THREAD_FULL_STATE;
m_state.SetError(
e_regSetGPR, Read,
::thread_get_state(m_thread->MachPortNumber(), __x86_64_THREAD_STATE,
::thread_get_state(m_thread->MachPortNumber(), flavor,
(thread_state_t)&m_state.context.gpr, &count));

if (!m_state.GetError(e_regSetGPR, Read)) {
m_state.hasFullGPRState = true;
} else {
m_state.hasFullGPRState = false;
count = e_regSetWordSizeGPR;
flavor = __x86_64_THREAD_STATE;
m_state.SetError(
e_regSetGPR, Read,
::thread_get_state(m_thread->MachPortNumber(), flavor,
(thread_state_t)&m_state.context.gpr, &count));
}
DNBLogThreadedIf(
LOG_THREAD,
"::thread_get_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x"
"::thread_get_state (0x%4.4x, %u (%s), &gpr, %u) => 0x%8.8x"
"\n\trax = %16.16llx rbx = %16.16llx rcx = %16.16llx rdx = %16.16llx"
"\n\trdi = %16.16llx rsi = %16.16llx rbp = %16.16llx rsp = %16.16llx"
"\n\t r8 = %16.16llx r9 = %16.16llx r10 = %16.16llx r11 = %16.16llx"
"\n\tr12 = %16.16llx r13 = %16.16llx r14 = %16.16llx r15 = %16.16llx"
"\n\trip = %16.16llx"
"\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx",
m_thread->MachPortNumber(), x86_THREAD_STATE64,
x86_THREAD_STATE64_COUNT, m_state.GetError(e_regSetGPR, Read),
"\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx"
"\n\t ds = %16.16llx es = %16.16llx ss = %16.16llx gsB = %16.16llx",
m_thread->MachPortNumber(), flavor,
m_state.hasFullGPRState ? "full" : "non-full",
m_state.hasFullGPRState ? e_regSetWordSizeGPRFull
: e_regSetWordSizeGPR,
m_state.GetError(e_regSetGPR, Read),
m_state.context.gpr.__rax, m_state.context.gpr.__rbx,
m_state.context.gpr.__rcx, m_state.context.gpr.__rdx,
m_state.context.gpr.__rdi, m_state.context.gpr.__rsi,
Expand All @@ -208,7 +225,9 @@ kern_return_t DNBArchImplX86_64::GetGPRState(bool force) {
m_state.context.gpr.__r14, m_state.context.gpr.__r15,
m_state.context.gpr.__rip, m_state.context.gpr.__rflags,
m_state.context.gpr.__cs, m_state.context.gpr.__fs,
m_state.context.gpr.__gs);
m_state.context.gpr.__gs, m_state.context.gpr.__ds,
m_state.context.gpr.__es, m_state.context.gpr.__ss,
m_state.context.gpr.__gsbase );

// DNBLogThreadedIf (LOG_THREAD, "thread_get_state(0x%4.4x, %u, &gpr, %u)
// => 0x%8.8x"
Expand Down Expand Up @@ -459,21 +478,26 @@ kern_return_t DNBArchImplX86_64::SetGPRState() {
"(SetGPRState() for stop_count = %u)",
m_thread->MachPortNumber(), kret, m_thread->Process()->StopCount());

mach_msg_type_number_t count =
m_state.hasFullGPRState ? e_regSetWordSizeGPRFull : e_regSetWordSizeGPR;
int flavor = m_state.hasFullGPRState ? __x86_64_THREAD_FULL_STATE
: __x86_64_THREAD_STATE;
m_state.SetError(e_regSetGPR, Write,
::thread_set_state(m_thread->MachPortNumber(),
__x86_64_THREAD_STATE,
::thread_set_state(m_thread->MachPortNumber(), flavor,
(thread_state_t)&m_state.context.gpr,
e_regSetWordSizeGPR));
count));
DNBLogThreadedIf(
LOG_THREAD,
"::thread_set_state (0x%4.4x, %u, &gpr, %u) => 0x%8.8x"
"::thread_set_state (0x%4.4x, %u (%s), &gpr, %u) => 0x%8.8x"
"\n\trax = %16.16llx rbx = %16.16llx rcx = %16.16llx rdx = %16.16llx"
"\n\trdi = %16.16llx rsi = %16.16llx rbp = %16.16llx rsp = %16.16llx"
"\n\t r8 = %16.16llx r9 = %16.16llx r10 = %16.16llx r11 = %16.16llx"
"\n\tr12 = %16.16llx r13 = %16.16llx r14 = %16.16llx r15 = %16.16llx"
"\n\trip = %16.16llx"
"\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx",
m_thread->MachPortNumber(), __x86_64_THREAD_STATE, e_regSetWordSizeGPR,
"\n\tflg = %16.16llx cs = %16.16llx fs = %16.16llx gs = %16.16llx"
"\n\t ds = %16.16llx es = %16.16llx ss = %16.16llx gsB = %16.16llx",
m_thread->MachPortNumber(), flavor,
m_state.hasFullGPRState ? "full" : "non-full", count,
m_state.GetError(e_regSetGPR, Write), m_state.context.gpr.__rax,
m_state.context.gpr.__rbx, m_state.context.gpr.__rcx,
m_state.context.gpr.__rdx, m_state.context.gpr.__rdi,
Expand All @@ -484,7 +508,9 @@ kern_return_t DNBArchImplX86_64::SetGPRState() {
m_state.context.gpr.__r13, m_state.context.gpr.__r14,
m_state.context.gpr.__r15, m_state.context.gpr.__rip,
m_state.context.gpr.__rflags, m_state.context.gpr.__cs,
m_state.context.gpr.__fs, m_state.context.gpr.__gs);
m_state.context.gpr.__fs, m_state.context.gpr.__gs,
m_state.context.gpr.__ds, m_state.context.gpr.__es,
m_state.context.gpr.__ss, m_state.context.gpr.__gsbase);
return m_state.GetError(e_regSetGPR, Write);
}

Expand Down Expand Up @@ -1157,6 +1183,10 @@ enum {
gpr_cs,
gpr_fs,
gpr_gs,
gpr_ds,
gpr_es,
gpr_ss,
gpr_gsbase,
gpr_eax,
gpr_ebx,
gpr_ecx,
Expand Down Expand Up @@ -1543,6 +1573,7 @@ enum debugserver_regnums {
debugserver_k5 = 123,
debugserver_k6 = 124,
debugserver_k7 = 125,
debugserver_gsbase = 126,
};

#define GPR_OFFSET(reg) (offsetof(DNBArchImplX86_64::GPR, __##reg))
Expand Down Expand Up @@ -1690,6 +1721,10 @@ const DNBRegisterInfo DNBArchImplX86_64::g_gpr_registers[] = {
DEFINE_GPR_ALT2(cs, NULL),
DEFINE_GPR_ALT2(fs, NULL),
DEFINE_GPR_ALT2(gs, NULL),
DEFINE_GPR_ALT2(ds, NULL),
DEFINE_GPR_ALT2(es, NULL),
DEFINE_GPR_ALT2(ss, NULL),
DEFINE_GPR_ALT2(gsbase, NULL),
DEFINE_GPR_PSEUDO_32(eax, rax),
DEFINE_GPR_PSEUDO_32(ebx, rbx),
DEFINE_GPR_PSEUDO_32(ecx, rcx),
Expand Down Expand Up @@ -2313,6 +2348,8 @@ bool DNBArchImplX86_64::GetRegisterValue(uint32_t set, uint32_t reg,
value->info = *regInfo;
switch (set) {
case e_regSetGPR:
if (reg > gpr_gs && !m_state.hasFullGPRState)
return false;
if (reg < k_num_gpr_registers) {
value->value.uint64 = ((uint64_t *)(&m_state.context.gpr))[reg];
return true;
Expand Down Expand Up @@ -2524,6 +2561,8 @@ bool DNBArchImplX86_64::SetRegisterValue(uint32_t set, uint32_t reg,
if (regInfo) {
switch (set) {
case e_regSetGPR:
if (reg > gpr_gs && !m_state.hasFullGPRState)
return false;
if (reg < k_num_gpr_registers) {
((uint64_t *)(&m_state.context.gpr))[reg] = value->value.uint64;
success = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ class DNBArchImplX86_64 : public DNBArchProtocol {
};

enum RegisterSetWordSize {
e_regSetWordSizeGPR = sizeof(GPR) / sizeof(int),
e_regSetWordSizeGPR = (sizeof(GPR) - 32) / sizeof(int),
e_regSetWordSizeGPRFull = sizeof(GPR) / sizeof(int),
e_regSetWordSizeFPU = sizeof(FPU) / sizeof(int),
e_regSetWordSizeEXC = sizeof(EXC) / sizeof(int),
e_regSetWordSizeAVX = sizeof(AVX) / sizeof(int),
Expand All @@ -130,6 +131,7 @@ class DNBArchImplX86_64 : public DNBArchProtocol {
kern_return_t fpu_errs[2]; // Read/Write errors
kern_return_t exc_errs[2]; // Read/Write errors
kern_return_t dbg_errs[2]; // Read/Write errors
bool hasFullGPRState;

State() {
uint32_t i;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define __x86_64_DEBUG_STATE 11
#define __x86_64_AVX_STATE 17
#define __x86_64_AVX512F_STATE 20
#define __x86_64_THREAD_FULL_STATE 23

typedef struct {
uint64_t __rax;
Expand All @@ -45,6 +46,10 @@ typedef struct {
uint64_t __cs;
uint64_t __fs;
uint64_t __gs;
uint64_t __ds;
uint64_t __es;
uint64_t __ss;
uint64_t __gsbase;
} __x86_64_thread_state_t;

typedef struct {
Expand Down
Loading