[15/25,RFC] GDBserver unit test to i386_tdesc
Commit Message
This patch adds a unit test in GDBserver to test dynamically created
target descriptions equal to these pre-generated ones.
gdb/gdbserver:
2017-06-06 Yao Qi <yao.qi@linaro.org>
* linux-x86-tdesc.c (i386_tdesc_test): New function.
(initialize_low_tdesc): Call register_self_test.
* tdesc.h: TODO.
---
gdb/gdbserver/linux-x86-tdesc.c | 45 +++++++++++++++++++++++++++++++++++++++++
gdb/gdbserver/tdesc.h | 42 +++++++++++++++++++++++++++++++++++++-
gdb/regformats/regdef.h | 12 +++++++++++
3 files changed, 98 insertions(+), 1 deletion(-)
Comments
On 06/12/2017 09:41 AM, Yao Qi wrote:
> This patch adds a unit test in GDBserver to test dynamically created
> target descriptions equal to these pre-generated ones.
>
> gdb/gdbserver:
Are these temporary tests? What's the plan for the pre-generated ones?
> +#if defined GDB_SELF_TEST && !defined IN_PROCESS_AGENT
> +#include "selftest.h"
> +
> +namespace selftests {
> +namespace gdbserver {
Considering that at some point we may want to wrap
all of gdbserver under "namespace gdbserver", this
namespace choice here seems like a poor choice.
s/gdbserver/tdesc_tests/ or some such?
> +static void
> +i386_tdesc_test ()
> +{
> + const struct target_desc *tdesc = i386_get_ipa_tdesc (X86_TDESC_MMX);
> +
> + SELF_CHECK (*tdesc == *tdesc_i386_mmx_linux);
> + delete tdesc;
> +
> + tdesc = i386_get_ipa_tdesc (X86_TDESC_SSE);
> + SELF_CHECK (*tdesc == *tdesc_i386_linux);
> + delete tdesc;
> +
> + tdesc = i386_get_ipa_tdesc (X86_TDESC_AVX);
> + SELF_CHECK (*tdesc == *tdesc_i386_avx_linux);
> + delete tdesc;
> +
> + tdesc = i386_get_ipa_tdesc (X86_TDESC_MPX);
> + SELF_CHECK (*tdesc == *tdesc_i386_mpx_linux);
> + delete tdesc;
> +
> + tdesc = i386_get_ipa_tdesc (X86_TDESC_AVX_MPX);
> + SELF_CHECK (*tdesc == *tdesc_i386_avx_mpx_linux);
> + delete tdesc;
> +
> + tdesc = i386_get_ipa_tdesc (X86_TDESC_AVX_AVX512);
> + SELF_CHECK (*tdesc == *tdesc_i386_avx_avx512_linux);
> + delete tdesc;
> +
> + tdesc = i386_get_ipa_tdesc (X86_TDESC_AVX_MPX_AVX512_PKU);
> + SELF_CHECK (*tdesc == *tdesc_i386_avx_mpx_avx512_pku_linux);
> + delete tdesc;
Would something like this, based on an array, work? :
struct
{
int idx;
const target_desc *tdesc;
}
tdesc_tests[] = {
{ X86_TDESC_MMX, tdesc_i386_mmx_linux },
{ X86_TDESC_SSE, tdesc_i386_linux },
...
};
for (auto &elem : tdesc_tests)
{
std::unique_ptr<const target_desc> tdesc (i386_get_ipa_tdesc (elem.idx));
SELF_CHECK (*elem.tdesc == *tdesc);
}
> diff --git a/gdb/gdbserver/tdesc.h b/gdb/gdbserver/tdesc.h
> index 2d4cbfa..e64f0b3 100644
> --- a/gdb/gdbserver/tdesc.h
> +++ b/gdb/gdbserver/tdesc.h
> @@ -19,7 +19,8 @@
> #ifndef TDESC_H
> #define TDESC_H
>
> -struct reg;
> +#include "regdef.h"
> +#include <cstring>
Odd that you needed cstring? string.h is one of the
system headers always pulled in by common/common-defs.h.
>
> typedef struct reg *tdesc_reg_p;
> DEF_VEC_P(tdesc_reg_p);
> @@ -60,6 +61,45 @@ public:
> xfree (reg);
> VEC_free (tdesc_reg_p, reg_defs);
> }
> + bool operator!= (const target_desc &other) const
Same comment about "operator!=" vs "operator==" as in
a previous patch.
Thanks,
Pedro Alves
Pedro Alves <palves@redhat.com> writes:
> On 06/12/2017 09:41 AM, Yao Qi wrote:
>> This patch adds a unit test in GDBserver to test dynamically created
>> target descriptions equal to these pre-generated ones.
>>
>> gdb/gdbserver:
>
> Are these temporary tests? What's the plan for the pre-generated ones?
They are not temporary tests, we'll keep the tests, but they won't
change. We also keep these pre-generated target descriptions, as legacy
target descriptions, for the tests. Once we finish the target
description transition, we can move these pre-generated target
descriptions into testsuite/ directory.
Note that, after we finish the change for a given architecture, all
target descriptions are dynamically generated, so there is no new
pre-generated target description, and we don't update the tests.
@@ -61,6 +61,47 @@ extern const struct target_desc *tdesc_i386_mpx_linux;
static const struct target_desc *i386_tdescs[X86_TDESC_LAST] = { };
+#if defined GDB_SELF_TEST && !defined IN_PROCESS_AGENT
+#include "selftest.h"
+
+namespace selftests {
+namespace gdbserver {
+static void
+i386_tdesc_test ()
+{
+ const struct target_desc *tdesc = i386_get_ipa_tdesc (X86_TDESC_MMX);
+
+ SELF_CHECK (*tdesc == *tdesc_i386_mmx_linux);
+ delete tdesc;
+
+ tdesc = i386_get_ipa_tdesc (X86_TDESC_SSE);
+ SELF_CHECK (*tdesc == *tdesc_i386_linux);
+ delete tdesc;
+
+ tdesc = i386_get_ipa_tdesc (X86_TDESC_AVX);
+ SELF_CHECK (*tdesc == *tdesc_i386_avx_linux);
+ delete tdesc;
+
+ tdesc = i386_get_ipa_tdesc (X86_TDESC_MPX);
+ SELF_CHECK (*tdesc == *tdesc_i386_mpx_linux);
+ delete tdesc;
+
+ tdesc = i386_get_ipa_tdesc (X86_TDESC_AVX_MPX);
+ SELF_CHECK (*tdesc == *tdesc_i386_avx_mpx_linux);
+ delete tdesc;
+
+ tdesc = i386_get_ipa_tdesc (X86_TDESC_AVX_AVX512);
+ SELF_CHECK (*tdesc == *tdesc_i386_avx_avx512_linux);
+ delete tdesc;
+
+ tdesc = i386_get_ipa_tdesc (X86_TDESC_AVX_MPX_AVX512_PKU);
+ SELF_CHECK (*tdesc == *tdesc_i386_avx_mpx_avx512_pku_linux);
+ delete tdesc;
+}
+}
+} // namespace selftests
+#endif /* GDB_SELF_TEST */
+
void
initialize_low_tdesc ()
{
@@ -72,6 +113,10 @@ initialize_low_tdesc ()
init_registers_i386_avx_mpx_linux ();
init_registers_i386_avx_avx512_linux ();
init_registers_i386_avx_mpx_avx512_pku_linux ();
+
+#if GDB_SELF_TEST
+ register_self_test (selftests::gdbserver::i386_tdesc_test);
+#endif
#endif
}
@@ -19,7 +19,8 @@
#ifndef TDESC_H
#define TDESC_H
-struct reg;
+#include "regdef.h"
+#include <cstring>
typedef struct reg *tdesc_reg_p;
DEF_VEC_P(tdesc_reg_p);
@@ -60,6 +61,45 @@ public:
xfree (reg);
VEC_free (tdesc_reg_p, reg_defs);
}
+ bool operator!= (const target_desc &other) const
+ {
+ if (VEC_length (tdesc_reg_p, reg_defs)
+ != VEC_length (tdesc_reg_p, other.reg_defs))
+ return true;
+
+ struct reg *reg;
+
+ for (int ix = 0;
+ VEC_iterate (tdesc_reg_p, reg_defs, ix, reg);
+ ix++)
+ {
+ struct reg *reg2
+ = VEC_index (tdesc_reg_p, other.reg_defs, ix);
+
+ if (reg != reg2 && *reg != *reg2)
+ return true;
+ }
+
+ /* Compare expedite_regs. */
+ int i = 0;
+ for (; expedite_regs[i] != NULL; i++)
+ {
+ if (strcmp (expedite_regs[i], other.expedite_regs[i]) != 0)
+ return true;
+ }
+ if (other.expedite_regs[i] != NULL)
+ return true;
+
+ if (strcmp (xmltarget, other.xmltarget) != 0)
+ return true;
+
+ return false;
+ }
+
+ bool operator== (const target_desc &other) const
+ {
+ return !(*this != other);
+ }
#endif
};
@@ -34,6 +34,18 @@ struct reg
/* The size (in bits) of the value of this register, as transmitted. */
int size;
+
+ bool operator== (const reg &other) const
+ {
+ return (strcmp (name, other.name) == 0
+ && offset == other.offset
+ && size == other.size);
+ }
+
+ bool operator!= (const reg &other) const
+ {
+ return !(*this == other);
+ }
};
#endif /* REGDEF_H */