diff options
Diffstat (limited to 'x86/gdbstub_sys.c')
| -rw-r--r-- | x86/gdbstub_sys.c | 350 |
1 files changed, 0 insertions, 350 deletions
diff --git a/x86/gdbstub_sys.c b/x86/gdbstub_sys.c deleted file mode 100644 index a73bc52..0000000 --- a/x86/gdbstub_sys.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (c) 2016-2019 Matt Borgerson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "gdbstub.h" - -#ifdef __STRICT_ANSI__ -#define asm __asm__ -#endif - -#define SERIAL_COM1 0x3f8 -#define SERIAL_COM2 0x2f8 -#define SERIAL_PORT SERIAL_COM1 - -#define NUM_IDT_ENTRIES 32 - -/***************************************************************************** - * BSS Data - ****************************************************************************/ - -static struct dbg_idt_gate dbg_idt_gates[NUM_IDT_ENTRIES]; -static struct dbg_state dbg_state; - -/***************************************************************************** - * Misc. Functions - ****************************************************************************/ - -void *dbg_sys_memset(void *ptr, int data, size_t len) -{ - char *p = ptr; - - while (len--) { - *p++ = (char)data; - } - - return ptr; -} - -/* - * Get current code segment (CS register). - */ -uint32_t dbg_get_cs(void) -{ - uint32_t cs; - - asm volatile ( - "push %%cs;" - "pop %%eax;" - /* Outputs */ : "=a" (cs) - /* Inputs */ : /* None */ - /* Clobbers */ : /* None */ - ); - - return cs; -} - -/***************************************************************************** - * Interrupt Management Functions - ****************************************************************************/ - -/* - * Initialize idt_gates with the interrupt handlers. - */ -int dbg_init_gates(void) -{ - size_t i; - uint16_t cs; - - cs = dbg_get_cs(); - for (i = 0; i < NUM_IDT_ENTRIES; i++) { - dbg_idt_gates[i].flags = 0x8E00; - dbg_idt_gates[i].segment = cs; - dbg_idt_gates[i].offset_low = - ((uint32_t)dbg_int_handlers[i] ) & 0xffff; - dbg_idt_gates[i].offset_high = - ((uint32_t)dbg_int_handlers[i] >> 16) & 0xffff; - } - - return 0; -} - -/* - * Load a new IDT. - */ -int dbg_load_idt(struct dbg_idtr *idtr) -{ - asm volatile ( - "lidt %0" - /* Outputs */ : /* None */ - /* Inputs */ : "m" (*idtr) - /* Clobbers */ : /* None */ - ); - - return 0; -} - -/* - * Get current IDT. - */ -int dbg_store_idt(struct dbg_idtr *idtr) -{ - asm volatile ( - "sidt %0" - /* Outputs */ : "=m" (*idtr) - /* Inputs */ : /* None */ - /* Clobbers */ : /* None */ - ); - - return 0; -} - -/* - * Hook a vector of the current IDT. - */ -int dbg_hook_idt(uint8_t vector, const void *function) -{ - struct dbg_idtr idtr; - struct dbg_idt_gate *gates; - - dbg_store_idt(&idtr); - gates = (struct dbg_idt_gate *)idtr.offset; - gates[vector].flags = 0x8E00; - gates[vector].segment = dbg_get_cs(); - gates[vector].offset_low = (((uint32_t)function) ) & 0xffff; - gates[vector].offset_high = (((uint32_t)function) >> 16) & 0xffff; - - return 0; -} - -/* - * Initialize IDT gates and load the new IDT. - */ -int dbg_init_idt(void) -{ - struct dbg_idtr idtr; - - dbg_init_gates(); - idtr.len = sizeof(dbg_idt_gates)-1; - idtr.offset = (uint32_t)dbg_idt_gates; - dbg_load_idt(&idtr); - - return 0; -} - -/* - * Common interrupt handler routine. - */ -void dbg_int_handler(struct dbg_interrupt_state *istate) -{ - dbg_interrupt(istate); -} - -/* - * Debug interrupt handler. - */ -void dbg_interrupt(struct dbg_interrupt_state *istate) -{ - dbg_sys_memset(&dbg_state.registers, 0, sizeof(dbg_state.registers)); - - /* Translate vector to signal */ - switch (istate->vector) { - case 1: dbg_state.signum = 5; break; - case 3: dbg_state.signum = 5; break; - default: dbg_state.signum = 7; - } - - /* Load Registers */ - dbg_state.registers[DBG_CPU_I386_REG_EAX] = istate->eax; - dbg_state.registers[DBG_CPU_I386_REG_ECX] = istate->ecx; - dbg_state.registers[DBG_CPU_I386_REG_EDX] = istate->edx; - dbg_state.registers[DBG_CPU_I386_REG_EBX] = istate->ebx; - dbg_state.registers[DBG_CPU_I386_REG_ESP] = istate->esp; - dbg_state.registers[DBG_CPU_I386_REG_EBP] = istate->ebp; - dbg_state.registers[DBG_CPU_I386_REG_ESI] = istate->esi; - dbg_state.registers[DBG_CPU_I386_REG_EDI] = istate->edi; - dbg_state.registers[DBG_CPU_I386_REG_PC] = istate->eip; - dbg_state.registers[DBG_CPU_I386_REG_CS] = istate->cs; - dbg_state.registers[DBG_CPU_I386_REG_PS] = istate->eflags; - dbg_state.registers[DBG_CPU_I386_REG_SS] = istate->ss; - dbg_state.registers[DBG_CPU_I386_REG_DS] = istate->ds; - dbg_state.registers[DBG_CPU_I386_REG_ES] = istate->es; - dbg_state.registers[DBG_CPU_I386_REG_FS] = istate->fs; - dbg_state.registers[DBG_CPU_I386_REG_GS] = istate->gs; - - dbg_main(&dbg_state); - - /* Restore Registers */ - istate->eax = dbg_state.registers[DBG_CPU_I386_REG_EAX]; - istate->ecx = dbg_state.registers[DBG_CPU_I386_REG_ECX]; - istate->edx = dbg_state.registers[DBG_CPU_I386_REG_EDX]; - istate->ebx = dbg_state.registers[DBG_CPU_I386_REG_EBX]; - istate->esp = dbg_state.registers[DBG_CPU_I386_REG_ESP]; - istate->ebp = dbg_state.registers[DBG_CPU_I386_REG_EBP]; - istate->esi = dbg_state.registers[DBG_CPU_I386_REG_ESI]; - istate->edi = dbg_state.registers[DBG_CPU_I386_REG_EDI]; - istate->eip = dbg_state.registers[DBG_CPU_I386_REG_PC]; - istate->cs = dbg_state.registers[DBG_CPU_I386_REG_CS]; - istate->eflags = dbg_state.registers[DBG_CPU_I386_REG_PS]; - istate->ss = dbg_state.registers[DBG_CPU_I386_REG_SS]; - istate->ds = dbg_state.registers[DBG_CPU_I386_REG_DS]; - istate->es = dbg_state.registers[DBG_CPU_I386_REG_ES]; - istate->fs = dbg_state.registers[DBG_CPU_I386_REG_FS]; - istate->gs = dbg_state.registers[DBG_CPU_I386_REG_GS]; -} - -/***************************************************************************** - * I/O Functions - ****************************************************************************/ - -/* - * Write to I/O port. - */ -void dbg_io_write_8(uint16_t port, uint8_t val) -{ - asm volatile ( - "outb %%al, %%dx;" - /* Outputs */ : /* None */ - /* Inputs */ : "a" (val), "d" (port) - /* Clobbers */ : /* None */ - ); -} - -/* - * Read from I/O port. - */ -uint8_t dbg_io_read_8(uint16_t port) -{ - uint8_t val; - - asm volatile ( - "inb %%dx, %%al;" - /* Outputs */ : "=a" (val) - /* Inputs */ : "d" (port) - /* Clobbers */ : /* None */ - ); - - return val; -} - -/***************************************************************************** - * NS16550 Serial Port (IO) - ****************************************************************************/ - -#define SERIAL_THR 0 -#define SERIAL_RBR 0 -#define SERIAL_LSR 5 - -int dbg_serial_getc(void) -{ - /* Wait for data */ - while ((dbg_io_read_8(SERIAL_PORT + SERIAL_LSR) & 1) == 0); - return dbg_io_read_8(SERIAL_PORT + SERIAL_RBR); -} - -int dbg_serial_putchar(int ch) -{ - /* Wait for THRE (bit 5) to be high */ - while ((dbg_io_read_8(SERIAL_PORT + SERIAL_LSR) & (1<<5)) == 0); - dbg_io_write_8(SERIAL_PORT + SERIAL_THR, ch); - return ch; -} - -/***************************************************************************** - * Debugging System Functions - ****************************************************************************/ - -/* - * Write one character to the debugging stream. - */ -int dbg_sys_putchar(int ch) -{ - return dbg_serial_putchar(ch); -} - -/* - * Read one character from the debugging stream. - */ -int dbg_sys_getc(void) -{ - return dbg_serial_getc() & 0xff; -} - -/* - * Read one byte from memory. - */ -int dbg_sys_mem_readb(address addr, char *val) -{ - *val = *(volatile char *)addr; - return 0; -} - -/* - * Write one byte to memory. - */ -int dbg_sys_mem_writeb(address addr, char val) -{ - *(volatile char *)addr = val; - return 0; -} - -/* - * Continue program execution. - */ -int dbg_sys_continue(void) -{ - dbg_state.registers[DBG_CPU_I386_REG_PS] &= ~(1<<8); - return 0; -} - -/* - * Single step the next instruction. - */ -int dbg_sys_step(void) -{ - dbg_state.registers[DBG_CPU_I386_REG_PS] |= 1<<8; - return 0; -} - -/* - * Debugger init function. - * - * Hooks the IDT to enable debugging. - */ -void dbg_start(void) -{ - /* Hook current IDT. */ - dbg_hook_idt(1, dbg_int_handlers[1]); - dbg_hook_idt(3, dbg_int_handlers[3]); - - /* Interrupt to start debugging. */ - asm volatile ("int3"); -} |
