1void xxx(const char __user *buffer) {
2 char mode;
3 // 宏实现,mode直接传就好,不需要取地址,返回0就是成功,返回非0就是失败
4 // 从对应类型的用户空间指针取值赋值给内部变量,数组取第一个,非数组直接取值
5 // 只支持1、2、4、8个字节的特定类型,不支持字符串
6 if (get_user(mode, buffer)) return;
7 // do something
8}
1// include/asm-generic/uaccess.h
2#define __get_user(x, ptr) \
3({ \
4 int __gu_err = -EFAULT; \
5 __chk_user_ptr(ptr); \
6 switch (sizeof(*(ptr))) { \
7 case 1: { \
8 unsigned char __x = 0; \
9 __gu_err = __get_user_fn(sizeof (*(ptr)), \
10 ptr, &__x); \
11 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
12 break; \
13 }; \
14 case 2: { \
15 unsigned short __x = 0; \
16 __gu_err = __get_user_fn(sizeof (*(ptr)), \
17 ptr, &__x); \
18 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
19 break; \
20 }; \
21 case 4: { \
22 unsigned int __x = 0; \
23 __gu_err = __get_user_fn(sizeof (*(ptr)), \
24 ptr, &__x); \
25 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
26 break; \
27 }; \
28 case 8: { \
29 unsigned long long __x = 0; \
30 __gu_err = __get_user_fn(sizeof (*(ptr)), \
31 ptr, &__x); \
32 (x) = *(__force __typeof__(*(ptr)) *) &__x; \
33 break; \
34 }; \
35 default: \
36 __get_user_bad(); \
37 break; \
38 } \
39 __gu_err; \
40})
41
42#define get_user(x, ptr) \
43({ \
44 const void __user *__p = (ptr); \
45 might_fault(); \
46 access_ok(VERIFY_READ, __p, sizeof(*ptr)) ? \
47 __get_user((x), (__typeof__(*(ptr)) __user *)__p) :\
48 ((x) = (__typeof__(*(ptr)))0,-EFAULT); \
49})
50
51#ifndef __get_user_fn
52static inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
53{
54 return unlikely(raw_copy_from_user(x, ptr, size)) ? -EFAULT : 0;
55}
56
57#define __get_user_fn(sz, u, k) __get_user_fn(sz, u, k)
58
59#endif
1// include/linux/init.h
2#define __init __section(".init.text") __cold __latent_entropy __noinitretpoline __nocfi
3#define __initdata __section(".init.data")
4#define __initconst __section(".init.rodata")
5#define __exitdata __section(".exit.data")
6#define __exit_call __used __section(".exitcall.exit")
7...
8#define __ref __section(".ref.text") noinline
9#define __refdata __section(".ref.data")
10#define __refconst __section(".ref.rodata")
11#define __exit __section(".exit.text") __exitused __cold notrace
12...
13/* Used for MEMORY_HOTPLUG */
14#define __meminit __section(".meminit.text") __cold notrace \
15 __latent_entropy
16#define __meminitdata __section(".meminit.data")
17#define __meminitconst __section(".meminit.rodata")
18#define __memexit __section(".memexit.text") __exitused __cold notrace
19#define __memexitdata __section(".memexit.data")
20#define __memexitconst __section(".memexit.rodata")