be表示big endian,大端,le表示小端。

__be32,__le32都是一样的,其实就是__u32,具体是什么端数据又系统决定的。

网络协议也是采用大端数据。

目前主要是用来发现大小端不匹配的错误。比如往big-endian的寄存器里面写入little-endian的数据。

cpu_to_be32()    /*convertcpu's byte ordertobig-endian*/

be32_to_cpu()   /*convert big-endiantocpu's byte order */

Sparse是一个C/C++源文件静态分析工具。

#define __bitwise __attribute__((bitwise))

typedef unsigned int __u32;

typedef __u32 __bitwise __be32;

__be32只是一个带有bitwise属性的整型类型,而这个属性对gcc本身没有任何作用,所以如果不利用sparse,__be32和__u32没有任何差别,但是如果利用sparse,它就能提供一种超强制的类型匹配检查。

比如下面这段代码:

int __bitwise i;

int __bitwise j;

i = j;

最后一句代码是要被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

而下面这样的代码就没有问题:

int __bitwise i, j;

i = j;

根据上面的这个极端例子可以看到,bitwise属性总是创建一个新的数据类型,所以一般的情况就是把bitwise用在typedef内,如前面看到的__be32类型。由于typedef本身会创建一个新数据类型,所以下面这样的代码是没有问题的:

__be32 i;

__be32 j;

i = j;

用在typedef内的bitwise貌似功能一已经发挥不了作用,但是正如其命名所示,它还有功能二,即强制安全位运算。这个怎么理解呢?举例来说,我们知道加法运算不是位运算安全的,因为加法运算会导致位循环移动;但与运算(后面有特例)、比较运算就是位运算安全的:

__be32 i;

__be32 j;

i += j;

i &= j;

倒数第二句代码将被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的意外操作都将提示告警:

kmalloc(GFP_KERNEL, size);

像上面这种参数搞反的情况,编译器检查不出来,但是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.不同类型之间的赋值将告警:

__be32 i;

__be32 j;

__le32 k;

int t;

i = j; // ok

i = 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)

2.即使是相同类型,如果操作不是位运算安全的,将告警:

__be32 i;

__be32 j;

i = i & j; // ok

i = i << j; // warning: incorrect type in assignment (different base types)

3.要对这些类型进行安全运输可以先进行强制转换(另外一个__force属性):

__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

根据字面意思,__be32等这些类型是用在有字节序(大小端)相关环境的。我们知道网络数据字节序为大端,而我们常用的x86 CPU为小端。假设要打印(printk)一个从网络上接收到数据包的源IP,我们可以这样:

printk(KERN_ALERT "source ip:%d\n", ntohl(iph->saddr));

当然,也可以这样:

printk(KERN_ALERT "source ip:%d\n", __be32_to_cpu(iph->saddr));

而大多数情况一般都是利用ntohl,毕竟这个是公开的接口,而带双下划线的__be32_to_cpu用得就比较少了,事实上ntohl就是__be32_to_cpu的宏定义:

#define ___ntohl(x) __be32_to_cpu(x)

#define ntohl(x) ___ntohl(x)

最后介绍一下Sparse的使用,使用非常简单,编译时输入:

make C=2

即可自动调用Sparse进行分析、检查。如果要单独的使用Sparse(详细选项请看man手册):

sparse hello.c

对于__be32等这些类型,如果没有检查,请注意是否定义了__CHECK_ENDIAN__宏,因为根据头文件linux/types.h内代码,只有当定义了__CHECK_ENDIAN__宏时,__bitwise才有效:

#ifdef __CHECK_ENDIAN__

#define __bitwise __bitwise__

#else

#define __bitwise

#endif

linux中cpu_to_be32,linux中sparce与__be32相关推荐

  1. php文件内含有隐藏的^m字符,【整理】如何取消Linux下,vi中显示的^M符号

    [整理]如何取消Linux下,vi中显示的^M符号 [背景知识] ^M 是ascii中的'\r', 回车符,是16进制的0x0D,8进制的015,十进制的13. 对于换行这个动作,unix下一般只有一 ...

  2. Linux网络编程--TCP中的三次握手和四次挥手

    服务器编程和客户端编程的大致流程如下: 三次握手是在客户端中的connect中完成的,具体如下: 那么上述说到的SYN     ACK这些是什么东西呢? 上述的截图取自<Linux高性能服务器编 ...

  3. linux平台下QtCreator中集成Valgrind系列工具

    linux平台下QtCreator中集成Valgrind系列工具 ###1.valgrind 安装 valgrind 安装 2.打开QtCreator >> Analyze 你就会发现 这 ...

  4. Apache源码包在LINUX(CENTOS6.8)中的安装(出现问题及解决)

    任务:在CENT6.8系统中安装Apache(版本为:httpd-2.4.41) 前提:由于源码包必须先编译后安装,所以必须先安装编译器:gcc 理论步骤: 1.检测gcc软件包,如果不存在则进行安装 ...

  5. Linux环境编程--linux中的perror、exit、_exit、wait 和 waitpid

    perror: #include<stdio.h>        #include<stdlib.h> 定义函数 void perror(const char *s);  pe ...

  6. Linux下HOOK动态链接库中API的方法

    2012年,我写了一篇介绍Windows系统下Ring3层API的hook方案--<一种注册表沙箱的思路.实现--Hook Nt函数>,其在底层使用了微软的Detours库.5年后,我又遇 ...

  7. python中执行linux命令(调用linux命令)_Python调用Linux bash命令

    import subprocess as sup  # 以下注释很多(为了自己以后不忘), 如果只是想在python中执行Linux命令, 看前5行就够了 # 3.5版本之后官方推荐使用sup.run ...

  8. 在 Azure 中的 Linux VM 上创建 MongoDB、Express、AngularJS 和 Node.js (MEAN) 堆栈

    本教程介绍如何在 Azure 中的 Linux VM 上实现 MongoDB.Express.AngularJS 和 Node.js (MEAN) 堆栈. 通过创建的 MEAN 堆栈,可以在数据库中添 ...

  9. vm虚拟机下linux安装python_VM中安装linux系统,安装VS Code,搭建Python环境

    VM中安装linux系统 在linux系统中安装VSCode(Visual Studio Code) 1.从官网下载安装包 2.在下载目录打开终端安装 sudo dpkg -i code_1.32.3 ...

最新文章

  1. Vue 4.0——整合font-awesome解决方案
  2. java java 大端_Java 大小端转换
  3. 网页设计图片向上浮动_利用js实现图片在浏览器中飘动(浮动窗口自由移动)效果...
  4. JVM 调优 1:“精通 JVM 调优,有过 JVM 调优经验”简历敢写吗?薪资涨 5k 的技巧
  5. 云筑网认证_云筑网集采平台怎么录入分包单位
  6. JQuery——实现Ajax应用
  7. 某面霸疯狂应聘IT名企的经历
  8. Luogu4438[HNOI/AHOI2018] 道路
  9. iostat 输出CPU、磁盘IO的使用情况统计信息
  10. TAP流量复制器在网络流量采集中的应用
  11. 多线程学习-基础( 十)一个synchronized(){/*代码块*/}简单案例分析
  12. html 毛笔书写效果,利用纯SVG+CSS keyframes animation动画实现手写毛笔字(书法)效果...
  13. 烽火算法2.0新升级,打击覆盖范围大大提升
  14. cad中能够既刷新视图又能刷新计算机图形数据库,建筑CAD练习题.doc
  15. 前端——获取手机验证码案例
  16. 【调研】消费者调研与市场调研的区别
  17. 程序员必备神器(GifCam)
  18. 零基础ATMEGA8(1)
  19. 城市规划图例符号_城市规划设计图层图例
  20. 第三方软件测试有什么作用?

热门文章

  1. BI软件是什么?应用BI工具能给企业带来什么
  2. 第三战:商鞅变法(变法始末修订版)秦并天下的战争机器,开动起来了
  3. 谷歌调整排序算法引发震荡 知名网站PR值下滑
  4. 页面静态化Freemaker
  5. 一加OPPO即将刷屏!5天4场新机发布会,其中三款都是90Hz屏幕
  6. 《C语言报错》链接错误LNK2001-----error LNK2001: unresolved external symbol _clrscr
  7. python读取hdf-eos5数据_《Python和HDF 5大数据应用》——2.4 你的第一个HDF5文件-阿里云开发者社区...
  8. jenkins 的安装
  9. JAVA实现PDF转HTML文档
  10. 计算机网络工程教程:基于cisco路由器和交换机,高等院校计算机技术与应用系列规划教材·计算机网络工程教程:基于cisco路由器和交换机...