fe4304baf2
First of all, thanks to Bob Tracy <rct@frus.com> and Michael Cree <mcree@orcon.net.nz> for testing. Especially to Bob, as he has done titanic multi-day git-bisect work that finally helped to reproduce and nail down the bug (http://bugzilla.kernel.org/show_bug.cgi?id=9457). [ev6-]stxncpy.S: it's t12, not t2 register that is supposed to contain the last byte offset upon return. As a result of wrong register use (which was my fault back in 2003, IIRC), under some circumstances extra terminating zero bytes were added to destination string. This particularly led to incorrect DEVPATH strings generated in uevent and therefore to udev problems. strncpy.S: unrelated bug I found while testing the above fix - destination is not properly zero-padded then a byte count exceeds source length. Actually this is addition to strncpy fix from last year. Signed-off-by: Ivan Kokshaysky <ink@jurassic.park.msu.ru> Cc: Richard Henderson <rth@twiddle.net> Cc: Bob Tracy <rct@frus.com> Cc: Michael Cree <mcree@orcon.net.nz> Cc: Kay Sievers <kay.sievers@vrfy.org> Cc: "Rafael J. Wysocki" <rjw@sisk.pl> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
81 lines
1.5 KiB
ArmAsm
81 lines
1.5 KiB
ArmAsm
/*
|
|
* arch/alpha/lib/strncpy.S
|
|
* Contributed by Richard Henderson (rth@tamu.edu)
|
|
*
|
|
* Copy no more than COUNT bytes of the null-terminated string from
|
|
* SRC to DST. If SRC does not cover all of COUNT, the balance is
|
|
* zeroed.
|
|
*
|
|
* Or, rather, if the kernel cared about that weird ANSI quirk. This
|
|
* version has cropped that bit o' nastiness as well as assuming that
|
|
* __stxncpy is in range of a branch.
|
|
*/
|
|
|
|
.set noat
|
|
.set noreorder
|
|
|
|
.text
|
|
|
|
.align 4
|
|
.globl strncpy
|
|
.ent strncpy
|
|
strncpy:
|
|
.frame $30, 0, $26
|
|
.prologue 0
|
|
|
|
mov $16, $0 # set return value now
|
|
beq $18, $zerolen
|
|
unop
|
|
bsr $23, __stxncpy # do the work of the copy
|
|
|
|
unop
|
|
bne $18, $multiword # do we have full words left?
|
|
subq $24, 1, $3 # nope
|
|
subq $27, 1, $4
|
|
|
|
or $3, $24, $3 # clear the bits between the last
|
|
or $4, $27, $4 # written byte and the last byte in COUNT
|
|
andnot $3, $4, $4
|
|
zap $1, $4, $1
|
|
|
|
stq_u $1, 0($16)
|
|
ret
|
|
|
|
.align 4
|
|
$multiword:
|
|
subq $27, 1, $2 # clear the final bits in the prev word
|
|
or $2, $27, $2
|
|
zapnot $1, $2, $1
|
|
subq $18, 1, $18
|
|
|
|
stq_u $1, 0($16)
|
|
addq $16, 8, $16
|
|
unop
|
|
beq $18, 1f
|
|
|
|
nop
|
|
unop
|
|
nop
|
|
blbc $18, 0f
|
|
|
|
stq_u $31, 0($16) # zero one word
|
|
subq $18, 1, $18
|
|
addq $16, 8, $16
|
|
beq $18, 1f
|
|
|
|
0: stq_u $31, 0($16) # zero two words
|
|
subq $18, 2, $18
|
|
stq_u $31, 8($16)
|
|
addq $16, 16, $16
|
|
bne $18, 0b
|
|
|
|
1: ldq_u $1, 0($16) # clear the leading bits in the final word
|
|
subq $24, 1, $2
|
|
or $2, $24, $2
|
|
|
|
zap $1, $2, $1
|
|
stq_u $1, 0($16)
|
|
$zerolen:
|
|
ret
|
|
|
|
.end strncpy
|