1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-06-15 06:41:47 +03:00
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> 2000-07-25 Bruno Haible <haible@clisp.cons.org>
* wctype/wctype.h (__wctrans_l): New declaration. * wctype/wctype.h (__wctrans_l): New declaration.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* Optimized, inlined string functions. i486 version. /* 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. This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or 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 /* We only provide optimizations if the user selects them and if
GNU CC is used. */ GNU CC is used. */
#if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \ #if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
&& defined __GNUC__ && __GNUC__ >= 2 && defined __GNUC__ && __GNUC__ >= 2 && !__BOUNDED_POINTERS__
#ifndef __STRING_INLINE #ifndef __STRING_INLINE
# ifdef __cplusplus # ifdef __cplusplus

View File

@ -39,15 +39,39 @@
We do a common implementation here. */ We do a common implementation here. */
#ifndef USE_AS_STRTOK_R #ifdef USE_AS_STRTOK_R
# define SAVE_PTR 0(%ecx)
#else
.bss .bss
.local save_ptr .local save_ptr
ASM_TYPE_DIRECTIVE (save_ptr, @object) ASM_TYPE_DIRECTIVE (save_ptr, @object)
.size save_ptr, 4 .size save_ptr, 4
save_ptr: save_ptr:
# if __BOUNDED_POINTERS__
.space 12
# else
.space 4 .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 #endif
.text .text
@ -57,12 +81,6 @@ save_ptr:
ret ret
#endif #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)) ENTRY (BP_SYM (FUNCTION))
ENTER ENTER
@ -89,36 +107,39 @@ ENTRY (BP_SYM (FUNCTION))
/* Note: %ecx = 0 !!! */ /* Note: %ecx = 0 !!! */
movl %edx, %edi movl %edx, %edi
#if !defined USE_AS_STRTOK_R && defined PIC movl STR(%esp), %edx /* Get start of string. */
movl 264(%esp), %edx /* Get start of string. */
#else
movl 260(%esp), %edx /* Get start of string. */
#endif
#ifdef USE_AS_STRTOK_R #ifdef USE_AS_STRTOK_R
/* The value is stored in the third argument. */ /* The value is stored in the third argument. */
movl 268(%esp), %eax movl SAVE(%esp), %eax
movl (%eax), %eax movl (%eax), %eax
#else #else
/* The value is in the local variable defined above. But /* The value is in the local variable defined above. But
we have to take care for PIC code. */ we have to take care for PIC code. */
# ifndef PIC movl SAVE_PTR, %eax
movl save_ptr, %eax
# else
movl save_ptr@GOTOFF(%ebx), %eax
# endif
#endif #endif
/* If the pointer is NULL we have to use the stored value of /* If the pointer is NULL we have to use the stored value of
the last run. */ the last run. */
cmpl $0, %edx cmpl $0, %edx
cmove %eax, %edx cmove %eax, %edx
#if __BOUNDED_POINTERS__
#if !defined USE_AS_STRTOK_R && defined PIC # ifdef USE_AS_STRTOK_R
movl 268(%esp), %eax /* Get start of delimiter set. */ movl SAVE(%esp), %ecx /* borrow %ecx for a moment */
#else # endif
movl 264(%esp), %eax /* Get start of delimiter set. */ 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 #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. /* For understanding the following code remember that %ecx == 0 now.
Although all the following instruction only modify %cl we always 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 */ L(2): movb (%eax), %cl /* get byte from stopset */
testb %cl, %cl /* is NUL char? */ 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 %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
movb 1(%eax), %cl /* get byte from stopset */ movb 1(%eax), %cl /* get byte from stopset */
testb $0xff, %cl /* is NUL char? */ 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 %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
movb 2(%eax), %cl /* get byte from stopset */ movb 2(%eax), %cl /* get byte from stopset */
testb $0xff, %cl /* is NUL char? */ 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 %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
movb 3(%eax), %cl /* get byte from stopset */ 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? */ testb $0xff, %cl /* is NUL char? */
jnz L(2) /* no => process next dword from stopset */ 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 /* We use a neat trick for the following loop. Normally we would
have to test for two termination conditions 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(10): incl %edx
L(9): incl %edx L(9): incl %edx
L(8): /* Remove the stopset table. */ L(8): cmpl %eax, %edx
addl $256, %esp
cmpl %eax, %edx
je L(returnNULL) /* There was no token anymore. */ je L(returnNULL) /* There was no token anymore. */
movb $0, (%edx) /* Terminate string. */ movb $0, (%edx) /* Terminate string. */
@ -217,22 +244,26 @@ L(8): /* Remove the stopset table. */
leal 1(%edx), %ecx leal 1(%edx), %ecx
cmovne %ecx, %edx cmovne %ecx, %edx
L(return):
/* Store the pointer to the next character. */ /* Store the pointer to the next character. */
#ifdef USE_AS_STRTOK_R # ifdef USE_AS_STRTOK_R
movl 12(%esp), %ecx 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
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 #endif
ret LEAVE
RET_PTR
L(returnNULL): L(returnNULL):
xorl %eax, %eax xorl %eax, %eax
jmp L(return) RETURN_NULL_BOUNDED_POINTER
jmp L(epilogue)
END (BP_SYM (FUNCTION)) END (BP_SYM (FUNCTION))

View File

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

View File

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

View File

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

View File

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

View File

@ -259,3 +259,6 @@ ENTRY(__memchr)
END(__memchr) END(__memchr)
weak_alias (__memchr, 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 /* Replacing the value failed. This means another thread was
faster and we don't need the copy anymore. */ faster and we don't need the copy anymore. */
free (copy_result); 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; return mount_proc;
} }

View File

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