2009-03-15  Ulrich Drepper  <drepper@redhat.com>
	[BZ #5807]
	* string/strlen.c (strlen): Fix omission in the expression to test
	for NUL bytes.
This commit is contained in:
Ulrich Drepper 2009-03-15 09:03:38 +00:00
parent fad070abc4
commit 71a5bd3e17
4 changed files with 36 additions and 151 deletions

View File

@ -1,3 +1,9 @@
2009-03-15 Ulrich Drepper <drepper@redhat.com>
[BZ #5807]
* string/strlen.c (strlen): Fix omission in the expression to test
for NUL bytes.
2009-03-14 Ulrich Drepper <drepper@redhat.com>
* crypt/sha256test.c (main): Perform 100,000 'a' test in a second way.

View File

@ -1,3 +1,9 @@
2009-03-15 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
(__pthread_cond_timedwait): Change to use cfi directives instead of
hand-coded unwind sections.
2009-03-10 Ulrich Drepper <drepper@redhat.com>
* init.c (nptl_freeres): Compile only for SHARED.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
/* Copyright (C) 2002-2005, 2007, 2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
@ -37,16 +37,19 @@
.type __pthread_cond_timedwait, @function
.align 16
__pthread_cond_timedwait:
.LSTARTCODE:
cfi_startproc
pushq %r12
.Lpush_r12:
cfi_adjust_cfa_offset(8)
cfi_rel_offset(%r12, 0)
pushq %r13
.Lpush_r13:
cfi_adjust_cfa_offset(8)
cfi_rel_offset(%r13, 0)
pushq %r14
.Lpush_r14:
cfi_adjust_cfa_offset(8)
cfi_rel_offset(%r14, 0)
#define FRAME_SIZE 80
subq $FRAME_SIZE, %rsp
.Lsubq:
cfi_adjust_cfa_offset(FRAME_SIZE)
cmpq $1000000000, 8(%rdx)
movl $EINVAL, %eax
@ -305,19 +308,25 @@ __pthread_cond_timedwait:
cmoveq %r14, %rax
18: addq $FRAME_SIZE, %rsp
.Laddq:
cfi_adjust_cfa_offset(-FRAME_SIZE)
popq %r14
.Lpop_r14:
cfi_adjust_cfa_offset(-8)
cfi_restore(%r14)
popq %r13
.Lpop_r13:
cfi_adjust_cfa_offset(-8)
cfi_restore(%r13)
popq %r12
.Lpop_r12:
cfi_adjust_cfa_offset(-8)
cfi_restore(%r12)
retq
/* Initial locking failed. */
1:
.LSbl1:
cfi_adjust_cfa_offset(3 * 8 + FRAME_SIZE)
cfi_rel_offset(%r12, FRAME_SIZE + 16)
cfi_rel_offset(%r13, FRAME_SIZE + 8)
cfi_rel_offset(%r14, FRAME_SIZE)
#if cond_lock != 0
addq $cond_lock, %rdi
#endif
@ -414,97 +423,7 @@ __pthread_cond_timedwait:
js 6b
jmp 21b
#endif
.LENDCODE:
cfi_endproc
.size __pthread_cond_timedwait, .-__pthread_cond_timedwait
versioned_symbol (libpthread, __pthread_cond_timedwait, pthread_cond_timedwait,
GLIBC_2_3_2)
.section .eh_frame,"a",@progbits
.LSTARTFRAME:
.long L(ENDCIE)-L(STARTCIE) # Length of the CIE.
.LSTARTCIE:
.long 0 # CIE ID.
.byte 1 # Version number.
#ifdef SHARED
.string "zR" # NUL-terminated augmentation
# string.
#else
.ascii "\0" # NUL-terminated augmentation
# string.
#endif
.uleb128 1 # Code alignment factor.
.sleb128 -8 # Data alignment factor.
.byte 16 # Return address register
# column.
#ifdef SHARED
.uleb128 1 # Augmentation value length.
.byte 0x1b # Encoding: DW_EH_PE_pcrel
# + DW_EH_PE_sdata4.
#endif
.byte 0x0c # DW_CFA_def_cfa
.uleb128 7
.uleb128 8
.byte 0x90 # DW_CFA_offset, column 0x8
.uleb128 1
.align 8
.LENDCIE:
.long .LENDFDE-.LSTARTFDE # Length of the FDE.
.LSTARTFDE:
.long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
#ifdef SHARED
.long .LSTARTCODE-. # PC-relative start address
# of the code
#else
.long .LSTARTCODE # Start address of the code.
#endif
.long .LENDCODE-.LSTARTCODE # Length of the code.
#ifdef SHARED
.uleb128 0 # No augmentation data.
#endif
.byte 0x40+.Lpush_r12-.LSTARTCODE # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 16
.byte 0x8c # DW_CFA_offset %r12
.uleb128 2
.byte 0x40+.Lpush_r13-.Lpush_r12 # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 24
.byte 0x8d # DW_CFA_offset %r13
.uleb128 3
.byte 0x40+.Lpush_r14-.Lpush_r13 # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 32
.byte 0x84 # DW_CFA_offset %r14
.uleb128 4
.byte 0x40+.Lsubq-.Lpush_r14 # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 32+FRAME_SIZE
.byte 3 # DW_CFA_advance_loc2
.2byte .Laddq-.Lsubq
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 32
.byte 0x40+.Lpop_r14-.Laddq # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 24
.byte 0xce # DW_CFA_restore %r14
.byte 0x40+.Lpop_r13-.Lpop_r14 # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 16
.byte 0xcd # DW_CFA_restore %r13
.byte 0x40+.Lpop_r12-.Lpop_r13 # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 8
.byte 0xcc # DW_CFA_restore %r12
.byte 0x40+.LSbl1-.Lpop_r12 # DW_CFA_advance_loc+N
.byte 14 # DW_CFA_def_cfa_offset
.uleb128 32+FRAME_SIZE
.byte 0x8c # DW_CFA_offset %r12
.uleb128 2
.byte 0x8d # DW_CFA_offset %r13
.uleb128 3
.byte 0x84 # DW_CFA_offset %r14
.uleb128 4
.align 8
.LENDFDE:

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1993, 1997, 2000, 2003 Free Software Foundation, Inc.
/* Copyright (C) 1991,1993,1997,2000,2003,2009 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Torbjorn Granlund (tege@sics.se),
with help from Dan Sahlin (dan@sics.se);
@ -32,7 +32,7 @@ strlen (str)
{
const char *char_ptr;
const unsigned long int *longword_ptr;
unsigned long int longword, magic_bits, himagic, lomagic;
unsigned long int longword, himagic, lomagic;
/* Handle the first few characters by reading one character at a time.
Do this until CHAR_PTR is aligned on a longword boundary. */
@ -56,14 +56,12 @@ strlen (str)
The 1-bits make sure that carries propagate to the next 0-bit.
The 0-bits provide holes for carries to fall into. */
magic_bits = 0x7efefeffL;
himagic = 0x80808080L;
lomagic = 0x01010101L;
if (sizeof (longword) > 4)
{
/* 64-bit version of the magic. */
/* Do the shift in two steps to avoid a warning if long has 32 bits. */
magic_bits = ((0x7efefefeL << 16) << 16) | 0xfefefeffL;
himagic = ((himagic << 16) << 16) | himagic;
lomagic = ((lomagic << 16) << 16) | lomagic;
}
@ -75,53 +73,9 @@ strlen (str)
if *any of the four* bytes in the longword in question are zero. */
for (;;)
{
/* We tentatively exit the loop if adding MAGIC_BITS to
LONGWORD fails to change any of the hole bits of LONGWORD.
1) Is this safe? Will it catch all the zero bytes?
Suppose there is a byte with all zeros. Any carry bits
propagating from its left will fall into the hole at its
least significant bit and stop. Since there will be no
carry from its most significant bit, the LSB of the
byte to the left will be unchanged, and the zero will be
detected.
2) Is this worthwhile? Will it ignore everything except
zero bytes? Suppose every byte of LONGWORD has a bit set
somewhere. There will be a carry into bit 8. If bit 8
is set, this will carry into bit 16. If bit 8 is clear,
one of bits 9-15 must be set, so there will be a carry
into bit 16. Similarly, there will be a carry into bit
24. If one of bits 24-30 is set, there will be a carry
into bit 31, so all of the hole bits will be changed.
The one misfire occurs when bits 24-30 are clear and bit
31 is set; in this case, the hole at bit 31 is not
changed. If we had access to the processor carry flag,
we could close this loophole by putting the fourth hole
at bit 32!
So it ignores everything except 128's, when they're aligned
properly. */
longword = *longword_ptr++;
if (
#if 0
/* Add MAGIC_BITS to LONGWORD. */
(((longword + magic_bits)
/* Set those bits that were unchanged by the addition. */
^ ~longword)
/* Look at only the hole bits. If any of the hole bits
are unchanged, most likely one of the bytes was a
zero. */
& ~magic_bits)
#else
((longword - lomagic) & himagic)
#endif
!= 0)
if (((longword - lomagic) & ~longword & himagic) != 0)
{
/* Which of the bytes was the zero? If none of them were, it was
a misfire; continue the search. */