aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog46
-rw-r--r--malloc/malloc.c54
-rw-r--r--sysdeps/alpha/memchr.S5
-rw-r--r--sysdeps/generic/bp-checks.h5
-rw-r--r--sysdeps/i386/bits/string.h2
-rw-r--r--sysdeps/i386/bp-asm.h18
-rw-r--r--sysdeps/i386/i486/bits/string.h4
-rw-r--r--sysdeps/i386/i686/strtok.S119
-rw-r--r--sysdeps/i386/memchr.S3
-rw-r--r--sysdeps/i386/strtok.S70
-rw-r--r--sysdeps/ia64/memchr.S15
-rw-r--r--sysdeps/m68k/memchr.S3
-rw-r--r--sysdeps/sparc/sparc32/memchr.S5
-rw-r--r--sysdeps/sparc/sparc64/memchr.S3
-rw-r--r--sysdeps/unix/sysv/linux/getsysstats.c9
-rw-r--r--sysdeps/vax/memchr.s4
16 files changed, 247 insertions, 118 deletions
diff --git a/ChangeLog b/ChangeLog
index 13e5219576..4b293da563 100644
--- a/ChangeLog
+++ b/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.
diff --git a/malloc/malloc.c b/malloc/malloc.c
index ce8de8015b..449ce8a486 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 5947a0bdef..c4e1d5e7aa 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 349bd81792..0da4657ae2 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 cf0285d847..eac8a36a22 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 bde1f6a14a..f4e4226044 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 54e5ac4620..b60807286c 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 96b3b5dc33..a982a4aa49 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 098e413cba..d01a31c855 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 47924b2237..ff8980a924 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 40f2bd09b5..e02945aa2e 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 968c129eb3..d69b806667 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 b770af1575..1c5bd83029 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 36446b6259..3fa8d8d195 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 dce568c417..9a2d7cfcda 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 22a8c2dc73..5c54ba8e79 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