将Linux C/C++应用程序从x86平台移植到IBM PowerLinux(3)
- UID
- 1029342
- 性别
- 男
|
将Linux C/C++应用程序从x86平台移植到IBM PowerLinux(3)
清单 3. 使用指令让字节顺序效果中立化
#include <stdio.h>#define BIG_ENDIAN 1#define LITTLE_ENDIAN 0#define BYTE_ORDER (( htonl(1)==1) ) // returns 1 or 0 depending on platformunion { int val; unsigned char c[sizeof(int)];}u;int main(void) { u.val = 0x89ABCDEF; #if (BYTE_ORDER == BIG_ENDIAN) printf("%X.%X.%X.%X\n", u.c[0], u.c[1], u.c[2], u.c[3]); #else /*!BYTE_ORDER == BIG_ENDIAN*/ printf("%X.%X.%X.%X\n", u.c[3], u.c[2], u.c[1], u.c[0]); #endif /*BYTE_ORDER == BIG_ENDIAN*/ exit(0);} 清单 4. 使用宏交换字节(对在运行时确定字节顺序很有用)
// Useful Endian Neutral Macros#include <endian.h> #if __BYTE_ORDER == __BIG_ENDIAN// No translation needed for big endian system#define sw2Bytes(val) val#define sw4Bytes(val) val#define sw8Bytes(val) val#else// Little Endian:Translate// Swap 2 byte, 16 bit values:#define sw2Bytes(val) \ ( (((val) >> 8) & 0x00FF) | (((val) << 8) & 0xFF00) )// Swap 4 byte, 32 bit values:#define sw4Bytes(val) \ ( (((val) >> 24) & 0x000000FF) | (((val) >> 8) & 0x0000FF00) | \ (((val) << 8) & 0x00FF0000) | (((val) << 24) & 0xFF000000) )// Swap 8 byte, 64 bit values:#define sw8Bytes(val) \ ( (((val) >> 56) & 0x00000000000000FF) | (((val) >> 40) & 0x000000000000FF00) | \ (((val) >> 24) & 0x0000000000FF0000) | (((val) >> 8) & 0x00000000FF000000) | \ (((val) << 8) & 0x000000FF00000000) | (((val) << 24) & 0x0000FF0000000000) | \ (((val) << 40) & 0x00FF000000000000) | (((val) << 56) & 0xFF00000000000000) )#endifint main(void) { int a=0x11121314; int b; b = sw4Bytes(a); // b is 0x12 in LE and BE}- 使用编译时选项
实现此目的的另一种方式是在编译器命令行上将 BYTE_ORDER 的值定义为 -DBYTE_ORDER=BIG_ENDIAN。在一个具有不同字节顺序的新平台上编译时,这会消除编辑设备驱动程序或应用程序中的每个文件的需求。只需编译用于构建该驱动程序或应用程序的 makefile。 字节顺序:特定于 Linux
事实证明,Linux 内核提供了一组特定的系统宏,它们可以从低位优先到高位优先和从高位优先到低位优先执行 16、32 和 64 位交换。这些宏对从 Linux x86 移植到 Linux on Power 以及让您大代码对字节顺序中立都很方便,无需担忧会在代码中编写大量 #ifdef __LITTLE_ENDIAN 条件指令。
例如:
cpu_to_le16(u16); // converts CPU endianness 4 bytes to little-endian
le16_to_cpu(u16); // converts little-endian 4 bytes to CPU endianness
这两个宏将一个值从 CPU 使用的字节顺序转换为一种无符号、低位优先、32 位数字,或者执行反向转换。例如,在 Linux on Power 系统上,le16_to_cpu(u16) 将低位优先转换为高位优先,而 cpu_to_le16(u16) 将高位优先转换为低位优先。根据使用的宏和运行的是哪个系统,如果没有工作要做,那么它们将会返回原始值。
这些宏和其他许多宏位于: /usr/include/linux/byteorder/big_endian.h> 和 /usr/include/linux/byteorder/little_endian.h 中。
您可以查看这些头文件来找到您需要的宏。您还可以根据名称中的模式推断出它们的用途。
您可以使用预定义的 GNU_C 预处理器指令,轻松地包含正确的 include 文件,如下所示:
#include <endian.h>#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ #include <linux/byteorder/big_endian.h>#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #include <linux/byteorder/little_endian.h>#else // …user defined endian header#endif 其他字节顺序考虑因素
从 x86 移植到 Power 时,不依赖于外部数据文件并且遵守严格的 C ANSI 编程标准的高级应用程序或许能够顺利地移植到 Linux on Power,且不会出现字节顺序问题。但是,字节顺序是一个需要理解的重要概念,而且在代码中识别这些漏洞的能力能够使得向 Linux on Power 的迁移变得很容易。
此外,在下一节中,我们将重点介绍 IBM Linux SDK 中提供的其他代码分析工具,它们可以帮助识别字节顺序问题。
选择要使用哪些迁移工具
类似于机械领域,移植工程师的 “技术” 工具箱中必须有许多工具,而且知道使用哪个工具可用来最大限度降低移植的难度。IBM Linux on Power SDK 和 IBM Rational Developer for Power Systems 都是独立、完整的集成开发环境 (IDE),可用于简化 Power 服务器上的移植和开发,是开发人员在移植到 Linux on Power 时可以使用的优秀技术工具。
IBM SDK for PowerLinux with Migration Advisor
IBM Software Development Kit for PowerLinux (SDK) 是一个免费、基于 Eclipse 的 IDE。该 SDK 集成了 C/C++ 源代码开发与 Advance Toolchain、链接后优化工具(比如 FDPR)和经典的 LInux 性能分析工具(包括 OProfile、Perf 和 Valgrind)。此外,IBM SDK for PowerLinux 中有一个叫做 Migration Advisor 的工具。Migration Advisor 工具的一个特性是代码检查器 和代码修复 特性,该工具可以分析代码中的 Linux/x86 漏洞,为您提供快速修复代码中的漏洞的选项或者提供手动修复它的建议。例如,下面的转换是从 x86 Linux 移植到 Linux on Power 时一种典型的字节顺序潜在问题。消息 “Cast with endianness issue checker” 表示存在这样的漏洞。 |
|
|
|
|
|