diff options
-rw-r--r-- | ChangeLog | 46 | ||||
-rw-r--r-- | malloc/malloc.c | 54 | ||||
-rw-r--r-- | sysdeps/alpha/memchr.S | 5 | ||||
-rw-r--r-- | sysdeps/generic/bp-checks.h | 5 | ||||
-rw-r--r-- | sysdeps/i386/bits/string.h | 2 | ||||
-rw-r--r-- | sysdeps/i386/bp-asm.h | 18 | ||||
-rw-r--r-- | sysdeps/i386/i486/bits/string.h | 4 | ||||
-rw-r--r-- | sysdeps/i386/i686/strtok.S | 119 | ||||
-rw-r--r-- | sysdeps/i386/memchr.S | 3 | ||||
-rw-r--r-- | sysdeps/i386/strtok.S | 70 | ||||
-rw-r--r-- | sysdeps/ia64/memchr.S | 15 | ||||
-rw-r--r-- | sysdeps/m68k/memchr.S | 3 | ||||
-rw-r--r-- | sysdeps/sparc/sparc32/memchr.S | 5 | ||||
-rw-r--r-- | sysdeps/sparc/sparc64/memchr.S | 3 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/getsysstats.c | 9 | ||||
-rw-r--r-- | sysdeps/vax/memchr.s | 4 |
16 files changed, 247 insertions, 118 deletions
@@ -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. diff --git a/malloc/malloc.c b/malloc/malloc.c index ce8de80..449ce8a 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -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; diff --git a/sysdeps/alpha/memchr.S b/sysdeps/alpha/memchr.S index 5947a0b..c4e1d5e 100644 --- a/sysdeps/alpha/memchr.S +++ b/sysdeps/alpha/memchr.S @@ -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 diff --git a/sysdeps/generic/bp-checks.h b/sysdeps/generic/bp-checks.h index 349bd81..0da4657 100644 --- a/sysdeps/generic/bp-checks.h +++ b/sysdeps/generic/bp-checks.h @@ -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)) diff --git a/sysdeps/i386/bits/string.h b/sysdeps/i386/bits/string.h index cf0285d..eac8a36 100644 --- a/sysdeps/i386/bits/string.h +++ b/sysdeps/i386/bits/string.h @@ -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 diff --git a/sysdeps/i386/bp-asm.h b/sysdeps/i386/bp-asm.h index bde1f6a..f4e4226 100644 --- a/sysdeps/i386/bp-asm.h +++ b/sysdeps/i386/bp-asm.h @@ -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 diff --git a/sysdeps/i386/i486/bits/string.h b/sysdeps/i386/i486/bits/string.h index 54e5ac4..b608072 100644 --- a/sysdeps/i386/i486/bits/string.h +++ b/sysdeps/i386/i486/bits/string.h @@ -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 diff --git a/sysdeps/i386/i686/strtok.S b/sysdeps/i386/i686/strtok.S index 96b3b5d..a982a4a 100644 --- a/sysdeps/i386/i686/strtok.S +++ b/sysdeps/i386/i686/strtok.S @@ -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)) diff --git a/sysdeps/i386/memchr.S b/sysdeps/i386/memchr.S index 098e413..d01a31c 100644 --- a/sysdeps/i386/memchr.S +++ b/sysdeps/i386/memchr.S @@ -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 diff --git a/sysdeps/i386/strtok.S b/sysdeps/i386/strtok.S index 47924b2..ff8980a 100644 --- a/sysdeps/i386/strtok.S +++ b/sysdeps/i386/strtok.S @@ -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 + +# ifdef PIC +# define SAVE_PTR save_ptr@GOTOFF(%ebx) +# else +# define SAVE_PTR save_ptr +# endif -#define FUNCTION strtok +# 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)) diff --git a/sysdeps/ia64/memchr.S b/sysdeps/ia64/memchr.S index 40f2bd0..e02945a 100644 --- a/sysdeps/ia64/memchr.S +++ b/sysdeps/ia64/memchr.S @@ -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 diff --git a/sysdeps/m68k/memchr.S b/sysdeps/m68k/memchr.S index 968c129..d69b806 100644 --- a/sysdeps/m68k/memchr.S +++ b/sysdeps/m68k/memchr.S @@ -226,3 +226,6 @@ L(L9:) END(__memchr) weak_alias (__memchr, memchr) +#if !__BOUNDED_POINTERS__ +weak_alias (__memchr, __ubp_memchr) +#endif diff --git a/sysdeps/sparc/sparc32/memchr.S b/sysdeps/sparc/sparc32/memchr.S index b770af1..1c5bd83 100644 --- a/sysdeps/sparc/sparc32/memchr.S +++ b/sysdeps/sparc/sparc32/memchr.S @@ -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 diff --git a/sysdeps/sparc/sparc64/memchr.S b/sysdeps/sparc/sparc64/memchr.S index 36446b6..3fa8d8d 100644 --- a/sysdeps/sparc/sparc64/memchr.S +++ b/sysdeps/sparc/sparc64/memchr.S @@ -259,3 +259,6 @@ ENTRY(__memchr) END(__memchr) weak_alias (__memchr, memchr) +#if !__BOUNDED_POINTERS__ +weak_alias (__memchr, __ubp_memchr) +#endif diff --git a/sysdeps/unix/sysv/linux/getsysstats.c b/sysdeps/unix/sysv/linux/getsysstats.c index dce568c..9a2d7cf 100644 --- a/sysdeps/unix/sysv/linux/getsysstats.c +++ b/sysdeps/unix/sysv/linux/getsysstats.c @@ -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; } diff --git a/sysdeps/vax/memchr.s b/sysdeps/vax/memchr.s index 22a8c2d..5c54ba8 100644 --- a/sysdeps/vax/memchr.s +++ b/sysdeps/vax/memchr.s @@ -69,4 +69,6 @@ ENTRY(__memchr, 0) brb 0b # and loop weak_alias (__memchr, memchr) -
\ No newline at end of file +#if !__BOUNDED_POINTERS__ +weak_alias (__memchr, __ubp_memchr) +#endif |