m_gdbserver/32bit-sse-valgrind-s1.xml \
m_gdbserver/32bit-sse-valgrind-s2.xml \
m_gdbserver/32bit-sse.xml \
+ m_gdbserver/64bit-avx-valgrind-s2.xml \
+ m_gdbserver/64bit-avx-valgrind-s1.xml \
+ m_gdbserver/64bit-avx.xml \
m_gdbserver/64bit-core-valgrind-s1.xml \
m_gdbserver/64bit-core-valgrind-s2.xml \
m_gdbserver/64bit-core.xml \
m_gdbserver/64bit-sse-valgrind-s1.xml \
m_gdbserver/64bit-sse-valgrind-s2.xml \
m_gdbserver/64bit-sse.xml \
+ m_gdbserver/amd64-avx-coresse-valgrind.xml \
+ m_gdbserver/amd64-avx-coresse.xml \
+ m_gdbserver/amd64-avx-linux-valgrind.xml \
+ m_gdbserver/amd64-avx-linux.xml \
m_gdbserver/amd64-coresse-valgrind.xml \
m_gdbserver/amd64-linux-valgrind.xml \
m_gdbserver/arm-core-valgrind-s1.xml \
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2012 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.avx.valgrind.s1">
+ <reg name="ymm0hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm1hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm2hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm3hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm4hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm5hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm6hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm7hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm8hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm9hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm10hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm11hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm12hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm13hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm14hs1" bitsize="128" type="uint128"/>
+ <reg name="ymm15hs1" bitsize="128" type="uint128"/>
+</feature>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2012 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.avx.valgrind.s2">
+ <reg name="ymm0hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm1hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm2hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm3hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm4hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm5hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm6hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm7hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm8hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm9hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm10hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm11hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm12hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm13hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm14hs2" bitsize="128" type="uint128"/>
+ <reg name="ymm15hs2" bitsize="128" type="uint128"/>
+</feature>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010-2012 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.avx">
+ <reg name="ymm0h" bitsize="128" type="uint128"/>
+ <reg name="ymm1h" bitsize="128" type="uint128"/>
+ <reg name="ymm2h" bitsize="128" type="uint128"/>
+ <reg name="ymm3h" bitsize="128" type="uint128"/>
+ <reg name="ymm4h" bitsize="128" type="uint128"/>
+ <reg name="ymm5h" bitsize="128" type="uint128"/>
+ <reg name="ymm6h" bitsize="128" type="uint128"/>
+ <reg name="ymm7h" bitsize="128" type="uint128"/>
+ <reg name="ymm8h" bitsize="128" type="uint128"/>
+ <reg name="ymm9h" bitsize="128" type="uint128"/>
+ <reg name="ymm10h" bitsize="128" type="uint128"/>
+ <reg name="ymm11h" bitsize="128" type="uint128"/>
+ <reg name="ymm12h" bitsize="128" type="uint128"/>
+ <reg name="ymm13h" bitsize="128" type="uint128"/>
+ <reg name="ymm14h" bitsize="128" type="uint128"/>
+ <reg name="ymm15h" bitsize="128" type="uint128"/>
+</feature>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010 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. -->
+
+<!-- AMD64 - core and sse. -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>i386:x86-64</architecture>
+ <xi:include href="64bit-core.xml"/>
+ <xi:include href="64bit-sse.xml"/>
+ <xi:include href="64bit-avx.xml"/>
+ <xi:include href="64bit-core-valgrind-s1.xml"/>
+ <xi:include href="64bit-sse-valgrind-s1.xml"/>
+ <xi:include href="64bit-avx-valgrind-s1.xml"/>
+ <xi:include href="64bit-core-valgrind-s2.xml"/>
+ <xi:include href="64bit-sse-valgrind-s2.xml"/>
+ <xi:include href="64bit-avx-valgrind-s2.xml"/>
+</target>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010 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. -->
+
+<!-- AMD64 - core and sse and avx. -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>i386:x86-64</architecture>
+ <xi:include href="64bit-core.xml"/>
+ <xi:include href="64bit-sse.xml"/>
+ <xi:include href="64bit-avx.xml"/>
+</target>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010 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. -->
+
+<!-- AMD64 with avx - Includes Linux-only special "register". -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>i386:x86-64</architecture>
+ <osabi>GNU/Linux</osabi>
+ <xi:include href="64bit-core.xml"/>
+ <xi:include href="64bit-sse.xml"/>
+ <xi:include href="64bit-linux.xml"/>
+ <xi:include href="64bit-avx.xml"/>
+ <xi:include href="64bit-core-valgrind-s1.xml"/>
+ <xi:include href="64bit-sse-valgrind-s1.xml"/>
+ <xi:include href="64bit-linux-valgrind-s1.xml"/>
+ <xi:include href="64bit-avx-valgrind-s1.xml"/>
+ <xi:include href="64bit-core-valgrind-s2.xml"/>
+ <xi:include href="64bit-sse-valgrind-s2.xml"/>
+ <xi:include href="64bit-linux-valgrind-s2.xml"/>
+ <xi:include href="64bit-avx-valgrind-s2.xml"/>
+</target>
--- /dev/null
+<?xml version="1.0"?>
+<!-- Copyright (C) 2010 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. -->
+
+<!-- AMD64 with avx - Includes Linux-only special "register". -->
+
+<!DOCTYPE target SYSTEM "gdb-target.dtd">
+<target>
+ <architecture>i386:x86-64</architecture>
+ <osabi>GNU/Linux</osabi>
+ <xi:include href="64bit-core.xml"/>
+ <xi:include href="64bit-sse.xml"/>
+ <xi:include href="64bit-linux.xml"/>
+ <xi:include href="64bit-avx.xml"/>
+</target>
}
}
- if ( (valgrind_target_xml() != NULL
- || valgrind_shadow_target_xml() != NULL)
+ if (valgrind_target_xml(VG_(clo_vgdb_shadow_registers)) != NULL
&& strncmp ("qXfer:features:read:", arg_own_buf, 20) == 0) {
CORE_ADDR ofs;
unsigned int len, doc_len;
}
if (strcmp (annex, "target.xml") == 0) {
- annex = NULL; // to replace it by the corresponding filename.
-
- /* If VG_(clo_vgdb_shadow_registers), try to use
- shadow_target_xml. Fallback to target_xml
- if not defined. */
- if (VG_(clo_vgdb_shadow_registers)) {
- annex = valgrind_shadow_target_xml();
- if (annex != NULL)
- /* Ensure the shadow registers are initialized. */
- initialize_shadow_low(True);
+ annex = valgrind_target_xml(VG_(clo_vgdb_shadow_registers));
+ if (annex != NULL && VG_(clo_vgdb_shadow_registers)) {
+ /* Ensure the shadow registers are initialized. */
+ initialize_shadow_low(True);
}
- if (annex == NULL)
- annex = valgrind_target_xml();
if (annex == NULL) {
strcpy (arg_own_buf, "E00");
return;
if (VG_(client_auxv))
strcat (arg_own_buf, ";qXfer:auxv:read+");
- if (valgrind_target_xml() != NULL
- || valgrind_shadow_target_xml() != NULL) {
+ if (valgrind_target_xml(VG_(clo_vgdb_shadow_registers)) != NULL) {
strcat (arg_own_buf, ";qXfer:features:read+");
/* if a new gdb connects to us, we have to reset the register
set to the normal register sets to allow this new gdb to
return 1; /* error or unsupported */
}
-char* valgrind_target_xml (void)
+char* valgrind_target_xml (Bool shadow_mode)
{
- return (char *) the_low_target.target_xml;
-}
-
-char* valgrind_shadow_target_xml (void)
-{
- return (char *) the_low_target.shadow_target_xml;
+ return (*the_low_target.target_xml) (shadow_mode);
}
int valgrind_insert_watchpoint (char type, CORE_ADDR addr, int len)
extern void initialize_shadow_low (Bool shadow_mode);
/* Returns the name of the xml target description file.
- returns NULL if no xml target description available. */
-extern char* valgrind_target_xml (void);
-
-/* Same but describes also the shadow registers. */
-extern char* valgrind_shadow_target_xml (void);
-
+ returns NULL if no xml target description available.
+ if shadow_mode, then returns the xml target description
+ with the shadow registers
+ else returns the xml target description only for
+ the normal registers. */
+extern char* valgrind_target_xml (Bool shadow_mode);
/* -------------------------------------------------------------------------- */
#include "regcache.h"
#include "pub_core_aspacemgr.h"
-#include "pub_tool_machine.h"
+#include "pub_core_machine.h"
#include "pub_core_threadstate.h"
#include "pub_core_transtab.h"
#include "pub_core_gdbserver.h"
{ "xmm15", 4128, 128 },
{ "mxcsr", 4256, 32 },
#if defined(VGO_linux)
- { "orig_rax", 4288, 64 }
+ { "orig_rax", 4288, 64 },
#endif
+ { "ymm0h", 4352, 128 }, // The ymm?h registers only to be given to GDB
+ { "ymm1h", 4480, 128 }, // if Valgrind is running with AVX instructions.
+ { "ymm2h", 4608, 128 },
+ { "ymm3h", 4736, 128 },
+ { "ymm4h", 4864, 128 },
+ { "ymm5h", 4992, 128 },
+ { "ymm6h", 5120, 128 },
+ { "ymm7h", 5248, 128 },
+ { "ymm8h", 5376, 128 },
+ { "ymm9h", 5504, 128 },
+ { "ymm10h", 5632, 128 },
+ { "ymm11h", 5760, 128 },
+ { "ymm12h", 5888, 128 },
+ { "ymm13h", 6016, 128 },
+ { "ymm14h", 6144, 128 },
+ { "ymm15h", 6272, 128 }
};
static const char *expedite_regs[] = { "rbp", "rsp", "rip", 0 };
-#define num_regs (sizeof (regs) / sizeof (regs[0]))
+#define max_num_regs (sizeof (regs) / sizeof (regs[0]))
+static int dyn_num_regs; // if no AVX, we have to give less registers to gdb.
+
static
CORE_ADDR get_pc (void)
transfer_direction dir, int size, Bool *mod)
{
ThreadState* tst = VG_(get_ThreadState)(tid);
- int set = abs_regno / num_regs;
- int regno = abs_regno % num_regs;
+ int set = abs_regno / dyn_num_regs;
+ int regno = abs_regno % dyn_num_regs;
*mod = False;
VexGuestAMD64State* amd64 = (VexGuestAMD64State*) get_arch (set, tst);
}
break;
case 57: *mod = False; break; // GDBTD???? VEX equivalent { "orig_rax"},
+ case 58: VG_(transfer) (&amd64->guest_YMM0[4], buf, dir, size, mod); break;
+ case 59: VG_(transfer) (&amd64->guest_YMM1[4], buf, dir, size, mod); break;
+ case 60: VG_(transfer) (&amd64->guest_YMM2[4], buf, dir, size, mod); break;
+ case 61: VG_(transfer) (&amd64->guest_YMM3[4], buf, dir, size, mod); break;
+ case 62: VG_(transfer) (&amd64->guest_YMM4[4], buf, dir, size, mod); break;
+ case 63: VG_(transfer) (&amd64->guest_YMM5[4], buf, dir, size, mod); break;
+ case 64: VG_(transfer) (&amd64->guest_YMM6[4], buf, dir, size, mod); break;
+ case 65: VG_(transfer) (&amd64->guest_YMM7[4], buf, dir, size, mod); break;
+ case 66: VG_(transfer) (&amd64->guest_YMM8[4], buf, dir, size, mod); break;
+ case 67: VG_(transfer) (&amd64->guest_YMM9[4], buf, dir, size, mod); break;
+ case 68: VG_(transfer) (&amd64->guest_YMM10[4], buf, dir, size, mod); break;
+ case 69: VG_(transfer) (&amd64->guest_YMM11[4], buf, dir, size, mod); break;
+ case 70: VG_(transfer) (&amd64->guest_YMM12[4], buf, dir, size, mod); break;
+ case 71: VG_(transfer) (&amd64->guest_YMM13[4], buf, dir, size, mod); break;
+ case 72: VG_(transfer) (&amd64->guest_YMM14[4], buf, dir, size, mod); break;
+ case 73: VG_(transfer) (&amd64->guest_YMM15[4], buf, dir, size, mod); break;
default: vg_assert(0);
}
}
+static
+Bool have_avx(void)
+{
+ VexArch va;
+ VexArchInfo vai;
+ VG_(machine_get_VexArchInfo) (&va, &vai);
+ return (vai.hwcaps & VEX_HWCAPS_AMD64_AVX ? True : False);
+}
+static
+char* target_xml (Bool shadow_mode)
+{
+ if (shadow_mode) {
+#if defined(VGO_linux)
+ if (have_avx())
+ return "amd64-avx-linux-valgrind.xml";
+ else
+ return "amd64-linux-valgrind.xml";
+#else
+ if (have_avx())
+ return "amd64-avx-coresse-valgrind.xml";
+ else
+ return "amd64-coresse-valgrind.xml";
+#endif
+ } else {
+#if defined(VGO_linux)
+ if (have_avx())
+ return "amd64-avx-linux.xml";
+ else
+ return NULL;
+#else
+ if (have_avx())
+ return "amd64-avx-coresse.xml";
+ else
+ return NULL;
+#endif
+ }
+}
+
static struct valgrind_target_ops low_target = {
- num_regs,
+ -1, // Must be computed at init time.
regs,
7, //RSP
transfer_register,
get_pc,
set_pc,
"amd64",
- NULL, // target_xml not needed.
-#if defined(VGO_linux)
- "amd64-linux-valgrind.xml"
-#else
- "amd64-coresse-valgrind.xml"
-#endif
+ target_xml
};
void amd64_init_architecture (struct valgrind_target_ops *target)
{
*target = low_target;
- set_register_cache (regs, num_regs);
+ if (have_avx())
+ dyn_num_regs = max_num_regs;
+ else
+ dyn_num_regs = max_num_regs - 16; // remove the AVX "high" registers.
+ target->num_regs = dyn_num_regs;
+ set_register_cache (regs, dyn_num_regs);
gdbserver_expedite_regs = expedite_regs;
}
}
}
+static
+char* target_xml (Bool shadow_mode)
+{
+ if (shadow_mode) {
+ return "arm-with-vfpv3-valgrind.xml";
+ } else {
+ return "arm-with-vfpv3.xml";
+ }
+}
+
static struct valgrind_target_ops low_target = {
num_regs,
regs,
get_pc,
set_pc,
"arm",
- "arm-with-vfpv3.xml",
- "arm-with-vfpv3-valgrind.xml"
+ target_xml
};
void arm_init_architecture (struct valgrind_target_ops *target)
}
}
+static
+char* target_xml (Bool shadow_mode)
+{
+ if (shadow_mode) {
+ return "powerpc-altivec32l-valgrind.xml";
+ } else {
+ return "powerpc-altivec32l.xml";
+ }
+}
+
static struct valgrind_target_ops low_target = {
num_regs,
regs,
get_pc,
set_pc,
"ppc32",
- "powerpc-altivec32l.xml",
- "powerpc-altivec32l-valgrind.xml"
+ target_xml
};
void ppc32_init_architecture (struct valgrind_target_ops *target)
}
}
+static
+char* target_xml (Bool shadow_mode)
+{
+ if (shadow_mode) {
+ return "powerpc-altivec64l-valgrind.xml";
+ } else {
+ return "powerpc-altivec64l.xml";
+ }
+}
+
static struct valgrind_target_ops low_target = {
num_regs,
regs,
get_pc,
set_pc,
"ppc64",
- "powerpc-altivec64l.xml",
- "powerpc-altivec64l-valgrind.xml"
+ target_xml
};
void ppc64_init_architecture (struct valgrind_target_ops *target)
}
}
+static
+char* target_xml (Bool shadow_mode)
+{
+ if (shadow_mode) {
+ return "s390x-generic-valgrind.xml";
+ } else {
+ return "s390x-generic.xml";
+ }
+}
+
static struct valgrind_target_ops low_target = {
num_regs,
regs,
get_pc,
set_pc,
"s390x",
- "s390x-generic.xml",
- "s390x-generic-valgrind.xml"
+ target_xml
};
void s390x_init_architecture (struct valgrind_target_ops *target)
}
}
+static
+char* target_xml (Bool shadow_mode)
+{
+ if (shadow_mode) {
+#if defined(VGO_linux)
+ return "i386-linux-valgrind.xml";
+#else
+ return "i386-coresse-valgrind.xml";
+#endif
+ } else {
+ return NULL;
+ }
+}
+
static struct valgrind_target_ops low_target = {
num_regs,
regs,
get_pc,
set_pc,
"i386",
- NULL, // target_xml not needed.
-#if defined(VGO_linux)
- "i386-linux-valgrind.xml"
-#else
- "i386-coresse-valgrind.xml"
-#endif
+ target_xml
};
void x86_init_architecture (struct valgrind_target_ops *target)
or NULL not to answer. */
const char *arch_string;
- /* Description of the set of registers.
+ /* Returns the target xml description of the set of registers.
For some architectures (e.g. arm), it is mandatory
to give a description of the registers, otherwise
gdb does not understand the reply to the 'g' packet
- (which is used to get the registers). */
- const char *target_xml;
+ (which is used to get the registers).
+ If shadow_mode, returns a target xml description
+ including the two shadow registers sets.
+ This is mandatory to use the option --vgdb-shadow-registers=yes.
+ Returns NULL if there is no target xml file*/
+ char* (*target_xml) (Bool shadow_mode);
- /* Same as target_xml, but describes also the two shadow
- registers set.
- This is mandatory to use the option --vgdb-shadow-registers=yes. */
- const char *shadow_target_xml;
};
extern void x86_init_architecture (struct valgrind_target_ops *target);
values instead of float values, as it is expected that these
shadow values are mostly used for memcheck validity bits. </para>
+<para>Intel/amd64 AVX registers <computeroutput>ymm0</computeroutput>
+to <computeroutput>ymm15</computeroutput> have also their shadow
+registers. However, GDB presents the shadow values using two
+"half" registers. For example, the half shadow registers for
+<computeroutput>ymm9</computeroutput> are
+<computeroutput>xmm9s1</computeroutput> (lower half for set 1),
+<computeroutput>ymm9hs1</computeroutput> (upper half for set 1),
+<computeroutput>xmm9s2</computeroutput> (lower half for set 2),
+<computeroutput>ymm9hs2</computeroutput> (upper half for set 2).
+Note the inconsistent notation for the names of the half registers:
+the lower part starts with an <computeroutput>x</computeroutput>,
+the upper part starts with an <computeroutput>y</computeroutput>
+and has an <computeroutput>h</computeroutput> before the shadow postfix.
+</para>
+<para>The special presentation of the AVX shadow registers is due
+to the fact that GDB retrieves independently the lower and upper half
+of the <computeroutput>ymm</computeroutput> registers. GDB however
+does not know that the shadow half registers have to be shown combined.
+</para>
</sect2>