diff --git a/.gitignore b/.gitignore index 58f71736..aec6d46c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ *.so *.so.* *.exe +*.dll qemu/config-all-devices.mak diff --git a/COMPILE.TXT b/COMPILE.TXT index baafd8fc..e5abd6af 100644 --- a/COMPILE.TXT +++ b/COMPILE.TXT @@ -62,6 +62,11 @@ Unicorn requires few dependent packages as follows. $ pacman -S mingw-w64-x86_64-glib2 $ pacman -S mingw-w64-x86_64-toolchain +- For Cygwin, "make", "gcc-core", "pkg-config", "libpcre-devel", "zlib-devel" and "libglib2.0-devel" are needed. + If apt-cyg is available, you can install these with: + + $ apt-cyg install make gcc-core pkg-config libpcre-devel zlib-devel libglib2.0-devel + [1] Tailor Unicorn to your need. @@ -172,7 +177,30 @@ Unicorn requires few dependent packages as follows. -[4] Cross-compile for Windows from *nix +[4] Compile and install from source on Cygwin + + To build Unicorn on Cygwin, run: + + $ ./make.sh + + After compiling, install Unicorn with: + + $ ./make.sh install + + Resulted files cygunicorn.dll, libunicorn.dll.a and libunicorn.a can be + used on Cygwin but not native Windows. + + NOTE: The core framework installed by "./make.sh install" consist of + following files: + + /usr/include/unicorn/*.h + /usr/bin/cygunicorn.dll + /usr/lib/libunicorn.dll.a + /usr/lib/libunicorn.a + + + +[5] Cross-compile for Windows from *nix To cross-compile for Windows, Linux & gcc-mingw-w64-i686 (and also gcc-mingw-w64-x86-64 for 64-bit binaries) are required. @@ -205,7 +233,7 @@ Unicorn requires few dependent packages as follows. -[5] Cross-compile for iOS from Mac OSX. +[6] Cross-compile for iOS from Mac OSX. To cross-compile for iOS (iPhone/iPad/iPod), Mac OSX with XCode installed is required. @@ -226,7 +254,7 @@ Unicorn requires few dependent packages as follows. -[6] Cross-compile for Android +[7] Cross-compile for Android To cross-compile for Android (smartphone/tablet), Android NDK is required. NOTE: Only ARM and ARM64 are currently supported. @@ -240,7 +268,7 @@ Unicorn requires few dependent packages as follows. -[7] By default, "cc" (default C compiler on the system) is used as compiler. +[8] By default, "cc" (default C compiler on the system) is used as compiler. - To use "clang" compiler instead, run the command below: @@ -252,20 +280,20 @@ Unicorn requires few dependent packages as follows. -[8] To uninstall Unicorn, run the command below: +[9] To uninstall Unicorn, run the command below: $ sudo ./make.sh uninstall -[9] Language bindings +[10] Language bindings Look for the bindings under directory bindings/, and refer to README file of corresponding languages. -[10] Unit tests +[11] Unit tests Automated unit tests use the cmocka unit testing framework (https://cmocka.org/). It can be installed in most Linux distros using the package manager, e.g. diff --git a/Makefile b/Makefile index 402e401c..c4f093c6 100644 --- a/Makefile +++ b/Makefile @@ -105,8 +105,10 @@ else IS_CYGWIN := $(shell $(CC) -dumpmachine | grep -i cygwin | wc -l) ifeq ($(IS_CYGWIN),1) EXT = dll -AR_EXT = lib +AR_EXT = a BIN_EXT = .exe +UNICORN_CFLAGS := $(UNICORN_CFLAGS:-fPIC=) +#UNICORN_QEMU_FLAGS += --disable-stack-protector else # mingw? IS_MINGW := $(shell $(CC) --version | grep -i mingw | wc -l) @@ -129,7 +131,10 @@ ifeq ($(UNICORN_SHARED),yes) ifeq ($(IS_MINGW),1) LIBRARY = $(BLDIR)/$(LIBNAME).$(EXT) else ifeq ($(IS_CYGWIN),1) -LIBRARY = $(BLDIR)/$(LIBNAME).$(EXT) +LIBRARY = $(BLDIR)/cyg$(LIBNAME).$(EXT) +LIBRARY_DLLA = $(BLDIR)/lib$(LIBNAME).$(EXT).$(AR_EXT) +$(LIBNAME)_LDFLAGS += -Wl,--out-implib=$(LIBRARY_DLLA) +$(LIBNAME)_LDFLAGS += -lssp else # *nix LIBRARY = $(BLDIR)/lib$(LIBNAME).$(VERSION_EXT) LIBRARY_SYMLINK = $(BLDIR)/lib$(LIBNAME).$(EXT) @@ -140,7 +145,7 @@ ifeq ($(UNICORN_STATIC),yes) ifeq ($(IS_MINGW),1) ARCHIVE = $(BLDIR)/$(LIBNAME).$(AR_EXT) else ifeq ($(IS_CYGWIN),1) -ARCHIVE = $(BLDIR)/$(LIBNAME).$(AR_EXT) +ARCHIVE = $(BLDIR)/lib$(LIBNAME).$(AR_EXT) else ARCHIVE = $(BLDIR)/lib$(LIBNAME).$(AR_EXT) endif @@ -163,6 +168,7 @@ LIBDIRARCH ?= lib LIBDIR ?= $(PREFIX)/$(LIBDIRARCH) INCDIR ?= $(PREFIX)/include +BINDIR ?= $(PREFIX)/bin LIBDATADIR ?= $(LIBDIR) @@ -188,9 +194,9 @@ all: compile_lib ifeq (,$(findstring yes,$(UNICORN_BUILD_CORE_ONLY))) ifeq ($(UNICORN_SHARED),yes) ifeq ($(V),0) - @$(INSTALL_DATA) $(LIBRARY) $(BLDIR)/samples/ + @$(INSTALL_LIB) $(LIBRARY) $(BLDIR)/samples/ else - $(INSTALL_DATA) $(LIBRARY) $(BLDIR)/samples/ + $(INSTALL_LIB) $(LIBRARY) $(BLDIR)/samples/ endif endif @@ -216,7 +222,7 @@ else endif compile_lib: config qemu/config-host.h-timestamp - rm -rf lib$(LIBNAME)* $(LIBNAME)*.lib $(LIBNAME)*.dll && cd qemu && $(MAKE) -j 8 + rm -rf lib$(LIBNAME)* $(LIBNAME)*.lib $(LIBNAME)*.dll cyg$(LIBNAME)*.dll && cd qemu && $(MAKE) -j 8 $(MAKE) unicorn cd samples && $(MAKE) clean @@ -226,9 +232,9 @@ $(LIBRARY): $(UC_TARGET_OBJ) uc.o hook.o ifeq ($(UNICORN_SHARED),yes) ifeq ($(V),0) $(call log,GEN,$(LIBRARY)) - @$(CC) $(CFLAGS) $($(LIBNAME)_LDFLAGS) -shared $^ -o $(LIBRARY) $(GLIB) -lm + @$(CC) $(CFLAGS) -shared $^ -o $(LIBRARY) $(GLIB) -lm $($(LIBNAME)_LDFLAGS) else - $(CC) $(CFLAGS) $($(LIBNAME)_LDFLAGS) -shared $^ -o $(LIBRARY) $(GLIB) -lm + $(CC) $(CFLAGS) -shared $^ -o $(LIBRARY) $(GLIB) -lm $($(LIBNAME)_LDFLAGS) endif ifneq (,$(LIBRARY_SYMLINK)) @ln -sf $(LIBRARY) $(LIBRARY_SYMLINK) @@ -261,21 +267,26 @@ test: all install: all $(PKGCFGF) - mkdir -p $(DESTDIR)/$(LIBDIR) + mkdir -p $(DESTDIR)$(LIBDIR) ifeq ($(UNICORN_SHARED),yes) - $(INSTALL_LIB) $(LIBRARY) $(DESTDIR)/$(LIBDIR) +ifeq ($(IS_CYGWIN),1) + $(INSTALL_LIB) $(LIBRARY) $(DESTDIR)$(BINDIR) + $(INSTALL_DATA) $(LIBRARY_DLLA) $(DESTDIR)$(LIBDIR) +else + $(INSTALL_LIB) $(LIBRARY) $(DESTDIR)$(LIBDIR) +endif ifneq ($(VERSION_EXT),) - cd $(DESTDIR)/$(LIBDIR) && \ + cd $(DESTDIR)$(LIBDIR) && \ ln -sf lib$(LIBNAME).$(VERSION_EXT) lib$(LIBNAME).$(EXT) endif endif ifeq ($(UNICORN_STATIC),yes) - $(INSTALL_DATA) $(ARCHIVE) $(DESTDIR)/$(LIBDIR) + $(INSTALL_DATA) $(ARCHIVE) $(DESTDIR)$(LIBDIR) endif - mkdir -p $(DESTDIR)/$(INCDIR)/$(LIBNAME) - $(INSTALL_DATA) include/unicorn/*.h $(DESTDIR)/$(INCDIR)/$(LIBNAME) - mkdir -p $(DESTDIR)/$(PKGCFGDIR) - $(INSTALL_DATA) $(PKGCFGF) $(DESTDIR)/$(PKGCFGDIR)/ + mkdir -p $(DESTDIR)$(INCDIR)/$(LIBNAME) + $(INSTALL_DATA) include/unicorn/*.h $(DESTDIR)$(INCDIR)/$(LIBNAME) + mkdir -p $(DESTDIR)$(PKGCFGDIR) + $(INSTALL_DATA) $(PKGCFGF) $(DESTDIR)$(PKGCFGDIR)/ TAG ?= HEAD @@ -301,13 +312,14 @@ header: FORCE uninstall: rm -rf $(INCDIR)/$(LIBNAME) rm -f $(LIBDIR)/lib$(LIBNAME).* + rm -f $(BINDIR)/cyg$(LIBNAME).* rm -f $(PKGCFGDIR)/$(LIBNAME).pc clean: $(MAKE) -C qemu clean rm -rf *.d *.o - rm -rf lib$(LIBNAME)* $(LIBNAME)*.lib $(LIBNAME)*.dll + rm -rf lib$(LIBNAME)* $(LIBNAME)*.lib $(LIBNAME)*.dll cyg$(LIBNAME)*.dll ifeq (,$(findstring yes,$(UNICORN_BUILD_CORE_ONLY))) cd samples && $(MAKE) clean rm -f $(BLDIR)/samples/lib$(LIBNAME).$(EXT) diff --git a/qemu/configure b/qemu/configure index c1c6d52e..7f6d9164 100755 --- a/qemu/configure +++ b/qemu/configure @@ -432,8 +432,7 @@ HOST_VARIANT_DIR="" case $targetos in CYGWIN*) - mingw32="yes" - QEMU_CFLAGS="-mno-cygwin $QEMU_CFLAGS" + linux="yes" ;; MINGW32*) mingw32="yes" diff --git a/qemu/tcg/i386/tcg-target.c b/qemu/tcg/i386/tcg-target.c index cc086497..ecf7615b 100644 --- a/qemu/tcg/i386/tcg-target.c +++ b/qemu/tcg/i386/tcg-target.c @@ -65,7 +65,7 @@ static const int tcg_target_reg_alloc_order[] = { static const int tcg_target_call_iarg_regs[] = { #if TCG_TARGET_REG_BITS == 64 -#if defined(_WIN64) +#if (defined(_WIN64)||defined(__CYGWIN__)) TCG_REG_RCX, TCG_REG_RDX, #else @@ -2191,7 +2191,7 @@ static int tcg_target_callee_save_regs[] = { #if TCG_TARGET_REG_BITS == 64 TCG_REG_RBP, TCG_REG_RBX, -#if defined(_WIN64) +#if (defined(_WIN64)||defined(__CYGWIN__)) TCG_REG_RDI, TCG_REG_RSI, #endif @@ -2316,7 +2316,7 @@ static void tcg_target_init(TCGContext *s) tcg_regset_set_reg(s->tcg_target_call_clobber_regs, TCG_REG_EDX); tcg_regset_set_reg(s->tcg_target_call_clobber_regs, TCG_REG_ECX); if (TCG_TARGET_REG_BITS == 64) { -#if !defined(_WIN64) +#if !(defined(_WIN64)||defined(__CYGWIN__)) tcg_regset_set_reg(s->tcg_target_call_clobber_regs, TCG_REG_RDI); tcg_regset_set_reg(s->tcg_target_call_clobber_regs, TCG_REG_RSI); #endif diff --git a/qemu/tcg/i386/tcg-target.h b/qemu/tcg/i386/tcg-target.h index 7a9980e7..7d350d90 100644 --- a/qemu/tcg/i386/tcg-target.h +++ b/qemu/tcg/i386/tcg-target.h @@ -67,7 +67,7 @@ typedef enum { /* used for function call generation */ #define TCG_REG_CALL_STACK TCG_REG_ESP #define TCG_TARGET_STACK_ALIGN 16 -#if defined(_WIN64) +#if defined(_WIN64) || (defined(__CYGWIN__)&&defined(__x86_64__)) #define TCG_TARGET_CALL_STACK_OFFSET 32 #else #define TCG_TARGET_CALL_STACK_OFFSET 0 diff --git a/qemu/util/oslib-posix.c b/qemu/util/oslib-posix.c index ac54f43e..c936b6e9 100644 --- a/qemu/util/oslib-posix.c +++ b/qemu/util/oslib-posix.c @@ -61,7 +61,9 @@ extern int daemon(int, int); #include #ifdef CONFIG_LINUX +#if !defined(__CYGWIN__) #include +#endif #include #endif diff --git a/samples/Makefile b/samples/Makefile index 6f8c456b..0904512a 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -48,8 +48,10 @@ AR_EXT = a IS_CYGWIN := $(shell $(CC) -dumpmachine | grep -i cygwin | wc -l) ifeq ($(IS_CYGWIN),1) CFLAGS := $(CFLAGS:-fPIC=) +LDFLAGS += -lssp +LDFLAGS_STATIC += -lssp BIN_EXT = .exe -AR_EXT = lib +AR_EXT = a else # mingw? IS_MINGW := $(shell $(CC) --version | grep -i mingw | wc -l) @@ -64,7 +66,7 @@ ifeq ($(UNICORN_STATIC),yes) ifeq ($(IS_MINGW),1) ARCHIVE = $(LIBDIR)/$(LIBNAME).$(AR_EXT) else ifeq ($(IS_CYGWIN),1) -ARCHIVE = $(LIBDIR)/$(LIBNAME).$(AR_EXT) +ARCHIVE = $(LIBDIR)/lib$(LIBNAME).$(AR_EXT) else ARCHIVE = $(LIBDIR)/lib$(LIBNAME).$(AR_EXT) #ARCHIVE_X86 = $(LIBDIR)/lib$(LIBNAME)_x86.$(AR_EXT)