/* 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, 2008, 2009,
- 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1988-2012 Free Software Foundation, Inc.
This file is part of GDB.
#include "features/i386/i386-avx.c"
#include "features/i386/i386-mmx.c"
+#include "ax.h"
+#include "ax-gdb.h"
+
/* Register names. */
static const char *i386_register_names[] =
its legitimate values. */
static const char att_flavor[] = "att";
static const char intel_flavor[] = "intel";
-static const char *valid_flavors[] =
+static const char *const valid_flavors[] =
{
att_flavor,
intel_flavor,
static int
i386_syscall_p (const gdb_byte *insn, int *lengthp)
{
- if (insn[0] == 0xcd)
+ /* Is it 'int $0x80'? */
+ if ((insn[0] == 0xcd && insn[1] == 0x80)
+ /* Or is it 'sysenter'? */
+ || (insn[0] == 0x0f && insn[1] == 0x34)
+ /* Or is it 'syscall'? */
+ || (insn[0] == 0x0f && insn[1] == 0x05))
{
*lengthp = 2;
return 1;
get_frame_register (this_frame, I386_EBP_REGNUM, buf);
cache->base = extract_unsigned_integer (buf, 4, byte_order);
if (cache->base == 0)
- return;
+ {
+ cache->base_p = 1;
+ return;
+ }
/* For normal frames, %eip is stored at 4(%ebp). */
cache->saved_regs[I386_EIP_REGNUM] = 4;
i386_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
gdb_byte insn;
+ struct symtab *symtab;
+
+ symtab = find_pc_symtab (pc);
+ if (symtab && symtab->epilogue_unwind_valid)
+ return 0;
if (target_read_memory (pc, &insn, 1))
return 0; /* Can't read memory at pc. */
static struct i386_frame_cache *
i386_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
{
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
- enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
volatile struct gdb_exception ex;
struct i386_frame_cache *cache;
- gdb_byte buf[4];
+ CORE_ADDR sp;
if (*this_cache)
return *this_cache;
TRY_CATCH (ex, RETURN_MASK_ERROR)
{
- /* Cache base will be %esp plus cache->sp_offset (-4). */
- get_frame_register (this_frame, I386_ESP_REGNUM, buf);
- cache->base = extract_unsigned_integer (buf, 4,
- byte_order) + cache->sp_offset;
-
- /* Cache pc will be the frame func. */
- cache->pc = get_frame_pc (this_frame);
+ cache->pc = get_frame_func (this_frame);
- /* The saved %esp will be at cache->base plus 8. */
+ /* At this point the stack looks as if we just entered the
+ function, with the return address at the top of the
+ stack. */
+ sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM);
+ cache->base = sp + cache->sp_offset;
cache->saved_sp = cache->base + 8;
-
- /* The saved %eip will be at cache->base plus 4. */
cache->saved_regs[I386_EIP_REGNUM] = cache->base + 4;
cache->base_p = 1;
i386_epilogue_frame_unwind_stop_reason (struct frame_info *this_frame,
void **this_cache)
{
- struct i386_frame_cache *cache
- = i386_epilogue_frame_cache (this_frame, this_cache);
+ struct i386_frame_cache *cache =
+ i386_epilogue_frame_cache (this_frame, this_cache);
if (!cache->base_p)
return UNWIND_UNAVAILABLE;
void **this_cache,
struct frame_id *this_id)
{
- struct i386_frame_cache *cache = i386_epilogue_frame_cache (this_frame,
- this_cache);
+ struct i386_frame_cache *cache =
+ i386_epilogue_frame_cache (this_frame, this_cache);
if (!cache->base_p)
return;
(*this_id) = frame_id_build (cache->base + 8, cache->pc);
}
+static struct value *
+i386_epilogue_frame_prev_register (struct frame_info *this_frame,
+ void **this_cache, int regnum)
+{
+ /* Make sure we've initialized the cache. */
+ i386_epilogue_frame_cache (this_frame, this_cache);
+
+ return i386_frame_prev_register (this_frame, this_cache, regnum);
+}
+
static const struct frame_unwind i386_epilogue_frame_unwind =
{
NORMAL_FRAME,
i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id,
- i386_frame_prev_register,
+ i386_epilogue_frame_prev_register,
NULL,
i386_epilogue_frame_sniffer
};
i386_in_stack_tramp_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
gdb_byte insn;
- char *name;
+ const char *name;
/* A stack trampoline is detected if no name is associated
to the current pc and if it points inside a trampoline
static int
i386_stack_tramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
- void **this_prologue_cache)
+ struct frame_info *this_frame,
+ void **this_cache)
{
if (frame_relative_level (this_frame) == 0)
return i386_in_stack_tramp_p (get_frame_arch (this_frame),
NORMAL_FRAME,
i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id,
- i386_frame_prev_register,
+ i386_epilogue_frame_prev_register,
NULL,
i386_stack_tramp_frame_sniffer
};
\f
+/* Generate a bytecode expression to get the value of the saved PC. */
+
+static void
+i386_gen_return_address (struct gdbarch *gdbarch,
+ struct agent_expr *ax, struct axs_value *value,
+ CORE_ADDR scope)
+{
+ /* The following sequence assumes the traditional use of the base
+ register. */
+ ax_reg (ax, I386_EBP_REGNUM);
+ ax_const_l (ax, 4);
+ ax_simple (ax, aop_add);
+ value->type = register_type (gdbarch, I386_EIP_REGNUM);
+ value->kind = axs_lvalue_memory;
+}
+\f
/* Signal trampolines. */
/* See the end of i386_push_dummy_call. */
return frame_id_build (fp + 8, get_frame_pc (this_frame));
}
+
+/* _Decimal128 function return values need 16-byte alignment on the
+ stack. */
+
+static CORE_ADDR
+i386_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
+{
+ return sp & -(CORE_ADDR)16;
+}
\f
/* Figure out where the longjmp will land. Slurp the args out of the
static const char default_struct_convention[] = "default";
static const char pcc_struct_convention[] = "pcc";
static const char reg_struct_convention[] = "reg";
-static const char *valid_conventions[] =
+static const char *const valid_conventions[] =
{
default_struct_convention,
pcc_struct_convention,
return (I387_ST0_REGNUM (tdep) + fpreg);
}
-enum register_status
-i386_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
- int regnum, gdb_byte *buf)
+/* A helper function for us by i386_pseudo_register_read_value and
+ amd64_pseudo_register_read_value. It does all the work but reads
+ the data into an already-allocated value. */
+
+void
+i386_pseudo_register_read_into_value (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ int regnum,
+ struct value *result_value)
{
gdb_byte raw_buf[MAX_REGISTER_SIZE];
enum register_status status;
+ gdb_byte *buf = value_contents_raw (result_value);
if (i386_mmx_regnum_p (gdbarch, regnum))
{
/* Extract (always little endian). */
status = regcache_raw_read (regcache, fpnum, raw_buf);
if (status != REG_VALID)
- return status;
- memcpy (buf, raw_buf, register_size (gdbarch, regnum));
+ mark_value_bytes_unavailable (result_value, 0,
+ TYPE_LENGTH (value_type (result_value)));
+ else
+ memcpy (buf, raw_buf, register_size (gdbarch, regnum));
}
else
{
I387_XMM0_REGNUM (tdep) + regnum,
raw_buf);
if (status != REG_VALID)
- return status;
- memcpy (buf, raw_buf, 16);
+ mark_value_bytes_unavailable (result_value, 0, 16);
+ else
+ memcpy (buf, raw_buf, 16);
/* Read upper 128bits. */
status = regcache_raw_read (regcache,
tdep->ymm0h_regnum + regnum,
raw_buf);
if (status != REG_VALID)
- return status;
- memcpy (buf + 16, raw_buf, 16);
+ mark_value_bytes_unavailable (result_value, 16, 32);
+ else
+ memcpy (buf + 16, raw_buf, 16);
}
else if (i386_word_regnum_p (gdbarch, regnum))
{
/* Extract (always little endian). */
status = regcache_raw_read (regcache, gpnum, raw_buf);
if (status != REG_VALID)
- return status;
- memcpy (buf, raw_buf, 2);
+ mark_value_bytes_unavailable (result_value, 0,
+ TYPE_LENGTH (value_type (result_value)));
+ else
+ memcpy (buf, raw_buf, 2);
}
else if (i386_byte_regnum_p (gdbarch, regnum))
{
upper registers. */
status = regcache_raw_read (regcache, gpnum % 4, raw_buf);
if (status != REG_VALID)
- return status;
- if (gpnum >= 4)
+ mark_value_bytes_unavailable (result_value, 0,
+ TYPE_LENGTH (value_type (result_value)));
+ else if (gpnum >= 4)
memcpy (buf, raw_buf + 1, 1);
else
memcpy (buf, raw_buf, 1);
else
internal_error (__FILE__, __LINE__, _("invalid regnum"));
}
+}
+
+static struct value *
+i386_pseudo_register_read_value (struct gdbarch *gdbarch,
+ struct regcache *regcache,
+ int regnum)
+{
+ struct value *result;
- return REG_VALID;
+ result = allocate_value (register_type (gdbarch, regnum));
+ VALUE_LVAL (result) = lval_register;
+ VALUE_REGNUM (result) = regnum;
+
+ i386_pseudo_register_read_into_value (gdbarch, regcache, regnum, result);
+
+ return result;
}
void
read_memory_unsigned_integer (pc + 2, 4, byte_order);
struct minimal_symbol *indsym =
indirect ? lookup_minimal_symbol_by_pc (indirect) : 0;
- char *symname = indsym ? SYMBOL_LINKAGE_NAME (indsym) : 0;
+ const char *symname = indsym ? SYMBOL_LINKAGE_NAME (indsym) : 0;
if (symname)
{
i386_sigtramp_p (struct frame_info *this_frame)
{
CORE_ADDR pc = get_frame_pc (this_frame);
- char *name;
+ const char *name;
find_pc_partial_function (pc, &name, NULL, NULL);
return (name && strcmp ("_sigtramp", name) == 0);
i386_svr4_sigtramp_p (struct frame_info *this_frame)
{
CORE_ADDR pc = get_frame_pc (this_frame);
- char *name;
+ const char *name;
/* UnixWare uses _sigacthandler. The origin of the other symbols is
currently unknown. */
};
/* Check that the given address appears suitable for a fast
- tracepoint, which on x86 means that we need an instruction of at
+ tracepoint, which on x86-64 means that we need an instruction of at
least 5 bytes, so that we can overwrite it with a 4-byte-offset
jump and not have to worry about program jumps to an address in the
- middle of the tracepoint jump. Returns 1 if OK, and writes a size
+ middle of the tracepoint jump. On x86, it may be possible to use
+ 4-byte jumps with a 2-byte offset to a trampoline located in the
+ bottom 64 KiB of memory. Returns 1 if OK, and writes a size
of instruction to replace, and 0 if not, plus an explanatory
string. */
int len, jumplen;
static struct ui_file *gdb_null = NULL;
- /* This is based on the target agent using a 4-byte relative jump.
- Alternate future possibilities include 8-byte offset for x86-84,
- or 3-byte jumps if the program has trampoline space close by. */
- jumplen = 5;
+ /* Ask the target for the minimum instruction length supported. */
+ jumplen = target_get_min_fast_tracepoint_insn_len ();
+
+ if (jumplen < 0)
+ {
+ /* If the target does not support the get_min_fast_tracepoint_insn_len
+ operation, assume that fast tracepoints will always be implemented
+ using 4-byte relative jumps on both x86 and x86-64. */
+ jumplen = 5;
+ }
+ else if (jumplen == 0)
+ {
+ /* If the target does support get_min_fast_tracepoint_insn_len but
+ returns zero, then the IPA has not loaded yet. In this case,
+ we optimistically assume that truncated 2-byte relative jumps
+ will be available on x86, and compensate later if this assumption
+ turns out to be incorrect. On x86-64 architectures, 4-byte relative
+ jumps will always be used. */
+ jumplen = (register_size (gdbarch, 0) == 8) ? 5 : 4;
+ }
/* Dummy file descriptor for the disassembler. */
if (!gdb_null)
/* Check for fit. */
len = gdb_print_insn (gdbarch, addr, gdb_null, NULL);
+ if (isize)
+ *isize = len;
+
if (len < jumplen)
{
/* Return a bit of target-specific detail to add to the caller's
len, jumplen);
return 0;
}
-
- if (isize)
- *isize = len;
- if (msg)
- *msg = NULL;
- return 1;
+ else
+ {
+ if (msg)
+ *msg = NULL;
+ return 1;
+ }
}
static int
tdep->record_regmap = i386_record_regmap;
+ set_gdbarch_long_long_align_bit (gdbarch, 32);
+
/* The format used for `long double' on almost all i386 targets is
the i387 extended floating-point format. In fact, of all targets
in the GCC 2.95 tree, only OSF/1 does it different, and insists
/* Call dummy code. */
set_gdbarch_push_dummy_call (gdbarch, i386_push_dummy_call);
+ set_gdbarch_frame_align (gdbarch, i386_frame_align);
set_gdbarch_convert_register_p (gdbarch, i386_convert_register_p);
set_gdbarch_register_to_value (gdbarch, i386_register_to_value);
set_gdbarch_fetch_pointer_argument (gdbarch, i386_fetch_pointer_argument);
/* Hook the function epilogue frame unwinder. This unwinder is
- appended to the list first, so that it supercedes the Dwarf
- unwinder in function epilogues (where the Dwarf unwinder
+ appended to the list first, so that it supercedes the DWARF
+ unwinder in function epilogues (where the DWARF unwinder
currently fails). */
frame_unwind_append_unwinder (gdbarch, &i386_epilogue_frame_unwind);
/* Hook in the DWARF CFI frame unwinder. This unwinder is appended
- to the list before the prologue-based unwinders, so that Dwarf
+ to the list before the prologue-based unwinders, so that DWARF
CFI info will be used if it is available. */
dwarf2_append_unwinders (gdbarch);
frame_base_set_default (gdbarch, &i386_frame_base);
/* Pseudo registers may be changed by amd64_init_abi. */
- set_gdbarch_pseudo_register_read (gdbarch, i386_pseudo_register_read);
+ set_gdbarch_pseudo_register_read_value (gdbarch,
+ i386_pseudo_register_read_value);
set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write);
set_tdesc_pseudo_register_type (gdbarch, i386_pseudo_register_type);
set_gdbarch_relocate_instruction (gdbarch, i386_relocate_instruction);
+ set_gdbarch_gen_return_address (gdbarch, i386_gen_return_address);
+
/* Hook in ABI-specific overrides, if they have been registered. */
info.tdep_info = (void *) tdesc_data;
gdbarch_init_osabi (info, gdbarch);