将libvex移植到Visual Studio编译平台下的经验总结
1. 两难
将libvex从Linux移植到Windows,移植工作聚集于Cross-Compiler,而不是预料的Cross-Platform。
VC++ Compiler到目前为止只支持C89标准,而这个标准规定,变量必须在代码块(即通过大括号包围起来的代码块)的最前面声明,参考
可以将*.c改成*.cpp,但是新的问题又出现了,在C代码中的类型转换是不需要显式写明的,但是C++却不允许这样做。
因此,在下面的选项之间两难:
1. 维持原来的*.c代码,将没有在代码块头部声明的变量,都移到代码块头部声明;
2. 修改为*.cpp代码,显式添加所有的类型转换;
二者都是很枯燥的工作,我最后选择的后者。
2. 怎样通过预定义的宏来判断当前的编译器是不是VC++
#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_COMPILER VexGuestLayout 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) } }; #else VexGuestLayout 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));