[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2] fuzz, test x86_emulator: disable sse before including always_inline fns



Workaround for compiler rejection of SSE-using always_inlines defined before
SSE is disabled.

Compiling with _FORTIFY_SOURCE or higher levels of optimization enabled
will always_inline several library fns (memset, memcpy, ...)
(with gcc 8.2.0 and glibc 2.28).

In fuzz and x86_emulator test, the compiler is instructed not
to generate SSE instructions via: #pragma GCC target("no-sse")
because those registers are needed for use by the workload.

The combination above causes compilation failure as the inline functions
use those instructions. This is resolved by reordering the inclusion of
<stdio.h> and <string.h> to after the pragma disabling SSE generation.

It would be preferable to locate the no-sse pragma within x86-emulate.h at the
top of the file, prior to including any other headers; unfortunately doing so
before <stdlib.h> causes compilation failure due to declaration of 'atof' with:
  "SSE register return with SSE disabled".
Fortunately there is no (known) current dependency on any always_inline
SSE-inclined function declared in <stdlib.h> or any of its dependencies, so the
pragma is therefore issued immediately after inclusion of <stdlib.h> with a
comment introduced to explain its location there.

Add compile-time checks for unwanted prior inclusion of <string.h> and
<stdio.h>, which are the two headers that provide the library functions that
are handled with wrappers and listed within "x86-emulate.h" as ones "we think
might access any of the FPU state".
* Use standard-defined "EOF" macro to detect prior <stdio.h> inclusion.
* Use "_STRING_H" (non-standardized guard macro) as best-effort
  for detection of prior <string.h> inclusion. This is non-universally
  viable but will provide error output on common GLIBC systems, so
  provides some defensive coverage.

Adds conditional #include <stdio.h> to x86-emulate.h because fwrite, printf,
etc. are referenced when WRAP has been defined.

Signed-off-by: Christopher Clark <christopher.clark6@xxxxxxxxxxxxxx>
---
Changes in v2:

* Added comment to explain the deliberate ordering of includes that might
  otherwise be believed to be incorrect.

* Added comment to explain the positioning of the no-sse pragma and the
  ordering of includes around it.

* Put the defensive header-inclusion compile-time checks right next to the
  inclusion of the headers that they are checking for.

* Narrowed the inclusion of stdio.h in x86-emulate.h to be conditional on
  WRAP being defined, since that condition determines the need to include it.
  Removed the include of stdio.h from wrappers.c as no longer required and to
  obviate the need for an explanatory comment about include ordering there.

* Use definition of 'EOF' to detect prior inclusion of <stdio.h>, since this
  is defined in the standard and increases portability to other C libraries.

* Added context information to the commit message.

 tools/fuzz/x86_instruction_emulator/fuzz-emul.c | 10 +++++++--
 tools/tests/x86_emulator/wrappers.c             |  1 -
 tools/tests/x86_emulator/x86-emulate.h          | 28 +++++++++++++++++++++++--
 3 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/tools/fuzz/x86_instruction_emulator/fuzz-emul.c 
b/tools/fuzz/x86_instruction_emulator/fuzz-emul.c
index 03a2473..0ffd0fb 100644
--- a/tools/fuzz/x86_instruction_emulator/fuzz-emul.c
+++ b/tools/fuzz/x86_instruction_emulator/fuzz-emul.c
@@ -6,9 +6,7 @@
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/mman.h>
@@ -16,6 +14,14 @@
 #include <xen/xen.h>
 
 #include "x86-emulate.h"
+/*
+ * include "x86-emulate.h" prior to <stdio.h> and <string.h>:
+ * x86-emulate.h disables use of SSE registers, while <stdio.h> and <string.h>
+ * declare functions that may be always_inline and use those registers
+ * unless they have been disabled earlier, which can fail to compile.
+ */
+#include <stdio.h>
+#include <string.h>
 #include "fuzz-emul.h"
 
 #define MSR_INDEX_MAX 16
diff --git a/tools/tests/x86_emulator/wrappers.c 
b/tools/tests/x86_emulator/wrappers.c
index d02013c..eba7cc9 100644
--- a/tools/tests/x86_emulator/wrappers.c
+++ b/tools/tests/x86_emulator/wrappers.c
@@ -1,5 +1,4 @@
 #include <stdarg.h>
-#include <stdio.h>
 
 #define WRAP(x) typeof(x) emul_##x
 #include "x86-emulate.h"
diff --git a/tools/tests/x86_emulator/x86-emulate.h 
b/tools/tests/x86_emulator/x86-emulate.h
index b249e46..07ea1e8 100644
--- a/tools/tests/x86_emulator/x86-emulate.h
+++ b/tools/tests/x86_emulator/x86-emulate.h
@@ -3,11 +3,35 @@
 #include <stddef.h>
 #include <stdint.h>
 #include <stdlib.h>
-#include <string.h>
-
+/*
+ * Use of sse registers must be disabled prior to the definition of
+ * always_inline functions that would use them (memcpy, memset, etc),
+ * so do this as early as possible, aiming to be before any always_inline
+ * functions that are used are declared.
+ * Unfortunately, this cannot be done prior to inclusion of <stdlib.h>
+ * due to functions such as 'atof' that have SSE register return declared,
+ * so do so here, immediately after that.
+ */
 #if __GNUC__ >= 6
 #pragma GCC target("no-sse")
 #endif
+ /*
+ * Attempt detection of unwanted prior inclusion of some headers known to use
+ * always_inline with SSE registers in some library / compiler / optimization
+ * combinations.
+ */
+#ifdef _STRING_H
+# error "Must not include <string.h> before x86-emulate.h"
+#endif
+#include <string.h>
+
+/* EOF is a standard macro defined in <stdio.h> so use it for detection */
+#ifdef EOF
+# error "Must not include <stdio.h> before x86-emulate.h"
+#endif
+#ifdef WRAP
+#include <stdio.h>
+#endif
 
 #include <xen/xen.h>
 
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.