/* Intel 386 target-dependent stuff.
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "arch-utils.h"
/* Return the name of register REGNUM. */
const char *
-i386_register_name (int regnum)
+i386_register_name (struct gdbarch *gdbarch, int regnum)
{
- if (i386_mmx_regnum_p (current_gdbarch, regnum))
+ if (i386_mmx_regnum_p (gdbarch, regnum))
return i386_mmx_names[regnum - I387_MM0_REGNUM];
if (regnum >= 0 && regnum < i386_num_register_names)
number used by GDB. */
static int
-i386_dbx_reg_to_regnum (int reg)
+i386_dbx_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
/* This implements what GCC calls the "default" register map
(dbx_register_map[]). */
}
/* This will hopefully provoke a warning. */
- return NUM_REGS + NUM_PSEUDO_REGS;
+ return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
}
/* Convert SVR4 register number REG to the appropriate register number
used by GDB. */
static int
-i386_svr4_reg_to_regnum (int reg)
+i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
/* This implements the GCC register map that tries to be compatible
with the SVR4 C compiler for DWARF (svr4_dbx_register_map[]). */
else if (reg >= 21 && reg <= 36)
{
/* The SSE and MMX registers have the same numbers as with dbx. */
- return i386_dbx_reg_to_regnum (reg);
+ return i386_dbx_reg_to_regnum (gdbarch, reg);
}
switch (reg)
}
/* This will hopefully provoke a warning. */
- return NUM_REGS + NUM_PSEUDO_REGS;
+ return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
}
#undef I387_ST0_REGNUM
This function is 64-bit safe. */
static const gdb_byte *
-i386_breakpoint_from_pc (CORE_ADDR *pc, int *len)
+i386_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len)
{
static gdb_byte break_insn[] = { 0xcc }; /* int 3 */
/* Return PC of first real instruction. */
static CORE_ADDR
-i386_skip_prologue (CORE_ADDR start_pc)
+i386_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
{
static gdb_byte pic_pat[6] =
{
{
gdb_byte buf[8];
- frame_unwind_register (next_frame, PC_REGNUM, buf);
+ frame_unwind_register (next_frame, gdbarch_pc_regnum (gdbarch), buf);
return extract_typed_address (buf, builtin_type_void_func_ptr);
}
\f
{
/* Read the value in from memory. */
read_memory (*addrp, valuep,
- register_size (current_gdbarch, regnum));
+ register_size (get_frame_arch (next_frame), regnum));
}
return;
}
i386_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache)
{
struct i386_frame_cache *cache;
- struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (next_frame));
CORE_ADDR addr;
gdb_byte buf[4];
This function is 64-bit safe. */
static int
-i386_get_longjmp_target (CORE_ADDR *pc)
+i386_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
{
gdb_byte buf[8];
CORE_ADDR sp, jb_addr;
- int jb_pc_offset = gdbarch_tdep (current_gdbarch)->jb_pc_offset;
+ int jb_pc_offset = gdbarch_tdep (get_frame_arch (frame))->jb_pc_offset;
int len = TYPE_LENGTH (builtin_type_void_func_ptr);
/* If JB_PC_OFFSET is -1, we have no way to find out where the
/* Don't use I386_ESP_REGNUM here, since this function is also used
for AMD64. */
- regcache_cooked_read (current_regcache, SP_REGNUM, buf);
+ get_frame_register (frame, gdbarch_sp_regnum (get_frame_arch (frame)), buf);
sp = extract_typed_address (buf, builtin_type_void_data_ptr);
if (target_read_memory (sp + len, buf, len))
return 0;
}
else
{
- int low_size = register_size (current_gdbarch, LOW_RETURN_REGNUM);
- int high_size = register_size (current_gdbarch, HIGH_RETURN_REGNUM);
+ int low_size = register_size (gdbarch, LOW_RETURN_REGNUM);
+ int high_size = register_size (gdbarch, HIGH_RETURN_REGNUM);
if (len <= low_size)
{
}
else
{
- int low_size = register_size (current_gdbarch, LOW_RETURN_REGNUM);
- int high_size = register_size (current_gdbarch, HIGH_RETURN_REGNUM);
+ int low_size = register_size (gdbarch, LOW_RETURN_REGNUM);
+ int high_size = register_size (gdbarch, HIGH_RETURN_REGNUM);
if (len <= low_size)
regcache_raw_write_part (regcache, LOW_RETURN_REGNUM, 0, len, valbuf);
/* Type for %eflags. */
struct type *i386_eflags_type;
-/* Types for the MMX and SSE registers. */
-struct type *i386_mmx_type;
-struct type *i386_sse_type;
+/* Type for %mxcsr. */
struct type *i386_mxcsr_type;
/* Construct types for ISA-specific registers. */
append_flags_type_flag (type, 21, "ID");
i386_eflags_type = type;
- /* The type we're building is this: */
-#if 0
- union __gdb_builtin_type_vec64i
- {
- int64_t uint64;
- int32_t v2_int32[2];
- int16_t v4_int16[4];
- int8_t v8_int8[8];
- };
-#endif
-
- type = init_composite_type ("__gdb_builtin_type_vec64i", TYPE_CODE_UNION);
- append_composite_type_field (type, "uint64", builtin_type_int64);
- append_composite_type_field (type, "v2_int32", builtin_type_v2_int32);
- append_composite_type_field (type, "v4_int16", builtin_type_v4_int16);
- append_composite_type_field (type, "v8_int8", builtin_type_v8_int8);
- TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
- TYPE_NAME (type) = "builtin_type_vec64i";
- i386_mmx_type = type;
-
- /* The type we're building is this: */
-#if 0
- union __gdb_builtin_type_vec128i
- {
- int128_t uint128;
- int64_t v2_int64[2];
- int32_t v4_int32[4];
- int16_t v8_int16[8];
- int8_t v16_int8[16];
- double v2_double[2];
- float v4_float[4];
- };
-#endif
-
- type = init_composite_type ("__gdb_builtin_type_vec128i", TYPE_CODE_UNION);
- append_composite_type_field (type, "v4_float", builtin_type_v4_float);
- append_composite_type_field (type, "v2_double", builtin_type_v2_double);
- append_composite_type_field (type, "v16_int8", builtin_type_v16_int8);
- append_composite_type_field (type, "v8_int16", builtin_type_v8_int16);
- append_composite_type_field (type, "v4_int32", builtin_type_v4_int32);
- append_composite_type_field (type, "v2_int64", builtin_type_v2_int64);
- append_composite_type_field (type, "uint128", builtin_type_int128);
- TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
- TYPE_NAME (type) = "builtin_type_vec128i";
- i386_sse_type = type;
-
type = init_flags_type ("builtin_type_i386_mxcsr", 4);
append_flags_type_flag (type, 0, "IE");
append_flags_type_flag (type, 1, "DE");
i386_mxcsr_type = type;
}
+/* Construct vector type for MMX registers. */
+struct type *
+i386_mmx_type (struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (!tdep->i386_mmx_type)
+ {
+ /* The type we're building is this: */
+#if 0
+ union __gdb_builtin_type_vec64i
+ {
+ int64_t uint64;
+ int32_t v2_int32[2];
+ int16_t v4_int16[4];
+ int8_t v8_int8[8];
+ };
+#endif
+
+ struct type *t;
+
+ t = init_composite_type ("__gdb_builtin_type_vec64i", TYPE_CODE_UNION);
+ append_composite_type_field (t, "uint64", builtin_type_int64);
+ append_composite_type_field (t, "v2_int32",
+ init_vector_type (builtin_type_int32, 2));
+ append_composite_type_field (t, "v4_int16",
+ init_vector_type (builtin_type_int16, 4));
+ append_composite_type_field (t, "v8_int8",
+ init_vector_type (builtin_type_int8, 8));
+
+ TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR;
+ TYPE_NAME (t) = "builtin_type_vec64i";
+ tdep->i386_mmx_type = t;
+ }
+
+ return tdep->i386_mmx_type;
+}
+
+struct type *
+i386_sse_type (struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (!tdep->i386_sse_type)
+ {
+ /* The type we're building is this: */
+#if 0
+ union __gdb_builtin_type_vec128i
+ {
+ int128_t uint128;
+ int64_t v2_int64[2];
+ int32_t v4_int32[4];
+ int16_t v8_int16[8];
+ int8_t v16_int8[16];
+ double v2_double[2];
+ float v4_float[4];
+ };
+#endif
+
+ struct type *t;
+
+ t = init_composite_type ("__gdb_builtin_type_vec128i", TYPE_CODE_UNION);
+ append_composite_type_field (t, "v4_float",
+ init_vector_type (builtin_type_float, 4));
+ append_composite_type_field (t, "v2_double",
+ init_vector_type (builtin_type_double, 2));
+ append_composite_type_field (t, "v16_int8",
+ init_vector_type (builtin_type_int8, 16));
+ append_composite_type_field (t, "v8_int16",
+ init_vector_type (builtin_type_int16, 8));
+ append_composite_type_field (t, "v4_int32",
+ init_vector_type (builtin_type_int32, 4));
+ append_composite_type_field (t, "v2_int64",
+ init_vector_type (builtin_type_int64, 2));
+ append_composite_type_field (t, "uint128", builtin_type_int128);
+
+ TYPE_FLAGS (t) |= TYPE_FLAG_VECTOR;
+ TYPE_NAME (t) = "builtin_type_vec128i";
+ tdep->i386_sse_type = t;
+ }
+
+ return tdep->i386_sse_type;
+}
+
/* Return the GDB type object for the "standard" data type of data in
register REGNUM. Perhaps %esi and %edi should go here, but
potentially they could be used for things other than address. */
return builtin_type_i387_ext;
if (i386_mmx_regnum_p (gdbarch, regnum))
- return i386_mmx_type;
+ return i386_mmx_type (gdbarch);
if (i386_sse_regnum_p (gdbarch, regnum))
- return i386_sse_type;
+ return i386_sse_type (gdbarch);
#define I387_ST0_REGNUM I386_ST0_REGNUM
-#define I387_NUM_XMM_REGS (gdbarch_tdep (current_gdbarch)->num_xmm_regs)
+#define I387_NUM_XMM_REGS (gdbarch_tdep (gdbarch)->num_xmm_regs)
if (regnum == I387_MXCSR_REGNUM)
return i386_mxcsr_type;
needs any special handling. */
static int
-i386_convert_register_p (int regnum, struct type *type)
+i386_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type)
{
int len = TYPE_LENGTH (type);
return 1;
}
- return i386_fp_regnum_p (regnum);
+ return i387_convert_register_p (gdbarch, regnum, type);
}
/* Read a value of type TYPE from register REGNUM in frame FRAME, and
while (len > 0)
{
gdb_assert (regnum != -1);
- gdb_assert (register_size (current_gdbarch, regnum) == 4);
+ gdb_assert (register_size (get_frame_arch (frame), regnum) == 4);
get_frame_register (frame, regnum, to);
regnum = i386_next_regnum (regnum);
while (len > 0)
{
gdb_assert (regnum != -1);
- gdb_assert (register_size (current_gdbarch, regnum) == 4);
+ gdb_assert (register_size (get_frame_arch (frame), regnum) == 4);
put_frame_register (frame, regnum, from);
regnum = i386_next_regnum (regnum);
}
\f
-#ifdef STATIC_TRANSFORM_NAME
-/* SunPRO encodes the static variables. This is not related to C++
- mangling, it is done for C too. */
-
-char *
-sunpro_static_transform_name (char *name)
-{
- char *p;
- if (IS_STATIC_TRANSFORM_NAME (name))
- {
- /* For file-local statics there will be a period, a bunch of
- junk (the contents of which match a string given in the
- N_OPT), a period and the name. For function-local statics
- there will be a bunch of junk (which seems to change the
- second character from 'A' to 'B'), a period, the name of the
- function, and the name. So just skip everything before the
- last period. */
- p = strrchr (name, '.');
- if (p != NULL)
- name = p + 1;
- }
- return name;
-}
-#endif /* STATIC_TRANSFORM_NAME */
-\f
-
/* Stuff for WIN32 PE style DLL's but is pretty generic really. */
CORE_ADDR
return arches->gdbarch;
/* Allocate space for the new architecture. */
- tdep = XMALLOC (struct gdbarch_tdep);
+ tdep = XCALLOC (1, struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
/* General-purpose registers. */
set_gdbarch_dwarf_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum);
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum);
- /* We don't define ECOFF_REG_TO_REGNUM, since ECOFF doesn't seem to
+ /* We don't set gdbarch_stab_reg_to_regnum, since ECOFF doesn't seem to
be in use on any of the supported i386 targets. */
set_gdbarch_print_float_info (gdbarch, i387_print_float_info);