mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-10 07:10:06 +00:00
update
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:
parent
ac55638813
commit
2ed5fd9a2a
46
ChangeLog
46
ChangeLog
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -226,3 +226,6 @@ L(L9:)
|
||||
END(__memchr)
|
||||
|
||||
weak_alias (__memchr, memchr)
|
||||
#if !__BOUNDED_POINTERS__
|
||||
weak_alias (__memchr, __ubp_memchr)
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -259,3 +259,6 @@ ENTRY(__memchr)
|
||||
END(__memchr)
|
||||
|
||||
weak_alias (__memchr, memchr)
|
||||
#if !__BOUNDED_POINTERS__
|
||||
weak_alias (__memchr, __ubp_memchr)
|
||||
#endif
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -69,4 +69,6 @@ ENTRY(__memchr, 0)
|
||||
brb 0b # and loop
|
||||
|
||||
weak_alias (__memchr, memchr)
|
||||
|
||||
#if !__BOUNDED_POINTERS__
|
||||
weak_alias (__memchr, __ubp_memchr)
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user