aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libc/string/memmove.c6
-rw-r--r--linker/linker.c9
2 files changed, 11 insertions, 4 deletions
diff --git a/libc/string/memmove.c b/libc/string/memmove.c
index 072104b6c..7c1e9b2fd 100644
--- a/libc/string/memmove.c
+++ b/libc/string/memmove.c
@@ -32,10 +32,10 @@ void *memmove(void *dst, const void *src, size_t n)
{
const char *p = src;
char *q = dst;
- /* We can use the optimized memcpy if the destination is below the
- * source (i.e. q < p), or if it is completely over it (i.e. q >= p+n).
+ /* We can use the optimized memcpy if the destination is completely below the
+ * source (i.e. q+n <= p), or if it is completely over it (i.e. q >= p+n).
*/
- if (__builtin_expect((q < p) || ((size_t)(q - p) >= n), 1)) {
+ if (__builtin_expect((q + n < p) || (q >= p + n), 1)) {
return memcpy(dst, src, n);
} else {
bcopy(src, dst, n);
diff --git a/linker/linker.c b/linker/linker.c
index bb31703bf..6a80ce7da 100644
--- a/linker/linker.c
+++ b/linker/linker.c
@@ -438,9 +438,16 @@ static unsigned elfhash(const char *_name)
while(*name) {
h = (h << 4) + *name++;
g = h & 0xf0000000;
- h ^= g;
+ /* The hash algorithm in the ELF ABI is as follows:
+ * if (g != 0)
+ * h ^=g >> 24;
+ * h &= ~g;
+ * But we can use the equivalent and faster implementation:
+ */
h ^= g >> 24;
}
+ /* Lift the operation out of the inner loop */
+ h &= 0x0fffffff;
return h;
}