Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

copy.c

Go to the documentation of this file.
00001 /* -*- linux-c -*- */
00002 /** @file copy.c
00003  * @brief Functions to copy from user space.
00004  */
00005 
00006 long _stp_strncpy_from_user(char *dst, const char __user *src, long count);
00007 //static long __stp_strncpy_from_user(char *dst, const char __user *src, long count);
00008 
00009 #if defined (__i386__)
00010 #define __stp_strncpy_from_user(dst,src,count,res)                         \
00011 do {                                                                       \
00012         int __d0, __d1, __d2;                                              \
00013         __asm__ __volatile__(                                              \
00014                 "       testl %1,%1\n"                                     \
00015                 "       jz 2f\n"                                           \
00016                 "0:     lodsb\n"                                           \
00017                 "       stosb\n"                                           \
00018                 "       testb %%al,%%al\n"                                 \
00019                 "       jz 1f\n"                                           \
00020                 "       decl %1\n"                                         \
00021                 "       jnz 0b\n"                                          \
00022                 "1:     subl %1,%0\n"                                      \
00023                 "2:\n"                                                     \
00024                 ".section .fixup,\"ax\"\n"                                 \
00025                 "3:     movl %5,%0\n"                                      \
00026                 "       jmp 2b\n"                                          \
00027                 ".previous\n"                                              \
00028                 ".section __ex_table,\"a\"\n"                              \
00029                 "       .align 4\n"                                        \
00030                 "       .long 0b,3b\n"                                     \
00031                 ".previous"                                                \
00032                 : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),      \
00033                   "=&D" (__d2)                                             \
00034                 : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
00035                 : "memory");                                               \
00036 } while (0)
00037 #elif defined (__x86_64__)
00038 #define __stp_strncpy_from_user(dst,src,count,res)                         \
00039 do {                                                                       \
00040         long __d0, __d1, __d2;                                             \
00041         __asm__ __volatile__(                                              \
00042                 "       testq %1,%1\n"                                     \
00043                 "       jz 2f\n"                                           \
00044                 "0:     lodsb\n"                                           \
00045                 "       stosb\n"                                           \
00046                 "       testb %%al,%%al\n"                                 \
00047                 "       jz 1f\n"                                           \
00048                 "       decq %1\n"                                         \
00049                 "       jnz 0b\n"                                          \
00050                 "1:     subq %1,%0\n"                                      \
00051                 "2:\n"                                                     \
00052                 ".section .fixup,\"ax\"\n"                                 \
00053                 "3:     movq %5,%0\n"                                      \
00054                 "       jmp 2b\n"                                          \
00055                 ".previous\n"                                              \
00056                 ".section __ex_table,\"a\"\n"                              \
00057                 "       .align 8\n"                                        \
00058                 "       .quad 0b,3b\n"                                     \
00059                 ".previous"                                                \
00060                 : "=r"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),      \
00061                   "=&D" (__d2)                                             \
00062                 : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
00063                 : "memory");                                               \
00064 } while (0)
00065 #endif
00066 
00067 /** Copy a NULL-terminated string from userspace.
00068  * On success, returns the length of the string (not including the trailing
00069  * NULL).
00070  *
00071  * If access to userspace fails, returns -EFAULT (some data may have been
00072  * copied).
00073  * @param dst Destination address, in kernel space.  This buffer must be at
00074  *         least <i>count</i> bytes long.
00075  * @param src Source address, in user space.
00076  * @param count Maximum number of bytes to copy, including the trailing NULL.
00077  * 
00078  * If <i>count</i> is smaller than the length of the string, copies 
00079  * <i>count</i> bytes and returns <i>count</i>.
00080  */
00081 
00082 long
00083 _stp_strncpy_from_user(char *dst, const char __user *src, long count)
00084 {
00085         long res;
00086         __stp_strncpy_from_user(dst, src, count, res);
00087         return res;
00088 }
00089 
00090 /** Copy a block of data from user space.
00091  *
00092  * If some data could not be copied, this function will pad the copied
00093  * data to the requested size using zero bytes.
00094 
00095  * @param dst Destination address, in kernel space.
00096  * @param src Source address, in user space.
00097  * @param count Number of bytes to copy.
00098  * @return number of bytes that could not be copied. On success, 
00099  * this will be zero.
00100  *
00101  */
00102 
00103 unsigned long inline
00104 _stp_copy_from_user (char *dst, const char __user *src, unsigned long count)
00105 {
00106         return __copy_from_user_inatomic(dst, src, count);
00107 }
00108 
00109 /** Copy an argv from user space to a List.
00110  *
00111  * @param list A list.
00112  * @param argv Source argv, in user space.
00113  * @return number of elements in <i>list</i>
00114  *
00115  * @b Example:
00116  * @include argv.c
00117  */
00118 
00119 int _stp_copy_argv_from_user (MAP list, char __user *__user *argv)
00120 {
00121         char str[128];
00122         char __user *vstr;
00123         int len;
00124 
00125         if (argv)
00126                 argv++;
00127 
00128         while (argv != NULL) {
00129                 if (get_user (vstr, argv))
00130                         break;
00131                 
00132                 if (vstr == NULL)
00133                         break;
00134                 
00135                 len = _stp_strncpy_from_user(str, vstr, 128);
00136                 str[len] = 0;
00137                 _stp_list_add_str (list, str);
00138                 argv++;
00139         }
00140         return list->num;
00141 }

Generated on Tue Mar 22 10:27:36 2005 for SystemTap.