linux中cpu_to_be32,linux中sparce与__be32
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相关推荐
- php文件内含有隐藏的^m字符,【整理】如何取消Linux下,vi中显示的^M符号
[整理]如何取消Linux下,vi中显示的^M符号 [背景知识] ^M 是ascii中的'\r', 回车符,是16进制的0x0D,8进制的015,十进制的13. 对于换行这个动作,unix下一般只有一 ...
- Linux网络编程--TCP中的三次握手和四次挥手
服务器编程和客户端编程的大致流程如下: 三次握手是在客户端中的connect中完成的,具体如下: 那么上述说到的SYN ACK这些是什么东西呢? 上述的截图取自<Linux高性能服务器编 ...
- linux平台下QtCreator中集成Valgrind系列工具
linux平台下QtCreator中集成Valgrind系列工具 ###1.valgrind 安装 valgrind 安装 2.打开QtCreator >> Analyze 你就会发现 这 ...
- Apache源码包在LINUX(CENTOS6.8)中的安装(出现问题及解决)
任务:在CENT6.8系统中安装Apache(版本为:httpd-2.4.41) 前提:由于源码包必须先编译后安装,所以必须先安装编译器:gcc 理论步骤: 1.检测gcc软件包,如果不存在则进行安装 ...
- Linux环境编程--linux中的perror、exit、_exit、wait 和 waitpid
perror: #include<stdio.h> #include<stdlib.h> 定义函数 void perror(const char *s); pe ...
- Linux下HOOK动态链接库中API的方法
2012年,我写了一篇介绍Windows系统下Ring3层API的hook方案--<一种注册表沙箱的思路.实现--Hook Nt函数>,其在底层使用了微软的Detours库.5年后,我又遇 ...
- python中执行linux命令(调用linux命令)_Python调用Linux bash命令
import subprocess as sup # 以下注释很多(为了自己以后不忘), 如果只是想在python中执行Linux命令, 看前5行就够了 # 3.5版本之后官方推荐使用sup.run ...
- 在 Azure 中的 Linux VM 上创建 MongoDB、Express、AngularJS 和 Node.js (MEAN) 堆栈
本教程介绍如何在 Azure 中的 Linux VM 上实现 MongoDB.Express.AngularJS 和 Node.js (MEAN) 堆栈. 通过创建的 MEAN 堆栈,可以在数据库中添 ...
- vm虚拟机下linux安装python_VM中安装linux系统,安装VS Code,搭建Python环境
VM中安装linux系统 在linux系统中安装VSCode(Visual Studio Code) 1.从官网下载安装包 2.在下载目录打开终端安装 sudo dpkg -i code_1.32.3 ...
最新文章
- Vue 4.0——整合font-awesome解决方案
- java java 大端_Java 大小端转换
- 网页设计图片向上浮动_利用js实现图片在浏览器中飘动(浮动窗口自由移动)效果...
- JVM 调优 1:“精通 JVM 调优,有过 JVM 调优经验”简历敢写吗?薪资涨 5k 的技巧
- 云筑网认证_云筑网集采平台怎么录入分包单位
- JQuery——实现Ajax应用
- 某面霸疯狂应聘IT名企的经历
- Luogu4438[HNOI/AHOI2018] 道路
- iostat 输出CPU、磁盘IO的使用情况统计信息
- TAP流量复制器在网络流量采集中的应用
- 多线程学习-基础( 十)一个synchronized(){/*代码块*/}简单案例分析
- html 毛笔书写效果,利用纯SVG+CSS keyframes animation动画实现手写毛笔字(书法)效果...
- 烽火算法2.0新升级,打击覆盖范围大大提升
- cad中能够既刷新视图又能刷新计算机图形数据库,建筑CAD练习题.doc
- 前端——获取手机验证码案例
- 【调研】消费者调研与市场调研的区别
- 程序员必备神器(GifCam)
- 零基础ATMEGA8(1)
- 城市规划图例符号_城市规划设计图层图例
- 第三方软件测试有什么作用?
热门文章
- BI软件是什么?应用BI工具能给企业带来什么
- 第三战:商鞅变法(变法始末修订版)秦并天下的战争机器,开动起来了
- 谷歌调整排序算法引发震荡 知名网站PR值下滑
- 页面静态化Freemaker
- 一加OPPO即将刷屏!5天4场新机发布会,其中三款都是90Hz屏幕
- 《C语言报错》链接错误LNK2001-----error LNK2001: unresolved external symbol _clrscr
- python读取hdf-eos5数据_《Python和HDF 5大数据应用》——2.4 你的第一个HDF5文件-阿里云开发者社区...
- jenkins 的安装
- JAVA实现PDF转HTML文档
- 计算机网络工程教程:基于cisco路由器和交换机,高等院校计算机技术与应用系列规划教材·计算机网络工程教程:基于cisco路由器和交换机...