]>
sourceware.org Git - systemtap.git/blob - runtime/linux/copy.c
2 * Copy from user space functions
3 * Copyright (C) 2005-2014 Red Hat Inc.
4 * Copyright (C) 2005 Intel Corporation.
6 * This file is part of systemtap, and is free software. You can
7 * redistribute it and/or modify it under the terms of the GNU General
8 * Public License (GPL); either version 2, or (at your option) any
12 #ifndef _STAPLINUX_COPY_C_ /* -*- linux-c -*- */
13 #define _STAPLINUX_COPY_C_
16 * @brief Functions to copy from user space.
19 /** @addtogroup copy Functions to copy from user space.
20 * Functions to copy from user space.
21 * None of these functions will sleep (for example to allow pages
22 * to be swapped in). It is possible (although rare) that the data
23 * in user space will not present and these functions will return an error.
27 #ifdef CONFIG_GENERIC_STRNCPY_FROM_USER
28 #define __stp_strncpy_from_user(dst,src,count,res) \
29 do { res = strncpy_from_user(dst, src, count); } while(0)
30 #else /* !CONFIG_GENERIC_STRNCPY_FROM_USER */
31 #if defined (__i386__)
32 #define __stp_strncpy_from_user(dst,src,count,res) \
34 int __d0, __d1, __d2; \
35 __asm__ __volatile__( \
40 " testb %%al,%%al\n" \
46 ".section .fixup,\"ax\"\n" \
50 ".section __ex_table,\"a\"\n" \
54 : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
56 : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
59 #elif defined (__x86_64__)
60 #define __stp_strncpy_from_user(dst,src,count,res) \
62 long __d0, __d1, __d2; \
63 __asm__ __volatile__( \
68 " testb %%al,%%al\n" \
74 ".section .fixup,\"ax\"\n" \
78 ".section __ex_table,\"a\"\n" \
82 : "=r"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \
84 : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
87 #elif defined (__powerpc__) || defined (__arm__)
88 #define __stp_strncpy_from_user(dst,src,count,res) \
89 do { res = __strncpy_from_user(dst, src, count); } while(0)
91 #elif defined (__s390__) || defined (__s390x__)|| defined (__aarch64__)
92 #define __stp_strncpy_from_user(dst,src,count,res) \
93 do { res = strncpy_from_user(dst, src, count); } while(0)
94 #elif defined (__ia64__)
95 #define __stp_strncpy_from_user(dst,src,count,res) \
96 do { res = __strncpy_from_user(dst, src, count); } while(0)
98 #endif /* !CONFIG_GENERIC_STRNCPY_FROM_USER */
101 /** Copy a NULL-terminated string from userspace.
102 * On success, returns the length of the string (not including the trailing
105 * If access to userspace fails, returns -EFAULT (some data may have been
107 * @param dst Destination address, in kernel space. This buffer must be at
108 * least <i>count</i> bytes long.
109 * @param src Source address, in user space.
110 * @param count Maximum number of bytes to copy, including the trailing NULL.
112 * If <i>count</i> is smaller than the length of the string, copies
113 * <i>count</i> bytes and returns <i>count</i>.
116 /* XXX: see also kread/uread in loc2c-runtime.h */
117 static long _stp_strncpy_from_user(char *dst
, const char __user
*src
, long count
)
120 mm_segment_t _oldfs
= get_fs();
123 if (access_ok(VERIFY_READ
, src
, count
)) /* XXX: bad_addr? */
124 __stp_strncpy_from_user(dst
, src
, count
, res
);
130 /** Copy a block of data from user space.
132 * If data could not be copied, this function will not modify the
135 * @param dst Destination address, in kernel space.
136 * @param src Source address, in user space.
137 * @param count Number of bytes to copy.
138 * @return number of bytes that could not be copied. On success,
143 /* XXX: see also kread/uread in loc2c-runtime.h */
144 static unsigned long _stp_copy_from_user(char *dst
, const char __user
*src
, unsigned long count
)
147 mm_segment_t _oldfs
= get_fs();
150 if (access_ok(VERIFY_READ
, src
, count
))
151 count
= __copy_from_user_inatomic(dst
, src
, count
);
153 /* Notice that if we fail, we don't modify
154 * the destination. In the failure case, we
155 * can't trust 'count' to be reasonable. */
164 #endif /* _STAPLINUX_COPY_C_ */
This page took 0.042914 seconds and 5 git commands to generate.