2000-07-26  Greg McGary  <greg@mcgary.org>

	* Makeconfig (+link-bounded, link-libc-bounded,
	link-extra-libs-bounded): New variables.
	(built-program-cmd): Omit $(run-program-prefix) for static BP tests.
	* Makerules (do-tests-clean, common-mostlyclean): Remove BP test files.
	* Rules (tests-bp.out): New variable.
	(tests): Conditionally add BP tests.
	(binaries-bounded): Add variable and associated rule.
	* csu/Makefile [build-bounded] (extra-objs, install-lib):
	Move conditional stuff after place where condition is defined.

	* malloc/malloc.c (bp-checks.h): Add #include.
	(mem2chunk, chunk_at_offset, bin_at): Wrap BOUNDED_1 around expression.
	(_bin_at): Add unbounded version of bin_at.
	(IAV, chunk_alloc): Use unbounded _bin_at.
	(mALLOc, rEALLOc, chunk_realloc, mEMALIGn, cALLOc,
	chunk2mem_check, realloc_check, malloc_starter, malloc_atfork):
	Wrap BOUNDED_N around return value.
	(chunk_realloc): Adjust oldsize once.

	* sysdeps/generic/bp-checks.h (__memchr): Remove incorrect decl.
	(__ubp_memchr): Add correct decl.
	(_CHECK_STRING): Use __ubp_memchr.
	* sysdeps/alpha/memchr.S [!__BOUNDED_POINTERS__] (__ubp_memchr):
	New alias for unbounded-pointer __memchr.
	* sysdeps/i386/memchr.S: Likewise.
	* sysdeps/ia64/memchr.S: Likewise.
	* sysdeps/m68k/memchr.S: Likewise.
	* sysdeps/sparc/sparc32/memchr.S: Likewise.
	* sysdeps/sparc/sparc64/memchr.S: Likewise.
	* sysdeps/vax/memchr.s: Likewise.

	* sysdeps/i386/strtok.S: Fix bounds checks to pass tests.
	(SAVE_PTR): New macro.  (save_ptr): Expand size as BP.
	(strtok): Don't bother to write into SAVE_PTR when returning NULL.
	* sysdeps/i386/i686/strtok.S: Likewise.
	* sysdeps/i386/bp-asm.h (RETURN_BOUNDED_POINTER,
	RETURN_NULL_BOUNDED_POINTER): Use %ecx as the scratch register.

	* sysdeps/i386/bits/string.h [!__BOUNDED_POINTERS__]: Disable inlines.
	* sysdeps/i386/i486/bits/string.h [!__BOUNDED_POINTERS__]: Likewise.

	* sysdeps/unix/sysv/linux/getsysstats.c (get_proc_path): Copy
	bounds of copy_result to mount_proc.
This commit is contained in:
Greg McGary 2000-07-26 18:21:25 +00:00
parent ac55638813
commit 2ed5fd9a2a
16 changed files with 247 additions and 118 deletions

View File

@ -1,3 +1,49 @@
2000-07-26 Greg McGary <greg@mcgary.org>
* Makeconfig (+link-bounded, link-libc-bounded,
link-extra-libs-bounded): New variables.
(built-program-cmd): Omit $(run-program-prefix) for static BP tests.
* Makerules (do-tests-clean, common-mostlyclean): Remove BP test files.
* Rules (tests-bp.out): New variable.
(tests): Conditionally add BP tests.
(binaries-bounded): Add variable and associated rule.
* csu/Makefile [build-bounded] (extra-objs, install-lib):
Move conditional stuff after place where condition is defined.
* malloc/malloc.c (bp-checks.h): Add #include.
(mem2chunk, chunk_at_offset, bin_at): Wrap BOUNDED_1 around expression.
(_bin_at): Add unbounded version of bin_at.
(IAV, chunk_alloc): Use unbounded _bin_at.
(mALLOc, rEALLOc, chunk_realloc, mEMALIGn, cALLOc,
chunk2mem_check, realloc_check, malloc_starter, malloc_atfork):
Wrap BOUNDED_N around return value.
(chunk_realloc): Adjust oldsize once.
* sysdeps/generic/bp-checks.h (__memchr): Remove incorrect decl.
(__ubp_memchr): Add correct decl.
(_CHECK_STRING): Use __ubp_memchr.
* sysdeps/alpha/memchr.S [!__BOUNDED_POINTERS__] (__ubp_memchr):
New alias for unbounded-pointer __memchr.
* sysdeps/i386/memchr.S: Likewise.
* sysdeps/ia64/memchr.S: Likewise.
* sysdeps/m68k/memchr.S: Likewise.
* sysdeps/sparc/sparc32/memchr.S: Likewise.
* sysdeps/sparc/sparc64/memchr.S: Likewise.
* sysdeps/vax/memchr.s: Likewise.
* sysdeps/i386/strtok.S: Fix bounds checks to pass tests.
(SAVE_PTR): New macro. (save_ptr): Expand size as BP.
(strtok): Don't bother to write into SAVE_PTR when returning NULL.
* sysdeps/i386/i686/strtok.S: Likewise.
* sysdeps/i386/bp-asm.h (RETURN_BOUNDED_POINTER,
RETURN_NULL_BOUNDED_POINTER): Use %ecx as the scratch register.
* sysdeps/i386/bits/string.h [!__BOUNDED_POINTERS__]: Disable inlines.
* sysdeps/i386/i486/bits/string.h [!__BOUNDED_POINTERS__]: Likewise.
* sysdeps/unix/sysv/linux/getsysstats.c (get_proc_path): Copy
bounds of copy_result to mount_proc.
2000-07-25 Bruno Haible <haible@clisp.cons.org>
* wctype/wctype.h (__wctrans_l): New declaration.

View File

@ -653,7 +653,7 @@ do { \
# endif
#endif
#include <bp-checks.h>
#ifndef DEFAULT_TRIM_THRESHOLD
#define DEFAULT_TRIM_THRESHOLD (128 * 1024)
@ -1291,8 +1291,8 @@ static void free_atfork();
/* conversion from malloc headers to user pointers, and back */
#define chunk2mem(p) ((Void_t*)((char*)(p) + 2*SIZE_SZ))
#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
#define chunk2mem(p) ((Void_t*)((char*)(p) + 2*SIZE_SZ))
#define mem2chunk(mem) BOUNDED_1((mchunkptr)((char*)(mem) - 2*SIZE_SZ))
/* pad request bytes into a usable size, return non-zero on overflow */
@ -1339,7 +1339,7 @@ static void free_atfork();
/* Treat space at ptr + offset as a chunk */
#define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s)))
#define chunk_at_offset(p, s) BOUNDED_1((mchunkptr)(((char*)(p)) + (s)))
@ -1406,7 +1406,8 @@ static void free_atfork();
/* access macros */
#define bin_at(a, i) ((mbinptr)((char*)&(((a)->av)[2*(i)+2]) - 2*SIZE_SZ))
#define bin_at(a, i) BOUNDED_1(_bin_at(a, i))
#define _bin_at(a, i) ((mbinptr)((char*)&(((a)->av)[2*(i)+2]) - 2*SIZE_SZ))
#define init_bin(a, i) ((a)->av[2*(i)+2] = (a)->av[2*(i)+3] = bin_at((a), (i)))
#define next_bin(b) ((mbinptr)((char*)(b) + 2 * sizeof(((arena*)0)->av[0])))
#define prev_bin(b) ((mbinptr)((char*)(b) - 2 * sizeof(((arena*)0)->av[0])))
@ -1492,7 +1493,7 @@ static void free_atfork();
/* Static bookkeeping data */
/* Helper macro to initialize bins */
#define IAV(i) bin_at(&main_arena, i), bin_at(&main_arena, i)
#define IAV(i) _bin_at(&main_arena, i), _bin_at(&main_arena, i)
static arena main_arena = {
{
@ -2710,7 +2711,7 @@ Void_t* mALLOc(bytes) size_t bytes;
if(!victim) return 0;
} else
(void)mutex_unlock(&ar_ptr->mutex);
return chunk2mem(victim);
return BOUNDED_N(chunk2mem(victim), bytes);
}
static mchunkptr
@ -2743,7 +2744,7 @@ chunk_alloc(ar_ptr, nb) arena *ar_ptr; INTERNAL_SIZE_T nb;
/* No traversal or size check necessary for small bins. */
q = bin_at(ar_ptr, idx);
q = _bin_at(ar_ptr, idx);
victim = last(q);
/* Also scan the next one, since it would have a remainder < MINSIZE */
@ -2851,7 +2852,7 @@ chunk_alloc(ar_ptr, nb) arena *ar_ptr; INTERNAL_SIZE_T nb;
for (;;)
{
startidx = idx; /* (track incomplete blocks) */
q = bin = bin_at(ar_ptr, idx);
q = bin = _bin_at(ar_ptr, idx);
/* For each bin in this block ... */
do
@ -3229,7 +3230,8 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
#if HAVE_MREMAP
newp = mremap_chunk(oldp, nb);
if(newp) return chunk2mem(newp);
if(newp)
return BOUNDED_N(chunk2mem(newp), bytes);
#endif
/* Note the extra SIZE_SZ overhead. */
if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */
@ -3262,7 +3264,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
newp = chunk_realloc(ar_ptr, oldp, oldsize, nb);
(void)mutex_unlock(&ar_ptr->mutex);
return newp ? chunk2mem(newp) : NULL;
return newp ? BOUNDED_N(chunk2mem(newp), bytes) : NULL;
}
static mchunkptr
@ -3294,6 +3296,7 @@ arena* ar_ptr; mchunkptr oldp; INTERNAL_SIZE_T oldsize, nb;
if ((long)(oldsize) < (long)(nb))
{
Void_t* oldmem = BOUNDED_N(chunk2mem(oldp), oldsize);
/* Try expanding forward */
@ -3329,6 +3332,8 @@ arena* ar_ptr; mchunkptr oldp; INTERNAL_SIZE_T oldsize, nb;
nextsize = 0;
}
oldsize -= SIZE_SZ;
/* Try shifting backwards. */
if (!prev_inuse(oldp))
@ -3348,7 +3353,7 @@ arena* ar_ptr; mchunkptr oldp; INTERNAL_SIZE_T oldsize, nb;
unlink(prev, bck, fwd);
newp = prev;
newsize += prevsize + nextsize;
MALLOC_COPY(chunk2mem(newp), chunk2mem(oldp), oldsize - SIZE_SZ);
MALLOC_COPY(BOUNDED_N(chunk2mem(newp), oldsize), oldmem, oldsize);
top(ar_ptr) = chunk_at_offset(newp, nb);
set_head(top(ar_ptr), (newsize - nb) | PREV_INUSE);
set_head_size(newp, nb);
@ -3363,7 +3368,7 @@ arena* ar_ptr; mchunkptr oldp; INTERNAL_SIZE_T oldsize, nb;
unlink(prev, bck, fwd);
newp = prev;
newsize += nextsize + prevsize;
MALLOC_COPY(chunk2mem(newp), chunk2mem(oldp), oldsize - SIZE_SZ);
MALLOC_COPY(BOUNDED_N(chunk2mem(newp), oldsize), oldmem, oldsize);
goto split;
}
}
@ -3374,7 +3379,7 @@ arena* ar_ptr; mchunkptr oldp; INTERNAL_SIZE_T oldsize, nb;
unlink(prev, bck, fwd);
newp = prev;
newsize += prevsize;
MALLOC_COPY(chunk2mem(newp), chunk2mem(oldp), oldsize - SIZE_SZ);
MALLOC_COPY(BOUNDED_N(chunk2mem(newp), oldsize), oldmem, oldsize);
goto split;
}
}
@ -3414,7 +3419,7 @@ arena* ar_ptr; mchunkptr oldp; INTERNAL_SIZE_T oldsize, nb;
}
/* Otherwise copy, free, and exit */
MALLOC_COPY(chunk2mem(newp), chunk2mem(oldp), oldsize - SIZE_SZ);
MALLOC_COPY(BOUNDED_N(chunk2mem(newp), oldsize), oldmem, oldsize);
chunk_free(ar_ptr, oldp);
return newp;
}
@ -3519,7 +3524,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
}
if(!p) return 0;
}
return chunk2mem(p);
return BOUNDED_N(chunk2mem(p), bytes);
}
static mchunkptr
@ -3727,7 +3732,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
}
if (p == 0) return 0;
}
mem = chunk2mem(p);
mem = BOUNDED_N(chunk2mem(p), n * elem_size);
/* Two optional cases in which clearing not necessary */
@ -3744,7 +3749,8 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
}
#endif
MALLOC_ZERO(mem, csz - SIZE_SZ);
csz -= SIZE_SZ;
MALLOC_ZERO(BOUNDED_N(chunk2mem(p), csz), csz);
return mem;
}
@ -4375,7 +4381,7 @@ chunk2mem_check(mchunkptr p, size_t sz)
chunk2mem_check(p, sz) mchunkptr p; size_t sz;
#endif
{
unsigned char* m_ptr = (unsigned char*)chunk2mem(p);
unsigned char* m_ptr = (unsigned char*)BOUNDED_N(chunk2mem(p), sz);
size_t i;
for(i = chunksize(p) - (chunk_is_mmapped(p) ? 2*SIZE_SZ+1 : SIZE_SZ+1);
@ -4581,7 +4587,8 @@ realloc_check(oldmem, bytes, caller)
/* Must alloc, copy, free. */
newp = (top_check() >= 0) ? chunk_alloc(&main_arena, nb) : NULL;
if (newp) {
MALLOC_COPY(chunk2mem(newp), oldmem, oldsize - 2*SIZE_SZ);
MALLOC_COPY(BOUNDED_N(chunk2mem(newp), nb),
oldmem, oldsize - 2*SIZE_SZ);
munmap_chunk(oldp);
}
}
@ -4598,7 +4605,8 @@ realloc_check(oldmem, bytes, caller)
memset((char*)oldmem + 2*sizeof(mbinptr), 0,
oldsize - (2*sizeof(mbinptr)+2*SIZE_SZ+1));
} else if(nb > oldsize+SIZE_SZ) {
memset((char*)chunk2mem(newp) + oldsize, 0, nb - (oldsize+SIZE_SZ));
memset((char*)BOUNDED_N(chunk2mem(newp), bytes) + oldsize,
0, nb - (oldsize+SIZE_SZ));
}
#endif
#if HAVE_MMAP
@ -4652,7 +4660,7 @@ malloc_starter(sz, caller) size_t sz; const Void_t *caller;
return 0;
victim = chunk_alloc(&main_arena, nb);
return victim ? chunk2mem(victim) : 0;
return victim ? BOUNDED_N(chunk2mem(victim), sz) : 0;
}
static void
@ -4695,7 +4703,7 @@ malloc_atfork(sz, caller) size_t sz; const Void_t *caller;
if(request2size(sz, nb))
return 0;
victim = chunk_alloc(&main_arena, nb);
return victim ? chunk2mem(victim) : 0;
return victim ? BOUNDED_N(chunk2mem(victim), sz) : 0;
} else {
if(top_check()<0 || request2size(sz+1, nb))
return 0;

View File

@ -67,7 +67,7 @@ ENTRY(__memchr)
unop # :
sll a1, 32, t1 #-e0 : t1 = chchchch00000000
or t1, a1, a1 # e1 : a1 = chchchchchchchch
extql t0, a0, t6 # e0 :
extql t0, a0, t6 # e0 :
beq t3, $first_quad # .. e1 :
ldq_u t5, -1(t4) #-e1 : eight or less bytes to search
@ -170,3 +170,6 @@ $not_found:
END(__memchr)
weak_alias (__memchr, memchr)
#if !__BOUNDED_POINTERS__
weak_alias (__memchr, __ubp_memchr)
#endif

View File

@ -26,7 +26,6 @@
#if __BOUNDED_POINTERS__
# define BOUNDS_VIOLATED (__builtin_trap (), 0)
extern int __memchr (const char *__unbounded, int, unsigned);
/* Verify that pointer's value >= low. Return pointer value. */
# define CHECK_BOUNDS_LOW(ARG) \
@ -45,10 +44,12 @@ extern int __memchr (const char *__unbounded, int, unsigned);
&& BOUNDS_VIOLATED), \
__ptrvalue (ARG))
extern void *__unbounded __ubp_memchr (const void *__unbounded, int, unsigned);
# define _CHECK_STRING(ARG, COND) \
(((COND) \
&& (__ptrvalue (ARG) < __ptrlow (ARG) \
|| !__memchr (__ptrvalue (ARG), '\0', \
|| !__ubp_memchr (__ptrvalue (ARG), '\0', \
(__ptrhigh (ARG) - __ptrvalue (ARG)))) \
&& BOUNDS_VIOLATED), \
__ptrvalue (ARG))

View File

@ -28,7 +28,7 @@
/* We only provide optimizations if the user selects them and if
GNU CC is used. */
#if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
&& defined __GNUC__ && __GNUC__ >= 2
&& defined __GNUC__ && __GNUC__ >= 2 && !__BOUNDED_POINTERS__
#ifndef __STRING_INLINE
# ifdef __cplusplus

View File

@ -80,21 +80,21 @@
/* Take bounds from BP_MEM and affix them to the pointer
value in %eax, stuffing all into memory at RTN(%esp).
Use %ecx as a scratch register. */
Use %edx as a scratch register. */
# define RETURN_BOUNDED_POINTER(BP_MEM) \
movl RTN(%esp), %ecx; \
movl %eax, 0(%ecx); \
movl RTN(%esp), %edx; \
movl %eax, 0(%edx); \
movl 4+BP_MEM, %eax; \
movl %eax, 4(%ecx); \
movl %eax, 4(%edx); \
movl 8+BP_MEM, %eax; \
movl %eax, 8(%ecx)
movl %eax, 8(%edx)
# define RETURN_NULL_BOUNDED_POINTER \
movl RTN(%esp), %ecx; \
movl %eax, 0(%ecx); \
movl %eax, 4(%ecx); \
movl %eax, 8(%ecx)
movl RTN(%esp), %edx; \
movl %eax, 0(%edx); \
movl %eax, 4(%edx); \
movl %eax, 8(%edx)
/* The caller of __errno_location is responsible for allocating space
for the three-word BP return-value and passing pushing its address

View File

@ -1,5 +1,5 @@
/* Optimized, inlined string functions. i486 version.
Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -28,7 +28,7 @@
/* We only provide optimizations if the user selects them and if
GNU CC is used. */
#if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
&& defined __GNUC__ && __GNUC__ >= 2
&& defined __GNUC__ && __GNUC__ >= 2 && !__BOUNDED_POINTERS__
#ifndef __STRING_INLINE
# ifdef __cplusplus

View File

@ -39,15 +39,39 @@
We do a common implementation here. */
#ifndef USE_AS_STRTOK_R
#ifdef USE_AS_STRTOK_R
# define SAVE_PTR 0(%ecx)
#else
.bss
.local save_ptr
ASM_TYPE_DIRECTIVE (save_ptr, @object)
.size save_ptr, 4
save_ptr:
# if __BOUNDED_POINTERS__
.space 12
# else
.space 4
# endif
#define FUNCTION BP_SYM (strtok)
# ifdef PIC
# define SAVE_PTR save_ptr@GOTOFF(%ebx)
# else
# define SAVE_PTR save_ptr
# endif
# define FUNCTION strtok
#endif
#if !defined USE_AS_STRTOK_R && defined PIC
# define PARMS LINKAGE+256+4 /* space for table and saved PIC register */
#else
# define PARMS LINKAGE+256 /* space for table */
#endif
#define RTN PARMS
#define STR RTN+RTN_SIZE
#define DELIM STR+PTR_SIZE
#ifdef USE_AS_STRTOK_R
# define SAVE DELIM+PTR_SIZE
#endif
.text
@ -57,12 +81,6 @@ save_ptr:
ret
#endif
#define PARMS LINKAGE /* no space for saved regs */
#define RTN PARMS
#define STR RTN+RTN_SIZE
#define DELIM STR+PTR_SIZE
#define SAVE DELIM+PTR_SIZE
ENTRY (BP_SYM (FUNCTION))
ENTER
@ -89,36 +107,39 @@ ENTRY (BP_SYM (FUNCTION))
/* Note: %ecx = 0 !!! */
movl %edx, %edi
#if !defined USE_AS_STRTOK_R && defined PIC
movl 264(%esp), %edx /* Get start of string. */
#else
movl 260(%esp), %edx /* Get start of string. */
#endif
movl STR(%esp), %edx /* Get start of string. */
#ifdef USE_AS_STRTOK_R
/* The value is stored in the third argument. */
movl 268(%esp), %eax
movl SAVE(%esp), %eax
movl (%eax), %eax
#else
/* The value is in the local variable defined above. But
we have to take care for PIC code. */
# ifndef PIC
movl save_ptr, %eax
# else
movl save_ptr@GOTOFF(%ebx), %eax
# endif
movl SAVE_PTR, %eax
#endif
/* If the pointer is NULL we have to use the stored value of
the last run. */
cmpl $0, %edx
cmove %eax, %edx
#if !defined USE_AS_STRTOK_R && defined PIC
movl 268(%esp), %eax /* Get start of delimiter set. */
#else
movl 264(%esp), %eax /* Get start of delimiter set. */
#if __BOUNDED_POINTERS__
# ifdef USE_AS_STRTOK_R
movl SAVE(%esp), %ecx /* borrow %ecx for a moment */
# endif
je L(0)
/* Save bounds of incoming non-NULL STR into save area. */
movl 4+STR(%esp), %eax
movl %eax, 4+SAVE_PTR
movl 8+STR(%esp), %eax
movl %eax, 8+SAVE_PTR
L(0): CHECK_BOUNDS_LOW (%edx, SAVE_PTR)
# ifdef USE_AS_STRTOK_R
xorl %ecx, %ecx /* restore %ecx to zero */
# endif
#endif
movl DELIM(%esp), %eax /* Get start of delimiter set. */
CHECK_BOUNDS_LOW (%eax, DELIM(%esp))
/* For understanding the following code remember that %ecx == 0 now.
Although all the following instruction only modify %cl we always
@ -126,17 +147,17 @@ ENTRY (BP_SYM (FUNCTION))
L(2): movb (%eax), %cl /* get byte from stopset */
testb %cl, %cl /* is NUL char? */
jz L(1) /* yes => start compare loop */
jz L(1_1) /* yes => start compare loop */
movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
movb 1(%eax), %cl /* get byte from stopset */
testb $0xff, %cl /* is NUL char? */
jz L(1) /* yes => start compare loop */
jz L(1_2) /* yes => start compare loop */
movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
movb 2(%eax), %cl /* get byte from stopset */
testb $0xff, %cl /* is NUL char? */
jz L(1) /* yes => start compare loop */
jz L(1_3) /* yes => start compare loop */
movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
movb 3(%eax), %cl /* get byte from stopset */
@ -145,7 +166,16 @@ L(2): movb (%eax), %cl /* get byte from stopset */
testb $0xff, %cl /* is NUL char? */
jnz L(2) /* no => process next dword from stopset */
L(1): leal -4(%edx), %eax /* prepare loop */
#if __BOUNDED_POINTERS__
jmp L(1_0) /* pointer is correct for bounds check */
L(1_3): incl %eax /* adjust pointer for bounds check */
L(1_2): incl %eax /* ditto */
L(1_1): incl %eax /* ditto */
L(1_0): CHECK_BOUNDS_HIGH (%eax, DELIM(%esp), jbe)
#else
L(1_3):; L(1_2):; L(1_1): /* fall through */
#endif
leal -4(%edx), %eax /* prepare loop */
/* We use a neat trick for the following loop. Normally we would
have to test for two termination conditions
@ -204,10 +234,7 @@ L(7): addl $4, %edx /* adjust pointer for full loop round */
L(10): incl %edx
L(9): incl %edx
L(8): /* Remove the stopset table. */
addl $256, %esp
cmpl %eax, %edx
L(8): cmpl %eax, %edx
je L(returnNULL) /* There was no token anymore. */
movb $0, (%edx) /* Terminate string. */
@ -217,22 +244,26 @@ L(8): /* Remove the stopset table. */
leal 1(%edx), %ecx
cmovne %ecx, %edx
L(return):
/* Store the pointer to the next character. */
#ifdef USE_AS_STRTOK_R
movl 12(%esp), %ecx
movl %edx, (%ecx)
#else
# ifndef PIC
movl %edx, save_ptr
# else
movl %edx, save_ptr@GOTOFF(%ebx)
popl %ebx
# ifdef USE_AS_STRTOK_R
movl SAVE(%esp), %ecx
# endif
movl %edx, SAVE_PTR
CHECK_BOUNDS_HIGH (%edx, SAVE_PTR, jb)
RETURN_BOUNDED_POINTER (SAVE_PTR)
L(epilogue):
/* Remove the stopset table. */
addl $256, %esp
#if !defined USE_AS_STRTOK_R && defined PIC
popl %ebx
#endif
ret
LEAVE
RET_PTR
L(returnNULL):
xorl %eax, %eax
jmp L(return)
RETURN_NULL_BOUNDED_POINTER
jmp L(epilogue)
END (BP_SYM (FUNCTION))

View File

@ -328,3 +328,6 @@ L(pop): popl %edi /* pop saved registers */
END (BP_SYM (__memchr))
weak_alias (BP_SYM (__memchr), BP_SYM (memchr))
#if !__BOUNDED_POINTERS__
weak_alias (__memchr, __ubp_memchr)
#endif

View File

@ -39,15 +39,27 @@
We do a common implementation here. */
#ifndef USE_AS_STRTOK_R
#ifdef USE_AS_STRTOK_R
# define SAVE_PTR 0(%ecx)
#else
.bss
.local save_ptr
ASM_TYPE_DIRECTIVE (save_ptr, @object)
.size save_ptr, 4
save_ptr:
# if __BOUNDED_POINTERS__
.space 12
# else
.space 4
# endif
#define FUNCTION strtok
# ifdef PIC
# define SAVE_PTR save_ptr@GOTOFF(%ebx)
# else
# define SAVE_PTR save_ptr
# endif
# define FUNCTION strtok
#endif
#define PARMS LINKAGE /* no space for saved regs */
@ -62,10 +74,9 @@ ENTRY (BP_SYM (FUNCTION))
movl STR(%esp), %edx
movl DELIM(%esp), %eax
CHECK_BOUNDS_LOW (%edx, STR(%esp))
CHECK_BOUNDS_LOW (%eax, DELIM(%esp))
#if !defined (USE_AS_STRTOK_R) && defined (PIC)
#if !defined USE_AS_STRTOK_R && defined PIC
pushl %ebx /* Save PIC register. */
call L(here)
L(here):
@ -76,7 +87,22 @@ L(here):
/* If the pointer is NULL we have to use the stored value of
the last run. */
cmpl $0, %edx
jne L(0)
#if __BOUNDED_POINTERS__
movl SAVE(%esp), %ecx
je L(0)
/* Save bounds of incoming non-NULL STR into save area. */
movl 4+STR(%esp), %eax
movl %eax, 4+SAVE_PTR
movl 8+STR(%esp), %eax
movl %eax, 8+SAVE_PTR
CHECK_BOUNDS_LOW (%edx, SAVE_PTR)
jmp L(1)
L(0): movl SAVE_PTR, %edx
CHECK_BOUNDS_LOW (%edx, SAVE_PTR)
jmp L(1)
#else
jne L(1)
#endif
#ifdef USE_AS_STRTOK_R
/* The value is stored in the third argument. */
@ -85,14 +111,10 @@ L(here):
#else
/* The value is in the local variable defined above. But
we have to take care for PIC code. */
# ifndef PIC
movl save_ptr, %edx
# else
movl save_ptr@GOTOFF(%ebx), %edx
# endif
movl SAVE_PTR, %edx
#endif
L(0):
L(1):
/* First we create a table with flags for all possible characters.
For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
supported by the C string functions we have 256 characters.
@ -195,7 +217,7 @@ L(2): movb (%eax), %cl /* get byte from stopset */
L(1_3): incl %eax /* adjust pointer for bounds check */
L(1_2): incl %eax /* ditto */
L(1_1): incl %eax /* ditto */
L(1_0): CHECK_BOUNDS_HIGH (%eax, DELIM(%esp), jb)
L(1_0): CHECK_BOUNDS_HIGH (%eax, DELIM(%esp), jbe)
#else
L(1_3):; L(1_2):; L(1_1): /* fall through */
#endif
@ -273,25 +295,17 @@ L(8): /* Remove the stopset table. */
incl %edx
L(11):
L(return):
/* Store the pointer to the next character. */
#ifdef USE_AS_STRTOK_R
movl SAVE(%esp), %ecx
movl %edx, (%ecx)
#else
# ifndef PIC
movl %edx, save_ptr
# else
movl %edx, save_ptr@GOTOFF(%ebx)
popl %ebx
# endif
#endif
#if __BOUNDED_POINTERS__
testl %eax, %eax
jz L(ret)
CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
RETURN_BOUNDED_POINTER (STR(%esp))
L(ret):
movl %edx, SAVE_PTR
CHECK_BOUNDS_HIGH (%edx, SAVE_PTR, jb)
RETURN_BOUNDED_POINTER (SAVE_PTR)
L(epilogue):
#if !defined USE_AS_STRTOK_R && defined PIC
popl %ebx
#endif
LEAVE
RET_PTR
@ -299,6 +313,6 @@ L(ret):
L(returnNULL):
xorl %eax, %eax
RETURN_NULL_BOUNDED_POINTER
jmp L(return)
jmp L(epilogue)
END (BP_SYM (FUNCTION))

View File

@ -33,8 +33,8 @@
possible; the remaining few bytes are searched one at a time.
The word by word search is performed by xor-ing the word with a word
containing chr in every byte. If there is a hit, the result will
contain a zero byte in the corresponding position. The presence and
containing chr in every byte. If there is a hit, the result will
contain a zero byte in the corresponding position. The presence and
position of that zero byte is detected with a czx instruction.
All the loops in this function could have had the internal branch removed
@ -63,7 +63,7 @@ ENTRY(__memchr)
.rotp p[MEMLAT+3]
mov saved_lc = ar.lc // save the loop counter
mov saved_pr = pr // save the predicates
mov ret0 = str
mov ret0 = str
and tmp = 7, str // tmp = str % 8
cmp.ne p7, p0 = r0, r0 // clear p7
extr.u chr = in1, 0, 8 // chr = (unsigned char) in1
@ -91,7 +91,7 @@ ENTRY(__memchr)
mux1 chrx8 = chr, @brcst ;; // get a word full of chr
mov ar.lc = loopcnt
mov pr.rot = 1 << 16 ;;
.l2:
.l2:
(p[0]) mov addr[0] = ret0
(p[0]) ld8 value[0] = [ret0], 8
(p[MEMLAT]) xor aux[0] = value[MEMLAT], chrx8
@ -100,7 +100,7 @@ ENTRY(__memchr)
(p7) br.cond.dpnt .foundit
br.ctop.dptk .l2
.srchfew:
adds loopcnt = -1, len
adds loopcnt = -1, len
cmp.eq p6, p0 = len, r0
(p6) br.cond.spnt .notfound ;;
mov ar.lc = loopcnt
@ -109,7 +109,7 @@ ENTRY(__memchr)
;;
cmp.eq p6, p0 = val, chr
(p6) br.cond.dpnt .foundit
br.cloop.sptk .l3 ;;
br.cloop.sptk .l3 ;;
.notfound:
cmp.ne p6, p0 = r0, r0 // clear p6 (p7 was already 0 when we got here)
mov ret0 = r0 ;; // return NULL
@ -124,3 +124,6 @@ ENTRY(__memchr)
END(__memchr)
weak_alias (__memchr, memchr)
#if !__BOUNDED_POINTERS__
weak_alias (__memchr, __ubp_memchr)
#endif

View File

@ -226,3 +226,6 @@ L(L9:)
END(__memchr)
weak_alias (__memchr, memchr)
#if !__BOUNDED_POINTERS__
weak_alias (__memchr, __ubp_memchr)
#endif

View File

@ -112,7 +112,7 @@ ENTRY(__memchr)
clr %o0
/* Check every byte. */
8: srl %g4, 24, %g5
8: srl %g4, 24, %g5
and %g5, 0xff, %g5
cmp %g5, %o1
be 4f
@ -143,3 +143,6 @@ ENTRY(__memchr)
END(__memchr)
weak_alias (__memchr, memchr)
#if !__BOUNDED_POINTERS__
weak_alias (__memchr, __ubp_memchr)
#endif

View File

@ -259,3 +259,6 @@ ENTRY(__memchr)
END(__memchr)
weak_alias (__memchr, memchr)
#if !__BOUNDED_POINTERS__
weak_alias (__memchr, __ubp_memchr)
#endif

View File

@ -85,6 +85,15 @@ get_proc_path (char *buffer, size_t bufsize)
/* Replacing the value failed. This means another thread was
faster and we don't need the copy anymore. */
free (copy_result);
#if __BOUNDED_POINTERS__
else
{
/* compare_and_swap only copied the pointer value, so we must
now copy the bounds as well. */
__ptrlow (mount_proc) = __ptrlow (copy_result);
__ptrhigh (mount_proc) = __ptrhigh (copy_result);
}
#endif
return mount_proc;
}

View File

@ -69,4 +69,6 @@ ENTRY(__memchr, 0)
brb 0b # and loop
weak_alias (__memchr, memchr)
#if !__BOUNDED_POINTERS__
weak_alias (__memchr, __ubp_memchr)
#endif