/* Target-dependent code for QNX Neutrino x86.
- Copyright 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Contributed by QNX Software Systems Ltd.
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)
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 <x86/context.h>. */
+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 */
};
-static struct nto_target_ops i386_nto_target;
+/* Given a GDB register number REGNUM, return the offset into
+ Neutrino's register structure or -1 if the register is unknown. */
-/* Given a gdb regno, return the offset into Neutrino's register structure
- or -1 if 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 < I386_NUM_GREGS; regno++)
- {
- int offset = nto_reg_offset (regno);
- if (offset == -1)
- regcache_raw_supply (current_regcache, regno, (char *) &empty);
- else
- regcache_raw_supply (current_regcache, 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
{
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:
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. */
i386_nto_target.register_area = i386nto_register_area;
i386_nto_target.regset_fill = i386nto_regset_fill;
i386_nto_target.fetch_link_map_offsets =
- i386nto_svr4_fetch_link_map_offsets;
+ svr4_ilp32_fetch_link_map_offsets;
}
static void
default which is [unfortunately] to decrement the PC. */
set_gdbarch_decr_pc_after_break (gdbarch, 0);
- /* NTO has shared libraries. */
- 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;
tdep->sigtramp_p = i386nto_sigtramp_p;
tdep->sigcontext_addr = i386nto_sigcontext_addr;
/* 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;