首页 > 代码库 > 将libvex移植到Visual Studio编译平台下的经验总结

将libvex移植到Visual Studio编译平台下的经验总结

1. 两难

将libvex从Linux移植到Windows,移植工作聚集于Cross-Compiler,而不是预料的Cross-Platform。

 

VC++ Compiler到目前为止只支持C89标准,而这个标准规定,变量必须在代码块(即通过大括号包围起来的代码块)的最前面声明,参考

http://stackoverflow.com/questions/13308944/how-to-simulate-c99-in-visual-studio-for-variables-declaration

可以将*.c改成*.cpp,但是新的问题又出现了,在C代码中的类型转换是不需要显式写明的,但是C++却不允许这样做。

 

因此,在下面的选项之间两难:

1. 维持原来的*.c代码,将没有在代码块头部声明的变量,都移到代码块头部声明;

2. 修改为*.cpp代码,显式添加所有的类型转换;

 

二者都是很枯燥的工作,我最后选择的后者。

 

2. 怎样通过预定义的宏来判断当前的编译器是不是VC++

 参考:http://stackoverflow.com/questions/5850358/is-there-a-preprocessor-define-that-is-defined-if-the-compiler-is-msvc

#if _MSC_VER && !__INTEL_COMPILER#else#endif

  

3. 需要做哪些移植修改

1. 带变长参数的宏

Gcc支持带变长参数的宏,就如printf一样;但VC++不支持;

修改方法:

#if _MSC_VER && !__INTEL_COMPILER#define DIP vex_printf#define DIS vex_sprintf#else#define DIP(format, args...)           	if (vex_traceflags & VEX_TRACE_FE)  	vex_printf(format, ## args)#define DIS(buf, format, args...)      	if (vex_traceflags & VEX_TRACE_FE)  	vex_sprintf(buf, format, ## args)#endif

  

2. 带自动补全中间值的case项目

Gcc支持自动补全范围的case项目,但是VC++不支持

修改方法:

//case 0xC0 ... 0xC7: /* FADD %st(?),%st(0) */			case 0xC0:			case 0xC1:			case 0xC2:			case 0xC3:			case 0xC4:			case 0xC5:			case 0xC6:			case 0xC7:

  

3. 数据结构成员的初始化

C支持,C++不支持

修改方法:

#if _MSC_VER && !__INTEL_COMPILERVexGuestLayout   armGuest_layout       = {           /* Total size of the guest state, in bytes. */          sizeof(VexGuestARMState),          /* Describe the stack pointer. */          offsetof(VexGuestARMState,guest_R13),          4,		  0,		  0,          /* Describe the instruction pointer. */          offsetof(VexGuestARMState,guest_R15T),          4,          /* Describe any sections to be regarded by Memcheck as             ‘always-defined‘. */          10,          /* flags thunk: OP is always defd, whereas DEP1 and DEP2             have to be tracked.  See detailed comment in gdefs.h on             meaning of thunk fields. */          { /* 0 */ ALWAYSDEFD(guest_R15T),                 /* 1 */ ALWAYSDEFD(guest_CC_OP),                 /* 2 */ ALWAYSDEFD(guest_CC_NDEP),                 /* 3 */ ALWAYSDEFD(guest_EMWARN),                 /* 4 */ ALWAYSDEFD(guest_TISTART),                 /* 5 */ ALWAYSDEFD(guest_TILEN),                 /* 6 */ ALWAYSDEFD(guest_NRADDR),                 /* 7 */ ALWAYSDEFD(guest_IP_AT_SYSCALL),                 /* 8 */ ALWAYSDEFD(guest_TPIDRURO),                 /* 9 */ ALWAYSDEFD(guest_ITSTATE)               }        };#elseVexGuestLayout   armGuest_layout       = {           /* Total size of the guest state, in bytes. */          .total_sizeB = sizeof(VexGuestARMState),          /* Describe the stack pointer. */          .offset_SP = offsetof(VexGuestARMState,guest_R13),          .sizeof_SP = 4,          /* Describe the instruction pointer. */          .offset_IP = offsetof(VexGuestARMState,guest_R15T),          .sizeof_IP = 4,          /* Describe any sections to be regarded by Memcheck as             ‘always-defined‘. */          .n_alwaysDefd = 10,          /* flags thunk: OP is always defd, whereas DEP1 and DEP2             have to be tracked.  See detailed comment in gdefs.h on             meaning of thunk fields. */          .alwaysDefd             = { /* 0 */ ALWAYSDEFD(guest_R15T),                 /* 1 */ ALWAYSDEFD(guest_CC_OP),                 /* 2 */ ALWAYSDEFD(guest_CC_NDEP),                 /* 3 */ ALWAYSDEFD(guest_EMWARN),                 /* 4 */ ALWAYSDEFD(guest_TISTART),                 /* 5 */ ALWAYSDEFD(guest_TILEN),                 /* 6 */ ALWAYSDEFD(guest_NRADDR),                 /* 7 */ ALWAYSDEFD(guest_IP_AT_SYSCALL),                 /* 8 */ ALWAYSDEFD(guest_TPIDRURO),                 /* 9 */ ALWAYSDEFD(guest_ITSTATE)               }        };#endif

  

4. 隐式类型转换

C支持, c++不支持

修改方法:

*arr = (HReg *)LibVEX_Alloc(*nregs * sizeof(HReg));