|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 10/11] x86emul/test: split generic and testcase specific parts
Both the build logic and the invocation have their blowfish specific
aspects abstracted out here. Additionally
- run native execution (if suitable) first (as that one failing
suggests a problem with the to be tested code itself, in which case
having the emulator have a go over it is kind of pointless)
- move the 64-bit tests up in blobs[] so 64-bit native execution will
also precede 32-bit emulation (on 64-bit systems only of course)
- instead of -msoft-float (we'd rather not have the compiler generate
such code), pass -fno-asynchronous-unwind-tables and -g0 (reducing
binary size of the helper images as well as [slightly] compilation
time)
- skip tests with zero length blobs (these can result from failed
compilation, but not failing the build in this case seems desirable:
it may allow partial testing - e.g. with older compilers - and
permits manually removing certain tests from the generated headers
without having to touch actual source code)
- constrain rIP to the actual blob range rather than looking for the
specific (fake) return address put on the stack
- also print the opcode when x86_emulate() fails
- print at least three progress dots (for relatively short tests)
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
v2: New.
--- a/tools/tests/x86_emulator/Makefile
+++ b/tools/tests/x86_emulator/Makefile
@@ -11,18 +11,21 @@ all: $(TARGET)
run: $(TARGET)
./$(TARGET)
-cflags-x86_32 := "-mno-accumulate-outgoing-args -Dstatic="
+TESTCASES := blowfish
-blowfish.h: blowfish.c blowfish.mk Makefile
- rm -f $@.new blowfish.bin
+blowfish-cflags := ""
+blowfish-cflags-x86_32 := "-mno-accumulate-outgoing-args -Dstatic="
+
+$(addsuffix .h,$(TESTCASES)): %.h: %.c testcase.mk Makefile
+ rm -f $@.new $*.bin
$(foreach arch,$(filter-out $(XEN_COMPILE_ARCH),x86_32)
$(XEN_COMPILE_ARCH), \
- for cflags in "" $(cflags-$(arch)); do \
- $(MAKE) -f blowfish.mk XEN_TARGET_ARCH=$(arch)
BLOWFISH_CFLAGS="$$cflags" all; \
+ for cflags in $($*-cflags) $($*-cflags-$(arch)); do \
+ $(MAKE) -f testcase.mk TESTCASE=$* XEN_TARGET_ARCH=$(arch)
$*-cflags="$$cflags" all; \
flavor=$$(echo $${cflags} | sed -e 's, .*,,' -e 'y,-=,__,') ; \
- (echo "static unsigned int blowfish_$(arch)$${flavor}[] = {"; \
- od -v -t x blowfish.bin | sed -e 's/^[0-9]* /0x/' -e 's/ /,
0x/g' -e 's/$$/,/'; \
+ (echo "static const unsigned int $*_$(arch)$${flavor}[] = {"; \
+ od -v -t x $*.bin | sed -e 's/^[0-9]* /0x/' -e 's/ /, 0x/g' -e
's/$$/,/'; \
echo "};") >>$@.new; \
- rm -f blowfish.bin; \
+ rm -f $*.bin; \
done; \
)
mv $@.new $@
@@ -32,7 +35,7 @@ $(TARGET): x86_emulate.o test_x86_emulat
.PHONY: clean
clean:
- rm -rf $(TARGET) *.o *~ core blowfish.h blowfish.bin x86_emulate
+ rm -rf $(TARGET) *.o *~ core $(addsuffix .h,$(TESTCASES)) *.bin
x86_emulate
.PHONY: distclean
distclean: clean
@@ -48,5 +51,5 @@ HOSTCFLAGS += $(CFLAGS_xeninclude)
x86_emulate.o: x86_emulate.c x86_emulate/x86_emulate.c
x86_emulate/x86_emulate.h
$(HOSTCC) $(HOSTCFLAGS) -D__XEN_TOOLS__ -c -g -o $@ $<
-test_x86_emulator.o: test_x86_emulator.c blowfish.h x86_emulate/x86_emulate.h
+test_x86_emulator.o: test_x86_emulator.c $(addsuffix .h,$(TESTCASES))
x86_emulate/x86_emulate.h
$(HOSTCC) $(HOSTCFLAGS) -c -g -o $@ $<
--- a/tools/tests/x86_emulator/blowfish.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-
-XEN_ROOT = $(CURDIR)/../../..
-CFLAGS =
-include $(XEN_ROOT)/tools/Rules.mk
-
-$(call cc-options-add,CFLAGS,CC,$(EMBEDDED_EXTRA_CFLAGS))
-
-CFLAGS += -fno-builtin -msoft-float $(BLOWFISH_CFLAGS)
-
-.PHONY: all
-all: blowfish.bin
-
-blowfish.bin: blowfish.c
- $(CC) $(CFLAGS) -c blowfish.c
- $(LD) $(LDFLAGS_DIRECT) -N -Ttext 0x100000 -o blowfish.tmp blowfish.o
- $(OBJCOPY) -O binary blowfish.tmp blowfish.bin
- rm -f blowfish.tmp
--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -8,19 +8,37 @@
#define verbose false /* Switch to true for far more logging. */
+static void blowfish_set_regs(struct cpu_user_regs *regs)
+{
+ regs->eax = 2;
+ regs->edx = 1;
+}
+
+static bool blowfish_check_regs(const struct cpu_user_regs *regs)
+{
+ return regs->eax == 2 && regs->edx == 1;
+}
+
static const struct {
const void *code;
size_t size;
unsigned int bitness;
const char*name;
+ void (*set_regs)(struct cpu_user_regs *);
+ bool (*check_regs)(const struct cpu_user_regs *);
} blobs[] = {
- { blowfish_x86_32, sizeof(blowfish_x86_32), 32, "blowfish" },
- { blowfish_x86_32_mno_accumulate_outgoing_args,
- sizeof(blowfish_x86_32_mno_accumulate_outgoing_args),
- 32, "blowfish (push)" },
+#define BLOWFISH(bits, desc, tag) \
+ { .code = blowfish_x86_##bits##tag, \
+ .size = sizeof(blowfish_x86_##bits##tag), \
+ .bitness = bits, .name = #desc, \
+ .set_regs = blowfish_set_regs, \
+ .check_regs = blowfish_check_regs }
#ifdef __x86_64__
- { blowfish_x86_64, sizeof(blowfish_x86_64), 64, "blowfish" },
+ BLOWFISH(64, blowfish, ),
#endif
+ BLOWFISH(32, blowfish, ),
+ BLOWFISH(32, blowfish (push), _mno_accumulate_outgoing_args),
+#undef BLOWFISH
};
/* EFLAGS bit definitions. */
@@ -2574,13 +2592,40 @@ int main(int argc, char **argv)
for ( j = 0; j < ARRAY_SIZE(blobs); j++ )
{
+ if ( !blobs[j].size )
+ {
+ printf("%-39s n/a\n", blobs[j].name);
+ continue;
+ }
+
memcpy(res, blobs[j].code, blobs[j].size);
ctxt.addr_size = ctxt.sp_size = blobs[j].bitness;
+ if ( ctxt.addr_size == sizeof(void *) * CHAR_BIT )
+ {
+ i = printf("Testing %s native execution...", blobs[j].name);
+ if ( blobs[j].set_regs )
+ blobs[j].set_regs(®s);
+ asm volatile (
+#if defined(__i386__)
+ "call *%%ecx"
+#else
+ "call *%%rcx"
+#endif
+ : "+a" (regs.eax), "+d" (regs.edx) : "c" (res)
+#ifdef __x86_64__
+ : "rsi", "rdi", "r8", "r9", "r10", "r11"
+#endif
+ );
+ if ( !blobs[j].check_regs(®s) )
+ goto fail;
+ printf("%*sokay\n", i < 40 ? 40 - i : 0, "");
+ }
+
printf("Testing %s %u-bit code sequence",
blobs[j].name, ctxt.addr_size);
- regs.eax = 2;
- regs.edx = 1;
+ if ( blobs[j].set_regs )
+ blobs[j].set_regs(®s);
regs.eip = (unsigned long)res;
regs.esp = (unsigned long)res + MMAP_SZ - 4;
if ( ctxt.addr_size == 64 )
@@ -2591,41 +2636,26 @@ int main(int argc, char **argv)
*(uint32_t *)(unsigned long)regs.esp = 0x12345678;
regs.eflags = 2;
i = 0;
- while ( regs.eip != 0x12345678 )
+ while ( regs.eip >= (unsigned long)res &&
+ regs.eip < (unsigned long)res + blobs[j].size )
{
if ( (i++ & 8191) == 0 )
printf(".");
rc = x86_emulate(&ctxt, &emulops);
if ( rc != X86EMUL_OKAY )
{
- printf("failed at %%eip == %08x\n", (unsigned int)regs.eip);
+ printf("failed at %%eip == %08lx (opcode %08x)\n",
+ (unsigned long)regs.eip, ctxt.opcode);
return 1;
}
}
- if ( (regs.esp != ((unsigned long)res + MMAP_SZ)) ||
- (regs.eax != 2) || (regs.edx != 1) )
+ for ( ; i < 2 * 8192; i += 8192 )
+ printf(".");
+ if ( (regs.eip != 0x12345678) ||
+ (regs.esp != ((unsigned long)res + MMAP_SZ)) ||
+ !blobs[j].check_regs(®s) )
goto fail;
printf("okay\n");
-
- if ( ctxt.addr_size != sizeof(void *) * CHAR_BIT )
- continue;
-
- i = printf("Testing %s native execution...", blobs[j].name);
- asm volatile (
-#if defined(__i386__)
- "movl $0x100000,%%ecx; call *%%ecx"
-#else
- "movl $0x100000,%%ecx; call *%%rcx"
-#endif
- : "=a" (regs.eax), "=d" (regs.edx)
- : "0" (2), "1" (1) : "ecx"
-#ifdef __x86_64__
- , "rsi", "rdi", "r8", "r9", "r10", "r11"
-#endif
- );
- if ( (regs.eax != 2) || (regs.edx != 1) )
- goto fail;
- printf("%*sokay\n", i < 40 ? 40 - i : 0, "");
}
return 0;
--- /dev/null
+++ b/tools/tests/x86_emulator/testcase.mk
@@ -0,0 +1,16 @@
+XEN_ROOT = $(CURDIR)/../../..
+CFLAGS :=
+include $(XEN_ROOT)/tools/Rules.mk
+
+$(call cc-options-add,CFLAGS,CC,$(EMBEDDED_EXTRA_CFLAGS))
+
+CFLAGS += -fno-builtin -fno-asynchronous-unwind-tables -g0
$($(TESTCASE)-cflags)
+
+.PHONY: all
+all: $(TESTCASE).bin
+
+%.bin: %.c
+ $(CC) $(filter-out -M% .%,$(CFLAGS)) -c $<
+ $(LD) $(LDFLAGS_DIRECT) -N -Ttext 0x100000 -o $*.tmp $*.o
+ $(OBJCOPY) -O binary $*.tmp $@
+ rm -f $*.tmp
Attachment:
x86emul-test-blowfish-generalize.patch _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |