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:
Christian Prochaska 2014-02-13 20:17:14 +01:00 committed by Christian Helmuth
parent dd974f00f7
commit 46374a6932
2 changed files with 36 additions and 24 deletions

View File

@ -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;

View File

@ -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;