📄 i386_stub.c
字号:
_msrval[0] = msrval[0]; _msrval[1] = msrval[1]; __set_mem_fault_trap (__do_write_msr); if (__mem_fault) return 0; return 1;}intcyg_hal_stub_process_query (char *pkt, char *buf, int bufsize){ unsigned long val1, val2, val3, val4; int i = 0, max_input = 0; if ('C' == pkt[0] && 'P' == pkt[1] && 'U' == pkt[2] && 'I' == pkt[3] && 'D' == pkt[4]) { for (i = 0; i <= max_input; i++) { asm volatile ("movl %4,%%eax\n" "cpuid\n" "movl %%eax,%0\n" "movl %%ebx,%1\n" "movl %%ecx,%2\n" "movl %%edx,%3\n" : "=m" (val1), "=m" (val2), "=m" (val3), "=m" (val4) : "m" (i) : "eax", "ebx", "ecx", "edx", "memory"); /* * get the max value to use to get all the CPUID info. */ if (i == 0) max_input = val1; /* * Swap the bytes around to handle endianness conversion: * ie 12345678 --> 78563412 */ val1 = (((val1 & 0x000000ff) << 24) | ((val1 & 0x0000ff00) << 8) | ((val1 & 0x00ff0000) >> 8) | ((val1 & 0xff000000) >> 24)); val2 = (((val2 & 0x000000ff) << 24) | ((val2 & 0x0000ff00) << 8) | ((val2 & 0x00ff0000) >> 8) | ((val2 & 0xff000000) >> 24)); val3 = (((val3 & 0x000000ff) << 24) | ((val3 & 0x0000ff00) << 8) | ((val3 & 0x00ff0000) >> 8) | ((val3 & 0xff000000) >> 24)); val4 = (((val4 & 0x000000ff) << 24) | ((val4 & 0x0000ff00) << 8) | ((val4 & 0x00ff0000) >> 8) | ((val4 & 0xff000000) >> 24)); /* * Generate the packet */ __mem2hex ((char *)&val1, buf, 8, 0); buf[8] = ','; buf += 9; __mem2hex ((char *)&val2, buf, 8, 0); buf[8] = ','; buf += 9; __mem2hex ((char *)&val3, buf, 8, 0); buf[8] = ','; buf += 9; __mem2hex ((char *)&val4, buf, 8, 0); buf[8] = ';'; buf += 9; } /* * The packet is complete. buf points just past the final semicolon. * Remove that semicolon and properly terminate the packet. */ *(buf - 1) = '\0'; return 1; } if ('M' == pkt[0] && 'S' == pkt[1] && 'R' == pkt[2]) { pkt += 4; if (__hexToInt (&pkt, &val1)) { target_register_t msrval[2]; // rdmsr implicitly sets _which_msr for subsequent REG_MSR read/write. if (rdmsr(val1, msrval)) __mem2hex ((char*)msrval, buf, 8, 0); else memcpy (buf, "INVALID", 8); } return 1; } return 0;}#endif // CYGHWR_HAL_I386_PENTIUM_GDB_REGS// Write the contents of register WHICH into VALUE as raw bytes. We// only support this for the MMX, FPU, and SSE registers.// Return true if it is a valid register.intget_register_as_bytes (regnames_t which, char *value){ target_register_t offset;#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS // Read the currently selected MSR if (which == REG_MSR) { if (rdmsr(_which_msr, _msrval)) { memcpy (value, _msrval, REGSIZE(which)); return 1; } return 0; } // We can't actually read the LDT or TR in software, so just return invalid. if (which == REG_LDT || which == REG_TR) return 0; if (which == REG_GDT || which == REG_IDT) { // GDB requires these to be sent base first though the CPU stores them // limit first in 6 bytes. Weird. offset = reg_offset(which); memcpy (value, (char *)_registers + offset + 2, 4); memcpy (value + 4, (char *)_registers + offset, 2); return 1; }#endif offset = reg_offset(which); if (offset != -1) { memcpy (value, (char *)_registers + offset, REGSIZE(which)); return 1; } return 0;}// Alter the contents of saved register WHICH to contain VALUE. We only// support this for the MMX, FPU, and SSE registers.intput_register_as_bytes (regnames_t which, char *value){ target_register_t offset;#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS // Write the currently selected MSR if (which == REG_MSR) return wrmsr(_which_msr, (target_register_t*)value); // We can't actually write the LDT OR TR in software, so just return invalid. if (which == REG_LDT || which == REG_TR) return 0; if (which == REG_GDT || which == REG_IDT) { // GDB sends these base first, though the CPU stores them // limit first. Weird. offset = reg_offset(which); memcpy ((char *)_registers + offset + 2, value, 4); memcpy ((char *)_registers + offset, value + 4, 2); return 1; }#endif offset = reg_offset(which); if (offset != -1) { memcpy ((char *)_registers + offset, value, REGSIZE(which)); return 1; } return 0;}/*---------------------------------------------------------------------- * Single-step support *//* Set things up so that the next user resume will execute one instruction. This may be done by setting breakpoints or setting a single step flag in the saved user registers, for example. *//* We just turn on the trap bit in the flags register for the particular thread. When it resumes, we'll get another debugger trap.*/void __single_step (void){ put_register(PS, get_register(PS) | PS_T) ;}/* Clear the single-step state. */void __clear_single_step (void){ put_register(PS, get_register(PS) & ~PS_T) ;}void __install_breakpoints (void){// FIXME();}void __clear_breakpoints (void){ __clear_breakpoint_list();}/* If the breakpoint we hit is in the breakpoint() instruction, return a non-zero value. */int isBreakpointFunction ;int__is_breakpoint_function (){ isBreakpointFunction = (get_register (PC) == (target_register_t)&_breakinst); return isBreakpointFunction ;}/* Skip the current instruction. Since this is only called by the stub when the PC points to a breakpoint or trap instruction, we can safely just skip 4. */void __skipinst (void){// FIXME() ;}#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS//----------------------------------------------------------------------// We apparently need these function even when no stubinclude// for Thread Debug purposesvoid hal_get_gdb_registers(CYG_ADDRWORD *dest, HAL_SavedRegisters * s){ GDB_SavedRegisters *d = (GDB_SavedRegisters *)dest; d->eax = s->eax; d->ebx = s->ebx; d->ecx = s->ecx; d->edx = s->edx; d->ebp = s->ebp; d->esp = s->esp; d->edi = s->edi; d->esi = s->esi; d->pc = s->pc; d->cs = s->cs; d->ps = s->eflags; d->ss = 0; asm volatile ("movw %%ss,%0\n" :"=m" (d->ss)); d->ds = 0; asm volatile ("movw %%ds,%0\n" :"=m" (d->ds)); d->es = 0; asm volatile ("movw %%es,%0\n" :"=m" (d->es)); d->fs = 0; asm volatile ("movw %%fs,%0\n" :"=m" (d->fs)); d->gs = 0; asm volatile ("movw %%gs,%0\n" :"=m" (d->gs));#ifdef CYGHWR_HAL_I386_FPU#ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY asm volatile ("fnop\n"); // force state save memcpy(&d->fcw, &s->fpucontext->fpstate[0], sizeof(s->fpucontext->fpstate));#ifdef CYGHWR_HAL_I386_PENTIUM_SSE memcpy(&d->xmm0[0], &s->fpucontext->xmm0[0], (16 * 8) + 4);#endif#else memcpy(&d->fcw, &s->fpucontext.fpstate[0], sizeof(s->fpucontext.fpstate));#ifdef CYGHWR_HAL_I386_PENTIUM_SSE memcpy(&d->xmm0[0], &s->fpucontext.xmm0[0], (16 * 8) + 4);#endif#endif#endif#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS { unsigned long val; asm volatile ("movl %%cr0,%0\n" "movl %0,%1\n" : "=r" (val), "=m" (d->cr0)); asm volatile ("movl %%cr2,%0\n" "movl %0,%1\n" : "=r" (val), "=m" (d->cr2)); asm volatile ("movl %%cr3,%0\n" "movl %0,%1\n" : "=r" (val), "=m" (d->cr3)); asm volatile ("movl %%cr4,%0\n" "movl %0,%1\n" : "=r" (val), "=m" (d->cr4)); asm volatile ("sgdt %0\n" :"=m" (d->gdtr)); asm volatile ("sidt %0\n" :"=m" (d->idtr)); }#endif // CYGHWR_HAL_I386_PENTIUM_GDB_REGS}void hal_set_gdb_registers(HAL_SavedRegisters * d, CYG_ADDRWORD * src){ GDB_SavedRegisters *s = (GDB_SavedRegisters *)src; d->eax = s->eax; d->ebx = s->ebx; d->ecx = s->ecx; d->edx = s->edx; d->ebp = s->ebp; d->esp = s->esp; d->edi = s->edi; d->esi = s->esi; d->pc = s->pc; d->cs = s->cs; d->eflags = s->ps;#ifdef CYGHWR_HAL_I386_FPU#ifdef CYGHWR_HAL_I386_FPU_SWITCH_LAZY memcpy(&d->fpucontext->fpstate[0], &s->fcw, sizeof(d->fpucontext->fpstate));#ifdef CYGHWR_HAL_I386_PENTIUM_SSE memcpy(&d->fpucontext->xmm0[0], &s->xmm0[0], (16 * 8) + 4);#endif#else memcpy(&d->fpucontext.fpstate[0], &s->fcw, sizeof(d->fpucontext.fpstate));#ifdef CYGHWR_HAL_I386_PENTIUM_SSE memcpy(&d->fpucontext.xmm0[0], &s->xmm0[0], (16 * 8) + 4);#endif#endif#endif#ifdef CYGHWR_HAL_I386_PENTIUM_GDB_REGS { unsigned long val; val = s->cr0; asm volatile ("movl %0,%%cr0\n" : : "r" (val)); val = s->cr2; asm volatile ("movl %0,%%cr2\n" : : "r" (val)); val = s->cr3; asm volatile ("movl %0,%%cr3\n" : : "r" (val)); val = s->cr4; asm volatile ("movl %0,%%cr4\n" : : "r" (val)); }#endif // CYGHWR_HAL_I386_PENTIUM_GDB_REGS}//----------------------------------------------------------------------// End
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -