linux kernel container_of and offsetof 一知半解
2013-03-04 16:08
225 查看
linux container_of(ptr,struct B, member)
1. ptr: struct B 一个对象,ptr 指向它的一个成员 例如
struct B {
int a;
char b;
};
struct B b_obj;
ptr = &b_obj.b;
2. struct B, 包含a,b两个成员变量
3. container_of的返回值:为b_obj对象的首地址。
4. 结论:container_of通过类定义的对象实例成员变量,找到该对象实例的首地址。其作用同offsetof(struct B, b)函数完全相反,offsetof 是通过类定义的对象实例,找到其成员变量的地址
5. 原来有一个结论,container_of(ptr, type, member)里面的type一直认为他不能是个指针,碰到指针想得到类对象的首地址就有点慌张,其实可以用typeof(*p_in)来作为type传送,这里的typeof是个返回什么类型的一个宏定义。 我们亦可以在linux内核内部的list_entry里面找到:
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
6. 附带一些关于typeof 的介绍:
sizeof(exp.)返回的是exp.的数据类型大小,那么typeof(exp.)返回的就是exp.的数据类型。值得注意的是在上面的话里 我们可以看到,如果编译选项中指定了使用标准C,那么gcc的扩展使用可能会受到影响,不过在gcc编译条件下使用__typeof__依然可以正常工 作,这和使用asm是一样的。当然如果是在其他的编译器条件下,这样做也不行了,只能自定义一个macro去使用,也就是说跟gcc没啥关系了,你愿意把 typeof咋实现都可以。
下面写一个小程序示例一下:)
#include <stdio.h>
typedef struct
{
int x;
char y;
}astruct, * pastrcut;
int main()
{
int sizem, sizew;
int x = 3;
typeof(&x) m;
sizem = sizeof(m);
*m = 5;
typeof(((astruct *)5)->y) w;
sizew = sizeof(w);
w = ''a'';
return 1;
}
首先看main函数里的m变量,这个变量的类型就是typeof(&x),
由于x是int型的(这里与x是否被赋值一点关系都没有)所以&x应该是int
*类型,那么typeof(&x)返回的类型就是int*,所以m自然也就是个int*类型的。之后我们看w变量,其类型是
typeof(((astruct *)8)->y),
其中astruct是一个被定义的结构类型,其中的y元素是char*类型,那么((astruct
*)8)->y是啥意思呢?在这里0并不是真正的变量,可以把它理解为一个替代使用的符号当然这个符号最好是一个数,其意思更可以理解为一个被赋值
了的变量,这个数可以不是0,3也可以8也可以,随便什么都可以。那么((astruct
*)0)->y仅仅就是表示了y这个变量,所以typeof的结果就是y元素的类型,也就是char。
1. ptr: struct B 一个对象,ptr 指向它的一个成员 例如
struct B {
int a;
char b;
};
struct B b_obj;
ptr = &b_obj.b;
2. struct B, 包含a,b两个成员变量
3. container_of的返回值:为b_obj对象的首地址。
4. 结论:container_of通过类定义的对象实例成员变量,找到该对象实例的首地址。其作用同offsetof(struct B, b)函数完全相反,offsetof 是通过类定义的对象实例,找到其成员变量的地址
5. 原来有一个结论,container_of(ptr, type, member)里面的type一直认为他不能是个指针,碰到指针想得到类对象的首地址就有点慌张,其实可以用typeof(*p_in)来作为type传送,这里的typeof是个返回什么类型的一个宏定义。 我们亦可以在linux内核内部的list_entry里面找到:
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
6. 附带一些关于typeof 的介绍:
sizeof(exp.)返回的是exp.的数据类型大小,那么typeof(exp.)返回的就是exp.的数据类型。值得注意的是在上面的话里 我们可以看到,如果编译选项中指定了使用标准C,那么gcc的扩展使用可能会受到影响,不过在gcc编译条件下使用__typeof__依然可以正常工 作,这和使用asm是一样的。当然如果是在其他的编译器条件下,这样做也不行了,只能自定义一个macro去使用,也就是说跟gcc没啥关系了,你愿意把 typeof咋实现都可以。
下面写一个小程序示例一下:)
#include <stdio.h>
typedef struct
{
int x;
char y;
}astruct, * pastrcut;
int main()
{
int sizem, sizew;
int x = 3;
typeof(&x) m;
sizem = sizeof(m);
*m = 5;
typeof(((astruct *)5)->y) w;
sizew = sizeof(w);
w = ''a'';
return 1;
}
首先看main函数里的m变量,这个变量的类型就是typeof(&x),
由于x是int型的(这里与x是否被赋值一点关系都没有)所以&x应该是int
*类型,那么typeof(&x)返回的类型就是int*,所以m自然也就是个int*类型的。之后我们看w变量,其类型是
typeof(((astruct *)8)->y),
其中astruct是一个被定义的结构类型,其中的y元素是char*类型,那么((astruct
*)8)->y是啥意思呢?在这里0并不是真正的变量,可以把它理解为一个替代使用的符号当然这个符号最好是一个数,其意思更可以理解为一个被赋值
了的变量,这个数可以不是0,3也可以8也可以,随便什么都可以。那么((astruct
*)0)->y仅仅就是表示了y这个变量,所以typeof的结果就是y元素的类型,也就是char。
相关文章推荐
- ANALYSIS AND EXPLOITATION OF A LINUX KERNEL VULNERABILITY (CVE-2016-0728)
- [[Journey to the Center of the Linux Kernel: Traffic Control, Shaping and QoS]]
- The Proccess of Loading and Executing a Specific Program in Linux Kernel
- ANALYSIS AND EXPLOITATION OF A LINUX KERNEL VULNERABILITY (CVE-2016-0728)
- ANALYSIS AND EXPLOITATION OF A LINUX KERNEL VULNERABILITY (CVE-2016-0728)
- unable to find the sources of your current Linux kernel. Specify KERN_DIR=<directory> and run Make a
- linux kernel typeof container_of
- Abuse of the Linux Kernel for Fun and Profit
- Review the Bit and Version and Kernel of CentOS
- 内核:offsetof + container_of 分析
- Linux Series Notes(1)-- Installing CentOS7 and configurating something essential of its
- HOWTO: Create and submit your first Linux kernel patch using GIT
- Manual Installation and Registration of Java Plugin for Linux
- VirtualBox + kgdb analysis of Linux kernel (v3.4.0-rc3)
- Solve a problem caused by Xhost and Installation of Expect tool on Linux
- linux内核细节- typeof、offsetof、container_of
- Linux Kernel source code of all versions - download
- The Mindmaps of Linux Kernel
- Linux kernel tweaking for performance and security on a busy Linux
- Inversion of Control Containers and the Dependency Injection pattern