run: $(TARGET)
./$(TARGET)
-.PHONY: blowfish.h
-blowfish.h:
- rm -f blowfish.bin
- XEN_TARGET_ARCH=x86_32 make -f blowfish.mk all
- (echo "static unsigned int blowfish32_code[] = {"; \
- od -v -t x blowfish.bin | sed 's/^[0-9]* /0x/' | sed 's/ /, 0x/g' | sed 's/$$/,/';\
- echo "};") >$@
- rm -f blowfish.bin
-ifeq ($(XEN_COMPILE_ARCH),x86_64)
- XEN_TARGET_ARCH=x86_64 make -f blowfish.mk all
- (echo "static unsigned int blowfish64_code[] = {"; \
- od -v -t x blowfish.bin | sed 's/^[0-9]* /0x/' | sed 's/ /, 0x/g' | sed 's/$$/,/';\
- echo "};") >>$@
- rm -f blowfish.bin
-endif
+cflags-x86_32 := "-mno-accumulate-outgoing-args -Dstatic="
+
+blowfish.h: blowfish.c blowfish.mk Makefile
+ rm -f $@.new blowfish.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; \
+ 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 "};") >>$@.new; \
+ rm -f blowfish.bin; \
+ done; \
+ )
+ mv $@.new $@
$(TARGET): x86_emulate.o test_x86_emulator.o
$(HOSTCC) -o $@ $^
$(call cc-options-add,CFLAGS,CC,$(EMBEDDED_EXTRA_CFLAGS))
-CFLAGS += -fno-builtin -msoft-float
+CFLAGS += -fno-builtin -msoft-float $(BLOWFISH_CFLAGS)
.PHONY: all
all: blowfish.bin
#include <errno.h>
+#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "x86_emulate/x86_emulate.h"
#include "blowfish.h"
+static const struct {
+ const void *code;
+ size_t size;
+ unsigned int bitness;
+ const char*name;
+} 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)" },
+#ifdef __x86_64__
+ { blowfish_x86_64, sizeof(blowfish_x86_64), 64, "blowfish" },
+#endif
+};
+
#define MMAP_SZ 16384
/* EFLAGS bit definitions. */
else
printf("skipped\n");
- for ( j = 1; j <= 2; j++ )
+ for ( j = 0; j < sizeof(blobs) / sizeof(*blobs); j++ )
{
-#if defined(__i386__)
- if ( j == 2 ) break;
- memcpy(res, blowfish32_code, sizeof(blowfish32_code));
-#else
- ctxt.addr_size = 16 << j;
- ctxt.sp_size = 16 << j;
- memcpy(res, (j == 1) ? blowfish32_code : blowfish64_code,
- (j == 1) ? sizeof(blowfish32_code) : sizeof(blowfish64_code));
-#endif
- printf("Testing blowfish %u-bit code sequence", j*32);
+ memcpy(res, blobs[j].code, blobs[j].size);
+ ctxt.addr_size = ctxt.sp_size = blobs[j].bitness;
+
+ printf("Testing %s %u-bit code sequence",
+ blobs[j].name, ctxt.addr_size);
regs.eax = 2;
regs.edx = 1;
regs.eip = (unsigned long)res;
regs.esp = (unsigned long)res + MMAP_SZ - 4;
- if ( j == 2 )
+ if ( ctxt.addr_size == 64 )
{
- ctxt.addr_size = ctxt.sp_size = 64;
*(uint32_t *)(unsigned long)regs.esp = 0;
regs.esp -= 4;
}
(regs.eax != 2) || (regs.edx != 1) )
goto fail;
printf("okay\n");
- }
- printf("%-40s", "Testing blowfish native execution...");
- asm volatile (
+ 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"
+ "movl $0x100000,%%ecx; call *%%ecx"
#else
- "movl $0x100000,%%ecx; call *%%rcx"
+ "movl $0x100000,%%ecx; call *%%rcx"
#endif
- : "=a" (regs.eax), "=d" (regs.edx)
- : "0" (2), "1" (1) : "ecx" );
- if ( (regs.eax != 2) || (regs.edx != 1) )
- goto fail;
- printf("okay\n");
+ : "=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;
ImplicitOps, ImplicitOps, DstReg|SrcMem|ModRM, DstReg|SrcNone|ModRM|Mov,
0, 0, 0, 0,
/* 0x68 - 0x6F */
- ImplicitOps|Mov, DstReg|SrcImm|ModRM|Mov,
- ImplicitOps|Mov, DstReg|SrcImmByte|ModRM|Mov,
+ DstImplicit|SrcImm|Mov, DstReg|SrcImm|ModRM|Mov,
+ DstImplicit|SrcImmByte|Mov, DstReg|SrcImmByte|ModRM|Mov,
ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov,
/* 0x70 - 0x77 */
ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
break;
case 0x68: /* push imm{16,32,64} */
- src.val = ((op_bytes == 2)
- ? (int32_t)insn_fetch_type(int16_t)
- : insn_fetch_type(int32_t));
- goto push;
+ case 0x6a: /* push imm8 */
+ push:
+ d |= Mov; /* force writeback */
+ dst.type = OP_MEM;
+ dst.bytes = mode_64bit() && (op_bytes == 4) ? 8 : op_bytes;
+ dst.val = src.val;
+ dst.mem.seg = x86_seg_ss;
+ dst.mem.off = sp_pre_dec(dst.bytes);
+ break;
case 0x69: /* imul imm16/32 */
case 0x6b: /* imul imm8 */
goto done;
goto imul;
- case 0x6a: /* push imm8 */
- src.val = insn_fetch_type(int8_t);
- push:
- d |= Mov; /* force writeback */
- dst.type = OP_MEM;
- dst.bytes = op_bytes;
- if ( mode_64bit() && (dst.bytes == 4) )
- dst.bytes = 8;
- dst.val = src.val;
- dst.mem.seg = x86_seg_ss;
- dst.mem.off = sp_pre_dec(dst.bytes);
- break;
-
case 0x6c ... 0x6d: /* ins %dx,%es:%edi */ {
unsigned long nr_reps = get_rep_prefix();
unsigned int port = (uint16_t)_regs.edx;