diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2008-07-02 18:17:48 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2008-07-02 18:17:48 +0000 |
commit | a9f7d0a7a7b134004b92092831bdefc6faf8213c (patch) | |
tree | 296ca87b94d60e11219f80a7c1ffaf726a14086d | |
parent | bb82bbe6ff1e97b1e2baba9436676aa9406fcef3 (diff) | |
download | cygnal-a9f7d0a7a7b134004b92092831bdefc6faf8213c.tar.gz cygnal-a9f7d0a7a7b134004b92092831bdefc6faf8213c.tar.bz2 cygnal-a9f7d0a7a7b134004b92092831bdefc6faf8213c.zip |
2008-07-02 Jeff Johnston <jjohnstn@redhat.com>
* libc/machine/mips/strncpy.c (strncpy): Fix logic so unaligned
source data is taken care of before loop unrolling.
-rw-r--r-- | newlib/ChangeLog | 5 | ||||
-rw-r--r-- | newlib/libc/machine/mips/strncpy.c | 20 |
2 files changed, 25 insertions, 0 deletions
diff --git a/newlib/ChangeLog b/newlib/ChangeLog index bc11fe183..1b24d0185 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,8 @@ +2008-07-02 Jeff Johnston <jjohnstn@redhat.com> + + * libc/machine/mips/strncpy.c (strncpy): Fix logic so unaligned + source data is taken care of before loop unrolling. + 2008-06-25 Hans-Peter Nilsson <hp@axis.com> Fix strict-aliasing issues with _strtod_r and Storeinc. diff --git a/newlib/libc/machine/mips/strncpy.c b/newlib/libc/machine/mips/strncpy.c index a2ceb2c77..324c45209 100644 --- a/newlib/libc/machine/mips/strncpy.c +++ b/newlib/libc/machine/mips/strncpy.c @@ -82,6 +82,26 @@ strncpy (char *dst0, const char *src0, size_t count) dst = (unsigned char *)dst0; src = (unsigned const char *)src0; + /* Take care of any odd bytes in the source data because we + * want to unroll where we read ahead 2 or 4 bytes at a time and then + * check each byte for the null terminator. This can result in + * a segfault for the case where the source pointer is unaligned, + * the null terminator is in valid memory, but reading 2 or 4 bytes at a + * time blindly eventually goes outside of valid memory. */ + while ((src & (UNROLL_FACTOR - 1)) != 0 && count > 0) + { + *dst++ = ch = *src++; + --count; + if (ch == '\0') + { + end = dst + count; + while (dst != end) + *dst++ = '\0'; + + return dst0; + } + } + if (__builtin_expect (count >= 4, 1)) { odd_bytes = (count & (UNROLL_FACTOR - 1)); |