linux内核中的container_of

在内核代码中,经常见到container_of函数,它是一个宏定义,定义在include\linux\kernel.h文件中

/**

* Container_of - cast a member of a structure out to the containing structure

                (将一个结构体的成员包含到指定的结构体中)

* @ptr:        the pointer to the member.

               (待包含的结构体成员指针)

* @type:      the type of the container struct this is embedded in.

                (将要包含的结构体,即最后要返回的结构体类型)

* @member:    the name of the within the struct.

               (指定的结构体中的成员)

**

*/  

#define container_of(ptr , type, member)({       \

       const typeof(((type *)0)->member) *__mptr = (ptr);       \

       (type *)((char *)__mptr – offsetof(type,member));})

通过代码中的英文注释,我们可以知道这个宏定义的作用是,将一个指定的指针变量(ptr)的内容作为指定的结构体类型(type)的指定成员(member)放到指定结构体(type)中,并返回直接结构体的指针(type)。内存存储示意图如下:

 

这个宏定义是怎么做到的呢?首先看第一句

Const typeof(((type *)0)->member) *__mptr = (ptr);

这里是定义一个指针变量__mptr,并赋值为ptr.

Typeof关键字的作用是返回变量或者表达式的数据类型,所以__mptr的指针类型和((type *)0)->member的指针类型一致;这句话的作用是为了保证ptr的类型与member的数据类型一致,当两者不一致时,编译器则会发出警告信息提醒开发者。

接下来看第二句

(type *)((char *)__mptr – offsetof(type,member));

这里是使用__mprt指针地址减去member成员在type结构体的偏移,即可得到想要的type结构体的指针,这个指针内存包含着ptr。

offsetof(type,member)表示member成员在type结构体的位置偏移,offsetof的定义如下:

扫描二维码关注公众号,回复: 9139677 查看本文章
#define offsetof(TYPE,MEMBER)  ((size_t)&((TYPE *)0)->MEMBER)

这里的&是取地址符号,取MEMBER相对于TYPE的地址,因为这里的开始地址是0,所以取出来的地址就是MEMBER在TYPE结构体中的偏移量。

 

至此,我们已经知道了container_of的作用和怎么实现的了,但是,我有一个疑惑,使用它是否存在篡改其它指针的内容的可能性,因为我们直接对指针做减法得到新的指针后直接使用,假如新的指针原先已经分配给别的变量,且该变量还在被使用,我认为就会存在被篡改的可能性。那内核是使用什么机制避免这样的事情发生的呢?

发布了2 篇原创文章 · 获赞 1 · 访问量 43

猜你喜欢

转载自blog.csdn.net/qq_36413391/article/details/104291965