4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
29 * The strlcpy() function copies at most dstsize-1 characters
30 * (dstsize being the size of the string buffer dst) from src
31 * to dst, truncating src if necessary. The result is always
32 * null-terminated. The function returns strlen(src). Buffer
33 * overflow can be checked as follows:
35 * if (strlcpy(dst, src, dstsize) >= dstsize)
39 #include <sys/asm_linkage.h>
41 ! strlcpy implementation is similar to that of strcpy
, except
42 ! in this case
, the maximum size of the detination must
be
43 ! tracked since it bounds our maximum copy size. However
,
44 ! we must still continue to check for zero since the routine
45 ! is expected to null-terminate any string that is within
46 ! the dest size bound.
48 ! this method starts by checking for
and arranging source alignment.
49 ! Once this has occurred
, we copy based upon destination alignment.
50 ! This is either by word
, halfword
, or byte. As this occurs
, we
51 ! check for
a zero-byte. If one is found
, we branch to
a method
52 ! which checks for the exact location of
a zero-byte within
a
53 ! larger word
/half-word quantity.
58 save
%sp
, -SA
(WINDOWSIZE
), %sp
59 subcc
%g0
, %i2
, %g4
! n
= -n
or n
== 0 ?
60 bz
,pn
%icc
, .getstrlen ! if 0 do nothing but strlen(src)
61 add %i1
, %i2
, %i3
! i3
= src
+ n
62 andcc
%i1
, 3, %i4
! word aligned?
63 bz
,pn
%icc
, .wordaligned
64 add %i0
, %i2
, %i2
! n
= dst + n
65 sub %i4
, 4, %i4
! bytes until src aligned
68 ldub
[%i3
+ %g4
], %l1
! l1
= src
[]
69 andcc
%l1
, 0xff, %g0
! null byte reached?
70 stub
%l1
, [%i2
+ %g4
] ! dst[] = src
[]
72 add %i2
, %g4
, %i2
! get single dest ptr for strlen
73 addcc
%g4
, 1, %g4
! src+
+ dest+
+ n-
-
74 bz
,pn
%icc
, .forcenullunalign ! n == 0, append null byte
75 addcc
%i4
, 1, %i4
! incr
, check align
80 sethi
%hi
(0x01010101), %i4
81 add %i2
, %g4
, %l0
! l0
= dest
82 or %i4
, %lo
(0x01010101), %i4
83 sub %i2
, 4, %i2
! pre-incr for in cpy loop
84 andcc
%l0
, 3, %g1
! word aligned?
85 bnz
%icc
, .dstnotaligned
86 sll
%i4
, 7, %i5
! Mycroft part deux
89 ld [%i3
+ %g4
], %l1
! l1
= src
[]
90 addcc
%g4
, 4, %g4
! n
+= 4, src
+= 4, dst +=4
91 bcs
,pn
%icc
, .lastword
92 andn
%i5
, %l1
, %g1
! ~word
& 0x80808080
93 sub %l1
, %i4
, %l0
! word
- 0x01010101
94 andcc
%l0
, %g1
, %g0
! doit
95 bz
,a,pt
%icc
, .storeword ! if expr == 0, no zero byte
96 st %l1
, [%i2
+ %g4
] ! dst[] = src
[]
99 add %i2
, %g4
, %i2
! ptr to dest
100 srl
%l1
, 24, %g1
! 1st byte
101 andcc
%g1
, 0xff, %g0
! test for end
103 stb %g1
, [%i2
] ! store byte
104 add %i2
, 1, %i2
! dst ++
105 srl
%l1
, 16, %g1
! 2nd byte
106 andcc
%g1
, 0xff, %g0
! zero byte ?
108 stb %g1
, [%i2
] ! store byte
109 add %i2
, 1, %i2
! dst ++
110 srl
%l1
, 8, %g1
! 3rd byte
111 andcc
%g1
, 0xff, %g0
! zero byte ?
113 stb %g1
, [%i2
] ! store byte
114 stb %l1
, [%i2
+ 1] ! store last byte
115 add %i2
, 1, %i2
! dst ++
118 sub %i2
, %i0
, %i0
! len
= dst - orig
dst
120 restore
%i0
, %g0
, %o0
124 sub %g4
, 4, %g4
! undo pre-incr
127 srl
%l1
, 24, %g1
! 1st byte
128 andcc
%g1
, 0xff, %g0
! zero byte?
130 stb %g1
, [%i2
] ! store byte
133 srl
%l1
, 16, %g1
! 2nd byte
134 add %i2
, 1, %i2
! dst+
+
135 andcc
%g1
, 0xff, %g0
! zero?
137 stb %g1
, [%i2
] ! store
140 srl
%l1
, 8, %g1
! 3rd byte
141 add %i2
, 1, %i2
! dst+
+
142 andcc
%g1
, 0xff, %g0
! zero?
144 stb %g1
, [%i2
] ! store
147 andcc
%l1
, 0xff, %g0
! zero?
148 add %i2
, 1, %i2
! dst+
+
158 andn
%i5
, %l1
, %g1
! word
& 0x80808080
159 sub %l1
, %i4
, %l0
! word
- 0x01010101
160 andcc
%l0
, %g1
, %g0
! do it
161 bz
,a,pt
%icc
, .searchword
162 add %i3
, 4, %i3
! src
+= 4
165 sll
%i5
, 24, %i5
! mask
1st byte
= 0xff000000
167 andcc
%l1
, %i5
, %g0
! cur byte
0?
168 srl
%i5
, 8, %i5
! mask next byte
169 bnz
,a %icc
, .searchbyte ! cur !=0 continue
173 sub %i3
, %i1
, %i0
! len
= src
- orig src
175 restore
%i0
, %g0
, %o0
179 cmp %g1
, 2 ! halfword aligned?
183 ld [%i3
+ %g4
], %l1
! load src word
184 addcc
%g4
, 4, %g4
! src
+=4 dst +=4
185 bcs
,pn
%icc
, .lastword
186 andn
%i5
, %l1
, %g1
! ~x
& 0x80808080
187 sub %l1
, %i4
, %l0
! x
- 0x01010101
188 andcc
%l0
, %g1
, %g0
! get your Mycroft on
189 bnz
,pn
%icc
, .zerobyte ! non-zero, we have zero byte
190 add %i2
, %g4
, %l0
! dst in ptr form
191 srl
%l1
, 24, %g1
! get
1st byte
, then
be hw aligned
193 srl
%l1
, 8, %g1
! 2nd
& 3rd bytes
196 stb %l1
, [%l0
+ 3] ! store
4th byte
199 ld [%i3
+ %g4
], %l1
! src word
201 addcc
%g4
, 4, %g4
! src
+= 4 dst += 4
202 bcs
,pn
%icc
, .lastword
203 andn
%i5
, %l1
, %g1
! ~x
& 0x80808080
204 sub %l1
, %i4
, %l0
! x
- 0x01010101
205 andcc
%l0
, %g1
, %g0
! Mycroft again.
..
206 bnz
,pn
%icc
, .zerobyte ! non-zer, we have zero byte
207 add %i2
, %g4
, %l0
! dst in ptr form
208 srl
%l1
, 16, %g1
! first two bytes
214 add %i2
, %g4
, %i2
! single
dst ptr
215 stb %g0
, [%i2
- 1] ! store terminating null byte
218 sethi
%hi
(0x01010101), %i4
! Mycroft.
..
219 or %i4
, %lo
(0x01010101), %i4
223 andcc
%i3
, 3, %g0
! word aligned?
224 bz
,a,pn
%icc
, .searchword2 ! search word at a time
225 ld [%i3
], %l1
! src word
226 ldub
[%i3
], %l1
! src byte
227 andcc
%l1
, 0xff, %g0
! end of src?
228 bnz
,a %icc
, .getstrlenloop
229 add %i3
, 1, %i3
! src
++
230 sub %i3
, %i1
, %i0
! len
= src
- orig src
232 restore
%i0
, %g0
, %o0