home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / lxapi32.zip / Include / asm / uaccess.h < prev   
C/C++ Source or Header  |  2002-04-26  |  8KB  |  254 lines

  1. /* $Id: uaccess.h,v 1.2 2002/04/26 23:09:21 smilcke Exp $ */
  2.  
  3. #ifndef __i386_UACCESS_H
  4. #define __i386_UACCESS_H
  5.  
  6. /*
  7.  * User space memory access functions
  8.  */
  9. //#include <linux/config.h>
  10. //#include <linux/sched.h>
  11. #include <asm/page.h>
  12.  
  13. #define VERIFY_READ 0
  14. #define VERIFY_WRITE 1
  15.  
  16. /*
  17.  * The fs value determines whether argument validity checking should be
  18.  * performed or not.  If get_fs() == USER_DS, checking is performed, with
  19.  * get_fs() == KERNEL_DS, checking is bypassed.
  20.  *
  21.  * For historical reasons, these macros are grossly misnamed.
  22.  */
  23.  
  24. #define MAKE_MM_SEG(s)    ((mm_segment_t) { (s) })
  25.  
  26.  
  27. #define KERNEL_DS    MAKE_MM_SEG(0xFFFFFFFF)
  28. #define USER_DS        MAKE_MM_SEG(PAGE_OFFSET)
  29.  
  30. #define get_ds()    (KERNEL_DS)
  31. #define get_fs()    (current->addr_limit)
  32. #define set_fs(x)    (current->addr_limit = (x))
  33.  
  34. #define segment_eq(a,b)    ((a).seg == (b).seg)
  35.  
  36. extern int __verify_write(const void *, unsigned long);
  37.  
  38. #define __addr_ok(addr) ((unsigned long)(addr) < (current->addr_limit.seg))
  39.  
  40. /*
  41.  * Uhhuh, this needs 33-bit arithmetic. We have a carry..
  42.  */
  43.  
  44. #if (defined(TARGET_OS2) && !defined(NOOS2LXAPI))
  45. extern int (*is_access_ok)(int type,void *addr,unsigned long size);
  46. #else
  47. int is_access_ok(int type, void *addr, unsigned long size);
  48. #endif
  49.  
  50. #define access_ok(type, addr, size)    is_access_ok((int)type, (void *)addr, size)
  51.  
  52. #define verify_area(type, addr, size) (access_ok(type, (void *)addr,size) ? 0 : -EFAULT)
  53.  
  54.  
  55. /*
  56.  * The exception table consists of pairs of addresses: the first is the
  57.  * address of an instruction that is allowed to fault, and the second is
  58.  * the address at which the program should continue.  No registers are
  59.  * modified, so it is entirely up to the continuation code to figure out
  60.  * what to do.
  61.  *
  62.  * All the routines below use bits of fixup code that are out of line
  63.  * with the main instruction path.  This means when everything is well,
  64.  * we don't even have to jump over them.  Further, they do not intrude
  65.  * on our cache or tlb entries.
  66.  */
  67.  
  68. struct exception_table_entry
  69. {
  70.     unsigned long insn, fixup;
  71. };
  72.  
  73. /* Returns 0 if exception not found and fixup otherwise.  */
  74. extern unsigned long search_exception_table(unsigned long);
  75.  
  76.  
  77. /*
  78.  * These are the main single-value transfer routines.  They automatically
  79.  * use the right size if we just have the right pointer type.
  80.  *
  81.  * This gets kind of ugly. We want to return _two_ values in "get_user()"
  82.  * and yet we don't want to do any pointers, because that is too much
  83.  * of a performance impact. Thus we have a few rather ugly macros here,
  84.  * and hide all the uglyness from the user.
  85.  *
  86.  * The "__xxx" versions of the user access functions are versions that
  87.  * do not verify the address space, that must have been done previously
  88.  * with a separate "access_ok()" call (this is used when we do multiple
  89.  * accesses to the same area of user memory).
  90.  */
  91.  
  92. /* Careful: we have to cast the result to the type of the pointer for sign reasons */
  93. #if (defined(TARGET_OS2) && !defined(NOOS2LXAPI))
  94. extern int (*get_user)(int size,void *dest,void *src);
  95. #else
  96. int get_user(int size, void *dest, void *src);
  97. #endif
  98.  
  99. extern void __put_user_bad(void);
  100.  
  101. #if (defined(TARGET_OS2) && !defined(NOOS2LXAPI))
  102. extern int (*put_user)(int x,void *ptr);
  103. #else
  104. int put_user(int x, void *ptr);
  105. #endif
  106.  
  107. #define __get_user(x,ptr) \
  108.   __get_user_nocheck((x),(ptr),sizeof(*(ptr)))
  109.  
  110. int __put_user(int size, int x, void *ptr);
  111.  
  112. #define __put_user_nocheck(x,ptr,size)            lksjdflksdjf
  113.  
  114. #define __put_user_size(x,ptr,size,retval)        asdlkfjsdklfj
  115.  
  116. struct __large_struct { unsigned long buf[100]; };
  117. #define __m(x) (*(struct __large_struct *)(x))
  118.  
  119. /*
  120.  * Tell gcc we read from memory instead of writing: this is because
  121.  * we do not write to any memory gcc knows about, so there are no
  122.  * aliasing issues.
  123.  */
  124. #define __put_user_asm(x, addr, err, itype, rtype, ltype)    lksjdf
  125.  
  126.  
  127. #define __get_user_nocheck(x,ptr,size)                lsjdf
  128.  
  129. extern long __get_user_bad(void);
  130.  
  131. #define __get_user_size(x,ptr,size,retval)        ksjdf
  132.  
  133. #define __get_user_asm(x, addr, err, itype, rtype, ltype)    sldkjf
  134.  
  135. /*
  136.  * The "xxx_ret" versions return constant specified in third argument, if
  137.  * something bad happens. These macros can be optimized for the
  138.  * case of just returning from the function xxx_ret is used.
  139.  */
  140.  
  141. #define put_user_ret(x,ptr,ret) ({ if (put_user(x,ptr)) return ret; })
  142.  
  143. #define get_user_ret(x,ptr,ret) if (get_user(sizeof(x), (void *)&x, (void *)ptr)) return ret;
  144.  
  145.  
  146. /*
  147.  * Copy To/From Userspace
  148.  */
  149.  
  150. /* Generic arbitrary sized copy.  */
  151. #if (defined(TARGET_OS2) && !defined(NOOS2LXAPI))
  152. extern void (*__copy_user)(void *to,const void *from,unsigned long n);
  153. #else
  154. void __copy_user(void *to, const void *from, unsigned long n);
  155. #endif
  156.  
  157. #if (defined(TARGET_OS2) && !defined(NOOS2LXAPI))
  158. extern void (*__copy_user_zeroing)(void *to,const void *from,unsigned long n);
  159. #else
  160. void __copy_user_zeroing(void *to, const void *from, unsigned long n);
  161. #endif
  162.  
  163. /* We let the __ versions of copy_from/to_user inline, because they're often
  164.  * used in fast paths and have only a small space overhead.
  165.  */
  166. static __inline unsigned long
  167. __generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
  168. {
  169.     __copy_user_zeroing(to,from,n);
  170.     return n;
  171. }
  172.  
  173. static __inline unsigned long
  174. __generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
  175. {
  176.     __copy_user(to,from,n);
  177.     return n;
  178. }
  179.  
  180.  
  181. /* Optimize just a little bit when we know the size of the move. */
  182. void __constant_copy_user(void *to, const void *from, unsigned long n);
  183.  
  184. /* Optimize just a little bit when we know the size of the move. */
  185. void __constant_copy_user_zeroing(void *to, const void *from, unsigned long n);
  186.  
  187. unsigned long __generic_copy_to_user(void *, const void *, unsigned long);
  188. unsigned long __generic_copy_from_user(void *, const void *, unsigned long);
  189.  
  190. static __inline unsigned long
  191. __constant_copy_to_user(void *to, const void *from, unsigned long n)
  192. {
  193.     if (access_ok(VERIFY_WRITE, to, n))
  194.         __constant_copy_user(to,from,n);
  195.     return n;
  196. }
  197.  
  198. static __inline unsigned long
  199. __constant_copy_from_user(void *to, const void *from, unsigned long n)
  200. {
  201.     if (access_ok(VERIFY_READ, (void *)from, n))
  202.         __constant_copy_user_zeroing(to,from,n);
  203.     return n;
  204. }
  205.  
  206. static __inline unsigned long
  207. __constant_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
  208. {
  209.     __constant_copy_user(to,from,n);
  210.     return n;
  211. }
  212.  
  213. static __inline unsigned long
  214. __constant_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
  215. {
  216.     __constant_copy_user_zeroing(to,from,n);
  217.     return n;
  218. }
  219.  
  220. #if (defined(TARGET_OS2) && !defined(NOOS2LXAPI))
  221. extern unsigned long (*copy_to_user)(void *to,const void *from,unsigned long n);
  222. #else
  223. unsigned long copy_to_user(void *to, const void *from, unsigned long n);
  224. #endif
  225.  
  226. #if (defined(TARGET_OS2) && !defined(NOOS2LXAPI))
  227. extern unsigned long (*copy_from_user)(void *to,const void *from,unsigned long n);
  228. #else
  229. unsigned long copy_from_user(void *to, const void *from, unsigned long n);
  230. #endif
  231.  
  232. #define copy_to_user_ret(to,from,n,retval) ({ if (copy_to_user(to,from,n)) return retval; })
  233.  
  234. #define copy_from_user_ret(to,from,n,retval) ({ if (copy_from_user(to,from,n)) return retval; })
  235.  
  236. #define __copy_to_user(to,from,n)            \
  237.     (__builtin_constant_p(n) ?            \
  238.      __constant_copy_to_user_nocheck((to),(from),(n)) :    \
  239.      __generic_copy_to_user_nocheck((to),(from),(n)))
  240.  
  241. #define __copy_from_user(to,from,n)            \
  242.     (__builtin_constant_p(n) ?            \
  243.      __constant_copy_from_user_nocheck((to),(from),(n)) :    \
  244.      __generic_copy_from_user_nocheck((to),(from),(n)))
  245.  
  246. long strncpy_from_user(char *dst, const char *src, long count);
  247. long __strncpy_from_user(char *dst, const char *src, long count);
  248. #define strlen_user(str) strnlen_user(str, ~0UL >> 1)
  249. long strnlen_user(const char *str, long n);
  250. unsigned long clear_user(void *mem, unsigned long len);
  251. unsigned long __clear_user(void *mem, unsigned long len);
  252.  
  253. #endif /* __i386_UACCESS_H */
  254.