linux中sparce与__be32
来源:互联网 发布:淘宝有访客无询单 编辑:程序博客网 时间:2024/05/16 01:57
__be32,__le32都是一样的,其实就是__u32,具体是什么端数据又系统决定的。
网络协议也是采用大端数据。
目前主要是用来发现大小端不匹配的错误。比如往big-endian的寄存器里面写入little-endian的数据。
cpu_to_be32() /*convert cpu's byte order to big-endian */
be32_to_cpu() /*convert big-endian to cpu's byte order */
Sparse是一个C/C++源文件静态分析工具。
__be32,其定义扩展开为:
<span style="font-size:18px;">#define __bitwise __attribute__((bitwise))typedef unsigned int __u32;typedef __u32 __bitwise __be32;</span>
__be32只是一个带有bitwise属性的整型类型,而这个属性对gcc本身没有任何作用,所以如果不利用sparse,__be32和__u32没有任何差别,但是如果利用sparse,它就能提供一种超强制的类型匹配检查。
比如下面这段代码:
<span style="font-size:18px;">int __bitwise i;int __bitwise j;…i = j;</span>
最后一句代码是要被sparse告警的,如下:
CHECK /home/lenky/hello/hello.c
/home/lenky/hello/hello.c:17:3: warning: incorrect type in assignment (different base types)
/home/lenky/hello/hello.c:17:3: expected restricted int i
/home/lenky/hello/hello.c:17:3: got restricted int j
而下面这样的代码就没有问题:
<span style="font-size:18px;">int __bitwise i, j;…i = j;</span>
根据上面的这个极端例子可以看到,bitwise属性总是创建一个新的数据类型,所以一般的情况就是把bitwise用在typedef内,如前面看到的__be32类型。由于typedef本身会创建一个新数据类型,所以下面这样的代码是没有问题的:
<span style="font-size:18px;">__be32 i;__be32 j;…i = j;</span>
用在typedef内的bitwise貌似功能一已经发挥不了作用,但是正如其命名所示,它还有功能二,即强制安全位运算。这个怎么理解呢?举例来说,我们知道加法运算不是位运算安全的,因为加法运算会导致位循环移动;但与运算(后面有特例)、比较运算就是位运算安全的:
<span style="font-size:18px;">__be32 i;__be32 j;…i += j;i &= j;</span>
倒数第二句代码将被sparse如下告警:
/home/lenky/hello/hello.c:17:3: warning: bad assignment (+=) to restricted __be32
另外的就是(特例),如果对一个bitwise的short或char做与运算也是不安全的。因为会导致类型提升,即转为int类型,此时可能会导致符号位改变。简而言之,bitwise的功能二就是保证数据位不丢失或循环移动。
我们的GFP_KERNEL就是一个带有bitwise属性的unsigned类型,所以对于GFP_KERNEL的意外操作都将提示告警:
<span style="font-size:18px;">kmalloc(GFP_KERNEL, size);</span>
像上面这种参数搞反的情况,编译器检查不出来,但是sparse却可以。
除了__be32,还有如下类似:
typedef __u16 __bitwise __le16;
typedef __u16 __bitwise __be16;
typedef __u32 __bitwise __le32;
typedef __u32 __bitwise __be32;
typedef __u64 __bitwise __le64;
typedef __u64 __bitwise __be64;
上面这些宏定义头文件linux/types.h内,对于一个__be32变量i,经过前面的分析可以知道如下几点:
1.不同类型之间的赋值将告警:
<span style="font-size:18px;">__be32 i;__be32 j;__le32 k;int t;…i = j; // oki = k; // warning: incorrect type in assignment (different base types)i =t; // warning: incorrect type in assignment (different base types)t = i; // warning: incorrect type in assignment (different base types)</span>
2.即使是相同类型,如果操作不是位运算安全的,将告警:
<span style="font-size:18px;">__be32 i;__be32 j;…i = i & j; // oki = i << j; // warning: incorrect type in assignment (different base types)</span>
3.要对这些类型进行安全运输可以先进行强制转换(另外一个__force属性):
<span style="font-size:18px;">__be32 i;__be32 j;__be32 sum;…sum = i + j; // warning: incorrect type in assignment (different base types)sum = cpu_to_be32(be32_to_cpu(i) + be32_to_cpu(j)); // ok</span>
根据字面意思,__be32等这些类型是用在有字节序(大小端)相关环境的。我们知道网络数据字节序为大端,而我们常用的x86 CPU为小端。假设要打印(printk)一个从网络上接收到数据包的源IP,我们可以这样:
<span style="font-size:18px;">printk(KERN_ALERT "source ip:%d\n", ntohl(iph->saddr));</span>
当然,也可以这样:
<span style="font-size:18px;">printk(KERN_ALERT "source ip:%d\n", __be32_to_cpu(iph->saddr));</span>
而大多数情况一般都是利用ntohl,毕竟这个是公开的接口,而带双下划线的__be32_to_cpu用得就比较少了,事实上ntohl就是__be32_to_cpu的宏定义:
<span style="font-size:18px;">#define ___ntohl(x) __be32_to_cpu(x)#define ntohl(x) ___ntohl(x)</span>
最后介绍一下Sparse的使用,使用非常简单,编译时输入:
<span style="font-size:18px;">make C=2</span>
即可自动调用Sparse进行分析、检查。如果要单独的使用Sparse(详细选项请看man手册):
<span style="font-size:18px;">sparse hello.c</span>
对于__be32等这些类型,如果没有检查,请注意是否定义了__CHECK_ENDIAN__宏,因为根据头文件linux/types.h内代码,只有当定义了__CHECK_ENDIAN__宏时,__bitwise才有效:
<span style="font-size:18px;">#ifdef __CHECK_ENDIAN__#define __bitwise __bitwise__#else#define __bitwise#endif</span>
- linux中sparce与__be32
- linux中sparce与__be32
- sparse与__be32
- typedef __u32 __bitwise __be32 means in linux [duplicate]
- 【Sparse】关于__attribute__((bitwise)),__le32,__be32等的理解
- linux中kmalloc()与vmalloc()
- linux中kmalloc()与vmalloc()
- linux中 likely与unlikely
- linux中 likely与unlikely
- linux中 likely与unlikely
- linux中 likely与unlikely
- linux中likely与unlikely
- Linux中$(( )) 与 $( )的区别
- Linux中( ) 与{ } 的区别
- linux中likely与unlikely
- linux中 likely与unlikely .
- linux中 likely与unlikely
- linux中 likely与unlikely
- poj2549
- Linux集群Hadoop2.5.1完全分布式安装
- 趣味CRACKME破解分析(发散思维)
- 网络之协议
- Android 开源框架Universal-Image-Loader完全解析(三)---可以防止图片错乱
- linux中sparce与__be32
- java学习入门
- [CS231n@Stanford] Assignment1-Q1
- JAVA学习笔记<基础篇>
- redis与spring集成
- Android WebView学习笔记
- 几种进程间的通信方式
- Python性能优化的20条建议
- 浏览器: webkit架构 目录结构