/* Intel 386 target-dependent stuff.
- Copyright (C) 1988-2020 Free Software Foundation, Inc.
+ Copyright (C) 1988-2024 Free Software Foundation, Inc.
This file is part of GDB.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-#include "defs.h"
+#include "extract-store-integer.h"
#include "opcode/i386.h"
#include "arch-utils.h"
#include "command.h"
#include "frame-unwind.h"
#include "inferior.h"
#include "infrun.h"
-#include "gdbcmd.h"
+#include "cli/cli-cmds.h"
#include "gdbcore.h"
#include "gdbtypes.h"
#include "objfiles.h"
#include "i387-tdep.h"
#include "gdbsupport/x86-xstate.h"
#include "x86-tdep.h"
+#include "expop.h"
#include "record.h"
#include "record-full.h"
#include <algorithm>
#include <unordered_set>
#include "producer.h"
+#include "infcall.h"
+#include "maint.h"
/* Register names. */
static const char * const i386_byte_names[] =
{
- "al", "cl", "dl", "bl",
+ "al", "cl", "dl", "bl",
"ah", "ch", "dh", "bh"
};
static int
i386_mmx_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int mm0_regnum = tdep->mm0_regnum;
if (mm0_regnum < 0)
int
i386_byte_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
regnum -= tdep->al_regnum;
return regnum >= 0 && regnum < tdep->num_byte_regs;
int
i386_word_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
regnum -= tdep->ax_regnum;
return regnum >= 0 && regnum < tdep->num_word_regs;
int
i386_dword_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int eax_regnum = tdep->eax_regnum;
if (eax_regnum < 0)
int
i386_zmmh_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int zmm0h_regnum = tdep->zmm0h_regnum;
if (zmm0h_regnum < 0)
int
i386_zmm_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int zmm0_regnum = tdep->zmm0_regnum;
if (zmm0_regnum < 0)
int
i386_k_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int k0_regnum = tdep->k0_regnum;
if (k0_regnum < 0)
static int
i386_ymmh_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int ymm0h_regnum = tdep->ymm0h_regnum;
if (ymm0h_regnum < 0)
int
i386_ymm_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int ymm0_regnum = tdep->ymm0_regnum;
if (ymm0_regnum < 0)
static int
i386_ymmh_avx512_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int ymm16h_regnum = tdep->ymm16h_regnum;
if (ymm16h_regnum < 0)
int
i386_ymm_avx512_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int ymm16_regnum = tdep->ymm16_regnum;
if (ymm16_regnum < 0)
int
i386_bnd_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int bnd0_regnum = tdep->bnd0_regnum;
if (bnd0_regnum < 0)
int
i386_xmm_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int num_xmm_regs = I387_NUM_XMM_REGS (tdep);
if (num_xmm_regs == 0)
int
i386_xmm_avx512_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int num_xmm_avx512_regs = I387_NUM_XMM_AVX512_REGS (tdep);
if (num_xmm_avx512_regs == 0)
static int
i386_mxcsr_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (I387_NUM_XMM_REGS (tdep) == 0)
return 0;
int
i386_fp_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (I387_ST0_REGNUM (tdep) < 0)
return 0;
int
i386_fpc_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (I387_ST0_REGNUM (tdep) < 0)
return 0;
- return (I387_FCTRL_REGNUM (tdep) <= regnum
+ return (I387_FCTRL_REGNUM (tdep) <= regnum
&& regnum < I387_XMM0_REGNUM (tdep));
}
static int
i386_bndr_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (I387_BND0R_REGNUM (tdep) < 0)
return 0;
static int
i386_mpx_ctrl_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (I387_BNDCFGU_REGNUM (tdep) < 0)
return 0;
bool
i386_pkru_regnum_p (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int pkru_regnum = tdep->pkru_regnum;
if (pkru_regnum < 0)
const char *
i386_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (i386_bnd_regnum_p (gdbarch, regnum))
return i386_bnd_names[regnum - tdep->bnd0_regnum];
if (i386_mmx_regnum_p (gdbarch, regnum))
else if (i386_word_regnum_p (gdbarch, regnum))
return i386_word_names[regnum - tdep->ax_regnum];
- internal_error (__FILE__, __LINE__, _("invalid regnum"));
+ internal_error (_("invalid regnum"));
}
/* Convert a dbx register number REG to the appropriate register
static int
i386_dbx_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
/* This implements what GCC calls the "default" register map
(dbx_register_map[]). */
static int
i386_svr4_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
/* This implements the GCC register map that tries to be compatible
with the SVR4 C compiler for DWARF (svr4_dbx_register_map[]). */
displaced_debug_printf ("%s->%s: %s",
paddress (gdbarch, from), paddress (gdbarch, to),
- displaced_step_dump_bytes (buf, len).c_str ());
+ bytes_to_string (buf, len).c_str ());
/* This is a work around for a problem with g++ 4.8. */
return displaced_step_copy_insn_closure_up (closure.release ());
i386_displaced_step_fixup (struct gdbarch *gdbarch,
struct displaced_step_copy_insn_closure *closure_,
CORE_ADDR from, CORE_ADDR to,
- struct regcache *regs)
+ struct regcache *regs, bool completed_p)
{
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
the displaced instruction; make it relative. Well, signal
handler returns don't need relocation either, but we use the
value of %eip to recognize those; see below. */
- if (! i386_absolute_jmp_p (insn)
- && ! i386_absolute_call_p (insn)
- && ! i386_ret_p (insn))
+ if (!completed_p
+ || (!i386_absolute_jmp_p (insn)
+ && !i386_absolute_call_p (insn)
+ && !i386_ret_p (insn)))
{
- ULONGEST orig_eip;
int insn_len;
- regcache_cooked_read_unsigned (regs, I386_EIP_REGNUM, &orig_eip);
+ CORE_ADDR pc = regcache_read_pc (regs);
/* A signal trampoline system call changes the %eip, resuming
execution of the main program after the signal handler has
it unrelocated. Goodness help us if there are PC-relative
system calls. */
if (i386_syscall_p (insn, &insn_len)
- && orig_eip != to + (insn - insn_start) + insn_len
+ && pc != to + (insn - insn_start) + insn_len
/* GDB can get control back after the insn after the syscall.
Presumably this is a kernel bug.
- i386_displaced_step_copy_insn ensures its a nop,
+ i386_displaced_step_copy_insn ensures it's a nop,
we add one to the length for it. */
- && orig_eip != to + (insn - insn_start) + insn_len + 1)
+ && pc != to + (insn - insn_start) + insn_len + 1)
displaced_debug_printf ("syscall changed %%eip; not relocating");
else
{
- ULONGEST eip = (orig_eip - insn_offset) & 0xffffffffUL;
+ ULONGEST eip = (pc - insn_offset) & 0xffffffffUL;
/* If we just stepped over a breakpoint insn, we don't backup
the pc on purpose; this is to match behaviour without
stepping. */
- regcache_cooked_write_unsigned (regs, I386_EIP_REGNUM, eip);
+ regcache_write_pc (regs, eip);
displaced_debug_printf ("relocated %%eip from %s to %s",
- paddress (gdbarch, orig_eip),
+ paddress (gdbarch, pc),
paddress (gdbarch, eip));
}
}
/* If the instruction was a call, the return address now atop the
stack is the address following the copied instruction. We need
to make it the address following the original instruction. */
- if (i386_call_p (insn))
+ if (completed_p && i386_call_p (insn))
{
ULONGEST esp;
ULONGEST retaddr;
cache->pc_in_eax = 1;
return current_pc;
}
-
+
if (buf[1] == proto1[1])
return pc + 4;
else
pushl constant
call _probe
addl $4, %esp
-
+
followed by
pushl %ebp
pushl -4(%reg)
"andl $-XXX, %esp" can be either 3 bytes or 6 bytes:
-
- 0x83 0xe4 0xf0 andl $-16, %esp
- 0x81 0xe4 0x00 0xff 0xff 0xff andl $-256, %esp
+
+ 0x83 0xe4 0xf0 andl $-16, %esp
+ 0x81 0xe4 0x00 0xff 0xff 0xff andl $-256, %esp
*/
gdb_byte buf[14];
/* MOD must be binary 10 and R/M must be binary 100. */
if ((buf[2] & 0xc7) != 0x44)
return pc;
-
+
/* REG has register number. Registers in pushl and leal have to
be the same. */
if (reg != ((buf[2] >> 3) & 7))
yet, and only the scratch registers %eax, %ecx and %edx can be
touched. */
-struct i386_insn i386_frame_setup_skip_insns[] =
+static i386_insn i386_frame_setup_skip_insns[] =
{
/* Check for `movb imm8, r' and `movl imm32, r'.
-
+
??? Should we handle 16-bit operand-sizes here? */
/* `movb imm8, %al' and `movb imm8, %ah' */
if (target_read_code (pc, &op, 1))
return pc;
- while (check)
+ while (check)
{
check = 0;
/* Ignore `nop' instruction. */
- if (op == 0x90)
+ if (op == 0x90)
{
pc += 1;
if (target_read_code (pc, &op, 1))
}
}
}
- return pc;
+ return pc;
}
/* Check whether PC points at a code that sets up a new stack frame.
if (limit <= pc)
return limit;
- /* Check for stack adjustment
+ /* Check for stack adjustment
subl $XXX, %esp
or
%ebx (and sometimes a harmless bug causes it to also save but not
restore %eax); however, the code below is willing to see the pushes
in any order, and will handle up to 8 of them.
-
+
If the setup sequence is at the end of the function, then the next
instruction will be a branch back to the start. */
struct compunit_symtab *cust = find_pc_compunit_symtab (func_addr);
/* LLVM backend (Clang/Flang) always emits a line note before the
- prologue and another one after. We trust clang to emit usable
- line notes. */
+ prologue and another one after. We trust clang and newer Intel
+ compilers to emit usable line notes. */
if (post_prologue_pc
&& (cust != NULL
- && COMPUNIT_PRODUCER (cust) != NULL
- && producer_is_llvm (COMPUNIT_PRODUCER (cust))))
+ && cust->producer () != NULL
+ && (producer_is_llvm (cust->producer ())
+ || producer_is_icc_ge_19 (cust->producer ()))))
return std::max (start_pc, post_prologue_pc);
}
-
+
cache.locals = -1;
pc = i386_analyze_prologue (gdbarch, start_pc, 0xffffffff, &cache);
if (cache.locals < 0)
gdb_byte buf[4];
if (target_read_code (pc + 1, buf, sizeof buf) == 0)
- {
+ {
/* Make sure address is computed correctly as a 32bit
integer even if CORE_ADDR is 64 bit wide. */
- struct bound_minimal_symbol s;
- CORE_ADDR call_dest;
+ struct bound_minimal_symbol s;
+ CORE_ADDR call_dest;
call_dest = pc + 5 + extract_signed_integer (buf, 4, byte_order);
call_dest = call_dest & 0xffffffffU;
- s = lookup_minimal_symbol_by_pc (call_dest);
- if (s.minsym != NULL
- && s.minsym->linkage_name () != NULL
- && strcmp (s.minsym->linkage_name (), "__main") == 0)
- pc += 5;
- }
+ s = lookup_minimal_symbol_by_pc (call_dest);
+ if (s.minsym != NULL
+ && s.minsym->linkage_name () != NULL
+ && strcmp (s.minsym->linkage_name (), "__main") == 0)
+ pc += 5;
+ }
}
return pc;
/* This function is 64-bit safe. */
static CORE_ADDR
-i386_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+i386_unwind_pc (struct gdbarch *gdbarch, const frame_info_ptr &next_frame)
{
gdb_byte buf[8];
/* Normal frames. */
static void
-i386_frame_cache_1 (struct frame_info *this_frame,
+i386_frame_cache_1 (const frame_info_ptr &this_frame,
struct i386_frame_cache *cache)
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
}
static struct i386_frame_cache *
-i386_frame_cache (struct frame_info *this_frame, void **this_cache)
+i386_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
{
struct i386_frame_cache *cache;
}
static void
-i386_frame_this_id (struct frame_info *this_frame, void **this_cache,
+i386_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
struct frame_id *this_id)
{
struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
}
static enum unwind_stop_reason
-i386_frame_unwind_stop_reason (struct frame_info *this_frame,
+i386_frame_unwind_stop_reason (const frame_info_ptr &this_frame,
void **this_cache)
{
struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
}
static struct value *
-i386_frame_prev_register (struct frame_info *this_frame, void **this_cache,
+i386_frame_prev_register (const frame_info_ptr &this_frame, void **this_cache,
int regnum)
{
struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
static const struct frame_unwind i386_frame_unwind =
{
+ "i386 prologue",
NORMAL_FRAME,
i386_frame_unwind_stop_reason,
i386_frame_this_id,
i386_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
gdb_byte insn;
- struct compunit_symtab *cust;
-
- cust = find_pc_compunit_symtab (pc);
- if (cust != NULL && COMPUNIT_EPILOGUE_UNWIND_VALID (cust))
- return 0;
-
if (target_read_memory (pc, &insn, 1))
return 0; /* Can't read memory at pc. */
return 1;
}
+static int
+i386_epilogue_frame_sniffer_1 (const struct frame_unwind *self,
+ const frame_info_ptr &this_frame,
+ void **this_prologue_cache, bool override_p)
+{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ CORE_ADDR pc = get_frame_pc (this_frame);
+
+ if (frame_relative_level (this_frame) != 0)
+ /* We're not in the inner frame, so assume we're not in an epilogue. */
+ return 0;
+
+ bool unwind_valid_p
+ = compunit_epilogue_unwind_valid (find_pc_compunit_symtab (pc));
+ if (override_p)
+ {
+ if (unwind_valid_p)
+ /* Don't override the symtab unwinders, skip
+ "i386 epilogue override". */
+ return 0;
+ }
+ else
+ {
+ if (!unwind_valid_p)
+ /* "i386 epilogue override" unwinder already ran, skip
+ "i386 epilogue". */
+ return 0;
+ }
+
+ /* Check whether we're in an epilogue. */
+ return i386_stack_frame_destroyed_p (gdbarch, pc);
+}
+
+static int
+i386_epilogue_override_frame_sniffer (const struct frame_unwind *self,
+ const frame_info_ptr &this_frame,
+ void **this_prologue_cache)
+{
+ return i386_epilogue_frame_sniffer_1 (self, this_frame, this_prologue_cache,
+ true);
+}
+
static int
i386_epilogue_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
+ const frame_info_ptr &this_frame,
void **this_prologue_cache)
{
- if (frame_relative_level (this_frame) == 0)
- return i386_stack_frame_destroyed_p (get_frame_arch (this_frame),
- get_frame_pc (this_frame));
- else
- return 0;
+ return i386_epilogue_frame_sniffer_1 (self, this_frame, this_prologue_cache,
+ false);
}
static struct i386_frame_cache *
-i386_epilogue_frame_cache (struct frame_info *this_frame, void **this_cache)
+i386_epilogue_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
{
struct i386_frame_cache *cache;
CORE_ADDR sp;
}
static enum unwind_stop_reason
-i386_epilogue_frame_unwind_stop_reason (struct frame_info *this_frame,
+i386_epilogue_frame_unwind_stop_reason (const frame_info_ptr &this_frame,
void **this_cache)
{
struct i386_frame_cache *cache =
}
static void
-i386_epilogue_frame_this_id (struct frame_info *this_frame,
+i386_epilogue_frame_this_id (const frame_info_ptr &this_frame,
void **this_cache,
struct frame_id *this_id)
{
}
static struct value *
-i386_epilogue_frame_prev_register (struct frame_info *this_frame,
+i386_epilogue_frame_prev_register (const frame_info_ptr &this_frame,
void **this_cache, int regnum)
{
/* Make sure we've initialized the cache. */
return i386_frame_prev_register (this_frame, this_cache, regnum);
}
+static const struct frame_unwind i386_epilogue_override_frame_unwind =
+{
+ "i386 epilogue override",
+ NORMAL_FRAME,
+ i386_epilogue_frame_unwind_stop_reason,
+ i386_epilogue_frame_this_id,
+ i386_epilogue_frame_prev_register,
+ NULL,
+ i386_epilogue_override_frame_sniffer
+};
+
static const struct frame_unwind i386_epilogue_frame_unwind =
{
+ "i386 epilogue",
NORMAL_FRAME,
i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id,
i386_epilogue_frame_prev_register,
- NULL,
+ NULL,
i386_epilogue_frame_sniffer
};
\f
/* Static chain passed in register. */
-struct i386_insn i386_tramp_chain_in_reg_insns[] =
+static i386_insn i386_tramp_chain_in_reg_insns[] =
{
/* `movl imm32, %eax' and `movl imm32, %ecx' */
{ 5, { 0xb8 }, { 0xfe } },
/* Static chain passed on stack (when regparm=3). */
-struct i386_insn i386_tramp_chain_on_stack_insns[] =
+static i386_insn i386_tramp_chain_on_stack_insns[] =
{
/* `push imm32' */
{ 5, { 0x68 }, { 0xff } },
static int
i386_stack_tramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
+ const frame_info_ptr &this_frame,
void **this_cache)
{
if (frame_relative_level (this_frame) == 0)
static const struct frame_unwind i386_stack_tramp_frame_unwind =
{
+ "i386 stack tramp",
NORMAL_FRAME,
i386_epilogue_frame_unwind_stop_reason,
i386_epilogue_frame_this_id,
i386_epilogue_frame_prev_register,
- NULL,
+ NULL,
i386_stack_tramp_frame_sniffer
};
\f
/* Signal trampolines. */
static struct i386_frame_cache *
-i386_sigtramp_frame_cache (struct frame_info *this_frame, void **this_cache)
+i386_sigtramp_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct i386_frame_cache *cache;
CORE_ADDR addr;
}
static enum unwind_stop_reason
-i386_sigtramp_frame_unwind_stop_reason (struct frame_info *this_frame,
+i386_sigtramp_frame_unwind_stop_reason (const frame_info_ptr &this_frame,
void **this_cache)
{
struct i386_frame_cache *cache =
}
static void
-i386_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
+i386_sigtramp_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
struct frame_id *this_id)
{
struct i386_frame_cache *cache =
}
static struct value *
-i386_sigtramp_frame_prev_register (struct frame_info *this_frame,
+i386_sigtramp_frame_prev_register (const frame_info_ptr &this_frame,
void **this_cache, int regnum)
{
/* Make sure we've initialized the cache. */
static int
i386_sigtramp_frame_sniffer (const struct frame_unwind *self,
- struct frame_info *this_frame,
+ const frame_info_ptr &this_frame,
void **this_prologue_cache)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
+ gdbarch *arch = get_frame_arch (this_frame);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (arch);
/* We shouldn't even bother if we don't have a sigcontext_addr
handler. */
static const struct frame_unwind i386_sigtramp_frame_unwind =
{
+ "i386 sigtramp",
SIGTRAMP_FRAME,
i386_sigtramp_frame_unwind_stop_reason,
i386_sigtramp_frame_this_id,
\f
static CORE_ADDR
-i386_frame_base_address (struct frame_info *this_frame, void **this_cache)
+i386_frame_base_address (const frame_info_ptr &this_frame, void **this_cache)
{
struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
};
static struct frame_id
-i386_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+i386_dummy_id (struct gdbarch *gdbarch, const frame_info_ptr &this_frame)
{
CORE_ADDR fp;
success. */
static int
-i386_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+i386_get_longjmp_target (const frame_info_ptr &frame, CORE_ADDR *pc)
{
gdb_byte buf[4];
CORE_ADDR sp, jb_addr;
struct gdbarch *gdbarch = get_frame_arch (frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
- int jb_pc_offset = gdbarch_tdep (gdbarch)->jb_pc_offset;
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
+ int jb_pc_offset = tdep->jb_pc_offset;
/* If JB_PC_OFFSET is -1, we have no way to find out where the
longjmp will land. */
type = check_typedef (type);
if ((type->code () == TYPE_CODE_DECFLOAT
|| (type->code () == TYPE_CODE_ARRAY && type->is_vector ()))
- && TYPE_LENGTH (type) == 16)
+ && type->length () == 16)
return 1;
if (type->code () == TYPE_CODE_ARRAY)
- return i386_16_byte_align_p (TYPE_TARGET_TYPE (type));
+ return i386_16_byte_align_p (type->target_type ());
if (type->code () == TYPE_CODE_STRUCT
|| type->code () == TYPE_CODE_UNION)
{
int i;
for (i = 0; i < type->num_fields (); i++)
{
- if (field_is_static (&type->field (i)))
+ if (type->field (i).is_static ())
continue;
if (i386_16_byte_align_p (type->field (i).type ()))
return 1;
for (i = thiscall ? 1 : 0; i < nargs; i++)
{
- int len = TYPE_LENGTH (value_enclosing_type (args[i]));
+ int len = args[i]->enclosing_type ()->length ();
if (write_pass)
{
- if (i386_16_byte_align_p (value_enclosing_type (args[i])))
+ if (i386_16_byte_align_p (args[i]->enclosing_type ()))
args_space_used = align_up (args_space_used, 16);
write_memory (sp + args_space_used,
- value_contents_all (args[i]), len);
+ args[i]->contents_all ().data (), len);
/* The System V ABI says that:
"An argument's size is increased, if necessary, to make it a
}
else
{
- if (i386_16_byte_align_p (value_enclosing_type (args[i])))
+ if (i386_16_byte_align_p (args[i]->enclosing_type ()))
args_space = align_up (args_space, 16);
args_space += align_up (len, 4);
}
/* The 'this' pointer needs to be in ECX. */
if (thiscall)
- regcache->cooked_write (I386_ECX_REGNUM, value_contents_all (args[0]));
+ regcache->cooked_write (I386_ECX_REGNUM,
+ args[0]->contents_all ().data ());
+
+ /* If the PLT is position-independent, the SYSTEM V ABI requires %ebx to be
+ set to the address of the GOT when doing a call to a PLT address.
+ Note that we do not try to determine whether the PLT is
+ position-independent, we just set the register regardless. */
+ CORE_ADDR func_addr = find_function_addr (function, nullptr, nullptr);
+ if (in_plt_section (func_addr))
+ {
+ struct objfile *objf = nullptr;
+ asection *asect = nullptr;
+ obj_section *osect = nullptr;
+
+ /* Get object file containing func_addr. */
+ obj_section *func_section = find_pc_section (func_addr);
+ if (func_section != nullptr)
+ objf = func_section->objfile;
+
+ if (objf != nullptr)
+ {
+ /* Get corresponding .got.plt or .got section. */
+ asect = bfd_get_section_by_name (objf->obfd.get (), ".got.plt");
+ if (asect == nullptr)
+ asect = bfd_get_section_by_name (objf->obfd.get (), ".got");
+ }
+
+ if (asect != nullptr)
+ /* Translate asection to obj_section. */
+ osect = maint_obj_section_from_bfd_section (objf->obfd.get (),
+ asect, objf);
+
+ if (osect != nullptr)
+ {
+ /* Store the section address in %ebx. */
+ store_unsigned_integer (buf, 4, byte_order, osect->addr ());
+ regcache->cooked_write (I386_EBX_REGNUM, buf);
+ }
+ else
+ {
+ /* If we would only do this for a position-independent PLT, it would
+ make sense to issue a warning here. */
+ }
+ }
/* MarkK wrote: This "+ 8" is all over the place:
(i386_frame_this_id, i386_sigtramp_frame_this_id,
i386_extract_return_value (struct gdbarch *gdbarch, struct type *type,
struct regcache *regcache, gdb_byte *valbuf)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- int len = TYPE_LENGTH (type);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
+ int len = type->length ();
gdb_byte buf[I386_MAX_REGISTER_SIZE];
- if (type->code () == TYPE_CODE_FLT)
+ /* _Float16 and _Float16 _Complex values are returned via xmm0. */
+ if (((type->code () == TYPE_CODE_FLT) && len == 2)
+ || ((type->code () == TYPE_CODE_COMPLEX) && len == 4))
+ {
+ regcache->raw_read (I387_XMM0_REGNUM (tdep), valbuf);
+ return;
+ }
+ else if (type->code () == TYPE_CODE_FLT)
{
if (tdep->st0_regnum < 0)
{
memcpy (valbuf + low_size, buf, len - low_size);
}
else
- internal_error (__FILE__, __LINE__,
- _("Cannot extract return value of %d bytes long."),
+ internal_error (_("Cannot extract return value of %d bytes long."),
len);
}
}
i386_store_return_value (struct gdbarch *gdbarch, struct type *type,
struct regcache *regcache, const gdb_byte *valbuf)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- int len = TYPE_LENGTH (type);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
+ int len = type->length ();
if (type->code () == TYPE_CODE_FLT)
{
valbuf + low_size);
}
else
- internal_error (__FILE__, __LINE__,
- _("Cannot store return value of %d bytes long."), len);
+ internal_error (_("Cannot store return value of %d bytes long."), len);
}
}
\f
static int
i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
enum type_code code = type->code ();
- int len = TYPE_LENGTH (type);
+ int len = type->length ();
gdb_assert (code == TYPE_CODE_STRUCT
|| code == TYPE_CODE_UNION
if (struct_convention == pcc_struct_convention
|| (struct_convention == default_struct_convention
- && tdep->struct_return == pcc_struct_return))
+ && tdep->struct_return == pcc_struct_return)
+ || TYPE_HAS_DYNAMIC_LENGTH (type))
return 0;
/* Structures consisting of a single `float', `double' or 'long
static enum return_value_convention
i386_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache,
- gdb_byte *readbuf, const gdb_byte *writebuf)
+ struct value **read_value, const gdb_byte *writebuf)
{
enum type_code code = type->code ();
|| code == TYPE_CODE_ARRAY)
&& !i386_reg_struct_return_p (gdbarch, type))
/* Complex double and long double uses the struct return convention. */
- || (code == TYPE_CODE_COMPLEX && TYPE_LENGTH (type) == 16)
- || (code == TYPE_CODE_COMPLEX && TYPE_LENGTH (type) == 24)
+ || (code == TYPE_CODE_COMPLEX && type->length () == 16)
+ || (code == TYPE_CODE_COMPLEX && type->length () == 24)
/* 128-bit decimal float uses the struct return convention. */
- || (code == TYPE_CODE_DECFLOAT && TYPE_LENGTH (type) == 16))
+ || (code == TYPE_CODE_DECFLOAT && type->length () == 16))
{
/* The System V ABI says that:
a record, so the convention applied to records also applies
to arrays. */
- if (readbuf)
+ if (read_value != nullptr)
{
ULONGEST addr;
regcache_raw_read_unsigned (regcache, I386_EAX_REGNUM, &addr);
- read_memory (addr, readbuf, TYPE_LENGTH (type));
+ *read_value = value_at_non_lval (type, addr);
}
return RETURN_VALUE_ABI_RETURNS_ADDRESS;
here. */
if (code == TYPE_CODE_STRUCT && type->num_fields () == 1)
{
- type = check_typedef (type->field (0).type ());
- return i386_return_value (gdbarch, function, type, regcache,
- readbuf, writebuf);
+ struct type *inner_type = check_typedef (type->field (0).type ());
+ enum return_value_convention result
+ = i386_return_value (gdbarch, function, inner_type, regcache,
+ read_value, writebuf);
+ if (read_value != nullptr)
+ (*read_value)->deprecated_set_type (type);
+ return result;
}
- if (readbuf)
- i386_extract_return_value (gdbarch, type, regcache, readbuf);
+ if (read_value != nullptr)
+ {
+ *read_value = value::allocate (type);
+ i386_extract_return_value (gdbarch, type, regcache,
+ (*read_value)->contents_raw ().data ());
+ }
if (writebuf)
i386_store_return_value (gdbarch, type, regcache, writebuf);
struct type *
i387_ext_type (struct gdbarch *gdbarch)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (!tdep->i387_ext_type)
{
static struct type *
i386_bnd_type (struct gdbarch *gdbarch)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (!tdep->i386_bnd_type)
static struct type *
i386_zmm_type (struct gdbarch *gdbarch)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (!tdep->i386_zmm_type)
{
int8_t v64_int8[64];
double v8_double[8];
float v16_float[16];
+ float16_t v32_half[32];
bfloat16_t v32_bfloat16[32];
};
#endif
"__gdb_builtin_type_vec512i", TYPE_CODE_UNION);
append_composite_type_field (t, "v32_bfloat16",
init_vector_type (bt->builtin_bfloat16, 32));
+ append_composite_type_field (t, "v32_half",
+ init_vector_type (bt->builtin_half, 32));
append_composite_type_field (t, "v16_float",
init_vector_type (bt->builtin_float, 16));
append_composite_type_field (t, "v8_double",
static struct type *
i386_ymm_type (struct gdbarch *gdbarch)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (!tdep->i386_ymm_type)
{
int8_t v32_int8[32];
double v4_double[4];
float v8_float[8];
+ float16_t v16_half[16];
bfloat16_t v16_bfloat16[16];
};
#endif
"__gdb_builtin_type_vec256i", TYPE_CODE_UNION);
append_composite_type_field (t, "v16_bfloat16",
init_vector_type (bt->builtin_bfloat16, 16));
+ append_composite_type_field (t, "v16_half",
+ init_vector_type (bt->builtin_half, 16));
append_composite_type_field (t, "v8_float",
init_vector_type (bt->builtin_float, 8));
append_composite_type_field (t, "v4_double",
static struct type *
i386_mmx_type (struct gdbarch *gdbarch)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (!tdep->i386_mmx_type)
{
return bt->builtin_int64;
}
- internal_error (__FILE__, __LINE__, _("invalid regnum"));
+ internal_error (_("invalid regnum"));
}
/* Map a cooked register onto a raw register or memory. For the i386,
the MMX registers need to be mapped onto floating point registers. */
static int
-i386_mmx_regnum_to_fp_regnum (readable_regcache *regcache, int regnum)
+i386_mmx_regnum_to_fp_regnum (const frame_info_ptr &next_frame, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
- int mmxreg, fpreg;
- ULONGEST fstat;
- int tos;
-
- mmxreg = regnum - tdep->mm0_regnum;
- regcache->raw_read (I387_FSTAT_REGNUM (tdep), &fstat);
- tos = (fstat >> 11) & 0x7;
- fpreg = (mmxreg + tos) % 8;
+ gdbarch *arch = frame_unwind_arch (next_frame);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (arch);
+ ULONGEST fstat
+ = frame_unwind_register_unsigned (next_frame, I387_FSTAT_REGNUM (tdep));
+ int tos = (fstat >> 11) & 0x7;
+ int mmxreg = regnum - tdep->mm0_regnum;
+ int fpreg = (mmxreg + tos) % 8;
return (I387_ST0_REGNUM (tdep) + fpreg);
}
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,
- readable_regcache *regcache,
- int regnum,
- struct value *result_value)
+value *
+i386_pseudo_register_read_value (gdbarch *gdbarch, const frame_info_ptr &next_frame,
+ const int pseudo_reg_num)
{
- gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
- enum register_status status;
- gdb_byte *buf = value_contents_raw (result_value);
-
- if (i386_mmx_regnum_p (gdbarch, regnum))
+ if (i386_mmx_regnum_p (gdbarch, pseudo_reg_num))
{
- int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
+ int fpnum = i386_mmx_regnum_to_fp_regnum (next_frame, pseudo_reg_num);
/* Extract (always little endian). */
- status = regcache->raw_read (fpnum, raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 0,
- TYPE_LENGTH (value_type (result_value)));
- else
- memcpy (buf, raw_buf, register_size (gdbarch, regnum));
+ return pseudo_from_raw_part (next_frame, pseudo_reg_num, fpnum, 0);
}
else
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (i386_bnd_regnum_p (gdbarch, regnum))
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
+ if (i386_bnd_regnum_p (gdbarch, pseudo_reg_num))
{
- regnum -= tdep->bnd0_regnum;
+ int i = pseudo_reg_num - tdep->bnd0_regnum;
/* Extract (always little endian). Read lower 128bits. */
- status = regcache->raw_read (I387_BND0R_REGNUM (tdep) + regnum,
- raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 0, 16);
- else
- {
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
- LONGEST upper, lower;
- int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
+ value *bndr_value
+ = value_of_register (I387_BND0R_REGNUM (tdep) + i, next_frame);
+ int size = builtin_type (gdbarch)->builtin_data_ptr->length ();
+ value *result
+ = value::allocate_register (next_frame, pseudo_reg_num);
- lower = extract_unsigned_integer (raw_buf, 8, byte_order);
- upper = extract_unsigned_integer (raw_buf + 8, 8, byte_order);
- upper = ~upper;
+ /* Copy the lower. */
+ bndr_value->contents_copy (result, 0, 0, size);
- memcpy (buf, &lower, size);
- memcpy (buf + size, &upper, size);
+ /* Copy the upper. */
+ bndr_value->contents_copy (result, size, 8, size);
+
+ /* If upper bytes are available, compute ones' complement. */
+ if (result->bytes_available (size, size))
+ {
+ bfd_endian byte_order
+ = gdbarch_byte_order (frame_unwind_arch (next_frame));
+ gdb::array_view<gdb_byte> upper_bytes
+ = result->contents_raw ().slice (size, size);
+ ULONGEST upper
+ = extract_unsigned_integer (upper_bytes, byte_order);
+ upper = ~upper;
+ store_unsigned_integer (upper_bytes, byte_order, upper);
}
- }
- else if (i386_k_regnum_p (gdbarch, regnum))
- {
- regnum -= tdep->k0_regnum;
- /* Extract (always little endian). */
- status = regcache->raw_read (tdep->k0_regnum + regnum, raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 0, 8);
- else
- memcpy (buf, raw_buf, 8);
+ return result;
}
- else if (i386_zmm_regnum_p (gdbarch, regnum))
+ else if (i386_zmm_regnum_p (gdbarch, pseudo_reg_num))
{
- regnum -= tdep->zmm0_regnum;
+ /* Which register is it, relative to zmm0. */
+ int i_0 = pseudo_reg_num - tdep->zmm0_regnum;
- if (regnum < num_lower_zmm_regs)
- {
- /* Extract (always little endian). Read lower 128bits. */
- status = regcache->raw_read (I387_XMM0_REGNUM (tdep) + regnum,
- raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 0, 16);
- else
- memcpy (buf, raw_buf, 16);
-
- /* Extract (always little endian). Read upper 128bits. */
- status = regcache->raw_read (tdep->ymm0h_regnum + regnum,
- raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 16, 16);
- else
- memcpy (buf + 16, raw_buf, 16);
- }
+ if (i_0 < num_lower_zmm_regs)
+ return pseudo_from_concat_raw (next_frame, pseudo_reg_num,
+ I387_XMM0_REGNUM (tdep) + i_0,
+ tdep->ymm0h_regnum + i_0,
+ tdep->zmm0h_regnum + i_0);
else
{
- /* Extract (always little endian). Read lower 128bits. */
- status = regcache->raw_read (I387_XMM16_REGNUM (tdep) + regnum
- - num_lower_zmm_regs,
- raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 0, 16);
- else
- memcpy (buf, raw_buf, 16);
-
- /* Extract (always little endian). Read upper 128bits. */
- status = regcache->raw_read (I387_YMM16H_REGNUM (tdep) + regnum
- - num_lower_zmm_regs,
- raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 16, 16);
- else
- memcpy (buf + 16, raw_buf, 16);
- }
+ /* Which register is it, relative to zmm16. */
+ int i_16 = i_0 - num_lower_zmm_regs;
- /* Read upper 256bits. */
- status = regcache->raw_read (tdep->zmm0h_regnum + regnum,
- raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 32, 32);
- else
- memcpy (buf + 32, raw_buf, 32);
+ return pseudo_from_concat_raw (next_frame, pseudo_reg_num,
+ I387_XMM16_REGNUM (tdep) + i_16,
+ I387_YMM16H_REGNUM (tdep) + i_16,
+ tdep->zmm0h_regnum + i_0);
+ }
}
- else if (i386_ymm_regnum_p (gdbarch, regnum))
+ else if (i386_ymm_regnum_p (gdbarch, pseudo_reg_num))
{
- regnum -= tdep->ymm0_regnum;
+ int i = pseudo_reg_num - tdep->ymm0_regnum;
- /* Extract (always little endian). Read lower 128bits. */
- status = regcache->raw_read (I387_XMM0_REGNUM (tdep) + regnum,
- raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 0, 16);
- else
- memcpy (buf, raw_buf, 16);
- /* Read upper 128bits. */
- status = regcache->raw_read (tdep->ymm0h_regnum + regnum,
- raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 16, 32);
- else
- memcpy (buf + 16, raw_buf, 16);
+ return pseudo_from_concat_raw (next_frame, pseudo_reg_num,
+ I387_XMM0_REGNUM (tdep) + i,
+ tdep->ymm0h_regnum + i);
}
- else if (i386_ymm_avx512_regnum_p (gdbarch, regnum))
+ else if (i386_ymm_avx512_regnum_p (gdbarch, pseudo_reg_num))
{
- regnum -= tdep->ymm16_regnum;
- /* Extract (always little endian). Read lower 128bits. */
- status = regcache->raw_read (I387_XMM16_REGNUM (tdep) + regnum,
- raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 0, 16);
- else
- memcpy (buf, raw_buf, 16);
- /* Read upper 128bits. */
- status = regcache->raw_read (tdep->ymm16h_regnum + regnum,
- raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 16, 16);
- else
- memcpy (buf + 16, raw_buf, 16);
+ int i = pseudo_reg_num - tdep->ymm16_regnum;
+
+ return pseudo_from_concat_raw (next_frame, pseudo_reg_num,
+ I387_XMM16_REGNUM (tdep) + i,
+ tdep->ymm16h_regnum + i);
}
- else if (i386_word_regnum_p (gdbarch, regnum))
+ else if (i386_word_regnum_p (gdbarch, pseudo_reg_num))
{
- int gpnum = regnum - tdep->ax_regnum;
+ int gpnum = pseudo_reg_num - tdep->ax_regnum;
/* Extract (always little endian). */
- status = regcache->raw_read (gpnum, raw_buf);
- if (status != REG_VALID)
- mark_value_bytes_unavailable (result_value, 0,
- TYPE_LENGTH (value_type (result_value)));
- else
- memcpy (buf, raw_buf, 2);
+ return pseudo_from_raw_part (next_frame, pseudo_reg_num, gpnum, 0);
}
- else if (i386_byte_regnum_p (gdbarch, regnum))
+ else if (i386_byte_regnum_p (gdbarch, pseudo_reg_num))
{
- int gpnum = regnum - tdep->al_regnum;
+ int gpnum = pseudo_reg_num - tdep->al_regnum;
/* Extract (always little endian). We read both lower and
upper registers. */
- status = regcache->raw_read (gpnum % 4, raw_buf);
- if (status != REG_VALID)
- 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);
+ return pseudo_from_raw_part (next_frame, pseudo_reg_num, gpnum % 4,
+ gpnum >= 4 ? 1 : 0);
}
else
- internal_error (__FILE__, __LINE__, _("invalid regnum"));
+ internal_error (_("invalid regnum"));
}
}
-static struct value *
-i386_pseudo_register_read_value (struct gdbarch *gdbarch,
- readable_regcache *regcache,
- int regnum)
-{
- struct value *result;
-
- 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
-i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
- int regnum, const gdb_byte *buf)
+i386_pseudo_register_write (gdbarch *gdbarch, const frame_info_ptr &next_frame,
+ const int pseudo_reg_num,
+ gdb::array_view<const gdb_byte> buf)
{
- gdb_byte raw_buf[I386_MAX_REGISTER_SIZE];
-
- if (i386_mmx_regnum_p (gdbarch, regnum))
+ if (i386_mmx_regnum_p (gdbarch, pseudo_reg_num))
{
- int fpnum = i386_mmx_regnum_to_fp_regnum (regcache, regnum);
+ int fpnum = i386_mmx_regnum_to_fp_regnum (next_frame, pseudo_reg_num);
- /* Read ... */
- regcache->raw_read (fpnum, raw_buf);
- /* ... Modify ... (always little endian). */
- memcpy (raw_buf, buf, register_size (gdbarch, regnum));
- /* ... Write. */
- regcache->raw_write (fpnum, raw_buf);
+ pseudo_to_raw_part (next_frame, buf, fpnum, 0);
}
else
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
- if (i386_bnd_regnum_p (gdbarch, regnum))
+ if (i386_bnd_regnum_p (gdbarch, pseudo_reg_num))
{
- ULONGEST upper, lower;
- int size = TYPE_LENGTH (builtin_type (gdbarch)->builtin_data_ptr);
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
+ int size = builtin_type (gdbarch)->builtin_data_ptr->length ();
+ bfd_endian byte_order
+ = gdbarch_byte_order (current_inferior ()->arch ());
/* New values from input value. */
- regnum -= tdep->bnd0_regnum;
- lower = extract_unsigned_integer (buf, size, byte_order);
- upper = extract_unsigned_integer (buf + size, size, byte_order);
-
- /* Fetching register buffer. */
- regcache->raw_read (I387_BND0R_REGNUM (tdep) + regnum,
- raw_buf);
+ int reg_index = pseudo_reg_num - tdep->bnd0_regnum;
+ int raw_regnum = I387_BND0R_REGNUM (tdep) + reg_index;
- upper = ~upper;
+ value *bndr_value = value_of_register (raw_regnum, next_frame);
+ gdb::array_view<gdb_byte> bndr_view
+ = bndr_value->contents_writeable ();
- /* Set register bits. */
- memcpy (raw_buf, &lower, 8);
- memcpy (raw_buf + 8, &upper, 8);
+ /* Copy lower bytes directly. */
+ copy (buf.slice (0, size), bndr_view.slice (0, size));
- regcache->raw_write (I387_BND0R_REGNUM (tdep) + regnum, raw_buf);
- }
- else if (i386_k_regnum_p (gdbarch, regnum))
- {
- regnum -= tdep->k0_regnum;
+ /* Convert and then copy upper bytes. */
+ ULONGEST upper
+ = extract_unsigned_integer (buf.slice (size, size), byte_order);
+ upper = ~upper;
+ store_unsigned_integer (bndr_view.slice (8, size), byte_order,
+ upper);
- regcache->raw_write (tdep->k0_regnum + regnum, buf);
+ put_frame_register (next_frame, raw_regnum, bndr_view);
}
- else if (i386_zmm_regnum_p (gdbarch, regnum))
+ else if (i386_zmm_regnum_p (gdbarch, pseudo_reg_num))
{
- regnum -= tdep->zmm0_regnum;
+ /* Which register is it, relative to zmm0. */
+ int reg_index_0 = pseudo_reg_num - tdep->zmm0_regnum;
- if (regnum < num_lower_zmm_regs)
- {
- /* Write lower 128bits. */
- regcache->raw_write (I387_XMM0_REGNUM (tdep) + regnum, buf);
- /* Write upper 128bits. */
- regcache->raw_write (I387_YMM0_REGNUM (tdep) + regnum, buf + 16);
- }
+ if (reg_index_0 < num_lower_zmm_regs)
+ pseudo_to_concat_raw (next_frame, buf,
+ I387_XMM0_REGNUM (tdep) + reg_index_0,
+ I387_YMM0_REGNUM (tdep) + reg_index_0,
+ tdep->zmm0h_regnum + reg_index_0);
else
{
- /* Write lower 128bits. */
- regcache->raw_write (I387_XMM16_REGNUM (tdep) + regnum
- - num_lower_zmm_regs, buf);
- /* Write upper 128bits. */
- regcache->raw_write (I387_YMM16H_REGNUM (tdep) + regnum
- - num_lower_zmm_regs, buf + 16);
+ /* Which register is it, relative to zmm16. */
+ int reg_index_16 = reg_index_0 - num_lower_zmm_regs;
+
+ pseudo_to_concat_raw (next_frame, buf,
+ I387_XMM16_REGNUM (tdep) + reg_index_16,
+ I387_YMM16H_REGNUM (tdep) + reg_index_16,
+ tdep->zmm0h_regnum + +reg_index_0);
}
- /* Write upper 256bits. */
- regcache->raw_write (tdep->zmm0h_regnum + regnum, buf + 32);
}
- else if (i386_ymm_regnum_p (gdbarch, regnum))
+ else if (i386_ymm_regnum_p (gdbarch, pseudo_reg_num))
{
- regnum -= tdep->ymm0_regnum;
+ int i = pseudo_reg_num - tdep->ymm0_regnum;
- /* ... Write lower 128bits. */
- regcache->raw_write (I387_XMM0_REGNUM (tdep) + regnum, buf);
- /* ... Write upper 128bits. */
- regcache->raw_write (tdep->ymm0h_regnum + regnum, buf + 16);
+ pseudo_to_concat_raw (next_frame, buf, I387_XMM0_REGNUM (tdep) + i,
+ tdep->ymm0h_regnum + i);
}
- else if (i386_ymm_avx512_regnum_p (gdbarch, regnum))
+ else if (i386_ymm_avx512_regnum_p (gdbarch, pseudo_reg_num))
{
- regnum -= tdep->ymm16_regnum;
+ int i = pseudo_reg_num - tdep->ymm16_regnum;
- /* ... Write lower 128bits. */
- regcache->raw_write (I387_XMM16_REGNUM (tdep) + regnum, buf);
- /* ... Write upper 128bits. */
- regcache->raw_write (tdep->ymm16h_regnum + regnum, buf + 16);
+ pseudo_to_concat_raw (next_frame, buf, I387_XMM16_REGNUM (tdep) + i,
+ tdep->ymm16h_regnum + i);
}
- else if (i386_word_regnum_p (gdbarch, regnum))
+ else if (i386_word_regnum_p (gdbarch, pseudo_reg_num))
{
- int gpnum = regnum - tdep->ax_regnum;
+ int gpnum = pseudo_reg_num - tdep->ax_regnum;
- /* Read ... */
- regcache->raw_read (gpnum, raw_buf);
- /* ... Modify ... (always little endian). */
- memcpy (raw_buf, buf, 2);
- /* ... Write. */
- regcache->raw_write (gpnum, raw_buf);
+ pseudo_to_raw_part (next_frame, buf, gpnum, 0);
}
- else if (i386_byte_regnum_p (gdbarch, regnum))
+ else if (i386_byte_regnum_p (gdbarch, pseudo_reg_num))
{
- int gpnum = regnum - tdep->al_regnum;
+ int gpnum = pseudo_reg_num - tdep->al_regnum;
- /* Read ... We read both lower and upper registers. */
- regcache->raw_read (gpnum % 4, raw_buf);
- /* ... Modify ... (always little endian). */
- if (gpnum >= 4)
- memcpy (raw_buf + 1, buf, 1);
- else
- memcpy (raw_buf, buf, 1);
- /* ... Write. */
- regcache->raw_write (gpnum % 4, raw_buf);
+ pseudo_to_raw_part (next_frame, buf, gpnum % 4, gpnum >= 4 ? 1 : 0);
}
else
- internal_error (__FILE__, __LINE__, _("invalid regnum"));
+ internal_error (_("invalid regnum"));
}
}
i386_ax_pseudo_register_collect (struct gdbarch *gdbarch,
struct agent_expr *ax, int regnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (i386_mmx_regnum_p (gdbarch, regnum))
{
ax_reg_mask (ax, I387_BND0R_REGNUM (tdep) + regnum);
return 0;
}
- else if (i386_k_regnum_p (gdbarch, regnum))
- {
- regnum -= tdep->k0_regnum;
- ax_reg_mask (ax, tdep->k0_regnum + regnum);
- return 0;
- }
else if (i386_zmm_regnum_p (gdbarch, regnum))
{
regnum -= tdep->zmm0_regnum;
return 0;
}
else
- internal_error (__FILE__, __LINE__, _("invalid regnum"));
+ internal_error (_("invalid regnum"));
return 1;
}
\f
i386_convert_register_p (struct gdbarch *gdbarch,
int regnum, struct type *type)
{
- int len = TYPE_LENGTH (type);
+ int len = type->length ();
/* Values may be spread across multiple registers. Most debugging
formats aren't expressive enough to specify the locations, so
return its contents in TO. */
static int
-i386_register_to_value (struct frame_info *frame, int regnum,
+i386_register_to_value (const frame_info_ptr &frame, int regnum,
struct type *type, gdb_byte *to,
int *optimizedp, int *unavailablep)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
- int len = TYPE_LENGTH (type);
+ int len = type->length ();
if (i386_fp_regnum_p (gdbarch, regnum))
return i387_register_to_value (frame, regnum, type, to,
gdb_assert (regnum != -1);
gdb_assert (register_size (gdbarch, regnum) == 4);
- if (!get_frame_register_bytes (frame, regnum, 0,
- register_size (gdbarch, regnum),
- to, optimizedp, unavailablep))
+ auto to_view
+ = gdb::make_array_view (to, register_size (gdbarch, regnum));
+ frame_info_ptr next_frame = get_next_frame_sentinel_okay (frame);
+ if (!get_frame_register_bytes (next_frame, regnum, 0, to_view,
+ optimizedp, unavailablep))
return 0;
regnum = i386_next_regnum (regnum);
REGNUM in frame FRAME. */
static void
-i386_value_to_register (struct frame_info *frame, int regnum,
+i386_value_to_register (const frame_info_ptr &frame, int regnum,
struct type *type, const gdb_byte *from)
{
- int len = TYPE_LENGTH (type);
+ int len = type->length ();
if (i386_fp_regnum_p (get_frame_arch (frame), regnum))
{
gdb_assert (regnum != -1);
gdb_assert (register_size (get_frame_arch (frame), regnum) == 4);
- put_frame_register (frame, regnum, from);
+ auto from_view = gdb::make_array_view (from, 4);
+ put_frame_register (get_next_frame_sentinel_okay (frame), regnum,
+ from_view);
regnum = i386_next_regnum (regnum);
len -= 4;
from += 4;
int regnum, const void *gregs, size_t len)
{
struct gdbarch *gdbarch = regcache->arch ();
- const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
const gdb_byte *regs = (const gdb_byte *) gregs;
int i;
int regnum, void *gregs, size_t len)
{
struct gdbarch *gdbarch = regcache->arch ();
- const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
gdb_byte *regs = (gdb_byte *) gregs;
int i;
int regnum, const void *fpregs, size_t len)
{
struct gdbarch *gdbarch = regcache->arch ();
- const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (len == I387_SIZEOF_FXSAVE)
{
int regnum, void *fpregs, size_t len)
{
struct gdbarch *gdbarch = regcache->arch ();
- const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
if (len == I387_SIZEOF_FXSAVE)
{
void *cb_data,
const struct regcache *regcache)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
cb (".reg", tdep->sizeof_gregset, tdep->sizeof_gregset, &i386_gregset, NULL,
cb_data);
/* Stuff for WIN32 PE style DLL's but is pretty generic really. */
CORE_ADDR
-i386_pe_skip_trampoline_code (struct frame_info *frame,
+i386_pe_skip_trampoline_code (const frame_info_ptr &frame,
CORE_ADDR pc, char *name)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
routine. */
int
-i386_sigtramp_p (struct frame_info *this_frame)
+i386_sigtramp_p (const frame_info_ptr &this_frame)
{
CORE_ADDR pc = get_frame_pc (this_frame);
const char *name;
routine. */
static int
-i386_svr4_sigtramp_p (struct frame_info *this_frame)
+i386_svr4_sigtramp_p (const frame_info_ptr &this_frame)
{
CORE_ADDR pc = get_frame_pc (this_frame);
const char *name;
address of the associated sigcontext (ucontext) structure. */
static CORE_ADDR
-i386_svr4_sigcontext_addr (struct frame_info *this_frame)
+i386_svr4_sigcontext_addr (const frame_info_ptr &this_frame)
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
Return true if the operand was parsed successfully, false
otherwise. */
-static bool
+static expr::operation_up
i386_stap_parse_special_token_triplet (struct gdbarch *gdbarch,
struct stap_parse_info *p)
{
int i;
long displacements[3];
const char *start;
- char *regname;
int len;
- struct stoken str;
char *endp;
got_minus[0] = false;
}
if (!isdigit ((unsigned char) *s))
- return false;
+ return {};
displacements[0] = strtol (s, &endp, 10);
s = endp;
if (*s != '+' && *s != '-')
{
/* We are not dealing with a triplet. */
- return false;
+ return {};
}
got_minus[1] = false;
}
if (!isdigit ((unsigned char) *s))
- return false;
+ return {};
displacements[1] = strtol (s, &endp, 10);
s = endp;
if (*s != '+' && *s != '-')
{
/* We are not dealing with a triplet. */
- return false;
+ return {};
}
got_minus[2] = false;
}
if (!isdigit ((unsigned char) *s))
- return false;
+ return {};
displacements[2] = strtol (s, &endp, 10);
s = endp;
if (*s != '(' || s[1] != '%')
- return false;
+ return {};
s += 2;
start = s;
++s;
if (*s++ != ')')
- return false;
+ return {};
len = s - start - 1;
- regname = (char *) alloca (len + 1);
-
- strncpy (regname, start, len);
- regname[len] = '\0';
+ std::string regname (start, len);
- if (user_reg_map_name_to_regnum (gdbarch, regname, len) == -1)
+ if (user_reg_map_name_to_regnum (gdbarch, regname.c_str (), len) == -1)
error (_("Invalid register name `%s' on expression `%s'."),
- regname, p->saved_arg);
+ regname.c_str (), p->saved_arg);
+ LONGEST value = 0;
for (i = 0; i < 3; i++)
{
- write_exp_elt_opcode (&p->pstate, OP_LONG);
- write_exp_elt_type
- (&p->pstate, builtin_type (gdbarch)->builtin_long);
- write_exp_elt_longcst (&p->pstate, displacements[i]);
- write_exp_elt_opcode (&p->pstate, OP_LONG);
+ LONGEST this_val = displacements[i];
if (got_minus[i])
- write_exp_elt_opcode (&p->pstate, UNOP_NEG);
+ this_val = -this_val;
+ value += this_val;
}
- write_exp_elt_opcode (&p->pstate, OP_REGISTER);
- str.ptr = regname;
- str.length = len;
- write_exp_string (&p->pstate, str);
- write_exp_elt_opcode (&p->pstate, OP_REGISTER);
-
- write_exp_elt_opcode (&p->pstate, UNOP_CAST);
- write_exp_elt_type (&p->pstate,
- builtin_type (gdbarch)->builtin_data_ptr);
- write_exp_elt_opcode (&p->pstate, UNOP_CAST);
-
- write_exp_elt_opcode (&p->pstate, BINOP_ADD);
- write_exp_elt_opcode (&p->pstate, BINOP_ADD);
- write_exp_elt_opcode (&p->pstate, BINOP_ADD);
+ p->arg = s;
- write_exp_elt_opcode (&p->pstate, UNOP_CAST);
- write_exp_elt_type (&p->pstate,
- lookup_pointer_type (p->arg_type));
- write_exp_elt_opcode (&p->pstate, UNOP_CAST);
+ using namespace expr;
- write_exp_elt_opcode (&p->pstate, UNOP_IND);
+ struct type *long_type = builtin_type (gdbarch)->builtin_long;
+ operation_up offset
+ = make_operation<long_const_operation> (long_type, value);
- p->arg = s;
+ operation_up reg
+ = make_operation<register_operation> (std::move (regname));
+ struct type *void_ptr = builtin_type (gdbarch)->builtin_data_ptr;
+ reg = make_operation<unop_cast_operation> (std::move (reg), void_ptr);
- return true;
+ operation_up sum
+ = make_operation<add_operation> (std::move (reg), std::move (offset));
+ struct type *arg_ptr_type = lookup_pointer_type (p->arg_type);
+ sum = make_operation<unop_cast_operation> (std::move (sum),
+ arg_ptr_type);
+ return make_operation<unop_ind_operation> (std::move (sum));
}
- return false;
+ return {};
}
/* Helper function for i386_stap_parse_special_token.
Return true if the operand was parsed successfully, false
otherwise. */
-static bool
+static expr::operation_up
i386_stap_parse_special_token_three_arg_disp (struct gdbarch *gdbarch,
struct stap_parse_info *p)
{
bool size_minus = false;
long size = 0;
const char *start;
- char *base;
int len_base;
- char *index;
int len_index;
- struct stoken base_token, index_token;
if (*s == '+')
++s;
}
if (offset_minus && !isdigit (*s))
- return false;
+ return {};
if (isdigit (*s))
{
}
if (*s != '(' || s[1] != '%')
- return false;
+ return {};
s += 2;
start = s;
++s;
if (*s != ',' || s[1] != '%')
- return false;
+ return {};
len_base = s - start;
- base = (char *) alloca (len_base + 1);
- strncpy (base, start, len_base);
- base[len_base] = '\0';
+ std::string base (start, len_base);
- if (user_reg_map_name_to_regnum (gdbarch, base, len_base) == -1)
+ if (user_reg_map_name_to_regnum (gdbarch, base.c_str (), len_base) == -1)
error (_("Invalid register name `%s' on expression `%s'."),
- base, p->saved_arg);
+ base.c_str (), p->saved_arg);
s += 2;
start = s;
++s;
len_index = s - start;
- index = (char *) alloca (len_index + 1);
- strncpy (index, start, len_index);
- index[len_index] = '\0';
+ std::string index (start, len_index);
- if (user_reg_map_name_to_regnum (gdbarch, index, len_index) == -1)
+ if (user_reg_map_name_to_regnum (gdbarch, index.c_str (),
+ len_index) == -1)
error (_("Invalid register name `%s' on expression `%s'."),
- index, p->saved_arg);
+ index.c_str (), p->saved_arg);
if (*s != ',' && *s != ')')
- return false;
+ return {};
if (*s == ',')
{
s = endp;
if (*s != ')')
- return false;
+ return {};
}
++s;
+ p->arg = s;
+
+ using namespace expr;
+
+ struct type *long_type = builtin_type (gdbarch)->builtin_long;
+ operation_up reg = make_operation<register_operation> (std::move (base));
- if (offset)
+ if (offset != 0)
{
- write_exp_elt_opcode (&p->pstate, OP_LONG);
- write_exp_elt_type (&p->pstate,
- builtin_type (gdbarch)->builtin_long);
- write_exp_elt_longcst (&p->pstate, offset);
- write_exp_elt_opcode (&p->pstate, OP_LONG);
if (offset_minus)
- write_exp_elt_opcode (&p->pstate, UNOP_NEG);
+ offset = -offset;
+ operation_up value
+ = make_operation<long_const_operation> (long_type, offset);
+ reg = make_operation<add_operation> (std::move (reg),
+ std::move (value));
}
- write_exp_elt_opcode (&p->pstate, OP_REGISTER);
- base_token.ptr = base;
- base_token.length = len_base;
- write_exp_string (&p->pstate, base_token);
- write_exp_elt_opcode (&p->pstate, OP_REGISTER);
+ operation_up ind_reg
+ = make_operation<register_operation> (std::move (index));
- if (offset)
- write_exp_elt_opcode (&p->pstate, BINOP_ADD);
-
- write_exp_elt_opcode (&p->pstate, OP_REGISTER);
- index_token.ptr = index;
- index_token.length = len_index;
- write_exp_string (&p->pstate, index_token);
- write_exp_elt_opcode (&p->pstate, OP_REGISTER);
-
- if (size)
+ if (size != 0)
{
- write_exp_elt_opcode (&p->pstate, OP_LONG);
- write_exp_elt_type (&p->pstate,
- builtin_type (gdbarch)->builtin_long);
- write_exp_elt_longcst (&p->pstate, size);
- write_exp_elt_opcode (&p->pstate, OP_LONG);
if (size_minus)
- write_exp_elt_opcode (&p->pstate, UNOP_NEG);
- write_exp_elt_opcode (&p->pstate, BINOP_MUL);
+ size = -size;
+ operation_up value
+ = make_operation<long_const_operation> (long_type, size);
+ ind_reg = make_operation<mul_operation> (std::move (ind_reg),
+ std::move (value));
}
- write_exp_elt_opcode (&p->pstate, BINOP_ADD);
-
- write_exp_elt_opcode (&p->pstate, UNOP_CAST);
- write_exp_elt_type (&p->pstate,
- lookup_pointer_type (p->arg_type));
- write_exp_elt_opcode (&p->pstate, UNOP_CAST);
-
- write_exp_elt_opcode (&p->pstate, UNOP_IND);
+ operation_up sum
+ = make_operation<add_operation> (std::move (reg),
+ std::move (ind_reg));
- p->arg = s;
-
- return true;
+ struct type *arg_ptr_type = lookup_pointer_type (p->arg_type);
+ sum = make_operation<unop_cast_operation> (std::move (sum),
+ arg_ptr_type);
+ return make_operation<unop_ind_operation> (std::move (sum));
}
- return false;
+ return {};
}
/* Implementation of `gdbarch_stap_parse_special_token', as defined in
gdbarch.h. */
-int
+expr::operation_up
i386_stap_parse_special_token (struct gdbarch *gdbarch,
struct stap_parse_info *p)
{
- /* In order to parse special tokens, we use a state-machine that go
- through every known token and try to get a match. */
- enum
- {
- TRIPLET,
- THREE_ARG_DISPLACEMENT,
- DONE
- };
- int current_state;
-
- current_state = TRIPLET;
-
/* The special tokens to be parsed here are:
- `register base + (register index * size) + offset', as represented
- Operands of the form `-8+3+1(%rbp)', which must be interpreted as
`*(-8 + 3 - 1 + (void *) $eax)'. */
- while (current_state != DONE)
- {
- switch (current_state)
- {
- case TRIPLET:
- if (i386_stap_parse_special_token_triplet (gdbarch, p))
- return 1;
- break;
-
- case THREE_ARG_DISPLACEMENT:
- if (i386_stap_parse_special_token_three_arg_disp (gdbarch, p))
- return 1;
- break;
- }
+ expr::operation_up result
+ = i386_stap_parse_special_token_triplet (gdbarch, p);
- /* Advancing to the next state. */
- ++current_state;
- }
+ if (result == nullptr)
+ result = i386_stap_parse_special_token_three_arg_disp (gdbarch, p);
- return 0;
+ return result;
}
/* Implementation of 'gdbarch_stap_adjust_register', as defined in
specified by the "[-]N@" prefix, and it is one of the registers that
we know has an extended variant available, then use the extended
version of the register instead. */
- if (register_size (gdbarch, regnum) < TYPE_LENGTH (p->arg_type)
+ if (register_size (gdbarch, regnum) < p->arg_type->length ()
&& reg_assoc.find (regname) != reg_assoc.end ())
return "e" + regname;
void
i386_svr4_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
/* System V Release 4 uses ELF. */
i386_elf_init_abi (info, gdbarch);
/* i386 register groups. In addition to the normal groups, add "mmx"
and "sse". */
-static struct reggroup *i386_sse_reggroup;
-static struct reggroup *i386_mmx_reggroup;
+static const reggroup *i386_sse_reggroup;
+static const reggroup *i386_mmx_reggroup;
static void
i386_init_reggroups (void)
{
reggroup_add (gdbarch, i386_sse_reggroup);
reggroup_add (gdbarch, i386_mmx_reggroup);
- reggroup_add (gdbarch, general_reggroup);
- reggroup_add (gdbarch, float_reggroup);
- reggroup_add (gdbarch, all_reggroup);
- reggroup_add (gdbarch, save_reggroup);
- reggroup_add (gdbarch, restore_reggroup);
- reggroup_add (gdbarch, vector_reggroup);
- reggroup_add (gdbarch, system_reggroup);
}
int
i386_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
- struct reggroup *group)
+ const struct reggroup *group)
{
- const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int fp_regnum_p, mmx_regnum_p, xmm_regnum_p, mxcsr_regnum_p,
ymm_regnum_p, ymmh_regnum_p, ymm_avx512_regnum_p, ymmh_avx512_regnum_p,
bndr_regnum_p, bnd_regnum_p, zmm_regnum_p, zmmh_regnum_p,
/* Get the ARGIth function argument for the current function. */
static CORE_ADDR
-i386_fetch_pointer_argument (struct frame_info *frame, int argi,
+i386_fetch_pointer_argument (const frame_info_ptr &frame, int argi,
struct type *type)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
struct i386_record_s *ir,
uint32_t iregnum)
{
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
int i;
/* Oza: Because of floating point insn push/pop of fpu stack is going to
else if (I386_SAVE_FPU_ENV_REG_STACK == iregnum)
{
for (i = I387_ST0_REGNUM (tdep); i <= I387_FOP_REGNUM (tdep); i++)
- {
if (record_full_arch_list_add_reg (ir->regcache, i))
return -1;
- }
}
else if ((iregnum >= I387_ST0_REGNUM (tdep)) &&
(iregnum <= I387_FOP_REGNUM (tdep)))
ULONGEST addr;
gdb_byte buf[I386_MAX_REGISTER_SIZE];
struct i386_record_s ir;
- struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
uint8_t rex_w = -1;
uint8_t rex_r = 0;
ir.gdbarch = gdbarch;
if (record_debug > 1)
- fprintf_unfiltered (gdb_stdlog, "Process record: i386_process_record "
- "addr = %s\n",
- paddress (gdbarch, ir.addr));
+ gdb_printf (gdb_stdlog, "Process record: i386_process_record "
+ "addr = %s\n",
+ paddress (gdbarch, ir.addr));
/* prefixes */
while (1)
ir.addr -= 1;
goto no_support;
}
- for (regnum = X86_RECORD_REAX_REGNUM;
+ for (regnum = X86_RECORD_REAX_REGNUM;
regnum <= X86_RECORD_REDI_REGNUM;
regnum++)
I386_RECORD_FULL_ARCH_LIST_ADD_REG (regnum);
ir.addr -= 1;
goto no_support;
}
- /* FALLTHROUGH */
+ [[fallthrough]];
case 0x0fb2: /* lss Gv */
case 0x0fb4: /* lfs Gv */
case 0x0fb5: /* lgs Gv */
I386_SAVE_FPU_REGS))
return -1;
}
- /* Fall through */
+ [[fallthrough]];
default:
if (record_full_arch_list_add_mem (addr64, 2))
return -1;
ir.addr -= 1;
goto no_support;
}
- /* FALLTHROUGH */
+ [[fallthrough]];
case 0xf5: /* cmc */
case 0xf8: /* clc */
case 0xf9: /* stc */
/* XXX */
case 0xcc: /* int3 */
- printf_unfiltered (_("Process record does not support instruction "
- "int3.\n"));
+ gdb_printf (gdb_stderr,
+ _("Process record does not support instruction "
+ "int3.\n"));
ir.addr -= 1;
goto no_support;
break;
if (interrupt != 0x80
|| tdep->i386_intx80_record == NULL)
{
- printf_unfiltered (_("Process record does not support "
- "instruction int 0x%02x.\n"),
- interrupt);
+ gdb_printf (gdb_stderr,
+ _("Process record does not support "
+ "instruction int 0x%02x.\n"),
+ interrupt);
ir.addr -= 2;
goto no_support;
}
/* XXX */
case 0xce: /* into */
- printf_unfiltered (_("Process record does not support "
- "instruction into.\n"));
+ gdb_printf (gdb_stderr,
+ _("Process record does not support "
+ "instruction into.\n"));
ir.addr -= 1;
goto no_support;
break;
break;
case 0x62: /* bound */
- printf_unfiltered (_("Process record does not support "
- "instruction bound.\n"));
+ gdb_printf (gdb_stderr,
+ _("Process record does not support "
+ "instruction bound.\n"));
ir.addr -= 1;
goto no_support;
break;
break;
case 0x0f30: /* wrmsr */
- printf_unfiltered (_("Process record does not support "
- "instruction wrmsr.\n"));
+ gdb_printf (gdb_stderr,
+ _("Process record does not support "
+ "instruction wrmsr.\n"));
ir.addr -= 2;
goto no_support;
break;
case 0x0f32: /* rdmsr */
- printf_unfiltered (_("Process record does not support "
- "instruction rdmsr.\n"));
+ gdb_printf (gdb_stderr,
+ _("Process record does not support "
+ "instruction rdmsr.\n"));
ir.addr -= 2;
goto no_support;
break;
+ case 0x0f01f9: /* rdtscp */
+ I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_RECX_REGNUM);
+ [[fallthrough]];
case 0x0f31: /* rdtsc */
I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_REAX_REGNUM);
I386_RECORD_FULL_ARCH_LIST_ADD_REG (X86_RECORD_REDX_REGNUM);
}
if (tdep->i386_sysenter_record == NULL)
{
- printf_unfiltered (_("Process record does not support "
- "instruction sysenter.\n"));
+ gdb_printf (gdb_stderr,
+ _("Process record does not support "
+ "instruction sysenter.\n"));
ir.addr -= 2;
goto no_support;
}
break;
case 0x0f35: /* sysexit */
- printf_unfiltered (_("Process record does not support "
- "instruction sysexit.\n"));
+ gdb_printf (gdb_stderr,
+ _("Process record does not support "
+ "instruction sysexit.\n"));
ir.addr -= 2;
goto no_support;
break;
int ret;
if (tdep->i386_syscall_record == NULL)
{
- printf_unfiltered (_("Process record does not support "
- "instruction syscall.\n"));
+ gdb_printf (gdb_stderr,
+ _("Process record does not support "
+ "instruction syscall.\n"));
ir.addr -= 2;
goto no_support;
}
break;
case 0x0f07: /* sysret */
- printf_unfiltered (_("Process record does not support "
- "instruction sysret.\n"));
+ gdb_printf (gdb_stderr,
+ _("Process record does not support "
+ "instruction sysret.\n"));
ir.addr -= 2;
goto no_support;
break;
break;
case 0xf4: /* hlt */
- printf_unfiltered (_("Process record does not support "
- "instruction hlt.\n"));
+ gdb_printf (gdb_stderr,
+ _("Process record does not support "
+ "instruction hlt.\n"));
ir.addr -= 1;
goto no_support;
break;
case 0x0f01:
if (i386_record_modrm (&ir))
return -1;
+ if (ir.modrm == 0xf9)
+ {
+ opcode = (opcode << 8) | 0xf9;
+ goto reswitch;
+ }
switch (ir.reg)
{
case 0: /* sgdt */
else if (ir.rm == 1)
break;
}
- /* Fall through. */
+ [[fallthrough]];
case 3: /* lidt */
if (ir.mod == 3)
{
return 0;
no_support:
- printf_unfiltered (_("Process record does not support instruction 0x%02x "
- "at address %s.\n"),
- (unsigned int) (opcode),
- paddress (gdbarch, ir.orig_addr));
+ gdb_printf (gdb_stderr,
+ _("Process record does not support instruction 0x%02x "
+ "at address %s.\n"),
+ (unsigned int) (opcode),
+ paddress (gdbarch, ir.orig_addr));
return -1;
}
|| strcmp (name, "_Float128") == 0
|| strcmp (name, "complex _Float128") == 0
|| strcmp (name, "complex(kind=16)") == 0
+ || strcmp (name, "COMPLEX(16)") == 0
+ || strcmp (name, "complex*32") == 0
+ || strcmp (name, "COMPLEX*32") == 0
|| strcmp (name, "quad complex") == 0
|| strcmp (name, "real(kind=16)") == 0
- || strcmp (name, "real*16") == 0)
- return floatformats_ia64_quad;
+ || strcmp (name, "real*16") == 0
+ || strcmp (name, "REAL*16") == 0
+ || strcmp (name, "REAL(16)") == 0)
+ return floatformats_ieee_quad;
return default_floatformat_for_type (gdbarch, name, len);
}
+/* Compute an XCR0 mask based on a target description. */
+
+static uint64_t
+i386_xcr0_from_tdesc (const struct target_desc *tdesc)
+{
+ if (! tdesc_has_registers (tdesc))
+ return 0;
+
+ const struct tdesc_feature *feature_core;
+
+ const struct tdesc_feature *feature_sse, *feature_avx, *feature_mpx,
+ *feature_avx512, *feature_pkeys;
+
+ /* Get core registers. */
+ feature_core = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.core");
+ if (feature_core == NULL)
+ return 0;
+
+ /* Get SSE registers. */
+ feature_sse = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.sse");
+
+ /* Try AVX registers. */
+ feature_avx = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx");
+
+ /* Try MPX registers. */
+ feature_mpx = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.mpx");
+
+ /* Try AVX512 registers. */
+ feature_avx512 = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx512");
+
+ /* Try PKEYS */
+ feature_pkeys = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys");
+
+ /* The XCR0 bits. */
+ uint64_t xcr0 = X86_XSTATE_X87;
+
+ if (feature_sse)
+ xcr0 |= X86_XSTATE_SSE;
+
+ if (feature_avx)
+ {
+ /* AVX register description requires SSE register description. */
+ if (!feature_sse)
+ return 0;
+
+ xcr0 |= X86_XSTATE_AVX;
+ }
+
+ if (feature_mpx)
+ xcr0 |= X86_XSTATE_MPX_MASK;
+
+ if (feature_avx512)
+ {
+ /* AVX512 register description requires AVX register description. */
+ if (!feature_avx)
+ return 0;
+
+ xcr0 |= X86_XSTATE_AVX512;
+ }
+
+ if (feature_pkeys)
+ xcr0 |= X86_XSTATE_PKRU;
+
+ return xcr0;
+}
+
static int
-i386_validate_tdesc_p (struct gdbarch_tdep *tdep,
+i386_validate_tdesc_p (i386_gdbarch_tdep *tdep,
struct tdesc_arch_data *tdesc_data)
{
const struct target_desc *tdesc = tdep->tdesc;
{
if ((type->code () == TYPE_CODE_INT
|| type->code () == TYPE_CODE_FLT)
- && TYPE_LENGTH (type) > 4)
+ && type->length () > 4)
return 4;
/* Handle x86's funny long double. */
if (type->code () == TYPE_CODE_FLT
- && gdbarch_long_double_bit (gdbarch) == TYPE_LENGTH (type) * 8)
+ && gdbarch_long_double_bit (gdbarch) == type->length () * 8)
return 4;
}
static struct gdbarch *
i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
- struct gdbarch_tdep *tdep;
- struct gdbarch *gdbarch;
const struct target_desc *tdesc;
int mm0_regnum;
int ymm0_regnum;
int bnd0_regnum;
int num_bnd_cooked;
+ x86_xsave_layout xsave_layout = target_fetch_x86_xsave_layout ();
+
+ /* If the target did not provide an XSAVE layout but the target
+ description includes registers from the XSAVE extended region,
+ use a fallback XSAVE layout. Specifically, this fallback layout
+ is used when writing out a local core dump for a remote
+ target. */
+ if (xsave_layout.sizeof_xsave == 0)
+ xsave_layout
+ = i387_fallback_xsave_layout (i386_xcr0_from_tdesc (info.target_desc));
+
/* If there is already a candidate, use it. */
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return arches->gdbarch;
+ for (arches = gdbarch_list_lookup_by_info (arches, &info);
+ arches != NULL;
+ arches = gdbarch_list_lookup_by_info (arches->next, &info))
+ {
+ /* Check that the XSAVE layout of ARCHES matches the layout for
+ the current target. */
+ i386_gdbarch_tdep *other_tdep
+ = gdbarch_tdep<i386_gdbarch_tdep> (arches->gdbarch);
+
+ if (other_tdep->xsave_layout == xsave_layout)
+ return arches->gdbarch;
+ }
/* Allocate space for the new architecture. Assume i386 for now. */
- tdep = XCNEW (struct gdbarch_tdep);
- gdbarch = gdbarch_alloc (&info, tdep);
+ gdbarch *gdbarch
+ = gdbarch_alloc (&info, gdbarch_tdep_up (new i386_gdbarch_tdep));
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
/* General-purpose registers. */
tdep->gregset_reg_offset = NULL;
set_gdbarch_register_to_value (gdbarch, i386_register_to_value);
set_gdbarch_value_to_register (gdbarch, i386_value_to_register);
- set_gdbarch_return_value (gdbarch, i386_return_value);
+ set_gdbarch_return_value_as_value (gdbarch, i386_return_value);
set_gdbarch_skip_prologue (gdbarch, i386_skip_prologue);
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
+ appended to the list first, so that it supersedes the DWARF
unwinder in function epilogues (where the DWARF unwinder
currently fails). */
- frame_unwind_append_unwinder (gdbarch, &i386_epilogue_frame_unwind);
+ if (info.bfd_arch_info->bits_per_word == 32)
+ frame_unwind_append_unwinder (gdbarch, &i386_epilogue_override_frame_unwind);
/* Hook in the DWARF CFI frame unwinder. This unwinder is appended
to the list before the prologue-based unwinders, so that DWARF
CFI info will be used if it is available. */
dwarf2_append_unwinders (gdbarch);
+ if (info.bfd_arch_info->bits_per_word == 32)
+ frame_unwind_append_unwinder (gdbarch, &i386_epilogue_frame_unwind);
+
frame_base_set_default (gdbarch, &i386_frame_base);
/* Pseudo registers may be changed by amd64_init_abi. */
if (!i386_validate_tdesc_p (tdep, tdesc_data.get ()))
{
- xfree (tdep);
gdbarch_free (gdbarch);
return NULL;
}
+ tdep->xsave_layout = xsave_layout;
num_bnd_cooked = (tdep->bnd0r_regnum > 0 ? I387_NUM_BND_REGS : 0);
tdep-> bnd0_regnum = -1;
/* Hook in the legacy prologue-based unwinders last (fallback). */
- frame_unwind_append_unwinder (gdbarch, &i386_stack_tramp_frame_unwind);
- frame_unwind_append_unwinder (gdbarch, &i386_sigtramp_frame_unwind);
- frame_unwind_append_unwinder (gdbarch, &i386_frame_unwind);
+ if (info.bfd_arch_info->bits_per_word == 32)
+ {
+ frame_unwind_append_unwinder (gdbarch, &i386_stack_tramp_frame_unwind);
+ frame_unwind_append_unwinder (gdbarch, &i386_sigtramp_frame_unwind);
+ frame_unwind_append_unwinder (gdbarch, &i386_frame_unwind);
+ }
/* If we have a register mapping, enable the generic core file
support, unless it has already been enabled. */
static unsigned long
i386_mpx_bd_base (void)
{
- struct regcache *rcache;
- struct gdbarch_tdep *tdep;
ULONGEST ret;
enum register_status regstatus;
- rcache = get_current_regcache ();
- tdep = gdbarch_tdep (rcache->arch ());
+ regcache *rcache = get_thread_regcache (inferior_thread ());
+ gdbarch *arch = rcache->arch ();
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (arch);
regstatus = regcache_raw_read_unsigned (rcache, tdep->bndcfgu_regnum, &ret);
int
i386_mpx_enabled (void)
{
- const struct gdbarch_tdep *tdep = gdbarch_tdep (get_current_arch ());
+ gdbarch *arch = get_current_arch ();
+ i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (arch);
const struct target_desc *tdesc = tdep->tdesc;
return (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.mpx") != NULL);
if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_i386
|| !i386_mpx_enabled ())
{
- printf_unfiltered (_("Intel Memory Protection Extensions not "
- "supported on this target.\n"));
+ gdb_printf (_("Intel Memory Protection Extensions not "
+ "supported on this target.\n"));
return;
}
if (args == NULL)
{
- printf_unfiltered (_("Address of pointer variable expected.\n"));
+ gdb_printf (_("Address of pointer variable expected.\n"));
return;
}
for (i = 0; i < 4; i++)
bt_entry[i] = read_memory_typed_address (bt_entry_addr
- + i * TYPE_LENGTH (data_ptr_type),
+ + i * data_ptr_type->length (),
data_ptr_type);
i386_mpx_print_bounds (bt_entry);
bt_entry_addr = i386_mpx_get_bt_entry (addr, bd_base);
for (i = 0; i < 2; i++)
bt_entry[i] = read_memory_typed_address (bt_entry_addr
- + i * TYPE_LENGTH (data_ptr_type),
+ + i * data_ptr_type->length (),
data_ptr_type);
bt_entry[0] = (uint64_t) lower;
bt_entry[1] = ~(uint64_t) upper;
for (i = 0; i < 2; i++)
write_memory_unsigned_integer (bt_entry_addr
- + i * TYPE_LENGTH (data_ptr_type),
- TYPE_LENGTH (data_ptr_type), byte_order,
+ + i * data_ptr_type->length (),
+ data_ptr_type->length (), byte_order,
bt_entry[i]);
}
void
_initialize_i386_tdep ()
{
- register_gdbarch_init (bfd_arch_i386, i386_gdbarch_init);
+ gdbarch_register (bfd_arch_i386, i386_gdbarch_init);
/* Add the variable that controls the disassembly flavor. */
add_setshow_enum_cmd ("disassembly-flavor", no_class, valid_flavors,
NULL, /* FIXME: i18n: */
&setlist, &showlist);
- /* Add "mpx" prefix for the set commands. */
-
- add_basic_prefix_cmd ("mpx", class_support, _("\
-Set Intel Memory Protection Extensions specific variables."),
- &mpx_set_cmdlist, "set mpx ",
- 0 /* allow-unknown */, &setlist);
-
- /* Add "mpx" prefix for the show commands. */
+ /* Add "mpx" prefix for the set and show commands. */
- add_show_prefix_cmd ("mpx", class_support, _("\
-Show Intel Memory Protection Extensions specific variables."),
- &mpx_show_cmdlist, "show mpx ",
- 0 /* allow-unknown */, &showlist);
+ add_setshow_prefix_cmd
+ ("mpx", class_support,
+ _("Set Intel Memory Protection Extensions specific variables."),
+ _("Show Intel Memory Protection Extensions specific variables."),
+ &mpx_set_cmdlist, &mpx_show_cmdlist, &setlist, &showlist);
/* Add "bound" command for the show mpx commands list. */
- add_cmd ("bound", no_class, i386_mpx_info_bounds,
+ cmd_list_element *c = add_cmd ("bound", no_class, i386_mpx_info_bounds,
"Show the memory bounds for a given array/pointer storage\
in the bound table.",
&mpx_show_cmdlist);
+ deprecate_cmd (c, nullptr);
/* Add "bound" command for the set mpx commands list. */
- add_cmd ("bound", no_class, i386_mpx_set_bounds,
+ c = add_cmd ("bound", no_class, i386_mpx_set_bounds,
"Set the memory bounds for a given array/pointer storage\
in the bound table.",
&mpx_set_cmdlist);
+ deprecate_cmd (c, nullptr);
gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_SVR4,
i386_svr4_init_abi);