mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 23:42:32 +00:00
gdb_monitor: show correct register state on FOC
On Genode/Fiasco.OC, when an unresolved page fault occurs, only the IP and SP registers are valid in the thread state read by GDB monitor. This was not taken into account so far and the other (possibly outdated) register values got reported to the client, too. With this patch, only IP and SP get reported to the client in the page fault case. Fixes #1063.
This commit is contained in:
parent
dd974f00f7
commit
46374a6932
@ -52,7 +52,7 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content)
|
||||
try { thread_state = get_current_thread_state(); }
|
||||
catch (...) { return 0; }
|
||||
|
||||
if (in_syscall(thread_state)) {
|
||||
if (in_syscall(thread_state) || thread_state.unresolved_page_fault) {
|
||||
switch((enum reg_index)regno)
|
||||
{
|
||||
case R0: PDBG("cannot determine contents of register R0"); return -1;
|
||||
@ -67,14 +67,18 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content)
|
||||
case R9: PDBG("cannot determine contents of register R9"); return -1;
|
||||
case R10: PDBG("cannot determine contents of register R10"); return -1;
|
||||
case R11:
|
||||
/* R11 can be calculated from SP. The offset can be found in
|
||||
* the disassembled 'Fiasco::l4_ipc()' function:
|
||||
* add r11, sp, #8 -> r11 = sp + 8
|
||||
* sub sp, sp, #20 -> r11 = (sp + 20) + 8
|
||||
*/
|
||||
*reg_content = (thread_state.sp + 20) + 8;
|
||||
PDBG("FP = %8lx", *reg_content);
|
||||
return 0;
|
||||
if (in_syscall(thread_state)) {
|
||||
/* R11 can be calculated from SP. The offset can be found in
|
||||
* the disassembled 'Fiasco::l4_ipc()' function:
|
||||
* add r11, sp, #8 -> r11 = sp + 8
|
||||
* sub sp, sp, #20 -> r11 = (sp + 20) + 8
|
||||
*/
|
||||
*reg_content = (thread_state.sp + 20) + 8;
|
||||
PDBG("FP = %8lx", *reg_content);
|
||||
return 0;
|
||||
} else {
|
||||
PDBG("cannot determine contents of register R11"); return -1;
|
||||
}
|
||||
case R12: PDBG("cannot determine contents of register R12"); return -1;
|
||||
case SP: *reg_content = thread_state.sp; PDBG("SP = %8lx", *reg_content); return 0;
|
||||
case LR: PDBG("cannot determine contents of register LR"); return -1;
|
||||
|
@ -51,29 +51,37 @@ extern "C" int genode_fetch_register(int regno, unsigned long *reg_content)
|
||||
try { thread_state = get_current_thread_state(); }
|
||||
catch (...) { return 0; }
|
||||
|
||||
if (in_syscall(thread_state)) {
|
||||
if (in_syscall(thread_state) || thread_state.unresolved_page_fault) {
|
||||
switch((enum reg_index)regno)
|
||||
{
|
||||
case EAX: PDBG("cannot determine contents of register EAX"); return -1;
|
||||
case ECX: PDBG("cannot determine contents of register ECX"); return -1;
|
||||
case EDX: PDBG("cannot determine contents of register EDX"); return -1;
|
||||
case EBX:
|
||||
/* When in a syscall, the user EBX has been pushed onto the stack at address ESP+4 */
|
||||
*reg_content = genode_read_memory_byte((void*)(thread_state.sp + 4)) +
|
||||
(genode_read_memory_byte((void*)(thread_state.sp + 5)) << 8) +
|
||||
(genode_read_memory_byte((void*)(thread_state.sp + 6)) << 16) +
|
||||
(genode_read_memory_byte((void*)(thread_state.sp + 7)) << 24);
|
||||
PDBG("EBX = %8lx", *reg_content);
|
||||
return 0;
|
||||
if (in_syscall(thread_state)) {
|
||||
/* When in a syscall, the user EBX has been pushed onto the stack at address ESP+4 */
|
||||
*reg_content = genode_read_memory_byte((void*)(thread_state.sp + 4)) +
|
||||
(genode_read_memory_byte((void*)(thread_state.sp + 5)) << 8) +
|
||||
(genode_read_memory_byte((void*)(thread_state.sp + 6)) << 16) +
|
||||
(genode_read_memory_byte((void*)(thread_state.sp + 7)) << 24);
|
||||
PDBG("EBX = %8lx", *reg_content);
|
||||
return 0;
|
||||
} else {
|
||||
PDBG("cannot determine contents of register EBX"); return -1;
|
||||
}
|
||||
case UESP: *reg_content = thread_state.sp; PDBG("ESP = %8lx", *reg_content); return 0;
|
||||
case EBP:
|
||||
/* When in a syscall, the user EBP has been pushed onto the stack at address ESP+0 */
|
||||
*reg_content = genode_read_memory_byte((void*)(thread_state.sp + 0)) +
|
||||
(genode_read_memory_byte((void*)(thread_state.sp + 1)) << 8) +
|
||||
(genode_read_memory_byte((void*)(thread_state.sp + 2)) << 16) +
|
||||
(genode_read_memory_byte((void*)(thread_state.sp + 3)) << 24);
|
||||
PDBG("EBP = %8lx", *reg_content);
|
||||
return 0;
|
||||
if (in_syscall(thread_state)) {
|
||||
/* When in a syscall, the user EBP has been pushed onto the stack at address ESP+0 */
|
||||
*reg_content = genode_read_memory_byte((void*)(thread_state.sp + 0)) +
|
||||
(genode_read_memory_byte((void*)(thread_state.sp + 1)) << 8) +
|
||||
(genode_read_memory_byte((void*)(thread_state.sp + 2)) << 16) +
|
||||
(genode_read_memory_byte((void*)(thread_state.sp + 3)) << 24);
|
||||
PDBG("EBP = %8lx", *reg_content);
|
||||
return 0;
|
||||
} else {
|
||||
PDBG("cannot determine contents of register EBP"); return -1;
|
||||
}
|
||||
case ESI: PDBG("cannot determine contents of register ESI"); return -1;
|
||||
case EDI: PDBG("cannot determine contents of register EDI"); return -1;
|
||||
case EIP: *reg_content = thread_state.ip; PDBG("EIP = %8lx", *reg_content); return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user