1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 20:47:45 +00:00

Kernel: Add ptrace commands for reading/writing the debug registers

This adds PT_PEEKDEBUG and PT_POKEDEBUG to allow for reading/writing
the debug registers, and updates the Kernel's debug handler to read the
new information from the debug status register.
This commit is contained in:
FalseHonesty 2021-04-15 12:34:51 -04:00 committed by Andreas Kling
parent 97a4c627cb
commit 3123ffb19d
6 changed files with 79 additions and 5 deletions

View file

@ -153,6 +153,19 @@ static KResultOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& par
return EFAULT;
return peer->process().poke_user_data(Userspace<u32*> { (FlatPtr)params.addr }, params.data);
case PT_PEEKDEBUG: {
Kernel::Syscall::SC_ptrace_peek_params peek_params {};
if (!copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr)))
return EFAULT;
auto result = peer->peek_debug_register(reinterpret_cast<uintptr_t>(peek_params.address));
if (result.is_error())
return result.error();
if (!copy_to_user(peek_params.out_data, &result.value()))
return EFAULT;
break;
}
case PT_POKEDEBUG:
return peer->poke_debug_register(reinterpret_cast<uintptr_t>(params.addr), params.data);
default:
return EINVAL;
}
@ -229,4 +242,56 @@ KResult Process::poke_user_data(Userspace<u32*> address, u32 data)
return KSuccess;
}
KResultOr<u32> Thread::peek_debug_register(u32 register_index)
{
u32 data;
switch (register_index) {
case 0:
data = m_debug_register_state.dr0;
break;
case 1:
data = m_debug_register_state.dr1;
break;
case 2:
data = m_debug_register_state.dr2;
break;
case 3:
data = m_debug_register_state.dr3;
break;
case 6:
data = m_debug_register_state.dr6;
break;
case 7:
data = m_debug_register_state.dr7;
break;
default:
return EINVAL;
}
return data;
}
KResult Thread::poke_debug_register(u32 register_index, u32 data)
{
switch (register_index) {
case 0:
m_debug_register_state.dr0 = data;
break;
case 1:
m_debug_register_state.dr1 = data;
break;
case 2:
m_debug_register_state.dr2 = data;
break;
case 3:
m_debug_register_state.dr3 = data;
break;
case 7:
m_debug_register_state.dr7 = data;
break;
default:
return EINVAL;
}
return KSuccess;
}
}