diff options
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 25 | ||||
-rw-r--r-- | gdb/gdbserver/Makefile.in | 4 | ||||
-rw-r--r-- | gdb/gdbserver/configure.srv | 3 | ||||
-rw-r--r-- | gdb/gdbserver/linux-amd64-ipa.c | 56 | ||||
-rw-r--r-- | gdb/gdbserver/linux-x86-low.c | 86 | ||||
-rw-r--r-- | gdb/gdbserver/linux-x86-tdesc-selftest.c | 90 | ||||
-rw-r--r-- | gdb/gdbserver/linux-x86-tdesc.c | 122 | ||||
-rw-r--r-- | gdb/gdbserver/linux-x86-tdesc.h | 49 |
8 files changed, 268 insertions, 167 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 30b4fec..0efb7e1 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,30 @@ 2017-09-05 Yao Qi <yao.qi@linaro.org> + * Makefile.in (arch-amd64.o): New rule. + * configure.srv: Append arch-amd64.o. + * linux-amd64-ipa.c: Include common/x86-xstate.h. + (get_ipa_tdesc): Call amd64_linux_read_description. + (initialize_low_tracepoint): Don't call init_registers_x32_XXX + and init_registers_amd64_XXX. + * linux-x86-low.c (x86_linux_read_description): Call + amd64_linux_read_description. + (x86_get_ipa_tdesc_idx): Call amd64_get_ipa_tdesc_idx. + (initialize_low_arch): Don't call init_registers_x32_XXX and + init_registers_amd64_XXX. + * linux-x86-tdesc-selftest.c: Declare init_registers_amd64_XXX + and tdesc_amd64_XXX. + [__x86_64__] (amd64_tdesc_test): New function. + (initialize_low_tdesc) [__x86_64__]: Call init_registers_x32_XXX + and init_registers_amd64_XXX. + * linux-x86-tdesc.c: Include arch/amd64.h. + (xcr0_to_tdesc_idx): New function. + (i386_linux_read_description): New function. + (amd64_get_ipa_tdesc_idx): New function. + * linux-x86-tdesc.h (amd64_get_ipa_tdesc_idx): Declare. + (amd64_get_ipa_tdesc): Declare. + +2017-09-05 Yao Qi <yao.qi@linaro.org> + * configure.srv (srv_i386_linux_xmlfiles): Remove i386/i386-XXX-linux.xml from it. diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index b552b69..1bbe515 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -532,6 +532,10 @@ arch-i386.o: ../arch/i386.c $(COMPILE) $< $(POSTCOMPILE) +arch-amd64.o: ../arch/amd64.c + $(COMPILE) $< + $(POSTCOMPILE) + # Rules for objects that go in the in-process agent. %-ipa.o: %-generated.c diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv index 946119c..95649f4 100644 --- a/gdb/gdbserver/configure.srv +++ b/gdb/gdbserver/configure.srv @@ -365,7 +365,7 @@ case "${target}" in ;; x86_64-*-linux*) srv_regobj="$srv_amd64_linux_regobj $srv_i386_linux_regobj" srv_tgtobj="$srv_linux_obj linux-x86-low.o x86-low.o x86-dregs.o i387-fp.o" - srv_tgtobj="${srv_tgtobj} arch-i386.o" + srv_tgtobj="${srv_tgtobj} arch-i386.o arch-amd64.o" srv_tgtobj="${srv_tgtobj} linux-x86-tdesc.o" srv_tgtobj="${srv_tgtobj} linux-btrace.o x86-linux.o" srv_tgtobj="${srv_tgtobj} x86-linux-dregs.o" @@ -381,6 +381,7 @@ case "${target}" in ipa_obj="${ipa_amd64_linux_regobj}" fi ipa_obj="${ipa_obj} linux-amd64-ipa.o linux-x86-tdesc-ipa.o" + ipa_obj="${ipa_obj} amd64-ipa.o" ;; x86_64-*-mingw*) srv_regobj="$srv_amd64_regobj" srv_tgtobj="x86-low.o x86-dregs.o i387-fp.o win32-low.o win32-i386-low.o" diff --git a/gdb/gdbserver/linux-amd64-ipa.c b/gdb/gdbserver/linux-amd64-ipa.c index 683339b..85d0d45 100644 --- a/gdb/gdbserver/linux-amd64-ipa.c +++ b/gdb/gdbserver/linux-amd64-ipa.c @@ -22,6 +22,7 @@ #include <sys/mman.h> #include "tracepoint.h" #include "linux-x86-tdesc.h" +#include "common/x86-xstate.h" /* Defined in auto-generated file amd64-linux.c. */ void init_registers_amd64_linux (void); @@ -174,38 +175,37 @@ supply_static_tracepoint_registers (struct regcache *regcache, const struct target_desc * get_ipa_tdesc (int idx) { + if (idx >= X86_TDESC_LAST) + { + internal_error (__FILE__, __LINE__, + "unknown ipa tdesc index: %d", idx); + } + #if defined __ILP32__ switch (idx) { case X86_TDESC_SSE: - return tdesc_x32_linux; + return amd64_linux_read_description (X86_XSTATE_SSE_MASK, true); case X86_TDESC_AVX: - return tdesc_x32_avx_linux; + return amd64_linux_read_description (X86_XSTATE_AVX_MASK, true); case X86_TDESC_AVX_AVX512: - return tdesc_x32_avx_avx512_linux; + return amd64_linux_read_description (X86_XSTATE_AVX_AVX512_MASK, true); default: break; } #else - switch (idx) - { - case X86_TDESC_SSE: - return tdesc_amd64_linux; - case X86_TDESC_AVX: - return tdesc_amd64_avx_linux; - case X86_TDESC_MPX: - return tdesc_amd64_mpx_linux; - case X86_TDESC_AVX_MPX: - return tdesc_amd64_avx_mpx_linux; - case X86_TDESC_AVX_MPX_AVX512_PKU: - return tdesc_amd64_avx_mpx_avx512_pku_linux; - case X86_TDESC_AVX_AVX512: - return tdesc_amd64_avx_avx512_linux; - default: - internal_error (__FILE__, __LINE__, - "unknown ipa tdesc index: %d", idx); - return tdesc_amd64_linux; - } + /* Map the tdesc index to xcr0 mask. */ + uint64_t idx2mask[X86_TDESC_LAST] = { + X86_XSTATE_X87_MASK, + X86_XSTATE_SSE_MASK, + X86_XSTATE_AVX_MASK, + X86_XSTATE_MPX_MASK, + X86_XSTATE_AVX_MPX_MASK, + X86_XSTATE_AVX_AVX512_MASK, + X86_XSTATE_AVX_MPX_AVX512_PKU_MASK, + }; + + return amd64_linux_read_description (idx2mask[idx], false); #endif internal_error (__FILE__, __LINE__, @@ -276,16 +276,4 @@ alloc_jump_pad_buffer (size_t size) void initialize_low_tracepoint (void) { -#if defined __ILP32__ - init_registers_x32_linux (); - init_registers_x32_avx_linux (); - init_registers_x32_avx_avx512_linux (); -#else - init_registers_amd64_linux (); - init_registers_amd64_avx_linux (); - init_registers_amd64_mpx_linux (); - init_registers_amd64_avx_mpx_linux (); - init_registers_amd64_avx_avx512_linux (); - init_registers_amd64_avx_mpx_avx512_pku_linux (); -#endif } diff --git a/gdb/gdbserver/linux-x86-low.c b/gdb/gdbserver/linux-x86-low.c index 54be82f..f09871a 100644 --- a/gdb/gdbserver/linux-x86-low.c +++ b/gdb/gdbserver/linux-x86-low.c @@ -817,58 +817,17 @@ x86_linux_read_description (void) if (machine == EM_X86_64) { #ifdef __x86_64__ - if (is_elf64) - { - if (xcr0_features) - { - switch (xcr0 & X86_XSTATE_ALL_MASK) - { - case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: - return tdesc_amd64_avx_mpx_avx512_pku_linux; - - case X86_XSTATE_AVX_AVX512_MASK: - return tdesc_amd64_avx_avx512_linux; - - case X86_XSTATE_AVX_MPX_MASK: - return tdesc_amd64_avx_mpx_linux; - - case X86_XSTATE_MPX_MASK: - return tdesc_amd64_mpx_linux; - - case X86_XSTATE_AVX_MASK: - return tdesc_amd64_avx_linux; + const target_desc *tdesc = NULL; - default: - return tdesc_amd64_linux; - } - } - else - return tdesc_amd64_linux; - } - else + if (xcr0_features) { - if (xcr0_features) - { - switch (xcr0 & X86_XSTATE_ALL_MASK) - { - case X86_XSTATE_AVX_MPX_AVX512_PKU_MASK: - /* No x32 MPX and PKU, fall back to avx_avx512. */ - return tdesc_x32_avx_avx512_linux; - - case X86_XSTATE_AVX_AVX512_MASK: - return tdesc_x32_avx_avx512_linux; - - case X86_XSTATE_MPX_MASK: /* No MPX on x32. */ - case X86_XSTATE_AVX_MASK: - return tdesc_x32_avx_linux; - - default: - return tdesc_x32_linux; - } - } - else - return tdesc_x32_linux; + tdesc = amd64_linux_read_description (xcr0 & X86_XSTATE_ALL_MASK, + !is_elf64); } + + if (tdesc == NULL) + tdesc = amd64_linux_read_description (X86_XSTATE_SSE_MASK, !is_elf64); + return tdesc; #endif } else @@ -2881,19 +2840,7 @@ x86_get_ipa_tdesc_idx (void) const struct target_desc *tdesc = regcache->tdesc; #ifdef __x86_64__ - if (tdesc == tdesc_amd64_linux || tdesc == tdesc_amd64_linux_no_xml - || tdesc == tdesc_x32_linux) - return X86_TDESC_SSE; - if (tdesc == tdesc_amd64_avx_linux || tdesc == tdesc_x32_avx_linux) - return X86_TDESC_AVX; - if (tdesc == tdesc_amd64_mpx_linux) - return X86_TDESC_MPX; - if (tdesc == tdesc_amd64_avx_mpx_linux) - return X86_TDESC_AVX_MPX; - if (tdesc == tdesc_amd64_avx_mpx_avx512_pku_linux || tdesc == tdesc_x32_avx_avx512_linux) - return X86_TDESC_AVX_MPX_AVX512_PKU; - if (tdesc == tdesc_amd64_avx_avx512_linux) - return X86_TDESC_AVX_AVX512; + return amd64_get_ipa_tdesc_idx (tdesc); #endif if (tdesc == tdesc_i386_linux_no_xml) @@ -2953,19 +2900,10 @@ initialize_low_arch (void) { /* Initialize the Linux target descriptions. */ #ifdef __x86_64__ - init_registers_amd64_linux (); - init_registers_amd64_avx_linux (); - init_registers_amd64_mpx_linux (); - init_registers_amd64_avx_mpx_linux (); - init_registers_amd64_avx_avx512_linux (); - init_registers_amd64_avx_mpx_avx512_pku_linux (); - - init_registers_x32_linux (); - init_registers_x32_avx_linux (); - init_registers_x32_avx_avx512_linux (); - tdesc_amd64_linux_no_xml = XNEW (struct target_desc); - copy_target_description (tdesc_amd64_linux_no_xml, tdesc_amd64_linux); + copy_target_description (tdesc_amd64_linux_no_xml, + amd64_linux_read_description (X86_XSTATE_SSE_MASK, + false)); tdesc_amd64_linux_no_xml->xmltarget = xmltarget_amd64_linux_no_xml; #endif diff --git a/gdb/gdbserver/linux-x86-tdesc-selftest.c b/gdb/gdbserver/linux-x86-tdesc-selftest.c index 558a25b..aa5a8e9 100644 --- a/gdb/gdbserver/linux-x86-tdesc-selftest.c +++ b/gdb/gdbserver/linux-x86-tdesc-selftest.c @@ -49,6 +49,46 @@ extern const struct target_desc *tdesc_i386_avx_mpx_avx512_pku_linux; void init_registers_i386_mpx_linux (void); extern const struct target_desc *tdesc_i386_mpx_linux; +#ifdef __x86_64__ + +/* Defined in auto-generated file amd64-linux.c. */ +void init_registers_amd64_linux (void); +extern const struct target_desc *tdesc_amd64_linux; + +/* Defined in auto-generated file amd64-avx-linux.c. */ +void init_registers_amd64_avx_linux (void); +extern const struct target_desc *tdesc_amd64_avx_linux; + +/* Defined in auto-generated file amd64-avx-avx512-linux.c. */ +void init_registers_amd64_avx_avx512_linux (void); +extern const struct target_desc *tdesc_amd64_avx_avx512_linux; + +/* Defined in auto-generated file amd64-avx-mpx-avx512-pku-linux.c. */ +void init_registers_amd64_avx_mpx_avx512_pku_linux (void); +extern const struct target_desc *tdesc_amd64_avx_mpx_avx512_pku_linux; + +/* Defined in auto-generated file amd64-avx-mpx-linux.c. */ +void init_registers_amd64_avx_mpx_linux (void); +extern const struct target_desc *tdesc_amd64_avx_mpx_linux; + +/* Defined in auto-generated file amd64-mpx-linux.c. */ +void init_registers_amd64_mpx_linux (void); +extern const struct target_desc *tdesc_amd64_mpx_linux; + +/* Defined in auto-generated file x32-linux.c. */ +void init_registers_x32_linux (void); +extern const struct target_desc *tdesc_x32_linux; + +/* Defined in auto-generated file x32-avx-linux.c. */ +void init_registers_x32_avx_linux (void); +extern const struct target_desc *tdesc_x32_avx_linux; + +/* Defined in auto-generated file x32-avx-avx512-linux.c. */ +void init_registers_x32_avx_avx512_linux (void); +extern const struct target_desc *tdesc_x32_avx_avx512_linux; + +#endif + namespace selftests { namespace tdesc { static void @@ -75,6 +115,41 @@ i386_tdesc_test () SELF_CHECK (*tdesc == *elem.tdesc); } } + +#ifdef __x86_64__ + +static void +amd64_tdesc_test () +{ + struct + { + unsigned int mask; + const target_desc *tdesc[2]; + } tdesc_tests[] = { + { X86_XSTATE_SSE_MASK, { tdesc_amd64_linux, tdesc_x32_linux } }, + { X86_XSTATE_AVX_MASK, { tdesc_amd64_avx_linux, tdesc_x32_avx_linux } }, + { X86_XSTATE_MPX_MASK, { tdesc_amd64_mpx_linux, tdesc_x32_avx_linux } }, + { X86_XSTATE_AVX_MPX_MASK, { tdesc_amd64_avx_mpx_linux, + tdesc_x32_avx_linux } }, + { X86_XSTATE_AVX_AVX512_MASK, { tdesc_amd64_avx_avx512_linux, + tdesc_x32_avx_avx512_linux } }, + { X86_XSTATE_AVX_MPX_AVX512_PKU_MASK, + { tdesc_amd64_avx_mpx_avx512_pku_linux, tdesc_x32_avx_avx512_linux } }, + }; + + for (auto &elem : tdesc_tests) + { + for (int i = 0; i < 2; i++) + { + const target_desc *tdesc = amd64_linux_read_description (elem.mask, + i); + + SELF_CHECK (*tdesc == *elem.tdesc[i]); + } + } +} + +#endif } } // namespace selftests @@ -90,4 +165,19 @@ initialize_low_tdesc () init_registers_i386_avx_mpx_avx512_pku_linux (); selftests::register_test (selftests::tdesc::i386_tdesc_test); + +#ifdef __x86_64__ + init_registers_x32_linux (); + init_registers_x32_avx_linux (); + init_registers_x32_avx_avx512_linux (); + + init_registers_amd64_linux (); + init_registers_amd64_avx_linux (); + init_registers_amd64_mpx_linux (); + init_registers_amd64_avx_mpx_linux (); + init_registers_amd64_avx_avx512_linux (); + init_registers_amd64_avx_mpx_avx512_pku_linux (); + + selftests::register_test (selftests::tdesc::amd64_tdesc_test); +#endif } diff --git a/gdb/gdbserver/linux-x86-tdesc.c b/gdb/gdbserver/linux-x86-tdesc.c index d1e262c..9eb61a7 100644 --- a/gdb/gdbserver/linux-x86-tdesc.c +++ b/gdb/gdbserver/linux-x86-tdesc.c @@ -22,36 +22,68 @@ #include "linux-x86-tdesc.h" #include "arch/i386.h" #include "common/x86-xstate.h" +#ifdef __x86_64__ +#include "arch/amd64.h" +#endif -static struct target_desc *i386_tdescs[X86_TDESC_LAST] = { }; +/* Return the right x86_linux_tdesc index for a given XCR0. Return + X86_TDESC_LAST if can't find a match. */ -#if defined __i386__ || !defined IN_PROCESS_AGENT - -/* Return the target description according to XCR0. */ - -const struct target_desc * -i386_linux_read_description (uint64_t xcr0) +static enum x86_linux_tdesc +xcr0_to_tdesc_idx (uint64_t xcr0, bool is_x32) { - struct target_desc **tdesc = NULL; - if (xcr0 & X86_XSTATE_PKRU) - tdesc = &i386_tdescs[X86_TDESC_AVX_MPX_AVX512_PKU]; + { + if (is_x32) + { + /* No x32 MPX and PKU, fall back to avx_avx512. */ + return X86_TDESC_AVX_AVX512; + } + else + return X86_TDESC_AVX_MPX_AVX512_PKU; + } else if (xcr0 & X86_XSTATE_AVX512) - tdesc = &i386_tdescs[X86_TDESC_AVX_AVX512]; + return X86_TDESC_AVX_AVX512; else if ((xcr0 & X86_XSTATE_AVX_MPX_MASK) == X86_XSTATE_AVX_MPX_MASK) - tdesc = &i386_tdescs[X86_TDESC_AVX_MPX]; + { + if (is_x32) /* No MPX on x32. */ + return X86_TDESC_AVX; + else + return X86_TDESC_AVX_MPX; + } else if (xcr0 & X86_XSTATE_MPX) - tdesc = &i386_tdescs[X86_TDESC_MPX]; + { + if (is_x32) /* No MPX on x32. */ + return X86_TDESC_AVX; + else + return X86_TDESC_MPX; + } else if (xcr0 & X86_XSTATE_AVX) - tdesc = &i386_tdescs[X86_TDESC_AVX]; + return X86_TDESC_AVX; else if (xcr0 & X86_XSTATE_SSE) - tdesc = &i386_tdescs[X86_TDESC_SSE]; + return X86_TDESC_SSE; else if (xcr0 & X86_XSTATE_X87) - tdesc = &i386_tdescs[X86_TDESC_MMX]; + return X86_TDESC_MMX; + else + return X86_TDESC_LAST; +} - if (tdesc == NULL) +static struct target_desc *i386_tdescs[X86_TDESC_LAST] = { }; + +#if defined __i386__ || !defined IN_PROCESS_AGENT + +/* Return the target description according to XCR0. */ + +const struct target_desc * +i386_linux_read_description (uint64_t xcr0) +{ + enum x86_linux_tdesc idx = xcr0_to_tdesc_idx (xcr0, false); + + if (idx == X86_TDESC_LAST) return NULL; + struct target_desc **tdesc = &i386_tdescs[idx]; + if (*tdesc == NULL) { *tdesc = i386_create_target_description (xcr0); @@ -68,7 +100,44 @@ i386_linux_read_description (uint64_t xcr0) } #endif +#ifdef __x86_64__ + +static target_desc *amd64_tdescs[X86_TDESC_LAST] = { }; +static target_desc *x32_tdescs[X86_TDESC_LAST] = { }; + +const struct target_desc * +amd64_linux_read_description (uint64_t xcr0, bool is_x32) +{ + enum x86_linux_tdesc idx = xcr0_to_tdesc_idx (xcr0, is_x32); + + if (idx == X86_TDESC_LAST) + return NULL; + + struct target_desc **tdesc = NULL; + + if (is_x32) + tdesc = &x32_tdescs[idx]; + else + tdesc = &amd64_tdescs[idx]; + + if (*tdesc == NULL) + { + *tdesc = amd64_create_target_description (xcr0, is_x32); + + init_target_desc (*tdesc); + +#ifndef IN_PROCESS_AGENT + static const char *expedite_regs_amd64[] = { "rbp", "rsp", "rip", NULL }; + (*tdesc)->expedite_regs = expedite_regs_amd64; +#endif + } + return *tdesc; +} + +#endif + #ifndef IN_PROCESS_AGENT + int i386_get_ipa_tdesc_idx (const struct target_desc *tdesc) { @@ -82,4 +151,23 @@ i386_get_ipa_tdesc_idx (const struct target_desc *tdesc) return X86_TDESC_MMX; } +#if defined __x86_64__ +int +amd64_get_ipa_tdesc_idx (const struct target_desc *tdesc) +{ + for (int i = 0; i < X86_TDESC_LAST; i++) + { + if (tdesc == amd64_tdescs[i]) + return i; + } + for (int i = 0; i < X86_TDESC_LAST; i++) + { + if (tdesc == x32_tdescs[i]) + return i; + } + + return X86_TDESC_SSE; +} + +#endif #endif diff --git a/gdb/gdbserver/linux-x86-tdesc.h b/gdb/gdbserver/linux-x86-tdesc.h index 03bd1f1..a6dc330 100644 --- a/gdb/gdbserver/linux-x86-tdesc.h +++ b/gdb/gdbserver/linux-x86-tdesc.h @@ -33,52 +33,19 @@ enum x86_linux_tdesc { X86_TDESC_LAST = 7, }; -#ifdef __x86_64__ - -#if defined __LP64__ || !defined IN_PROCESS_AGENT -/* Defined in auto-generated file amd64-linux.c. */ -void init_registers_amd64_linux (void); -extern const struct target_desc *tdesc_amd64_linux; - -/* Defined in auto-generated file amd64-avx-linux.c. */ -void init_registers_amd64_avx_linux (void); -extern const struct target_desc *tdesc_amd64_avx_linux; - -/* Defined in auto-generated file amd64-avx-avx512-linux.c. */ -void init_registers_amd64_avx_avx512_linux (void); -extern const struct target_desc *tdesc_amd64_avx_avx512_linux; - -/* Defined in auto-generated file amd64-avx-mpx-avx512-pku-linux.c. */ -void init_registers_amd64_avx_mpx_avx512_pku_linux (void); -extern const struct target_desc *tdesc_amd64_avx_mpx_avx512_pku_linux; - -/* Defined in auto-generated file amd64-avx-mpx-linux.c. */ -void init_registers_amd64_avx_mpx_linux (void); -extern const struct target_desc *tdesc_amd64_avx_mpx_linux; - -/* Defined in auto-generated file amd64-mpx-linux.c. */ -void init_registers_amd64_mpx_linux (void); -extern const struct target_desc *tdesc_amd64_mpx_linux; +#if defined __i386__ || !defined IN_PROCESS_AGENT +int i386_get_ipa_tdesc_idx (const struct target_desc *tdesc); #endif -#if defined __ILP32__ || !defined IN_PROCESS_AGENT -/* Defined in auto-generated file x32-linux.c. */ -void init_registers_x32_linux (void); -extern const struct target_desc *tdesc_x32_linux; - -/* Defined in auto-generated file x32-avx-linux.c. */ -void init_registers_x32_avx_linux (void); -extern const struct target_desc *tdesc_x32_avx_linux; - -/* Defined in auto-generated file x32-avx-avx512-linux.c. */ -void init_registers_x32_avx_avx512_linux (void); -extern const struct target_desc *tdesc_x32_avx_avx512_linux; +#if defined __x86_64__ && !defined IN_PROCESS_AGENT +int amd64_get_ipa_tdesc_idx (const struct target_desc *tdesc); #endif -#endif +const struct target_desc *i386_get_ipa_tdesc (int idx); -#if defined __i386__ || !defined IN_PROCESS_AGENT -int i386_get_ipa_tdesc_idx (const struct target_desc *tdesc); +#ifdef __x86_64__ +const struct target_desc *amd64_linux_read_description (uint64_t xcr0, + bool is_x32); #endif const struct target_desc *i386_linux_read_description (uint64_t xcr0); |