X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fi386-tdep.c;h=8a4d59f6fdae8ec785462d0ceedcd6501b955cf0;hb=a7785f8c797183eb363e95c201343df67d8536c6;hp=2ac2f151730ed3cd7f3af9951599c47c3c484f36;hpb=9a3c826307ae6ad4dd6fbd72431e7d9d4947f1dd;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 2ac2f15173..8a4d59f6fd 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -1,6 +1,6 @@ /* Intel 386 target-dependent stuff. - Copyright (C) 1988-2015 Free Software Foundation, Inc. + Copyright (C) 1988-2017 Free Software Foundation, Inc. This file is part of GDB. @@ -53,6 +53,7 @@ #include "features/i386/i386.c" #include "features/i386/i386-avx.c" #include "features/i386/i386-mpx.c" +#include "features/i386/i386-avx-mpx.c" #include "features/i386/i386-avx512.c" #include "features/i386/i386-mmx.c" @@ -65,6 +66,7 @@ #include "expression.h" #include "parser-defs.h" #include +#include /* Register names. */ @@ -502,11 +504,11 @@ i386_dbx_reg_to_regnum (struct gdbarch *gdbarch, int reg) return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); } -/* Convert SVR4 register number REG to the appropriate register number +/* Convert SVR4 DWARF register number REG to the appropriate register number used by GDB. */ static int -i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg) +i386_svr4_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); @@ -544,8 +546,20 @@ i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg) case 45: return I386_GS_REGNUM; } - /* This will hopefully provoke a warning. */ - return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + return -1; +} + +/* Wrapper on i386_svr4_dwarf_reg_to_regnum to return + num_regs + num_pseudo_regs for other debug formats. */ + +static int +i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg) +{ + int regnum = i386_svr4_dwarf_reg_to_regnum (gdbarch, reg); + + if (regnum == -1) + return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + return regnum; } @@ -574,14 +588,10 @@ static const char *disassembly_flavor = att_flavor; This function is 64-bit safe. */ -static const gdb_byte * -i386_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, int *len) -{ - static gdb_byte break_insn[] = { 0xcc }; /* int 3 */ +constexpr gdb_byte i386_break_insn[] = { 0xcc }; /* int 3 */ + +typedef BP_MANIPULATION (i386_break_insn) i386_breakpoint; - *len = sizeof (break_insn); - return break_insn; -} /* Displaced instruction handling. */ @@ -1352,7 +1362,7 @@ i386_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc, if (current_pc > pc + offset_and) cache->saved_sp_reg = regnums[reg]; - return min (pc + offset + 3, current_pc); + return std::min (pc + offset + 3, current_pc); } /* Maximum instruction length we need to handle. */ @@ -1823,7 +1833,7 @@ i386_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) && (cust != NULL && COMPUNIT_PRODUCER (cust) != NULL && startswith (COMPUNIT_PRODUCER (cust), "clang "))) - return max (start_pc, post_prologue_pc); + return std::max (start_pc, post_prologue_pc); } cache.locals = -1; @@ -3006,7 +3016,7 @@ i386_bnd_type (struct gdbarch *gdbarch) if (!tdep->i386_bnd_type) { - struct type *t, *bound_t; + struct type *t; const struct builtin_type *bt = builtin_type (gdbarch); /* The type we're building is described bellow: */ @@ -3407,9 +3417,6 @@ i386_pseudo_register_read_into_value (struct gdbarch *gdbarch, } else if (i386_byte_regnum_p (gdbarch, regnum)) { - /* Check byte pseudo registers last since this function will - be called from amd64_pseudo_register_read, which handles - byte pseudo registers differently. */ int gpnum = regnum - tdep->al_regnum; /* Extract (always little endian). We read both lower and @@ -3572,9 +3579,6 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, } else if (i386_byte_regnum_p (gdbarch, regnum)) { - /* Check byte pseudo registers last since this function will - be called from amd64_pseudo_register_read, which handles - byte pseudo registers differently. */ int gpnum = regnum - tdep->al_regnum; /* Read ... We read both lower and upper registers. */ @@ -3591,6 +3595,88 @@ i386_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, internal_error (__FILE__, __LINE__, _("invalid regnum")); } } + +/* Implement the 'ax_pseudo_register_collect' gdbarch method. */ + +int +i386_ax_pseudo_register_collect (struct gdbarch *gdbarch, + struct agent_expr *ax, int regnum) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (i386_mmx_regnum_p (gdbarch, regnum)) + { + /* MMX to FPU register mapping depends on current TOS. Let's just + not care and collect everything... */ + int i; + + ax_reg_mask (ax, I387_FSTAT_REGNUM (tdep)); + for (i = 0; i < 8; i++) + ax_reg_mask (ax, I387_ST0_REGNUM (tdep) + i); + return 0; + } + else if (i386_bnd_regnum_p (gdbarch, regnum)) + { + regnum -= tdep->bnd0_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; + if (regnum < num_lower_zmm_regs) + { + ax_reg_mask (ax, I387_XMM0_REGNUM (tdep) + regnum); + ax_reg_mask (ax, tdep->ymm0h_regnum + regnum); + } + else + { + ax_reg_mask (ax, I387_XMM16_REGNUM (tdep) + regnum + - num_lower_zmm_regs); + ax_reg_mask (ax, I387_YMM16H_REGNUM (tdep) + regnum + - num_lower_zmm_regs); + } + ax_reg_mask (ax, tdep->zmm0h_regnum + regnum); + return 0; + } + else if (i386_ymm_regnum_p (gdbarch, regnum)) + { + regnum -= tdep->ymm0_regnum; + ax_reg_mask (ax, I387_XMM0_REGNUM (tdep) + regnum); + ax_reg_mask (ax, tdep->ymm0h_regnum + regnum); + return 0; + } + else if (i386_ymm_avx512_regnum_p (gdbarch, regnum)) + { + regnum -= tdep->ymm16_regnum; + ax_reg_mask (ax, I387_XMM16_REGNUM (tdep) + regnum); + ax_reg_mask (ax, tdep->ymm16h_regnum + regnum); + return 0; + } + else if (i386_word_regnum_p (gdbarch, regnum)) + { + int gpnum = regnum - tdep->ax_regnum; + + ax_reg_mask (ax, gpnum); + return 0; + } + else if (i386_byte_regnum_p (gdbarch, regnum)) + { + int gpnum = regnum - tdep->al_regnum; + + ax_reg_mask (ax, gpnum % 4); + return 0; + } + else + internal_error (__FILE__, __LINE__, _("invalid regnum")); + return 1; +} /* Return the register number of the register allocated by GCC after @@ -4826,17 +4912,12 @@ i386_record_lea_modrm (struct i386_record_s *irp) { if (record_full_memory_query) { - int q; - - target_terminal_ours (); - q = yquery (_("\ + if (yquery (_("\ Process record ignores the memory change of instruction at address %s\n\ because it can't get the value of the segment register.\n\ Do you want to stop the program?"), - paddress (gdbarch, irp->orig_addr)); - target_terminal_inferior (); - if (q) - return -1; + paddress (gdbarch, irp->orig_addr))) + return -1; } return 0; @@ -5717,16 +5798,11 @@ i386_process_record (struct gdbarch *gdbarch, struct regcache *regcache, { if (record_full_memory_query) { - int q; - - target_terminal_ours (); - q = yquery (_("\ + if (yquery (_("\ Process record ignores the memory change of instruction at address %s\n\ because it can't get the value of the segment register.\n\ Do you want to stop the program?"), - paddress (gdbarch, ir.orig_addr)); - target_terminal_inferior (); - if (q) + paddress (gdbarch, ir.orig_addr))) return -1; } } @@ -6391,16 +6467,11 @@ Do you want to stop the program?"), /* addr += ((uint32_t) read_register (I386_ES_REGNUM)) << 4; */ if (record_full_memory_query) { - int q; - - target_terminal_ours (); - q = yquery (_("\ + if (yquery (_("\ Process record ignores the memory change of instruction at address %s\n\ because it can't get the value of the segment register.\n\ Do you want to stop the program?"), - paddress (gdbarch, ir.orig_addr)); - target_terminal_inferior (); - if (q) + paddress (gdbarch, ir.orig_addr))) return -1; } } @@ -6946,17 +7017,12 @@ Do you want to stop the program?"), { if (record_full_memory_query) { - int q; - - target_terminal_ours (); - q = yquery (_("\ + if (yquery (_("\ Process record ignores the memory change of instruction at address %s\n\ because it can't get the value of the segment register.\n\ Do you want to stop the program?"), - paddress (gdbarch, ir.orig_addr)); - target_terminal_inferior (); - if (q) - return -1; + paddress (gdbarch, ir.orig_addr))) + return -1; } } else @@ -7003,16 +7069,11 @@ Do you want to stop the program?"), { if (record_full_memory_query) { - int q; - - target_terminal_ours (); - q = yquery (_("\ + if (yquery (_("\ Process record ignores the memory change of instruction at address %s\n\ because it can't get the value of the segment register.\n\ Do you want to stop the program?"), - paddress (gdbarch, ir.orig_addr)); - target_terminal_inferior (); - if (q) + paddress (gdbarch, ir.orig_addr))) return -1; } } @@ -8097,6 +8158,23 @@ i386_fast_tracepoint_valid_at (struct gdbarch *gdbarch, CORE_ADDR addr, } } +/* Return a floating-point format for a floating-point variable of + length LEN in bits. If non-NULL, NAME is the name of its type. + If no suitable type is found, return NULL. */ + +const struct floatformat ** +i386_floatformat_for_type (struct gdbarch *gdbarch, + const char *name, int len) +{ + if (len == 128 && name) + if (strcmp (name, "__float128") == 0 + || strcmp (name, "_Float128") == 0 + || strcmp (name, "complex _Float128") == 0) + return floatformats_ia64_quad; + + return default_floatformat_for_type (gdbarch, name, len); +} + static int i386_validate_tdesc_p (struct gdbarch_tdep *tdep, struct tdesc_arch_data *tdesc_data) @@ -8238,6 +8316,8 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, } +/* Note: This is called for both i386 and amd64. */ + static struct gdbarch * i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { @@ -8249,15 +8329,13 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) int ymm0_regnum; int bnd0_regnum; int num_bnd_cooked; - int k0_regnum; - int zmm0_regnum; /* If there is already a candidate, use it. */ arches = gdbarch_list_lookup_by_info (arches, &info); if (arches != NULL) return arches->gdbarch; - /* Allocate space for the new architecture. */ + /* Allocate space for the new architecture. Assume i386 for now. */ tdep = XCNEW (struct gdbarch_tdep); gdbarch = gdbarch_alloc (&info, tdep); @@ -8308,6 +8386,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) alignment. */ set_gdbarch_long_double_bit (gdbarch, 96); + /* Support for floating-point data type variants. */ + set_gdbarch_floatformat_for_type (gdbarch, i386_floatformat_for_type); + /* Register numbers of various important registers. */ set_gdbarch_sp_regnum (gdbarch, I386_ESP_REGNUM); /* %esp */ set_gdbarch_pc_regnum (gdbarch, I386_EIP_REGNUM); /* %eip */ @@ -8349,7 +8430,7 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_sdb_reg_to_regnum (gdbarch, i386_dbx_reg_to_regnum); /* Use the SVR4 register numbering scheme for DWARF 2. */ - set_gdbarch_dwarf2_reg_to_regnum (gdbarch, i386_svr4_reg_to_regnum); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, i386_svr4_dwarf_reg_to_regnum); /* 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. */ @@ -8375,7 +8456,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Stack grows downward. */ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); - set_gdbarch_breakpoint_from_pc (gdbarch, i386_breakpoint_from_pc); + set_gdbarch_breakpoint_kind_from_pc (gdbarch, i386_breakpoint::kind_from_pc); + set_gdbarch_sw_breakpoint_from_kind (gdbarch, i386_breakpoint::bp_from_kind); + set_gdbarch_decr_pc_after_break (gdbarch, 1); set_gdbarch_max_insn_length (gdbarch, I386_MAX_INSN_LEN); @@ -8411,6 +8494,8 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_pseudo_register_read_value (gdbarch, i386_pseudo_register_read_value); set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write); + set_gdbarch_ax_pseudo_register_collect (gdbarch, + i386_ax_pseudo_register_collect); set_tdesc_pseudo_register_type (gdbarch, i386_pseudo_register_type); set_tdesc_pseudo_register_name (gdbarch, i386_pseudo_register_name); @@ -8477,8 +8562,10 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_insn_is_ret (gdbarch, i386_insn_is_ret); set_gdbarch_insn_is_jump (gdbarch, i386_insn_is_jump); - /* Hook in ABI-specific overrides, if they have been registered. */ - info.tdep_info = (struct gdbarch_tdep_info *) tdesc_data; + /* Hook in ABI-specific overrides, if they have been registered. + Note: If INFO specifies a 64 bit arch, this is where we turn + a 32-bit i386 into a 64-bit amd64. */ + info.tdep_info = tdesc_data; gdbarch_init_osabi (info, gdbarch); if (!i386_validate_tdesc_p (tdep, tdesc_data)) @@ -8606,6 +8693,8 @@ i386_target_description (uint64_t xcr0) case X86_XSTATE_MPX_AVX512_MASK: case X86_XSTATE_AVX512_MASK: return tdesc_i386_avx512; + case X86_XSTATE_AVX_MPX_MASK: + return tdesc_i386_avx_mpx; case X86_XSTATE_MPX_MASK: return tdesc_i386_mpx; case X86_XSTATE_AVX_MASK: @@ -8626,7 +8715,6 @@ i386_mpx_bd_base (void) struct gdbarch_tdep *tdep; ULONGEST ret; enum register_status regstatus; - struct gdb_exception except; rcache = get_current_regcache (); tdep = gdbarch_tdep (get_regcache_arch (rcache)); @@ -8639,9 +8727,7 @@ i386_mpx_bd_base (void) return ret & MPX_BASE_MASK; } -/* Check if the current target is MPX enabled. */ - -static int +int i386_mpx_enabled (void) { const struct gdbarch_tdep *tdep = gdbarch_tdep (get_current_arch ()); @@ -8682,7 +8768,8 @@ i386_mpx_get_bt_entry (CORE_ADDR ptr, CORE_ADDR bd_base) bt_mask = (CORE_ADDR) MPX_BT_MASK; if ( sizeof (CORE_ADDR) == 4) - error (_("operation not supported")); + error (_("bound table examination not supported\ + for 64-bit process with 32-bit GDB")); } else { @@ -8723,22 +8810,22 @@ i386_mpx_print_bounds (const CORE_ADDR bt_entry[4]) if (bounds_in_map == 1) { - ui_out_text (uiout, "Null bounds on map:"); - ui_out_text (uiout, " pointer value = "); - ui_out_field_core_addr (uiout, "pointer-value", gdbarch, bt_entry[2]); - ui_out_text (uiout, "."); - ui_out_text (uiout, "\n"); + uiout->text ("Null bounds on map:"); + uiout->text (" pointer value = "); + uiout->field_core_addr ("pointer-value", gdbarch, bt_entry[2]); + uiout->text ("."); + uiout->text ("\n"); } else { - ui_out_text (uiout, "{lbound = "); - ui_out_field_core_addr (uiout, "lower-bound", gdbarch, bt_entry[0]); - ui_out_text (uiout, ", ubound = "); + uiout->text ("{lbound = "); + uiout->field_core_addr ("lower-bound", gdbarch, bt_entry[0]); + uiout->text (", ubound = "); /* The upper bound is stored in 1's complement. */ - ui_out_field_core_addr (uiout, "upper-bound", gdbarch, ~bt_entry[1]); - ui_out_text (uiout, "}: pointer value = "); - ui_out_field_core_addr (uiout, "pointer-value", gdbarch, bt_entry[2]); + uiout->field_core_addr ("upper-bound", gdbarch, ~bt_entry[1]); + uiout->text ("}: pointer value = "); + uiout->field_core_addr ("pointer-value", gdbarch, bt_entry[2]); if (gdbarch_ptr_bit (gdbarch) == 64) size = ( (~(int64_t) bt_entry[1]) - (int64_t) bt_entry[0]); @@ -8750,12 +8837,12 @@ i386_mpx_print_bounds (const CORE_ADDR bt_entry[4]) one to the size. */ size = (size > -1 ? size + 1 : size); - ui_out_text (uiout, ", size = "); - ui_out_field_fmt (uiout, "size", "%s", plongest (size)); + uiout->text (", size = "); + uiout->field_fmt ("size", "%s", plongest (size)); - ui_out_text (uiout, ", metadata = "); - ui_out_field_core_addr (uiout, "metadata", gdbarch, bt_entry[3]); - ui_out_text (uiout, "\n"); + uiout->text (", metadata = "); + uiout->field_core_addr ("metadata", gdbarch, bt_entry[3]); + uiout->text ("\n"); } } @@ -8772,9 +8859,10 @@ i386_mpx_info_bounds (char *args, int from_tty) struct gdbarch *gdbarch = get_current_arch (); struct type *data_ptr_type = builtin_type (gdbarch)->builtin_data_ptr; - if (!i386_mpx_enabled ()) + if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_i386 + || !i386_mpx_enabled ()) { - printf_unfiltered (_("Intel(R) Memory Protection Extensions not " + printf_unfiltered (_("Intel Memory Protection Extensions not " "supported on this target.\n")); return; } @@ -8794,7 +8882,7 @@ i386_mpx_info_bounds (char *args, int from_tty) for (i = 0; i < 4; i++) bt_entry[i] = read_memory_typed_address (bt_entry_addr - + i * data_ptr_type->length, + + i * TYPE_LENGTH (data_ptr_type), data_ptr_type); i386_mpx_print_bounds (bt_entry); @@ -8815,8 +8903,9 @@ i386_mpx_set_bounds (char *args, int from_tty) enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct type *data_ptr_type = builtin_type (gdbarch)->builtin_data_ptr; - if (!i386_mpx_enabled ()) - error (_("Intel(R) Memory Protection Extensions not supported\ + if (gdbarch_bfd_arch_info (gdbarch)->arch != bfd_arch_i386 + || !i386_mpx_enabled ()) + error (_("Intel Memory Protection Extensions not supported\ on this target.")); if (args == NULL) @@ -8840,14 +8929,15 @@ i386_mpx_set_bounds (char *args, int from_tty) 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 * data_ptr_type->length, + + i * TYPE_LENGTH (data_ptr_type), 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 * data_ptr_type->length, - data_ptr_type->length, byte_order, + write_memory_unsigned_integer (bt_entry_addr + + i * TYPE_LENGTH (data_ptr_type), + TYPE_LENGTH (data_ptr_type), byte_order, bt_entry[i]); } @@ -8902,14 +8992,14 @@ is \"default\"."), /* Add "mpx" prefix for the set commands. */ add_prefix_cmd ("mpx", class_support, set_mpx_cmd, _("\ -Set Intel(R) Memory Protection Extensions specific variables."), +Set Intel Memory Protection Extensions specific variables."), &mpx_set_cmdlist, "set mpx ", 0 /* allow-unknown */, &setlist); /* Add "mpx" prefix for the show commands. */ add_prefix_cmd ("mpx", class_support, show_mpx_cmd, _("\ -Show Intel(R) Memory Protection Extensions specific variables."), +Show Intel Memory Protection Extensions specific variables."), &mpx_show_cmdlist, "show mpx ", 0 /* allow-unknown */, &showlist); @@ -8943,6 +9033,7 @@ Show Intel(R) Memory Protection Extensions specific variables."), initialize_tdesc_i386_mmx (); initialize_tdesc_i386_avx (); initialize_tdesc_i386_mpx (); + initialize_tdesc_i386_avx_mpx (); initialize_tdesc_i386_avx512 (); /* Tell remote stub that we support XML target description. */