1*f0089e39SRichard Lowe /*
2*f0089e39SRichard Lowe * CDDL HEADER START
3*f0089e39SRichard Lowe *
4*f0089e39SRichard Lowe * The contents of this file are subject to the terms of the
5*f0089e39SRichard Lowe * Common Development and Distribution License, Version 1.0 only
6*f0089e39SRichard Lowe * (the "License"). You may not use this file except in compliance
7*f0089e39SRichard Lowe * with the License.
8*f0089e39SRichard Lowe *
9*f0089e39SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*f0089e39SRichard Lowe * or http://www.opensolaris.org/os/licensing.
11*f0089e39SRichard Lowe * See the License for the specific language governing permissions
12*f0089e39SRichard Lowe * and limitations under the License.
13*f0089e39SRichard Lowe *
14*f0089e39SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
15*f0089e39SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*f0089e39SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
17*f0089e39SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
18*f0089e39SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
19*f0089e39SRichard Lowe *
20*f0089e39SRichard Lowe * CDDL HEADER END
21*f0089e39SRichard Lowe */
22*f0089e39SRichard Lowe /*
23*f0089e39SRichard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24*f0089e39SRichard Lowe * Use is subject to license terms.
25*f0089e39SRichard Lowe */
26*f0089e39SRichard Lowe
27*f0089e39SRichard Lowe /*
28*f0089e39SRichard Lowe * Miscellaneous C routines for copying data around without
29*f0089e39SRichard Lowe * descending into assembler. Compilers are pretty good at
30*f0089e39SRichard Lowe * scheduling instructions, and humans are pretty hopeless at
31*f0089e39SRichard Lowe * writing correct assembler.
32*f0089e39SRichard Lowe */
33*f0089e39SRichard Lowe
34*f0089e39SRichard Lowe #include <sys/types.h>
35*f0089e39SRichard Lowe #include <sys/systm.h>
36*f0089e39SRichard Lowe #include <sys/errno.h>
37*f0089e39SRichard Lowe #include <sys/param.h>
38*f0089e39SRichard Lowe
39*f0089e39SRichard Lowe /*
40*f0089e39SRichard Lowe * copyinstr_noerr and copyoutstr_noerr can be implemented completely
41*f0089e39SRichard Lowe * in C on machines with shared user and kernel context.
42*f0089e39SRichard Lowe */
43*f0089e39SRichard Lowe static int
copystr_nofault(const char * src,char * dst,size_t maxlength,size_t * lencopied)44*f0089e39SRichard Lowe copystr_nofault(const char *src, char *dst, size_t maxlength,
45*f0089e39SRichard Lowe size_t *lencopied)
46*f0089e39SRichard Lowe {
47*f0089e39SRichard Lowe int error = 0;
48*f0089e39SRichard Lowe size_t leftover;
49*f0089e39SRichard Lowe
50*f0089e39SRichard Lowe if ((leftover = maxlength) == 0)
51*f0089e39SRichard Lowe error = ENAMETOOLONG;
52*f0089e39SRichard Lowe else
53*f0089e39SRichard Lowe do {
54*f0089e39SRichard Lowe leftover--;
55*f0089e39SRichard Lowe if ((*dst++ = *src++) == '\0')
56*f0089e39SRichard Lowe break;
57*f0089e39SRichard Lowe if (leftover == 0) {
58*f0089e39SRichard Lowe error = ENAMETOOLONG;
59*f0089e39SRichard Lowe break;
60*f0089e39SRichard Lowe }
61*f0089e39SRichard Lowe /*CONSTCOND*/
62*f0089e39SRichard Lowe } while (1);
63*f0089e39SRichard Lowe
64*f0089e39SRichard Lowe if (lencopied)
65*f0089e39SRichard Lowe *lencopied = maxlength - leftover;
66*f0089e39SRichard Lowe return (error);
67*f0089e39SRichard Lowe }
68*f0089e39SRichard Lowe
69*f0089e39SRichard Lowe
70*f0089e39SRichard Lowe int
copyinstr_noerr(const char * uaddr,char * kaddr,size_t maxlength,size_t * lencopied)71*f0089e39SRichard Lowe copyinstr_noerr(const char *uaddr, char *kaddr, size_t maxlength,
72*f0089e39SRichard Lowe size_t *lencopied)
73*f0089e39SRichard Lowe {
74*f0089e39SRichard Lowe char *ua = (char *)uaddr;
75*f0089e39SRichard Lowe
76*f0089e39SRichard Lowe ASSERT((uintptr_t)kaddr > kernelbase);
77*f0089e39SRichard Lowe
78*f0089e39SRichard Lowe if ((uintptr_t)ua > kernelbase) {
79*f0089e39SRichard Lowe /*
80*f0089e39SRichard Lowe * force fault at kernelbase
81*f0089e39SRichard Lowe */
82*f0089e39SRichard Lowe ua = (char *)kernelbase;
83*f0089e39SRichard Lowe }
84*f0089e39SRichard Lowe return (copystr_nofault(ua, kaddr, maxlength, lencopied));
85*f0089e39SRichard Lowe }
86*f0089e39SRichard Lowe
87*f0089e39SRichard Lowe int
copyoutstr_noerr(const char * kaddr,char * uaddr,size_t maxlength,size_t * lencopied)88*f0089e39SRichard Lowe copyoutstr_noerr(const char *kaddr, char *uaddr, size_t maxlength,
89*f0089e39SRichard Lowe size_t *lencopied)
90*f0089e39SRichard Lowe {
91*f0089e39SRichard Lowe char *ua = (char *)uaddr;
92*f0089e39SRichard Lowe
93*f0089e39SRichard Lowe ASSERT((uintptr_t)kaddr > kernelbase);
94*f0089e39SRichard Lowe
95*f0089e39SRichard Lowe if ((uintptr_t)ua > kernelbase) {
96*f0089e39SRichard Lowe /*
97*f0089e39SRichard Lowe * force fault at kernelbase
98*f0089e39SRichard Lowe */
99*f0089e39SRichard Lowe ua = (char *)kernelbase;
100*f0089e39SRichard Lowe }
101*f0089e39SRichard Lowe return (copystr_nofault(kaddr, ua, maxlength, lencopied));
102*f0089e39SRichard Lowe }
103