musl: update to latest git to fix MIPS and PowerPC TLS issues
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 46134
This commit is contained in:
parent
0aa351196a
commit
2475351cb1
1 changed files with 392 additions and 137 deletions
|
@ -1,11 +1,98 @@
|
|||
From bafa38541e911806b74a1ab094a404bbdd692ade Mon Sep 17 00:00:00 2001
|
||||
From: Steven Barth <steven@midlink.org>
|
||||
Date: Sat, 20 Jun 2015 16:59:48 +0200
|
||||
Subject: [PATCH] commit 55d061f031085f24d138664c897791aebe9a2fab Author: Rich
|
||||
Felker <dalias@aerifal.cx> Date: Sat Jun 20 03:01:07 2015 +0000
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
commit 6ba5517a460c6c438f64d69464fdfc3269a4c91a
|
||||
Author: Rich Felker <dalias@aerifal.cx>
|
||||
Date: Thu Jun 25 22:22:00 2015 +0000
|
||||
|
||||
fix local-dynamic model TLS on mips and powerpc
|
||||
|
||||
the TLS ABI spec for mips, powerpc, and some other (presently
|
||||
unsupported) RISC archs has the return value of __tls_get_addr offset
|
||||
by +0x8000 and the result of DTPOFF relocations offset by -0x8000. I
|
||||
had previously assumed this part of the ABI was actually just an
|
||||
implementation detail, since the adjustments cancel out. however, when
|
||||
the local dynamic model is used for accessing TLS that's known to be
|
||||
in the same DSO, either of the following may happen:
|
||||
|
||||
1. the -0x8000 offset may already be applied to the argument structure
|
||||
passed to __tls_get_addr at ld time, without any opportunity for
|
||||
runtime relocations.
|
||||
|
||||
2. __tls_get_addr may be used with a zero offset argument to obtain a
|
||||
base address for the module's TLS, to which the caller then applies
|
||||
immediate offsets for individual objects accessed using the local
|
||||
dynamic model. since the immediate offsets have the -0x8000 adjustment
|
||||
applied to them, the base address they use needs to include the
|
||||
+0x8000 offset.
|
||||
|
||||
it would be possible, but more complex, to store the pointers in the
|
||||
dtv[] array with the +0x8000 offset pre-applied, to avoid the runtime
|
||||
cost of adding 0x8000 on each call to __tls_get_addr. this change
|
||||
could be made later if measurements show that it would help.
|
||||
|
||||
commit ce337daa00e42d4f2d9a4d9ae0ed51b20249d924
|
||||
Author: Rich Felker <dalias@aerifal.cx>
|
||||
Date: Tue Jun 23 04:03:42 2015 +0000
|
||||
|
||||
make dynamic linker work around MAP_FAILED mmap failure on nommu kernels
|
||||
|
||||
previously, loading of additional libraries beyond libc/ldso did not
|
||||
work on nommu kernels, nor did loading programs via invocation of the
|
||||
dynamic linker as a command.
|
||||
|
||||
commit a59341420fdedb288d9ff80e73609ae44e9cf258
|
||||
Author: Rich Felker <dalias@aerifal.cx>
|
||||
Date: Tue Jun 23 00:12:25 2015 +0000
|
||||
|
||||
reimplement strverscmp to fix corner cases
|
||||
|
||||
this interface is non-standardized and is a GNU invention, and as
|
||||
such, our implementation should match the behavior of the GNU
|
||||
function. one peculiarity the old implementation got wrong was the
|
||||
handling of all-zero digit sequences: they are supposed to compare
|
||||
greater than digit sequences of which they are a proper prefix, as in
|
||||
009 < 00.
|
||||
|
||||
in addition, high bytes were treated with char signedness rather than
|
||||
as unsigned. this was wrong regardless of what the GNU function does
|
||||
since the resulting order relation varied by arch.
|
||||
|
||||
the new strverscmp implementation makes explicit the cases where the
|
||||
order differs from what strcmp would produce, of which there are only
|
||||
two.
|
||||
|
||||
commit 153e952e1a688859d7095345b17e6c1df74a295c
|
||||
Author: Rich Felker <dalias@aerifal.cx>
|
||||
Date: Mon Jun 22 20:33:28 2015 +0000
|
||||
|
||||
fix regression/typo that disabled __simple_malloc when calloc is used
|
||||
|
||||
commit ba819787ee93ceae94efd274f7849e317c1bff58 introduced this
|
||||
regression. since the __malloc0 weak alias was not properly provided
|
||||
by __simple_malloc, use of calloc forced the full malloc to be linked.
|
||||
|
||||
commit ba819787ee93ceae94efd274f7849e317c1bff58
|
||||
Author: Rich Felker <dalias@aerifal.cx>
|
||||
Date: Mon Jun 22 18:50:09 2015 +0000
|
||||
|
||||
fix calloc when __simple_malloc implementation is used
|
||||
|
||||
previously, calloc's implementation encoded assumptions about the
|
||||
implementation of malloc, accessing a size_t word just prior to the
|
||||
allocated memory to determine if it was obtained by mmap to optimize
|
||||
out the zero-filling. when __simple_malloc is used (static linking a
|
||||
program with no realloc/free), it doesn't matter if the result of this
|
||||
check is wrong, since all allocations are zero-initialized anyway. but
|
||||
the access could be invalid if it crosses a page boundary or if the
|
||||
pointer is not sufficiently aligned, which can happen for very small
|
||||
allocations.
|
||||
|
||||
this patch fixes the issue by moving the zero-fill logic into malloc.c
|
||||
with the full malloc, as a new function named __malloc0, which is
|
||||
provided by a weak alias to __simple_malloc (which always gives
|
||||
zero-filled memory) when the full malloc is not in use.
|
||||
|
||||
commit 55d061f031085f24d138664c897791aebe9a2fab
|
||||
Author: Rich Felker <dalias@aerifal.cx>
|
||||
Date: Sat Jun 20 03:01:07 2015 +0000
|
||||
|
||||
provide __stack_chk_fail_local in libc.a
|
||||
|
||||
|
@ -427,79 +514,6 @@ Date: Fri Jun 5 10:39:42 2015 +0300
|
|||
|
||||
commit 68630b55c0c7219fe9df70dc28ffbf9efc8021d8 made the new locale to
|
||||
be assigned unconditonally resulting in crashes later on.
|
||||
---
|
||||
arch/arm/syscall_arch.h | 4 ++
|
||||
arch/sh/src/__set_thread_area.c | 34 ++++++++++++++++
|
||||
arch/sh/src/__unmapself.c | 19 +++++++++
|
||||
arch/sh/src/atomic.c | 72 ++++++++++++++++++++++++++++++----
|
||||
arch/sh/src/sh_atomic.h | 15 +++++++
|
||||
arch/sh/syscall_arch.h | 2 +-
|
||||
include/ctype.h | 1 +
|
||||
include/stdlib.h | 3 +-
|
||||
src/ctype/__ctype_get_mb_cur_max.c | 5 ++-
|
||||
src/ctype/isascii.c | 1 +
|
||||
src/env/__stack_chk_fail.c | 4 ++
|
||||
src/internal/libc.h | 2 -
|
||||
src/internal/locale_impl.h | 12 ++++++
|
||||
src/internal/sh/syscall.s | 2 +-
|
||||
src/internal/stdio_impl.h | 6 ++-
|
||||
src/ldso/dynlink.c | 37 +++++++++---------
|
||||
src/locale/c_locale.c | 15 +++++++
|
||||
src/locale/iconv.c | 6 +++
|
||||
src/locale/langinfo.c | 3 +-
|
||||
src/locale/locale_map.c | 12 +-----
|
||||
src/locale/newlocale.c | 15 ++-----
|
||||
src/locale/uselocale.c | 4 +-
|
||||
src/malloc/expand_heap.c | 72 ++++++++++++++++++++++++++++++++++
|
||||
src/malloc/lite_malloc.c | 49 ++++++++++++-----------
|
||||
src/malloc/malloc.c | 80 ++++++++++++++------------------------
|
||||
src/multibyte/btowc.c | 5 ++-
|
||||
src/multibyte/internal.h | 7 ++++
|
||||
src/multibyte/mbrtowc.c | 2 +
|
||||
src/multibyte/mbsrtowcs.c | 19 +++++++++
|
||||
src/multibyte/mbtowc.c | 2 +
|
||||
src/multibyte/wcrtomb.c | 9 +++++
|
||||
src/multibyte/wctob.c | 4 +-
|
||||
src/passwd/nscd_query.c | 12 ++++--
|
||||
src/process/sh/vfork.s | 23 +++++++++++
|
||||
src/regex/fnmatch.c | 3 +-
|
||||
src/signal/sh/restore.s | 4 +-
|
||||
src/stdio/__fdopen.c | 8 +---
|
||||
src/stdio/__stdio_exit.c | 3 +-
|
||||
src/stdio/__stdio_read.c | 11 +-----
|
||||
src/stdio/__stdio_write.c | 14 +------
|
||||
src/stdio/fclose.c | 6 +--
|
||||
src/stdio/fflush.c | 5 +--
|
||||
src/stdio/fgetwc.c | 15 +++++--
|
||||
src/stdio/fmemopen.c | 8 +---
|
||||
src/stdio/fopen.c | 2 +-
|
||||
src/stdio/fputwc.c | 7 +++-
|
||||
src/stdio/fputws.c | 7 +++-
|
||||
src/stdio/fwide.c | 11 +++---
|
||||
src/stdio/ofl.c | 16 ++++++++
|
||||
src/stdio/ofl_add.c | 11 ++++++
|
||||
src/stdio/open_memstream.c | 8 +---
|
||||
src/stdio/open_wmemstream.c | 8 +---
|
||||
src/stdio/ungetwc.c | 18 ++++-----
|
||||
src/stdio/vfwprintf.c | 5 ++-
|
||||
src/stdio/vfwscanf.c | 2 +-
|
||||
src/thread/__unmapself.c | 29 ++++++++++++++
|
||||
src/thread/mips/__unmapself.s | 1 +
|
||||
src/thread/pthread_create.c | 6 ++-
|
||||
src/thread/sh/__set_thread_area.s | 6 ---
|
||||
src/thread/sh/__unmapself.s | 10 ++---
|
||||
src/thread/sh/clone.s | 4 +-
|
||||
src/thread/sh/syscall_cp.s | 2 +-
|
||||
src/unistd/sh/pipe.s | 2 +-
|
||||
63 files changed, 548 insertions(+), 242 deletions(-)
|
||||
create mode 100644 arch/sh/src/__set_thread_area.c
|
||||
create mode 100644 arch/sh/src/__unmapself.c
|
||||
create mode 100644 arch/sh/src/sh_atomic.h
|
||||
create mode 100644 src/locale/c_locale.c
|
||||
create mode 100644 src/malloc/expand_heap.c
|
||||
create mode 100644 src/process/sh/vfork.s
|
||||
create mode 100644 src/stdio/ofl.c
|
||||
create mode 100644 src/stdio/ofl_add.c
|
||||
|
||||
diff --git a/arch/arm/syscall_arch.h b/arch/arm/syscall_arch.h
|
||||
index 199ad2a..64461ec 100644
|
||||
|
@ -513,6 +527,30 @@ index 199ad2a..64461ec 100644
|
|||
+#define VDSO_USEFUL
|
||||
+#define VDSO_CGT_SYM "__vdso_clock_gettime"
|
||||
+#define VDSO_CGT_VER "LINUX_2.6"
|
||||
diff --git a/arch/mips/pthread_arch.h b/arch/mips/pthread_arch.h
|
||||
index f8e35ae..904a248 100644
|
||||
--- a/arch/mips/pthread_arch.h
|
||||
+++ b/arch/mips/pthread_arch.h
|
||||
@@ -13,4 +13,6 @@ static inline struct pthread *__pthread_self()
|
||||
#define TLS_ABOVE_TP
|
||||
#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
|
||||
|
||||
+#define DTP_OFFSET 0x8000
|
||||
+
|
||||
#define CANCEL_REG_IP (3-(union {int __i; char __b;}){1}.__b)
|
||||
diff --git a/arch/powerpc/pthread_arch.h b/arch/powerpc/pthread_arch.h
|
||||
index 4115ec8..1cbfc22 100644
|
||||
--- a/arch/powerpc/pthread_arch.h
|
||||
+++ b/arch/powerpc/pthread_arch.h
|
||||
@@ -12,6 +12,8 @@ static inline struct pthread *__pthread_self()
|
||||
#define TLS_ABOVE_TP
|
||||
#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
|
||||
|
||||
+#define DTP_OFFSET 0x8000
|
||||
+
|
||||
// offset of the PC register in mcontext_t, divided by the system wordsize
|
||||
// the kernel calls the ip "nip", it's the first saved value after the 32
|
||||
// GPRs.
|
||||
diff --git a/arch/sh/src/__set_thread_area.c b/arch/sh/src/__set_thread_area.c
|
||||
new file mode 100644
|
||||
index 0000000..1d3e022
|
||||
|
@ -854,6 +892,21 @@ index 9b8385e..f5e4d9b 100644
|
|||
#define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1)
|
||||
+
|
||||
+#endif
|
||||
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h
|
||||
index e29f9c8..3890bb5 100644
|
||||
--- a/src/internal/pthread_impl.h
|
||||
+++ b/src/internal/pthread_impl.h
|
||||
@@ -94,6 +94,10 @@ struct __timer {
|
||||
#define CANARY canary
|
||||
#endif
|
||||
|
||||
+#ifndef DTP_OFFSET
|
||||
+#define DTP_OFFSET 0
|
||||
+#endif
|
||||
+
|
||||
#define SIGTIMER 32
|
||||
#define SIGCANCEL 33
|
||||
#define SIGSYNCCALL 34
|
||||
diff --git a/src/internal/sh/syscall.s b/src/internal/sh/syscall.s
|
||||
index d00712a..331918a 100644
|
||||
--- a/src/internal/sh/syscall.s
|
||||
|
@ -892,10 +945,62 @@ index e1325fe..0dd7fb5 100644
|
|||
#define feof(f) ((f)->flags & F_EOF)
|
||||
#define ferror(f) ((f)->flags & F_ERR)
|
||||
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
|
||||
index 42b056d..7e56693 100644
|
||||
index 42b056d..d2a7249 100644
|
||||
--- a/src/ldso/dynlink.c
|
||||
+++ b/src/ldso/dynlink.c
|
||||
@@ -536,7 +536,8 @@ static void *map_library(int fd, struct dso *dso)
|
||||
@@ -337,7 +337,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
|
||||
*reloc_addr = def.dso->tls_id;
|
||||
break;
|
||||
case REL_DTPOFF:
|
||||
- *reloc_addr = tls_val + addend;
|
||||
+ *reloc_addr = tls_val + addend - DTP_OFFSET;
|
||||
break;
|
||||
#ifdef TLS_ABOVE_TP
|
||||
case REL_TPOFF:
|
||||
@@ -423,6 +423,28 @@ static void reclaim_gaps(struct dso *dso)
|
||||
}
|
||||
}
|
||||
|
||||
+static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
|
||||
+{
|
||||
+ char *q = mmap(p, n, prot, flags, fd, off);
|
||||
+ if (q != MAP_FAILED || errno != EINVAL) return q;
|
||||
+ /* Fallbacks for MAP_FIXED failure on NOMMU kernels. */
|
||||
+ if (flags & MAP_ANONYMOUS) {
|
||||
+ memset(p, 0, n);
|
||||
+ return p;
|
||||
+ }
|
||||
+ ssize_t r;
|
||||
+ if (lseek(fd, off, SEEK_SET) < 0) return MAP_FAILED;
|
||||
+ for (q=p; n; q+=r, off+=r, n-=r) {
|
||||
+ r = read(fd, q, n);
|
||||
+ if (r < 0 && errno != EINTR) return MAP_FAILED;
|
||||
+ if (!r) {
|
||||
+ memset(q, 0, n);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return p;
|
||||
+}
|
||||
+
|
||||
static void *map_library(int fd, struct dso *dso)
|
||||
{
|
||||
Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
|
||||
@@ -524,19 +546,20 @@ static void *map_library(int fd, struct dso *dso)
|
||||
prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
|
||||
((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
|
||||
((ph->p_flags&PF_X) ? PROT_EXEC : 0));
|
||||
- if (mmap(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
|
||||
+ if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
|
||||
goto error;
|
||||
if (ph->p_memsz > ph->p_filesz) {
|
||||
size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
|
||||
size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
|
||||
memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
|
||||
- if (pgbrk-(size_t)base < this_max && mmap((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
|
||||
+ if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
|
||||
if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
|
||||
|
@ -905,7 +1010,7 @@ index 42b056d..7e56693 100644
|
|||
goto error;
|
||||
break;
|
||||
}
|
||||
@@ -927,7 +928,8 @@ static void reloc_all(struct dso *p)
|
||||
@@ -927,7 +950,8 @@ static void reloc_all(struct dso *p)
|
||||
do_relocs(p, (void *)(p->base+dyn[DT_RELA]), dyn[DT_RELASZ], 3);
|
||||
|
||||
if (head != &ldso && p->relro_start != p->relro_end &&
|
||||
|
@ -915,7 +1020,25 @@ index 42b056d..7e56693 100644
|
|||
error("Error relocating %s: RELRO protection failed: %m",
|
||||
p->name);
|
||||
if (runtime) longjmp(*rtld_fail, 1);
|
||||
@@ -1192,6 +1194,17 @@ _Noreturn void __dls3(size_t *sp)
|
||||
@@ -1078,7 +1102,7 @@ void *__tls_get_new(size_t *v)
|
||||
__block_all_sigs(&set);
|
||||
if (v[0]<=(size_t)self->dtv[0]) {
|
||||
__restore_sigs(&set);
|
||||
- return (char *)self->dtv[v[0]]+v[1];
|
||||
+ return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
|
||||
}
|
||||
|
||||
/* This is safe without any locks held because, if the caller
|
||||
@@ -1111,7 +1135,7 @@ void *__tls_get_new(size_t *v)
|
||||
if (p->tls_id == v[0]) break;
|
||||
}
|
||||
__restore_sigs(&set);
|
||||
- return mem + v[1];
|
||||
+ return mem + v[1] + DTP_OFFSET;
|
||||
}
|
||||
|
||||
static void update_tls_size()
|
||||
@@ -1192,6 +1216,17 @@ _Noreturn void __dls3(size_t *sp)
|
||||
char **argv_orig = argv;
|
||||
char **envp = argv+argc+1;
|
||||
|
||||
|
@ -933,7 +1056,7 @@ index 42b056d..7e56693 100644
|
|||
/* Setup early thread pointer in builtin_tls for ldso/libc itself to
|
||||
* use during dynamic linking. If possible it will also serve as the
|
||||
* thread pointer at runtime. */
|
||||
@@ -1200,25 +1213,11 @@ _Noreturn void __dls3(size_t *sp)
|
||||
@@ -1200,25 +1235,11 @@ _Noreturn void __dls3(size_t *sp)
|
||||
a_crash();
|
||||
}
|
||||
|
||||
|
@ -1117,6 +1240,36 @@ index b70a0c1..0fc5ecb 100644
|
|||
|
||||
return old == global ? LC_GLOBAL_LOCALE : old;
|
||||
}
|
||||
diff --git a/src/malloc/calloc.c b/src/malloc/calloc.c
|
||||
index c3dfb47..436c0b0 100644
|
||||
--- a/src/malloc/calloc.c
|
||||
+++ b/src/malloc/calloc.c
|
||||
@@ -1,22 +1,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
+void *__malloc0(size_t);
|
||||
+
|
||||
void *calloc(size_t m, size_t n)
|
||||
{
|
||||
- void *p;
|
||||
- size_t *z;
|
||||
if (n && m > (size_t)-1/n) {
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
- n *= m;
|
||||
- p = malloc(n);
|
||||
- if (!p) return 0;
|
||||
- /* Only do this for non-mmapped chunks */
|
||||
- if (((size_t *)p)[-1] & 7) {
|
||||
- /* Only write words that are not already zero */
|
||||
- m = (n + sizeof *z - 1)/sizeof *z;
|
||||
- for (z=p; m; m--, z++) if (*z) *z=0;
|
||||
- }
|
||||
- return p;
|
||||
+ return __malloc0(n * m);
|
||||
}
|
||||
diff --git a/src/malloc/expand_heap.c b/src/malloc/expand_heap.c
|
||||
new file mode 100644
|
||||
index 0000000..d8c0be7
|
||||
|
@ -1196,10 +1349,10 @@ index 0000000..d8c0be7
|
|||
+ return area;
|
||||
+}
|
||||
diff --git a/src/malloc/lite_malloc.c b/src/malloc/lite_malloc.c
|
||||
index 7643fc2..008549d 100644
|
||||
index 7643fc2..09ac575 100644
|
||||
--- a/src/malloc/lite_malloc.c
|
||||
+++ b/src/malloc/lite_malloc.c
|
||||
@@ -4,43 +4,46 @@
|
||||
@@ -4,43 +4,47 @@
|
||||
#include <errno.h>
|
||||
#include "libc.h"
|
||||
|
||||
|
@ -1269,8 +1422,9 @@ index 7643fc2..008549d 100644
|
|||
}
|
||||
|
||||
weak_alias(__simple_malloc, malloc);
|
||||
+weak_alias(__simple_malloc, __malloc0);
|
||||
diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c
|
||||
index d4de2dc..290fda1 100644
|
||||
index d4de2dc..eb68d55 100644
|
||||
--- a/src/malloc/malloc.c
|
||||
+++ b/src/malloc/malloc.c
|
||||
@@ -13,7 +13,6 @@
|
||||
|
@ -1394,6 +1548,24 @@ index d4de2dc..290fda1 100644
|
|||
}
|
||||
|
||||
static int adjust_size(size_t *n)
|
||||
@@ -378,6 +356,17 @@ void *malloc(size_t n)
|
||||
return CHUNK_TO_MEM(c);
|
||||
}
|
||||
|
||||
+void *__malloc0(size_t n)
|
||||
+{
|
||||
+ void *p = malloc(n);
|
||||
+ if (p && !IS_MMAPPED(MEM_TO_CHUNK(p))) {
|
||||
+ size_t *z;
|
||||
+ n = (n + sizeof *z - 1)/sizeof *z;
|
||||
+ for (z=p; n; n--, z++) if (*z) *z=0;
|
||||
+ }
|
||||
+ return p;
|
||||
+}
|
||||
+
|
||||
void *realloc(void *p, size_t n)
|
||||
{
|
||||
struct chunk *self, *next;
|
||||
diff --git a/src/multibyte/btowc.c b/src/multibyte/btowc.c
|
||||
index 9d2c3b1..8acd0a2 100644
|
||||
--- a/src/multibyte/btowc.c
|
||||
|
@ -2106,6 +2278,92 @@ index ac5c2c2..223aad4 100644
|
|||
|
||||
for (p=fmt; *p; p++) {
|
||||
|
||||
diff --git a/src/string/strverscmp.c b/src/string/strverscmp.c
|
||||
index 6f37cc6..4daf276 100644
|
||||
--- a/src/string/strverscmp.c
|
||||
+++ b/src/string/strverscmp.c
|
||||
@@ -2,40 +2,33 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
-int strverscmp(const char *l, const char *r)
|
||||
+int strverscmp(const char *l0, const char *r0)
|
||||
{
|
||||
- int haszero=1;
|
||||
- while (*l==*r) {
|
||||
- if (!*l) return 0;
|
||||
+ const unsigned char *l = (const void *)l0;
|
||||
+ const unsigned char *r = (const void *)r0;
|
||||
+ size_t i, dp, j;
|
||||
+ int z = 1;
|
||||
|
||||
- if (*l=='0') {
|
||||
- if (haszero==1) {
|
||||
- haszero=0;
|
||||
- }
|
||||
- } else if (isdigit(*l)) {
|
||||
- if (haszero==1) {
|
||||
- haszero=2;
|
||||
- }
|
||||
- } else {
|
||||
- haszero=1;
|
||||
- }
|
||||
- l++; r++;
|
||||
+ /* Find maximal matching prefix and track its maximal digit
|
||||
+ * suffix and whether those digits are all zeros. */
|
||||
+ for (dp=i=0; l[i]==r[i]; i++) {
|
||||
+ int c = l[i];
|
||||
+ if (!c) return 0;
|
||||
+ if (!isdigit(c)) dp=i+1, z=1;
|
||||
+ else if (c!='0') z=0;
|
||||
}
|
||||
- if (haszero==1 && (*l=='0' || *r=='0')) {
|
||||
- haszero=0;
|
||||
- }
|
||||
- if ((isdigit(*l) && isdigit(*r) ) && haszero) {
|
||||
- size_t lenl=0, lenr=0;
|
||||
- while (isdigit(l[lenl]) ) lenl++;
|
||||
- while (isdigit(r[lenr]) ) lenr++;
|
||||
- if (lenl==lenr) {
|
||||
- return (*l - *r);
|
||||
- } else if (lenl>lenr) {
|
||||
- return 1;
|
||||
- } else {
|
||||
- return -1;
|
||||
- }
|
||||
- } else {
|
||||
- return (*l - *r);
|
||||
+
|
||||
+ if (l[dp]!='0' && r[dp]!='0') {
|
||||
+ /* If we're not looking at a digit sequence that began
|
||||
+ * with a zero, longest digit string is greater. */
|
||||
+ for (j=i; isdigit(l[j]); j++)
|
||||
+ if (!isdigit(r[j])) return 1;
|
||||
+ if (isdigit(r[j])) return -1;
|
||||
+ } else if (z && dp<i && (isdigit(l[i]) || isdigit(r[i]))) {
|
||||
+ /* Otherwise, if common prefix of digit sequence is
|
||||
+ * all zeros, digits order less than non-digits. */
|
||||
+ return (unsigned char)(l[i]-'0') - (unsigned char)(r[i]-'0');
|
||||
}
|
||||
+
|
||||
+ return l[i] - r[i];
|
||||
}
|
||||
diff --git a/src/thread/__tls_get_addr.c b/src/thread/__tls_get_addr.c
|
||||
index 3633396..84a413d 100644
|
||||
--- a/src/thread/__tls_get_addr.c
|
||||
+++ b/src/thread/__tls_get_addr.c
|
||||
@@ -8,9 +8,9 @@ void *__tls_get_addr(size_t *v)
|
||||
__attribute__((__visibility__("hidden")))
|
||||
void *__tls_get_new(size_t *);
|
||||
if (v[0]<=(size_t)self->dtv[0])
|
||||
- return (char *)self->dtv[v[0]]+v[1];
|
||||
+ return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
|
||||
return __tls_get_new(v);
|
||||
#else
|
||||
- return (char *)self->dtv[1]+v[1];
|
||||
+ return (char *)self->dtv[1]+v[1]+DTP_OFFSET;
|
||||
#endif
|
||||
}
|
||||
diff --git a/src/thread/__unmapself.c b/src/thread/__unmapself.c
|
||||
index e69de29..1d3bee1 100644
|
||||
--- a/src/thread/__unmapself.c
|
||||
|
@ -2263,6 +2521,3 @@ index d865ae3..46c4908 100644
|
|||
|
||||
! work around hardware bug
|
||||
or r0, r0
|
||||
--
|
||||
2.1.4
|
||||
|
Loading…
Reference in a new issue