Changeset View
Changeset View
Standalone View
Standalone View
devel/gdb/files/commit-1163a4b7a3
- This file was added.
Property | Old Value | New Value |
---|---|---|
fbsd:nokeywords | null | yes \ No newline at end of property |
svn:eol-style | null | native \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
commit 1163a4b7a38a79ebd153dc5ee76ce93877d21dbd | |||||
Author: John Baldwin <jhb@FreeBSD.org> | |||||
Date: Tue Mar 12 13:39:02 2019 -0700 | |||||
Support the fs_base and gs_base registers on i386. | |||||
As on amd64, these registers hold the base address of the fs and gs | |||||
segments, respectively. For i386 these two registers are 32 bits. | |||||
gdb/ChangeLog: | |||||
* amd64-fbsd-nat.c (amd64_fbsd_nat_target::read_description): | |||||
Update calls to i386_target_description to add 'segments' | |||||
parameter. | |||||
* amd64-tdep.c (amd64_init_abi): Set tdep->fsbase_regnum. Don't | |||||
add segment base registers. | |||||
* arch/i386.c (i386_create_target_description): Add 'segments' | |||||
parameter to enable segment base registers. | |||||
* arch/i386.h (i386_create_target_description): Likewise. | |||||
* features/i386/32bit-segments.xml: New file. | |||||
* features/i386/32bit-segments.c: Generate. | |||||
* i386-fbsd-nat.c (i386_fbsd_nat_target::read_description): Update | |||||
call to i386_target_description to add 'segments' parameter. | |||||
* i386-fbsd-tdep.c (i386fbsd_core_read_description): Likewise. | |||||
* i386-go32-tdep.c (i386_go32_init_abi): Likewise. | |||||
* i386-linux-tdep.c (i386_linux_read_description): Likewise. | |||||
* i386-tdep.c (i386_validate_tdesc_p): Add segment base registers | |||||
if feature is present. | |||||
(i386_gdbarch_init): Pass I386_NUM_REGS to set_gdbarch_num_regs. | |||||
Add 'segments' parameter to call to i386_target_description. | |||||
(i386_target_description): Add 'segments' parameter to enable | |||||
segment base registers. | |||||
(_initialize_i386_tdep) [GDB_SELF_TEST]: Add 'segments' parameter | |||||
to call to i386_target_description. | |||||
* i386-tdep.h (struct gdbarch_tdep): Add 'fsbase_regnum'. | |||||
(enum i386_regnum): Add I386_FSBASE_REGNUM and I386_GSBASE_REGNUM. | |||||
Define I386_NUM_REGS. | |||||
(i386_target_description): Add 'segments' parameter to enable | |||||
segment base registers. | |||||
gdb/gdbserver/ChangeLog: | |||||
* linux-x86-tdesc.c (i386_linux_read_description): Update call to | |||||
i386_create_target_description for 'segments' parameter. | |||||
* lynx-i386-low.c (lynx_i386_arch_setup): Likewise. | |||||
* nto-x86-low.c (nto_x86_arch_setup): Likewise. | |||||
* win32-i386-low.c (i386_arch_setup): Likewise. | |||||
diff --git gdb/amd64-fbsd-nat.c gdb/amd64-fbsd-nat.c | |||||
index 74ef240766..9fff763dd3 100644 | |||||
--- gdb/amd64-fbsd-nat.c | |||||
+++ gdb/amd64-fbsd-nat.c | |||||
@@ -190,13 +190,13 @@ amd64_fbsd_nat_target::read_description () | |||||
if (is64) | |||||
return amd64_target_description (xcr0, true); | |||||
else | |||||
- return i386_target_description (xcr0); | |||||
+ return i386_target_description (xcr0, false); | |||||
} | |||||
#endif | |||||
if (is64) | |||||
return amd64_target_description (X86_XSTATE_SSE_MASK, true); | |||||
else | |||||
- return i386_target_description (X86_XSTATE_SSE_MASK); | |||||
+ return i386_target_description (X86_XSTATE_SSE_MASK, false); | |||||
} | |||||
#if defined(HAVE_PT_GETDBREGS) && defined(USE_SIGTRAP_SIGINFO) | |||||
diff --git gdb/amd64-tdep.c gdb/amd64-tdep.c | |||||
index 3f61997d66..d5892954d7 100644 | |||||
--- gdb/amd64-tdep.c | |||||
+++ gdb/amd64-tdep.c | |||||
@@ -3107,15 +3107,7 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch, | |||||
if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.segments") != NULL) | |||||
{ | |||||
- const struct tdesc_feature *feature = | |||||
- tdesc_find_feature (tdesc, "org.gnu.gdb.i386.segments"); | |||||
- struct tdesc_arch_data *tdesc_data_segments = | |||||
- (struct tdesc_arch_data *) info.tdep_info; | |||||
- | |||||
- tdesc_numbered_register (feature, tdesc_data_segments, | |||||
- AMD64_FSBASE_REGNUM, "fs_base"); | |||||
- tdesc_numbered_register (feature, tdesc_data_segments, | |||||
- AMD64_GSBASE_REGNUM, "gs_base"); | |||||
+ tdep->fsbase_regnum = AMD64_FSBASE_REGNUM; | |||||
} | |||||
if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys") != NULL) | |||||
diff --git gdb/arch/i386.c gdb/arch/i386.c | |||||
index 7d2901333b..ab24cf71cb 100644 | |||||
--- gdb/arch/i386.c | |||||
+++ gdb/arch/i386.c | |||||
@@ -28,11 +28,12 @@ | |||||
#include "../features/i386/32bit-avx512.c" | |||||
#include "../features/i386/32bit-mpx.c" | |||||
#include "../features/i386/32bit-pkeys.c" | |||||
+#include "../features/i386/32bit-segments.c" | |||||
/* Create i386 target descriptions according to XCR0. */ | |||||
target_desc * | |||||
-i386_create_target_description (uint64_t xcr0, bool is_linux) | |||||
+i386_create_target_description (uint64_t xcr0, bool is_linux, bool segments) | |||||
{ | |||||
target_desc *tdesc = allocate_target_description (); | |||||
@@ -53,6 +54,9 @@ i386_create_target_description (uint64_t xcr0, bool is_linux) | |||||
if (is_linux) | |||||
regnum = create_feature_i386_32bit_linux (tdesc, regnum); | |||||
+ if (segments) | |||||
+ regnum = create_feature_i386_32bit_segments (tdesc, regnum); | |||||
+ | |||||
if (xcr0 & X86_XSTATE_AVX) | |||||
regnum = create_feature_i386_32bit_avx (tdesc, regnum); | |||||
diff --git gdb/arch/i386.h gdb/arch/i386.h | |||||
index fa85438080..9a831cea30 100644 | |||||
--- gdb/arch/i386.h | |||||
+++ gdb/arch/i386.h | |||||
@@ -21,6 +21,7 @@ | |||||
#include "common/tdesc.h" | |||||
#include <stdint.h> | |||||
-target_desc *i386_create_target_description (uint64_t xcr0, bool is_linux); | |||||
+target_desc *i386_create_target_description (uint64_t xcr0, bool is_linux, | |||||
+ bool segments); | |||||
#endif /* ARCH_I386_H */ | |||||
diff --git gdb/features/i386/32bit-segments.c gdb/features/i386/32bit-segments.c | |||||
new file mode 100644 | |||||
index 0000000000..c22c3dfbc3 | |||||
--- /dev/null | |||||
+++ gdb/features/i386/32bit-segments.c | |||||
@@ -0,0 +1,15 @@ | |||||
+/* THIS FILE IS GENERATED. -*- buffer-read-only: t -*- vi:set ro: | |||||
+ Original: 32bit-segments.xml */ | |||||
+ | |||||
+#include "common/tdesc.h" | |||||
+ | |||||
+static int | |||||
+create_feature_i386_32bit_segments (struct target_desc *result, long regnum) | |||||
+{ | |||||
+ struct tdesc_feature *feature; | |||||
+ | |||||
+ feature = tdesc_create_feature (result, "org.gnu.gdb.i386.segments"); | |||||
+ tdesc_create_reg (feature, "fs_base", regnum++, 1, NULL, 32, "int"); | |||||
+ tdesc_create_reg (feature, "gs_base", regnum++, 1, NULL, 32, "int"); | |||||
+ return regnum; | |||||
+} | |||||
diff --git gdb/features/i386/32bit-segments.xml gdb/features/i386/32bit-segments.xml | |||||
new file mode 100644 | |||||
index 0000000000..098948e5ec | |||||
--- /dev/null | |||||
+++ gdb/features/i386/32bit-segments.xml | |||||
@@ -0,0 +1,12 @@ | |||||
+<?xml version="1.0"?> | |||||
+<!-- Copyright (C) 2016-2018 Free Software Foundation, Inc. | |||||
+ | |||||
+ Copying and distribution of this file, with or without modification, | |||||
+ are permitted in any medium without royalty provided the copyright | |||||
+ notice and this notice are preserved. --> | |||||
+ | |||||
+<!DOCTYPE feature SYSTEM "gdb-target.dtd"> | |||||
+<feature name="org.gnu.gdb.i386.segments"> | |||||
+ <reg name="fs_base" bitsize="32" type="int"/> | |||||
+ <reg name="gs_base" bitsize="32" type="int"/> | |||||
+</feature> | |||||
diff --git gdb/gdbserver/linux-x86-tdesc.c gdb/gdbserver/linux-x86-tdesc.c | |||||
index 04bccc84ed..8f24a3d72d 100644 | |||||
--- gdb/gdbserver/linux-x86-tdesc.c | |||||
+++ gdb/gdbserver/linux-x86-tdesc.c | |||||
@@ -87,7 +87,7 @@ i386_linux_read_description (uint64_t xcr0) | |||||
if (*tdesc == NULL) | |||||
{ | |||||
- *tdesc = i386_create_target_description (xcr0, true); | |||||
+ *tdesc = i386_create_target_description (xcr0, true, false); | |||||
init_target_desc (*tdesc, i386_expedite_regs); | |||||
} | |||||
diff --git gdb/gdbserver/lynx-i386-low.c gdb/gdbserver/lynx-i386-low.c | |||||
index bc1027dc52..e47f6b92f6 100644 | |||||
--- gdb/gdbserver/lynx-i386-low.c | |||||
+++ gdb/gdbserver/lynx-i386-low.c | |||||
@@ -331,7 +331,7 @@ static void | |||||
lynx_i386_arch_setup (void) | |||||
{ | |||||
struct target_desc *tdesc | |||||
- = i386_create_target_description (X86_XSTATE_SSE_MASK, false); | |||||
+ = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false); | |||||
init_target_desc (tdesc, i386_expedite_regs); | |||||
diff --git gdb/gdbserver/nto-x86-low.c gdb/gdbserver/nto-x86-low.c | |||||
index 1b00f7f6cc..cfbe7ba6d8 100644 | |||||
--- gdb/gdbserver/nto-x86-low.c | |||||
+++ gdb/gdbserver/nto-x86-low.c | |||||
@@ -89,7 +89,7 @@ nto_x86_arch_setup (void) | |||||
{ | |||||
the_low_target.num_regs = 16; | |||||
struct target_desc *tdesc | |||||
- = i386_create_target_description (X86_XSTATE_SSE_MASK, false); | |||||
+ = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false); | |||||
init_target_desc (tdesc, i386_expedite_regs); | |||||
diff --git gdb/gdbserver/win32-i386-low.c gdb/gdbserver/win32-i386-low.c | |||||
index 3be75d2bf2..7b187d3bea 100644 | |||||
--- gdb/gdbserver/win32-i386-low.c | |||||
+++ gdb/gdbserver/win32-i386-low.c | |||||
@@ -439,7 +439,7 @@ i386_arch_setup (void) | |||||
false, false); | |||||
const char **expedite_regs = amd64_expedite_regs; | |||||
#else | |||||
- tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false); | |||||
+ tdesc = i386_create_target_description (X86_XSTATE_SSE_MASK, false, false); | |||||
const char **expedite_regs = i386_expedite_regs; | |||||
#endif | |||||
diff --git gdb/i386-fbsd-nat.c gdb/i386-fbsd-nat.c | |||||
index 2309b76506..7106e90801 100644 | |||||
--- gdb/i386-fbsd-nat.c | |||||
+++ gdb/i386-fbsd-nat.c | |||||
@@ -160,7 +160,7 @@ i386_fbsd_nat_target::read_description () | |||||
if (x86bsd_xsave_len == 0) | |||||
xcr0 = X86_XSTATE_SSE_MASK; | |||||
- return i386_target_description (xcr0); | |||||
+ return i386_target_description (xcr0, false); | |||||
} | |||||
#endif | |||||
diff --git gdb/i386-fbsd-tdep.c gdb/i386-fbsd-tdep.c | |||||
index 236edd692a..2f28bad728 100644 | |||||
--- gdb/i386-fbsd-tdep.c | |||||
+++ gdb/i386-fbsd-tdep.c | |||||
@@ -267,7 +267,7 @@ i386fbsd_core_read_description (struct gdbarch *gdbarch, | |||||
struct target_ops *target, | |||||
bfd *abfd) | |||||
{ | |||||
- return i386_target_description (i386fbsd_core_read_xcr0 (abfd)); | |||||
+ return i386_target_description (i386fbsd_core_read_xcr0 (abfd), false); | |||||
} | |||||
/* Similar to i386_supply_fpregset, but use XSAVE extended state. */ | |||||
diff --git gdb/i386-go32-tdep.c gdb/i386-go32-tdep.c | |||||
index 06833c346c..30db72d880 100644 | |||||
--- gdb/i386-go32-tdep.c | |||||
+++ gdb/i386-go32-tdep.c | |||||
@@ -35,7 +35,7 @@ i386_go32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) | |||||
/* DJGPP does not support the SSE registers. */ | |||||
if (!tdesc_has_registers (info.target_desc)) | |||||
- tdep->tdesc = i386_target_description (X86_XSTATE_X87_MASK); | |||||
+ tdep->tdesc = i386_target_description (X86_XSTATE_X87_MASK, false); | |||||
/* Native compiler is GCC, which uses the SVR4 register numbering | |||||
even in COFF and STABS. See the comment in i386_gdbarch_init, | |||||
diff --git gdb/i386-linux-tdep.c gdb/i386-linux-tdep.c | |||||
index da81715061..fa6b86f1c8 100644 | |||||
--- gdb/i386-linux-tdep.c | |||||
+++ gdb/i386-linux-tdep.c | |||||
@@ -694,7 +694,7 @@ i386_linux_read_description (uint64_t xcr0) | |||||
[(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]; | |||||
if (*tdesc == NULL) | |||||
- *tdesc = i386_create_target_description (xcr0, true); | |||||
+ *tdesc = i386_create_target_description (xcr0, true, false); | |||||
return *tdesc; | |||||
} | |||||
diff --git gdb/i386-tdep.c gdb/i386-tdep.c | |||||
index bc9ba752ed..4e63832b0e 100644 | |||||
--- gdb/i386-tdep.c | |||||
+++ gdb/i386-tdep.c | |||||
@@ -8175,7 +8175,7 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, | |||||
const struct tdesc_feature *feature_core; | |||||
const struct tdesc_feature *feature_sse, *feature_avx, *feature_mpx, | |||||
- *feature_avx512, *feature_pkeys; | |||||
+ *feature_avx512, *feature_pkeys, *feature_segments; | |||||
int i, num_regs, valid_p; | |||||
if (! tdesc_has_registers (tdesc)) | |||||
@@ -8198,6 +8198,9 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, | |||||
/* Try AVX512 registers. */ | |||||
feature_avx512 = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx512"); | |||||
+ /* Try segment base registers. */ | |||||
+ feature_segments = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.segments"); | |||||
+ | |||||
/* Try PKEYS */ | |||||
feature_pkeys = tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys"); | |||||
@@ -8307,6 +8310,16 @@ i386_validate_tdesc_p (struct gdbarch_tdep *tdep, | |||||
tdep->mpx_register_names[i]); | |||||
} | |||||
+ if (feature_segments) | |||||
+ { | |||||
+ if (tdep->fsbase_regnum < 0) | |||||
+ tdep->fsbase_regnum = I386_FSBASE_REGNUM; | |||||
+ valid_p &= tdesc_numbered_register (feature_segments, tdesc_data, | |||||
+ tdep->fsbase_regnum, "fs_base"); | |||||
+ valid_p &= tdesc_numbered_register (feature_segments, tdesc_data, | |||||
+ tdep->fsbase_regnum + 1, "gs_base"); | |||||
+ } | |||||
+ | |||||
if (feature_pkeys) | |||||
{ | |||||
tdep->xcr0 |= X86_XSTATE_PKRU; | |||||
@@ -8543,14 +8556,14 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | |||||
/* Even though the default ABI only includes general-purpose registers, | |||||
floating-point registers and the SSE registers, we have to leave a | |||||
gap for the upper AVX, MPX and AVX512 registers. */ | |||||
- set_gdbarch_num_regs (gdbarch, I386_PKEYS_NUM_REGS); | |||||
+ set_gdbarch_num_regs (gdbarch, I386_NUM_REGS); | |||||
set_gdbarch_gnu_triplet_regexp (gdbarch, i386_gnu_triplet_regexp); | |||||
/* Get the x86 target description from INFO. */ | |||||
tdesc = info.target_desc; | |||||
if (! tdesc_has_registers (tdesc)) | |||||
- tdesc = i386_target_description (X86_XSTATE_SSE_MASK); | |||||
+ tdesc = i386_target_description (X86_XSTATE_SSE_MASK, false); | |||||
tdep->tdesc = tdesc; | |||||
tdep->num_core_regs = I386_NUM_GREGS + I387_NUM_REGS; | |||||
@@ -8592,6 +8605,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | |||||
tdep->pkru_regnum = -1; | |||||
tdep->num_pkeys_regs = 0; | |||||
+ /* No segment base registers. */ | |||||
+ tdep->fsbase_regnum = -1; | |||||
+ | |||||
tdesc_data = tdesc_data_alloc (); | |||||
set_gdbarch_relocate_instruction (gdbarch, i386_relocate_instruction); | |||||
@@ -8717,20 +8733,21 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) | |||||
/* Return the target description for a specified XSAVE feature mask. */ | |||||
const struct target_desc * | |||||
-i386_target_description (uint64_t xcr0) | |||||
+i386_target_description (uint64_t xcr0, bool segments) | |||||
{ | |||||
static target_desc *i386_tdescs \ | |||||
- [2/*SSE*/][2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/] = {}; | |||||
+ [2/*SSE*/][2/*AVX*/][2/*MPX*/][2/*AVX512*/][2/*PKRU*/][2/*segments*/] = {}; | |||||
target_desc **tdesc; | |||||
tdesc = &i386_tdescs[(xcr0 & X86_XSTATE_SSE) ? 1 : 0] | |||||
[(xcr0 & X86_XSTATE_AVX) ? 1 : 0] | |||||
[(xcr0 & X86_XSTATE_MPX) ? 1 : 0] | |||||
[(xcr0 & X86_XSTATE_AVX512) ? 1 : 0] | |||||
- [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]; | |||||
+ [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0] | |||||
+ [segments ? 1 : 0]; | |||||
if (*tdesc == NULL) | |||||
- *tdesc = i386_create_target_description (xcr0, false); | |||||
+ *tdesc = i386_create_target_description (xcr0, false, segments); | |||||
return *tdesc; | |||||
} | |||||
@@ -9072,7 +9089,7 @@ Show Intel Memory Protection Extensions specific variables."), | |||||
for (auto &a : xml_masks) | |||||
{ | |||||
- auto tdesc = i386_target_description (a.mask); | |||||
+ auto tdesc = i386_target_description (a.mask, false); | |||||
selftests::record_xml_tdesc (a.xml, tdesc); | |||||
} | |||||
diff --git gdb/i386-tdep.h gdb/i386-tdep.h | |||||
index 2532306e5c..c0d494824c 100644 | |||||
--- gdb/i386-tdep.h | |||||
+++ gdb/i386-tdep.h | |||||
@@ -200,6 +200,10 @@ struct gdbarch_tdep | |||||
/* PKEYS register names. */ | |||||
const char **pkeys_register_names; | |||||
+ /* Register number for %fsbase. Set this to -1 to indicate the | |||||
+ absence of segment base registers. */ | |||||
+ int fsbase_regnum; | |||||
+ | |||||
/* Target description. */ | |||||
const struct target_desc *tdesc; | |||||
@@ -296,7 +300,9 @@ enum i386_regnum | |||||
I386_K7_REGNUM = I386_K0_REGNUM + 7, | |||||
I386_ZMM0H_REGNUM, /* %zmm0h */ | |||||
I386_ZMM7H_REGNUM = I386_ZMM0H_REGNUM + 7, | |||||
- I386_PKRU_REGNUM | |||||
+ I386_PKRU_REGNUM, | |||||
+ I386_FSBASE_REGNUM, | |||||
+ I386_GSBASE_REGNUM | |||||
}; | |||||
/* Register numbers of RECORD_REGMAP. */ | |||||
@@ -337,6 +343,7 @@ enum record_i386_regnum | |||||
#define I386_MPX_NUM_REGS (I386_BNDSTATUS_REGNUM + 1) | |||||
#define I386_AVX512_NUM_REGS (I386_ZMM7H_REGNUM + 1) | |||||
#define I386_PKEYS_NUM_REGS (I386_PKRU_REGNUM + 1) | |||||
+#define I386_NUM_REGS (I386_GSBASE_REGNUM + 1) | |||||
/* Size of the largest register. */ | |||||
#define I386_MAX_REGISTER_SIZE 64 | |||||
@@ -440,7 +447,8 @@ extern int i386_svr4_reg_to_regnum (struct gdbarch *gdbarch, int reg); | |||||
extern int i386_process_record (struct gdbarch *gdbarch, | |||||
struct regcache *regcache, CORE_ADDR addr); | |||||
-extern const struct target_desc *i386_target_description (uint64_t xcr0); | |||||
+extern const struct target_desc *i386_target_description (uint64_t xcr0, | |||||
+ bool segments); | |||||
/* Return true iff the current target is MPX enabled. */ | |||||
extern int i386_mpx_enabled (void); |