分类: LINUX
2010-12-15 09:46:22
源码:linux/arch/i386/lib/usercopy.c copy_to_user: - Copy a block of data into user space. @to: Destination address, in user space. @from: Source address, in kernel space. @n: Number of bytes to copy. 849unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) 850{
851 if (access_ok(VERIFY_WRITE, to, n)) 852 n = __copy_to_user(to, from, n);853 return n; 854} copy_from_user: - Copy a block of data from user space. @to: Destination address, in kernel space. @from: Source address, in user space. @n: Number of bytes to copy. 874unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) 875{ 876 if (access_ok(VERIFY_READ, from, n)) 877 n = __copy_from_user(to, from, n); 878 else 879 memset(to, 0, n); 880 return n; 881} |
|
源码:linux/include/asm-frv/uaccess.h 282static inline unsigned long __must_check 283__copy_to_user(void __user *to, const void *from, unsigned long n) 284{ 285 might_sleep(); 286 return __copy_to_user_inatomic(to, from, n); 287} 276#define __copy_to_user_inatomic(to, from, n) (memcpy(____force(to), (from), (n)), 0) 289static inline unsigned long 290__copy_from_user(void *to, const void __user *from, unsigned long n) 291{ 292 might_sleep(); 293 return __copy_from_user_inatomic(to, from, n); 294} 275#define __copy_from_user_inatomic(to, from, n) (memcpy((to), ____force(from), (n)), 0) |
源码定义:linux/include/asm-i386/uaccess.h 197#define put_user(x,ptr) 198({ int __ret_pu; 199 __typeof__(*(ptr)) __pu_val; 200 __chk_user_ptr(ptr); 201 __pu_val = x; 202 switch(sizeof(*(ptr))) { 203 case 1: __put_user_1(__pu_val, ptr); break; 204 case 2: __put_user_2(__pu_val, ptr); break; 205 case 4: __put_user_4(__pu_val, ptr); break; 206 case 8: __put_user_8(__pu_val, ptr); break; 207 default:__put_user_X(__pu_val, ptr); break; 208 } 209 __ret_pu; 210}) |
27# define __chk_user_ptr(x) (void)0 取得ptr指向的0地址,然后 __pu_val = x;可以得到x的偏移地址,这样就可以指向x。 318#define container_of(ptr, type, member) ({ 319 const typeof( ((type *)0)->member ) *__mptr = (ptr); 320 (type *)( (char *)__mptr - offsetof(type,member) );}) |
173#define __put_user_1(x, ptr) __asm__ __volatile__("call __put_user_1":"=a" (__ret_pu):"0" ((typeof(*(ptr)))(x)), "c" (ptr)) 174#define __put_user_2(x, ptr) __asm__ __volatile__("call __put_user_2":"=a" (__ret_pu):"0" ((typeof(*(ptr)))(x)), "c" (ptr)) 175#define __put_user_4(x, ptr) __asm__ __volatile__("call __put_user_4":"=a" (__ret_pu):"0" ((typeof(*(ptr)))(x)), "c" (ptr)) 176#define __put_user_8(x, ptr) __asm__ __volatile__("call __put_user_8":"=a" (__ret_pu):"A" ((typeof(*(ptr)))(x)), "c" (ptr)) 177#define __put_user_X(x, ptr) __asm__ __volatile__("call __put_user_X":"=a" (__ret_pu):"c" (ptr)) |