/* * \brief Fiasco(x86)-specific helper functions for GDB server * \author Christian Prochaska * \date 2011-05-06 */ /* * Copyright (C) 2011-2012 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. */ extern "C" { #define private _private #include "genode-low.h" #define _private private } #include #include "i386.h" #include "cpu_session_component.h" #include "gdbserver_platform_helper.h" #include "gdb_stub_thread.h" using namespace Genode; extern "C" int genode_fetch_register(int regno, unsigned long *reg_content) { Thread_state thread_state; try { thread_state = get_current_thread_state(); } catch (...) { return 0; } switch((enum reg_index)regno) { /* TODO: implement the backend function that tells gdbserver that these registers cannot be fetched */ 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: 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 * * looking for syscall pattern: * EIP-2: cd 30 int $30 */ if ((genode_read_memory_byte((void*)(thread_state.ip - 1)) == 0x30) && (genode_read_memory_byte((void*)(thread_state.ip - 2)) == 0xcd)) { *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("ESP = %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; case EFL: PDBG("cannot determine contents of register EFLAGS"); return -1; case CS: PDBG("cannot determine contents of register CS"); return -1; case SS: PDBG("cannot determine contents of register SS"); return -1; case DS: PDBG("cannot determine contents of register DS"); return -1; case ES: PDBG("cannot determine contents of register ES"); return -1; case FS: PDBG("cannot determine contents of register FS"); return -1; case GS: PDBG("cannot determine contents of register GS"); return -1; } return -1; }