/* Intel 386 target-dependent stuff. Copyright (C) 1988, 1989, 1991, 1994 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "defs.h" #include "frame.h" #include "inferior.h" #include "gdbcore.h" #include "target.h" #include "floatformat.h" #include "symtab.h" #include "i386-thread-status.h" #include "i386-next-tdep.h" #define FETCH_REG(rdata, rnum, sdata) \ store_unsigned_integer ((rdata) + (REGISTER_BYTE (rnum)), (REGISTER_RAW_SIZE (rnum)), (sdata)) #define STORE_REG(rdata, rnum, sdata) \ (sdata) = extract_unsigned_integer ((rdata) + (REGISTER_BYTE (rnum)), (REGISTER_RAW_SIZE (rnum))) void i386_next_fetch_gp_registers (unsigned char *rdata, gdb_i386_thread_state_t *gp_regs) { } void i386_next_store_gp_registers (unsigned char *rdata, gdb_i386_thread_state_t *gp_regs) { } void i386_next_fetch_sp_registers (unsigned char *rdata, gdb_i386_thread_state_t *sp_regs) { /* these need to match the REGISTER_NAMES table from tm-i386.h */ FETCH_REG (rdata, 0, sp_regs->eax); FETCH_REG (rdata, 1, sp_regs->ecx); FETCH_REG (rdata, 2, sp_regs->edx); FETCH_REG (rdata, 3, sp_regs->ebx); FETCH_REG (rdata, 4, sp_regs->esp); FETCH_REG (rdata, 5, sp_regs->ebp); FETCH_REG (rdata, 6, sp_regs->esi); FETCH_REG (rdata, 7, sp_regs->edi); FETCH_REG (rdata, 8, sp_regs->eip); FETCH_REG (rdata, 9, sp_regs->eflags); FETCH_REG (rdata, 10, sp_regs->cs); FETCH_REG (rdata, 11, sp_regs->ss); FETCH_REG (rdata, 12, sp_regs->ds); FETCH_REG (rdata, 13, sp_regs->es); FETCH_REG (rdata, 14, sp_regs->fs); FETCH_REG (rdata, 15, sp_regs->gs); } void i386_next_store_sp_registers (unsigned char *rdata, gdb_i386_thread_state_t *sp_regs) { /* these need to match the REGISTER_NAMES table from tm-i386.h */ STORE_REG (rdata, 0, sp_regs->eax); STORE_REG (rdata, 1, sp_regs->ecx); STORE_REG (rdata, 2, sp_regs->edx); STORE_REG (rdata, 3, sp_regs->ebx); STORE_REG (rdata, 4, sp_regs->esp); STORE_REG (rdata, 5, sp_regs->ebp); STORE_REG (rdata, 6, sp_regs->esi); STORE_REG (rdata, 7, sp_regs->edi); STORE_REG (rdata, 8, sp_regs->eip); STORE_REG (rdata, 9, sp_regs->eflags); STORE_REG (rdata, 10, sp_regs->cs); STORE_REG (rdata, 11, sp_regs->ss); STORE_REG (rdata, 12, sp_regs->ds); STORE_REG (rdata, 13, sp_regs->es); STORE_REG (rdata, 14, sp_regs->fs); STORE_REG (rdata, 15, sp_regs->gs); } void i386_next_fetch_fp_registers (unsigned char *rdata, gdb_i386_thread_fpstate_t *fp_regs) { } void i386_next_store_fp_registers (unsigned char *rdata, gdb_i386_thread_fpstate_t *fp_regs) { } /* mread -- read memory (unsigned) and apply a bitmask */ static unsigned long mread (addr, len, mask) CORE_ADDR addr; unsigned long len, mask; { long ret = read_memory_unsigned_integer (addr, len); if (mask) { ret &= mask; } return ret; } CORE_ADDR i386_next_skip_trampoline_code (pc) CORE_ADDR pc; { unsigned char opcode1 = (unsigned char) mread (pc, 1, 0); CORE_ADDR new_pc = pc; /* first test: static shlib jumptable */ if (opcode1 == 0xe9) /* jmpl xxxx */ return (pc + mread (pc+1, 4, 0) + 5); /* second test: dynamic shlib jumptable (1st entry point) */ if (opcode1 == 0xe8 && mread (pc+1, 4, 0) == 0 && /* calll pc+5 */ mread (pc+5, 1, 0) == 0x58 && /* popl %eax */ mread (pc+6, 2, 0) == 0x908b && /* movl y(%eax),%edx */ mread (pc+12, 2, 0) == 0xe2ff) /* jmpl %edx */ pc = new_pc = mread (pc + mread (pc+8, 4, 0) + 5, 4, 0); /* and fall thru to do next test (both might succeed) */ #if 0 /* third test: dynamic shlib table (as yet unresolved entry) */ if (mread (pc, 2, 0) == 0x808d && /* leal y(%eax),%eax */ mread (pc+6, 1, 0) == 0x50 && /* pushl %eax */ mread (pc+7, 1, 0) == 0xe9) /* jmpl dyld */ pc = new_pc = (CORE_ADDR) get_symbol_stub_real_address (pc, NULL); #endif return new_pc; } int i386_next_in_solib_return_trampoline (CORE_ADDR pc, char *name) { return 0; } int i386_next_in_solib_call_trampoline (CORE_ADDR pc, char *name) { if (i386_next_skip_trampoline_code (pc) != pc) { return 1; } return 0; } CORE_ADDR sigtramp_saved_pc (frame) struct frame_info *frame; { return 0; }