X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fi386-nto-tdep.c;h=666a077d32599c99217065e9a399da13121151b4;hb=9bdcbae7fe5d41beb308223fd65123fb700e2e1d;hp=a80c7a47f988e2873511255477768cecd90d80f5;hpb=41d041d67127783bcb817154c71354e26dbef6d0;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/i386-nto-tdep.c b/gdb/i386-nto-tdep.c index a80c7a47f9..666a077d32 100644 --- a/gdb/i386-nto-tdep.c +++ b/gdb/i386-nto-tdep.c @@ -1,6 +1,6 @@ -/* i386-nto-tdep.c - i386 specific functionality for QNX Neutrino. +/* Target-dependent code for QNX Neutrino x86. - Copyright 2003 Free Software Foundation, Inc. + Copyright (C) 2003, 2004 Free Software Foundation, Inc. Contributed by QNX Software Systems Ltd. @@ -18,20 +18,25 @@ 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., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ -#include "gdb_string.h" -#include "gdb_assert.h" #include "defs.h" #include "frame.h" -#include "target.h" +#include "osabi.h" #include "regcache.h" -#include "solib-svr4.h" +#include "target.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + #include "i386-tdep.h" -#include "nto-tdep.h" -#include "osabi.h" #include "i387-tdep.h" +#include "nto-tdep.h" +#include "solib-svr4.h" + +/* Target vector for QNX NTO x86. */ +static struct nto_target_ops i386_nto_target; #ifndef X86_CPU_FXSR #define X86_CPU_FXSR (1L << 12) @@ -42,45 +47,51 @@ that is just filler. Don't ask me, ask the kernel guys. */ #define NUM_GPREGS 13 -/* Map a GDB register number to an offset in the reg structure. */ -static int regmap[] = { - (7 * 4), /* eax */ - (6 * 4), /* ecx */ - (5 * 4), /* edx */ - (4 * 4), /* ebx */ - (11 * 4), /* esp */ - (2 * 4), /* epb */ - (1 * 4), /* esi */ - (0 * 4), /* edi */ - (8 * 4), /* eip */ - (10 * 4), /* eflags */ - (9 * 4), /* cs */ - (12 * 4), /* ss */ - (-1 * 4) /* filler */ +/* Mapping between the general-purpose registers in `struct xxx' + format and GDB's register cache layout. */ + +/* From . */ +static int i386nto_gregset_reg_offset[] = +{ + 7 * 4, /* %eax */ + 6 * 4, /* %ecx */ + 5 * 4, /* %edx */ + 4 * 4, /* %ebx */ + 11 * 4, /* %esp */ + 2 * 4, /* %epb */ + 1 * 4, /* %esi */ + 0 * 4, /* %edi */ + 8 * 4, /* %eip */ + 10 * 4, /* %eflags */ + 9 * 4, /* %cs */ + 12 * 4, /* %ss */ + -1 /* filler */ }; -/* Given a gdb regno, return the offset into Neutrino's register structure - or -1 if register is unknown. */ +/* Given a GDB register number REGNUM, return the offset into + Neutrino's register structure or -1 if the register is unknown. */ + static int -nto_reg_offset (int regno) +nto_reg_offset (int regnum) { - return (regno >= 0 && regno < NUM_GPREGS) ? regmap[regno] : -1; + if (regnum >= 0 && regnum < ARRAY_SIZE (i386nto_gregset_reg_offset)) + return i386nto_gregset_reg_offset[regnum]; + + return -1; } static void i386nto_supply_gregset (char *gpregs) { - unsigned regno; - int empty = 0; + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - for (regno = 0; regno < FP0_REGNUM; regno++) - { - int offset = nto_reg_offset (regno); - if (offset == -1) - supply_register (regno, (char *) &empty); - else - supply_register (regno, gpregs + offset); - } + if(tdep->gregset == NULL) + tdep->gregset = regset_alloc (current_gdbarch, i386_supply_gregset, + i386_collect_gregset); + + gdb_assert (tdep->gregset_reg_offset == i386nto_gregset_reg_offset); + tdep->gregset->supply_regset (tdep->gregset, current_regcache, -1, + gpregs, NUM_GPREGS * 4); } static void @@ -97,7 +108,7 @@ i386nto_supply_regset (int regset, char *data) { switch (regset) { - case NTO_REG_GENERAL: /* QNX has different ordering of GP regs than GDB. */ + case NTO_REG_GENERAL: i386nto_supply_gregset (data); break; case NTO_REG_FLOAT: @@ -111,9 +122,9 @@ i386nto_regset_id (int regno) { if (regno == -1) return NTO_REG_END; - else if (regno < FP0_REGNUM) + else if (regno < I386_NUM_GREGS) return NTO_REG_GENERAL; - else if (regno < FPC_REGNUM) + else if (regno < I386_NUM_GREGS + I386_NUM_FREGS) return NTO_REG_FLOAT; return -1; /* Error. */ @@ -176,7 +187,7 @@ i386nto_regset_fill (int regset, char *data) { int offset = nto_reg_offset (regno); if (offset != -1) - regcache_collect (regno, data + offset); + regcache_raw_collect (current_regcache, regno, data + offset); } } else if (regset == NTO_REG_FLOAT) @@ -192,42 +203,16 @@ i386nto_regset_fill (int regset, char *data) return 0; } -static struct link_map_offsets * -i386nto_svr4_fetch_link_map_offsets (void) -{ - static struct link_map_offsets lmo; - static struct link_map_offsets *lmp = NULL; - - if (lmp == NULL) - { - lmp = &lmo; - - lmo.r_debug_size = 8; /* The actual size is 20 bytes, but - only 8 bytes are used. */ - lmo.r_map_offset = 4; - lmo.r_map_size = 4; - - lmo.link_map_size = 20; /* The actual size is 552 bytes, but - only 20 bytes are used. */ - lmo.l_addr_offset = 0; - lmo.l_addr_size = 4; - - lmo.l_name_offset = 4; - lmo.l_name_size = 4; - - lmo.l_next_offset = 12; - lmo.l_next_size = 4; - - lmo.l_prev_offset = 16; - lmo.l_prev_size = 4; - } - - return lmp; -} +/* Return whether the frame preceding NEXT_FRAME corresponds to a QNX + Neutrino sigtramp routine. */ static int -i386nto_pc_in_sigtramp (CORE_ADDR pc, char *name) +i386nto_sigtramp_p (struct frame_info *next_frame) { + CORE_ADDR pc = frame_pc_unwind (next_frame); + char *name; + + find_pc_partial_function (pc, &name, NULL, NULL); return name && strcmp ("__signalstub", name) == 0; } @@ -242,7 +227,7 @@ i386nto_sigcontext_addr (struct frame_info *next_frame) char buf[4]; CORE_ADDR sp; - frame_unwind_register (next_frame, SP_REGNUM, buf); + frame_unwind_register (next_frame, I386_ESP_REGNUM, buf); sp = extract_unsigned_integer (buf, 4); return sp + I386_NTO_SIGCONTEXT_OFFSET; @@ -251,15 +236,15 @@ i386nto_sigcontext_addr (struct frame_info *next_frame) static void init_i386nto_ops (void) { - current_nto_target.nto_regset_id = i386nto_regset_id; - current_nto_target.nto_supply_gregset = i386nto_supply_gregset; - current_nto_target.nto_supply_fpregset = i386nto_supply_fpregset; - current_nto_target.nto_supply_altregset = nto_dummy_supply_regset; - current_nto_target.nto_supply_regset = i386nto_supply_regset; - current_nto_target.nto_register_area = i386nto_register_area; - current_nto_target.nto_regset_fill = i386nto_regset_fill; - current_nto_target.nto_fetch_link_map_offsets = - i386nto_svr4_fetch_link_map_offsets; + i386_nto_target.regset_id = i386nto_regset_id; + i386_nto_target.supply_gregset = i386nto_supply_gregset; + i386_nto_target.supply_fpregset = i386nto_supply_fpregset; + i386_nto_target.supply_altregset = nto_dummy_supply_regset; + i386_nto_target.supply_regset = i386nto_supply_regset; + i386_nto_target.register_area = i386nto_register_area; + i386_nto_target.regset_fill = i386nto_regset_fill; + i386_nto_target.fetch_link_map_offsets = + svr4_ilp32_fetch_link_map_offsets; } static void @@ -267,17 +252,21 @@ i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + /* Deal with our strange signals. */ + nto_initialize_signals (); + /* NTO uses ELF. */ i386_elf_init_abi (info, gdbarch); - /* Neutrino rewinds to look more normal. */ + /* Neutrino rewinds to look more normal. Need to override the i386 + default which is [unfortunately] to decrement the PC. */ set_gdbarch_decr_pc_after_break (gdbarch, 0); - /* NTO has shared libraries. */ - set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section); - set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); + tdep->gregset_reg_offset = i386nto_gregset_reg_offset; + tdep->gregset_num_regs = ARRAY_SIZE (i386nto_gregset_reg_offset); + tdep->sizeof_gregset = NUM_GPREGS * 4; - set_gdbarch_pc_in_sigtramp (gdbarch, i386nto_pc_in_sigtramp); + tdep->sigtramp_p = i386nto_sigtramp_p; tdep->sigcontext_addr = i386nto_sigcontext_addr; tdep->sc_pc_offset = 56; tdep->sc_sp_offset = 68; @@ -285,8 +274,8 @@ i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Setjmp()'s return PC saved in EDX (5). */ tdep->jb_pc_offset = 20; /* 5x32 bit ints in. */ - set_solib_svr4_fetch_link_map_offsets (gdbarch, - i386nto_svr4_fetch_link_map_offsets); + set_solib_svr4_fetch_link_map_offsets + (gdbarch, svr4_ilp32_fetch_link_map_offsets); /* Our loader handles solib relocations slightly differently than svr4. */ TARGET_SO_RELOCATE_SECTION_ADDRESSES = nto_relocate_section_addresses; @@ -294,12 +283,18 @@ i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Supply a nice function to find our solibs. */ TARGET_SO_FIND_AND_OPEN_SOLIB = nto_find_and_open_solib; - init_i386nto_ops (); + /* Our linker code is in libc. */ + TARGET_SO_IN_DYNSYM_RESOLVE_CODE = nto_in_dynsym_resolve_code; + + nto_set_target (&i386_nto_target); } void _initialize_i386nto_tdep (void) { + init_i386nto_ops (); gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO, i386nto_init_abi); + gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour, + nto_elf_osabi_sniffer); }