From 5ce7c00aadc63e34d8629b36b8c7cf3c9ee0c380 Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sat, 5 Jul 2014 13:20:23 +0200 Subject: remove addon patches --- toolchain/uclibc/patches/xxx-origin.patch | 177 -- toolchain/uclibc/patches/xxx-sparc-wait4.patch | 12 - toolchain/uclibc/patches/xxx-xtensa-nptl.patch | 3515 ------------------------ 3 files changed, 3704 deletions(-) delete mode 100644 toolchain/uclibc/patches/xxx-origin.patch delete mode 100644 toolchain/uclibc/patches/xxx-sparc-wait4.patch delete mode 100644 toolchain/uclibc/patches/xxx-xtensa-nptl.patch (limited to 'toolchain/uclibc') diff --git a/toolchain/uclibc/patches/xxx-origin.patch b/toolchain/uclibc/patches/xxx-origin.patch deleted file mode 100644 index 42b524017..000000000 --- a/toolchain/uclibc/patches/xxx-origin.patch +++ /dev/null @@ -1,177 +0,0 @@ -diff -Nur uClibc-git/ldso/ldso/dl-elf.c uClibc-origin/ldso/ldso/dl-elf.c ---- uClibc-git/ldso/ldso/dl-elf.c 2014-02-03 12:32:56.000000000 +0100 -+++ uClibc-origin/ldso/ldso/dl-elf.c 2014-02-17 14:44:13.000000000 +0100 -@@ -133,56 +133,59 @@ - * in uClibc/ldso/util/ldd.c */ - static struct elf_resolve * - search_for_named_library(const char *name, unsigned rflags, const char *path_list, -- struct dyn_elf **rpnt) -+ struct dyn_elf **rpnt, const char *origin) - { -- char *path, *path_n, *mylibname; -+ char *mylibname; -+ const char *p, *pn; - struct elf_resolve *tpnt; -- int done; -+ int plen; - - if (path_list==NULL) - return NULL; - -- /* We need a writable copy of this string, but we don't -- * need this allocated permanently since we don't want -- * to leak memory, so use alloca to put path on the stack */ -- done = _dl_strlen(path_list); -- path = alloca(done + 1); -- - /* another bit of local storage */ - mylibname = alloca(2050); - -- _dl_memcpy(path, path_list, done+1); -- - /* Unlike ldd.c, don't bother to eliminate double //s */ - - /* Replace colons with zeros in path_list */ - /* : at the beginning or end of path maps to CWD */ - /* :: anywhere maps CWD */ - /* "" maps to CWD */ -- done = 0; -- path_n = path; -- do { -- if (*path == 0) { -- *path = ':'; -- done = 1; -+ for (p = path_list; p != NULL; p = pn) { -+ pn = _dl_strchr(p + 1, ':'); -+ if (pn != NULL) { -+ plen = pn - p; -+ pn++; -+ } else -+ plen = _dl_strlen(p); -+ -+ if (plen >= 7 && _dl_memcmp(p, "$ORIGIN", 7) == 0) { -+ int olen; -+ if (rflags && plen != 7) -+ continue; -+ if (origin == NULL) -+ continue; -+ for (olen = _dl_strlen(origin) - 1; olen >= 0 && origin[olen] != '/'; olen--) -+ ; -+ if (olen <= 0) -+ continue; -+ _dl_memcpy(&mylibname[0], origin, olen); -+ _dl_memcpy(&mylibname[olen], p + 7, plen - 7); -+ mylibname[olen + plen - 7] = 0; -+ } else if (plen != 0) { -+ _dl_memcpy(mylibname, p, plen); -+ mylibname[plen] = 0; -+ } else { -+ _dl_strcpy(mylibname, "."); - } -- if (*path == ':') { -- *path = 0; -- if (*path_n) -- _dl_strcpy(mylibname, path_n); -- else -- _dl_strcpy(mylibname, "."); /* Assume current dir if empty path */ -- _dl_strcat(mylibname, "/"); -- _dl_strcat(mylibname, name); --#ifdef __LDSO_SAFE_RUNPATH__ -- if (*mylibname == '/') --#endif -- if ((tpnt = _dl_load_elf_shared_library(rflags, rpnt, mylibname)) != NULL) -- return tpnt; -- path_n = path+1; -- } -- path++; -- } while (!done); -+ _dl_strcat(mylibname, "/"); -+ _dl_strcat(mylibname, name); -+ -+ tpnt = _dl_load_elf_shared_library(rflags, rpnt, mylibname); -+ if (tpnt != NULL) -+ return tpnt; -+ } - return NULL; - } - -@@ -234,7 +237,7 @@ - if (pnt) { - pnt += (unsigned long) tpnt->dynamic_info[DT_STRTAB]; - _dl_if_debug_dprint("\tsearching RPATH='%s'\n", pnt); -- if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt)) != NULL) -+ if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt, tpnt->libname)) != NULL) - return tpnt1; - } - #endif -@@ -243,7 +246,7 @@ - /* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */ - if (_dl_library_path) { - _dl_if_debug_dprint("\tsearching LD_LIBRARY_PATH='%s'\n", _dl_library_path); -- if ((tpnt1 = search_for_named_library(libname, rflags, _dl_library_path, rpnt)) != NULL) -+ if ((tpnt1 = search_for_named_library(libname, rflags, _dl_library_path, rpnt, NULL)) != NULL) - { - return tpnt1; - } -@@ -257,7 +260,7 @@ - if (pnt) { - pnt += (unsigned long) tpnt->dynamic_info[DT_STRTAB]; - _dl_if_debug_dprint("\tsearching RUNPATH='%s'\n", pnt); -- if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt)) != NULL) -+ if ((tpnt1 = search_for_named_library(libname, rflags, pnt, rpnt, NULL)) != NULL) - return tpnt1; - } - #endif -@@ -291,7 +294,7 @@ - /* Look for libraries wherever the shared library loader - * was installed */ - _dl_if_debug_dprint("\tsearching ldso dir='%s'\n", _dl_ldsopath); -- tpnt1 = search_for_named_library(libname, rflags, _dl_ldsopath, rpnt); -+ tpnt1 = search_for_named_library(libname, rflags, _dl_ldsopath, rpnt, NULL); - if (tpnt1 != NULL) - return tpnt1; - #endif -@@ -304,7 +307,7 @@ - #ifndef __LDSO_CACHE_SUPPORT__ - ":" UCLIBC_RUNTIME_PREFIX "usr/X11R6/lib" - #endif -- , rpnt); -+ , rpnt, NULL); - if (tpnt1 != NULL) - return tpnt1; - -diff -Nur uClibc-git/ldso/ldso/ldso.c uClibc-origin/ldso/ldso/ldso.c ---- uClibc-git/ldso/ldso/ldso.c 2014-02-03 12:32:56.000000000 +0100 -+++ uClibc-origin/ldso/ldso/ldso.c 2014-02-17 12:34:00.000000000 +0100 -@@ -403,6 +403,20 @@ - return p - list; - } - -+static void _dl_setup_progname(const char *argv0) -+{ -+ char image[PATH_MAX]; -+ ssize_t s; -+ -+ s = _dl_readlink("/proc/self/exe", image, sizeof(image)); -+ if (s > 0 && image[0] == '/') { -+ image[s] = 0; -+ _dl_progname = _dl_strdup(image); -+ } else if (argv0) { -+ _dl_progname = argv0; -+ } -+} -+ - void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, - ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp, char **argv - DL_GET_READY_TO_RUN_EXTRA_PARMS) -@@ -454,9 +468,7 @@ - * been fixed up by now. Still no function calls outside of this - * library, since the dynamic resolver is not yet ready. - */ -- if (argv[0]) { -- _dl_progname = argv[0]; -- } -+ _dl_setup_progname(argv[0]); - - #ifdef __DSBT__ - _dl_ldso_dsbt = (void *)tpnt->dynamic_info[DT_DSBT_BASE_IDX]; diff --git a/toolchain/uclibc/patches/xxx-sparc-wait4.patch b/toolchain/uclibc/patches/xxx-sparc-wait4.patch deleted file mode 100644 index e219ed773..000000000 --- a/toolchain/uclibc/patches/xxx-sparc-wait4.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -Nur uClibc-0.9.33.2.orig/include/sys/wait.h uClibc-0.9.33.2/include/sys/wait.h ---- uClibc-0.9.33.2.orig/include/sys/wait.h 2014-03-01 19:15:53.000000000 +0100 -+++ uClibc-0.9.33.2/include/sys/wait.h 2014-03-01 19:16:42.000000000 +0100 -@@ -176,7 +176,7 @@ - #endif /* Use BSD. */ - - #ifdef _LIBC --extern __pid_t __wait4_nocancel(__pid_t, __WAIT_STATUS, int, struct rusage *) attribute_hidden; -+extern __pid_t __wait4_nocancel(__pid_t, __WAIT_STATUS, int, struct rusage *); - #endif - - diff --git a/toolchain/uclibc/patches/xxx-xtensa-nptl.patch b/toolchain/uclibc/patches/xxx-xtensa-nptl.patch deleted file mode 100644 index 16241e161..000000000 --- a/toolchain/uclibc/patches/xxx-xtensa-nptl.patch +++ /dev/null @@ -1,3515 +0,0 @@ -diff -Nur uClibc-git/include/elf.h uClibc-xtensa/include/elf.h ---- uClibc-git/include/elf.h 2014-06-02 17:40:33.826710944 +0200 -+++ uClibc-xtensa/include/elf.h 2014-06-03 16:03:19.065886532 +0200 -@@ -3072,8 +3071,11 @@ - #define R_XTENSA_SLOT12_ALT 47 - #define R_XTENSA_SLOT13_ALT 48 - #define R_XTENSA_SLOT14_ALT 49 -+#define R_XTENSA_TLSDESC_FN 50 -+#define R_XTENSA_TLSDESC_ARG 51 -+#define R_XTENSA_TLS_TPOFF 53 - /* Keep this the last entry. */ --#define R_XTENSA_NUM 50 -+#define R_XTENSA_NUM 54 - - /* C6X specific relocs */ - #define R_C6000_NONE 0 -diff -Nur uClibc-git/include/link.h uClibc-xtensa/include/link.h ---- uClibc-git/include/link.h 2014-06-02 17:40:33.846711055 +0200 -+++ uClibc-xtensa/include/link.h 2014-06-03 15:28:27.185347373 +0200 -@@ -132,6 +132,8 @@ - size_t l_tls_modid; - /* Nonzero if _dl_init_static_tls should be called for this module */ - unsigned int l_need_tls_init:1; -+ /* Address of TLS descriptor hash table. */ -+ void *l_tlsdesc_table; - #endif - #endif - }; -diff -Nur uClibc-git/ldso/include/dl-hash.h uClibc-xtensa/ldso/include/dl-hash.h ---- uClibc-git/ldso/include/dl-hash.h 2014-06-02 17:40:33.902711365 +0200 -+++ uClibc-xtensa/ldso/include/dl-hash.h 2014-06-03 15:29:09.505536959 +0200 -@@ -70,6 +70,8 @@ - size_t l_tls_modid; - /* Nonzero if _dl_init_static_tls should be called for this module */ - unsigned int l_need_tls_init:1; -+ /* Address of TLS descriptor hash table. */ -+ void *l_tlsdesc_table; - #endif - - ElfW(Addr) mapaddr; -diff -Nur uClibc-git/ldso/include/inline-hashtab.h uClibc-xtensa/ldso/include/inline-hashtab.h ---- uClibc-git/ldso/include/inline-hashtab.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-xtensa/ldso/include/inline-hashtab.h 2014-06-03 11:57:42.031052092 +0200 -@@ -0,0 +1,265 @@ -+/* -+ * The hashcode handling code below is heavily inspired in libiberty's -+ * hashtab code, but with most adaptation points and support for -+ * deleting elements removed. -+ * -+ * Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -+ * Contributed by Vladimir Makarov (vmakarov@cygnus.com). -+ */ -+ -+#ifndef INLINE_HASHTAB_H -+# define INLINE_HASHTAB_H 1 -+ -+static __always_inline unsigned long -+higher_prime_number(unsigned long n) -+{ -+ /* These are primes that are near, but slightly smaller than, a power of two. */ -+ static const unsigned long primes[] = { -+ 7, -+ 13, -+ 31, -+ 61, -+ 127, -+ 251, -+ 509, -+ 1021, -+ 2039, -+ 4093, -+ 8191, -+ 16381, -+ 32749, -+ 65521, -+ 131071, -+ 262139, -+ 524287, -+ 1048573, -+ 2097143, -+ 4194301, -+ 8388593, -+ 16777213, -+ 33554393, -+ 67108859, -+ 134217689, -+ 268435399, -+ 536870909, -+ 1073741789, -+ /* 4294967291 */ -+ ((unsigned long) 2147483647) + ((unsigned long) 2147483644), -+ }; -+ const unsigned long *low = &primes[0]; -+ const unsigned long *high = &primes[ARRAY_SIZE(primes)]; -+ -+ while (low != high) { -+ const unsigned long *mid = low + (high - low) / 2; -+ if (n > *mid) -+ low = mid + 1; -+ else -+ high = mid; -+ } -+ -+#if 0 -+ /* If we've run out of primes, abort. */ -+ if (n > *low) { -+ fprintf(stderr, "Cannot find prime bigger than %lu\n", n); -+ abort(); -+ } -+#endif -+ -+ return *low; -+} -+ -+struct funcdesc_ht -+{ -+ /* Table itself */ -+ void **entries; -+ -+ /* Current size (in entries) of the hash table */ -+ size_t size; -+ -+ /* Current number of elements */ -+ size_t n_elements; -+}; -+ -+static __always_inline struct funcdesc_ht * -+htab_create(void) -+{ -+ struct funcdesc_ht *ht = _dl_malloc(sizeof(*ht)); -+ size_t ent_size; -+ -+ if (!ht) -+ return NULL; -+ ht->size = 3; -+ ent_size = sizeof(void *) * ht->size; -+ ht->entries = _dl_malloc(ent_size); -+ if (!ht->entries) -+ return NULL; -+ -+ ht->n_elements = 0; -+ _dl_memset(ht->entries, 0, ent_size); -+ -+ return ht; -+} -+ -+/* -+ * This is only called from _dl_loadaddr_unmap, so it's safe to call -+ * _dl_free(). See the discussion below. -+ */ -+static __always_inline void -+htab_delete(struct funcdesc_ht *htab) -+{ -+ size_t i; -+ -+ for (i = htab->size - 1; i >= 0; i--) -+ if (htab->entries[i]) -+ _dl_free(htab->entries[i]); -+ -+ _dl_free(htab->entries); -+ _dl_free(htab); -+} -+ -+/* -+ * Similar to htab_find_slot, but without several unwanted side effects: -+ * - Does not call htab->eq_f when it finds an existing entry. -+ * - Does not change the count of elements/searches/collisions in the -+ * hash table. -+ * This function also assumes there are no deleted entries in the table. -+ * HASH is the hash value for the element to be inserted. -+ */ -+static __always_inline void ** -+find_empty_slot_for_expand(struct funcdesc_ht *htab, int hash) -+{ -+ size_t size = htab->size; -+ unsigned int index = hash % size; -+ void **slot = htab->entries + index; -+ int hash2; -+ -+ if (!*slot) -+ return slot; -+ -+ hash2 = 1 + hash % (size - 2); -+ for (;;) { -+ index += hash2; -+ if (index >= size) -+ index -= size; -+ -+ slot = htab->entries + index; -+ if (!*slot) -+ return slot; -+ } -+} -+ -+/* -+ * The following function changes size of memory allocated for the -+ * entries and repeatedly inserts the table elements. The occupancy -+ * of the table after the call will be about 50%. Naturally the hash -+ * table must already exist. Remember also that the place of the -+ * table entries is changed. If memory allocation failures are allowed, -+ * this function will return zero, indicating that the table could not be -+ * expanded. If all goes well, it will return a non-zero value. -+ */ -+static __always_inline int -+htab_expand(struct funcdesc_ht *htab, int (*hash_fn) (void *)) -+{ -+ void **oentries; -+ void **olimit; -+ void **p; -+ void **nentries; -+ size_t nsize; -+ -+ oentries = htab->entries; -+ olimit = oentries + htab->size; -+ -+ /* -+ * Resize only when table after removal of unused elements is either -+ * too full or too empty. -+ */ -+ if (htab->n_elements * 2 > htab->size) -+ nsize = higher_prime_number(htab->n_elements * 2); -+ else -+ nsize = htab->size; -+ -+ nentries = _dl_malloc(sizeof(*nentries) * nsize); -+ _dl_memset(nentries, 0, sizeof(*nentries) * nsize); -+ if (nentries == NULL) -+ return 0; -+ htab->entries = nentries; -+ htab->size = nsize; -+ -+ p = oentries; -+ do { -+ if (*p) -+ *find_empty_slot_for_expand(htab, hash_fn(*p)) = *p; -+ p++; -+ } while (p < olimit); -+ -+#if 0 -+ /* -+ * We can't tell whether this was allocated by the _dl_malloc() -+ * built into ld.so or malloc() in the main executable or libc, -+ * and calling free() for something that wasn't malloc()ed could -+ * do Very Bad Things (TM). Take the conservative approach -+ * here, potentially wasting as much memory as actually used by -+ * the hash table, even if multiple growths occur. That's not -+ * so bad as to require some overengineered solution that would -+ * enable us to keep track of how it was allocated. -+ */ -+ _dl_free(oentries); -+#endif -+ return 1; -+} -+ -+/* -+ * This function searches for a hash table slot containing an entry -+ * equal to the given element. To delete an entry, call this with -+ * INSERT = 0, then call htab_clear_slot on the slot returned (possibly -+ * after doing some checks). To insert an entry, call this with -+ * INSERT = 1, then write the value you want into the returned slot. -+ * When inserting an entry, NULL may be returned if memory allocation -+ * fails. -+ */ -+static __always_inline void ** -+htab_find_slot(struct funcdesc_ht *htab, void *ptr, int insert, -+ int (*hash_fn)(void *), int (*eq_fn)(void *, void *)) -+{ -+ unsigned int index; -+ int hash, hash2; -+ size_t size; -+ void **entry; -+ -+ if (htab->size * 3 <= htab->n_elements * 4 && -+ htab_expand(htab, hash_fn) == 0) -+ return NULL; -+ -+ hash = hash_fn(ptr); -+ -+ size = htab->size; -+ index = hash % size; -+ -+ entry = &htab->entries[index]; -+ if (!*entry) -+ goto empty_entry; -+ else if (eq_fn(*entry, ptr)) -+ return entry; -+ -+ hash2 = 1 + hash % (size - 2); -+ for (;;) { -+ index += hash2; -+ if (index >= size) -+ index -= size; -+ -+ entry = &htab->entries[index]; -+ if (!*entry) -+ goto empty_entry; -+ else if (eq_fn(*entry, ptr)) -+ return entry; -+ } -+ -+ empty_entry: -+ if (!insert) -+ return NULL; -+ -+ htab->n_elements++; -+ return entry; -+} -+ -+#endif -diff -Nur uClibc-git/ldso/include/ldsodefs.h uClibc-xtensa/ldso/include/ldsodefs.h ---- uClibc-git/ldso/include/ldsodefs.h 2014-06-02 17:40:33.922711475 +0200 -+++ uClibc-xtensa/ldso/include/ldsodefs.h 2014-06-03 16:10:51.175659505 +0200 -@@ -62,13 +62,18 @@ - - extern void _dl_allocate_static_tls (struct link_map *map) - internal_function attribute_hidden; -+extern int _dl_try_allocate_static_tls (struct link_map* map) -+ internal_function attribute_hidden; - - /* Taken from glibc/elf/dl-reloc.c */ - #define CHECK_STATIC_TLS(sym_map) \ - do { \ -- if (unlikely((sym_map)->l_tls_offset == NO_TLS_OFFSET)) \ -+ if (__builtin_expect ((sym_map)->l_tls_offset == NO_TLS_OFFSET, 0)) \ - _dl_allocate_static_tls (sym_map); \ - } while (0) -+#define TRY_STATIC_TLS(sym_map) \ -+ (__builtin_expect ((sym_map)->l_tls_offset != NO_TLS_OFFSET, 1) \ -+ || _dl_try_allocate_static_tls (sym_map) == 0) - - /* These are internal entry points to the two halves of _dl_allocate_tls, - only used within rtld.c itself at startup time. */ -diff -Nur uClibc-git/ldso/include/tlsdeschtab.h uClibc-xtensa/ldso/include/tlsdeschtab.h ---- uClibc-git/ldso/include/tlsdeschtab.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-xtensa/ldso/include/tlsdeschtab.h 2014-06-03 14:58:29.681335708 +0200 -@@ -0,0 +1,119 @@ -+/* Hash table for TLS descriptors. -+ Copyright (C) 2005-2013 Free Software Foundation, Inc. -+ This file is part of the GNU C Library. -+ Contributed by Alexandre Oliva -+ -+ uClibc port by Baruch Siach -+ -+ The GNU C Library is free software; you can redistribute it and/or -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#ifndef TLSDESCHTAB_H -+# define TLSDESCHTAB_H 1 -+ -+# ifdef SHARED -+ -+# include -+ -+inline static int -+hash_tlsdesc (void *p) -+{ -+ struct tlsdesc_dynamic_arg *td = p; -+ -+ /* We know all entries are for the same module, so ti_offset is the -+ only distinguishing entry. */ -+ return td->tlsinfo.ti_offset; -+} -+ -+inline static int -+eq_tlsdesc (void *p, void *q) -+{ -+ struct tlsdesc_dynamic_arg *tdp = p, *tdq = q; -+ -+ return tdp->tlsinfo.ti_offset == tdq->tlsinfo.ti_offset; -+} -+ -+inline static int -+map_generation (struct link_map *map) -+{ -+ size_t idx = map->l_tls_modid; -+ struct dtv_slotinfo_list *listp = GL(dl_tls_dtv_slotinfo_list); -+ -+ /* Find the place in the dtv slotinfo list. */ -+ do -+ { -+ /* Does it fit in the array of this list element? */ -+ if (idx < listp->len) -+ { -+ /* We should never get here for a module in static TLS, so -+ we can assume that, if the generation count is zero, we -+ still haven't determined the generation count for this -+ module. */ -+ if (listp->slotinfo[idx].gen) -+ return listp->slotinfo[idx].gen; -+ else -+ break; -+ } -+ idx -= listp->len; -+ listp = listp->next; -+ } -+ while (listp != NULL); -+ -+ /* If we get to this point, the module still hasn't been assigned an -+ entry in the dtv slotinfo data structures, and it will when we're -+ done with relocations. At that point, the module will get a -+ generation number that is one past the current generation, so -+ return exactly that. */ -+ return GL(dl_tls_generation) + 1; -+} -+ -+void * -+internal_function -+_dl_make_tlsdesc_dynamic (struct link_map *map, size_t ti_offset) -+{ -+ struct funcdesc_ht *ht; -+ void **entry; -+ struct tlsdesc_dynamic_arg *td, test; -+ -+ ht = map->l_tlsdesc_table; -+ if (! ht) -+ { -+ ht = htab_create (); -+ if (! ht) -+ return 0; -+ map->l_tlsdesc_table = ht; -+ } -+ -+ test.tlsinfo.ti_module = map->l_tls_modid; -+ test.tlsinfo.ti_offset = ti_offset; -+ entry = htab_find_slot (ht, &test, 1, hash_tlsdesc, eq_tlsdesc); -+ if (*entry) -+ { -+ td = *entry; -+ return td; -+ } -+ -+ *entry = td = _dl_malloc (sizeof (struct tlsdesc_dynamic_arg)); -+ /* This may be higher than the map's generation, but it doesn't -+ matter much. Worst case, we'll have one extra DTV update per -+ thread. */ -+ td->gen_count = map_generation (map); -+ td->tlsinfo = test.tlsinfo; -+ -+ return td; -+} -+ -+# endif /* SHARED */ -+ -+#endif -diff -Nur uClibc-git/ldso/ldso/dl-tls.c uClibc-xtensa/ldso/ldso/dl-tls.c ---- uClibc-git/ldso/ldso/dl-tls.c 2014-06-02 17:40:33.946711608 +0200 -+++ uClibc-xtensa/ldso/ldso/dl-tls.c 2014-06-03 16:10:28.547570023 +0200 -@@ -100,20 +100,16 @@ - * the static TLS area already allocated for each running thread. If this - * object's TLS segment is too big to fit, we fail. If it fits, - * we set MAP->l_tls_offset and return. -- * This function intentionally does not return any value but signals error -- * directly, as static TLS should be rare and code handling it should -- * not be inlined as much as possible. - */ --void --internal_function __attribute_noinline__ --_dl_allocate_static_tls (struct link_map *map) -+int -+internal_function -+_dl_try_allocate_static_tls (struct link_map* map) - { - /* If the alignment requirements are too high fail. */ - if (map->l_tls_align > _dl_tls_static_align) - { - fail: -- _dl_dprintf(2, "cannot allocate memory in static TLS block"); -- _dl_exit(30); -+ return -1; - } - - # ifdef TLS_TCB_AT_TP -@@ -169,6 +165,23 @@ - } - else - map->l_need_tls_init = 1; -+ -+ return 0; -+} -+ -+/* -+ * This function intentionally does not return any value but signals error -+ * directly, as static TLS should be rare and code handling it should -+ * not be inlined as much as possible. -+ */ -+void -+internal_function __attribute_noinline__ -+_dl_allocate_static_tls (struct link_map *map) -+{ -+ if (_dl_try_allocate_static_tls (map)) { -+ _dl_dprintf(2, "cannot allocate memory in static TLS block"); -+ _dl_exit(30); -+ } - } - - #ifdef SHARED -diff -Nur uClibc-git/ldso/ldso/fdpic/dl-inlines.h uClibc-xtensa/ldso/ldso/fdpic/dl-inlines.h ---- uClibc-git/ldso/ldso/fdpic/dl-inlines.h 2014-06-02 17:40:33.950711630 +0200 -+++ uClibc-xtensa/ldso/ldso/fdpic/dl-inlines.h 2014-06-03 11:57:43.263058897 +0200 -@@ -5,6 +5,8 @@ - * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - */ - -+#include -+ - /* Initialize a DL_LOADADDR_TYPE given a got pointer and a complete load map. */ - static __always_inline void - __dl_init_loadaddr_map(struct elf32_fdpic_loadaddr *loadaddr, Elf32_Addr dl_boot_got_pointer, -@@ -143,269 +145,18 @@ - return 0; - } - --/* -- * The hashcode handling code below is heavily inspired in libiberty's -- * hashtab code, but with most adaptation points and support for -- * deleting elements removed. -- * -- * Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -- * Contributed by Vladimir Makarov (vmakarov@cygnus.com). -- */ --static __always_inline unsigned long --higher_prime_number(unsigned long n) --{ -- /* These are primes that are near, but slightly smaller than, a power of two. */ -- static const unsigned long primes[] = { -- 7, -- 13, -- 31, -- 61, -- 127, -- 251, -- 509, -- 1021, -- 2039, -- 4093, -- 8191, -- 16381, -- 32749, -- 65521, -- 131071, -- 262139, -- 524287, -- 1048573, -- 2097143, -- 4194301, -- 8388593, -- 16777213, -- 33554393, -- 67108859, -- 134217689, -- 268435399, -- 536870909, -- 1073741789, -- /* 4294967291 */ -- ((unsigned long) 2147483647) + ((unsigned long) 2147483644), -- }; -- const unsigned long *low = &primes[0]; -- const unsigned long *high = &primes[ARRAY_SIZE(primes)]; -- -- while (low != high) { -- const unsigned long *mid = low + (high - low) / 2; -- if (n > *mid) -- low = mid + 1; -- else -- high = mid; -- } -- --#if 0 -- /* If we've run out of primes, abort. */ -- if (n > *low) { -- fprintf(stderr, "Cannot find prime bigger than %lu\n", n); -- abort(); -- } --#endif -- -- return *low; --} -- --struct funcdesc_ht --{ -- /* Table itself */ -- struct funcdesc_value **entries; -- -- /* Current size (in entries) of the hash table */ -- size_t size; -- -- /* Current number of elements */ -- size_t n_elements; --}; -- --static __always_inline int --hash_pointer(const void *p) -+static int -+hash_pointer(void *p) - { - return (int) ((long)p >> 3); - } - --static __always_inline struct funcdesc_ht * --htab_create(void) --{ -- struct funcdesc_ht *ht = _dl_malloc(sizeof(*ht)); -- size_t ent_size; -- -- if (!ht) -- return NULL; -- ht->size = 3; -- ent_size = sizeof(struct funcdesc_ht_value *) * ht->size; -- ht->entries = _dl_malloc(ent_size); -- if (!ht->entries) -- return NULL; -- -- ht->n_elements = 0; -- _dl_memset(ht->entries, 0, ent_size); -- -- return ht; --} -- --/* -- * This is only called from _dl_loadaddr_unmap, so it's safe to call -- * _dl_free(). See the discussion below. -- */ --static __always_inline void --htab_delete(struct funcdesc_ht *htab) --{ -- size_t i; -- -- for (i = htab->size - 1; i >= 0; i--) -- if (htab->entries[i]) -- _dl_free(htab->entries[i]); -- -- _dl_free(htab->entries); -- _dl_free(htab); --} -- --/* -- * Similar to htab_find_slot, but without several unwanted side effects: -- * - Does not call htab->eq_f when it finds an existing entry. -- * - Does not change the count of elements/searches/collisions in the -- * hash table. -- * This function also assumes there are no deleted entries in the table. -- * HASH is the hash value for the element to be inserted. -- */ --static __always_inline struct funcdesc_value ** --find_empty_slot_for_expand(struct funcdesc_ht *htab, int hash) -+static int -+eq_pointer(void *p, void *q) - { -- size_t size = htab->size; -- unsigned int index = hash % size; -- struct funcdesc_value **slot = htab->entries + index; -- int hash2; -- -- if (!*slot) -- return slot; -- -- hash2 = 1 + hash % (size - 2); -- for (;;) { -- index += hash2; -- if (index >= size) -- index -= size; -- -- slot = htab->entries + index; -- if (!*slot) -- return slot; -- } --} -- --/* -- * The following function changes size of memory allocated for the -- * entries and repeatedly inserts the table elements. The occupancy -- * of the table after the call will be about 50%. Naturally the hash -- * table must already exist. Remember also that the place of the -- * table entries is changed. If memory allocation failures are allowed, -- * this function will return zero, indicating that the table could not be -- * expanded. If all goes well, it will return a non-zero value. -- */ --static __always_inline int --htab_expand(struct funcdesc_ht *htab) --{ -- struct funcdesc_value **oentries; -- struct funcdesc_value **olimit; -- struct funcdesc_value **p; -- struct funcdesc_value **nentries; -- size_t nsize; -- -- oentries = htab->entries; -- olimit = oentries + htab->size; -- -- /* -- * Resize only when table after removal of unused elements is either -- * too full or too empty. -- */ -- if (htab->n_elements * 2 > htab->size) -- nsize = higher_prime_number(htab->n_elements * 2); -- else -- nsize = htab->size; -- -- nentries = _dl_malloc(sizeof(*nentries) * nsize); -- _dl_memset(nentries, 0, sizeof(*nentries) * nsize); -- if (nentries == NULL) -- return 0; -- htab->entries = nentries; -- htab->size = nsize; -- -- p = oentries; -- do { -- if (*p) -- *find_empty_slot_for_expand(htab, hash_pointer((*p)->entry_point)) = *p; -- p++; -- } while (p < olimit); -- --#if 0 -- /* -- * We can't tell whether this was allocated by the _dl_malloc() -- * built into ld.so or malloc() in the main executable or libc, -- * and calling free() for something that wasn't malloc()ed could -- * do Very Bad Things (TM). Take the conservative approach -- * here, potentially wasting as much memory as actually used by -- * the hash table, even if multiple growths occur. That's not -- * so bad as to require some overengineered solution that would -- * enable us to keep track of how it was allocated. -- */ -- _dl_free(oentries); --#endif -- return 1; --} -- --/* -- * This function searches for a hash table slot containing an entry -- * equal to the given element. To delete an entry, call this with -- * INSERT = 0, then call htab_clear_slot on the slot returned (possibly -- * after doing some checks). To insert an entry, call this with -- * INSERT = 1, then write the value you want into the returned slot. -- * When inserting an entry, NULL may be returned if memory allocation -- * fails. -- */ --static __always_inline struct funcdesc_value ** --htab_find_slot(struct funcdesc_ht *htab, void *ptr, int insert) --{ -- unsigned int index; -- int hash, hash2; -- size_t size; -- struct funcdesc_value **entry; -- -- if (htab->size * 3 <= htab->n_elements * 4 && -- htab_expand(htab) == 0) -- return NULL; -- -- hash = hash_pointer(ptr); -- -- size = htab->size; -- index = hash % size; -- -- entry = &htab->entries[index]; -- if (!*entry) -- goto empty_entry; -- else if ((*entry)->entry_point == ptr) -- return entry; -- -- hash2 = 1 + hash % (size - 2); -- for (;;) { -- index += hash2; -- if (index >= size) -- index -= size; -- -- entry = &htab->entries[index]; -- if (!*entry) -- goto empty_entry; -- else if ((*entry)->entry_point == ptr) -- return entry; -- } -- -- empty_entry: -- if (!insert) -- return NULL; -+ struct funcdesc_value *entry = p; - -- htab->n_elements++; -- return entry; -+ return entry->entry_point == q; - } - - void * -@@ -424,7 +175,7 @@ - tpnt->funcdesc_ht = ht; - } - -- entry = htab_find_slot(ht, entry_point, 1); -+ entry = htab_find_slot(ht, entry_point, 1, hash_pointer, eq_pointer); - if (*entry) { - _dl_assert((*entry)->entry_point == entry_point); - return _dl_stabilize_funcdesc(*entry); -@@ -459,7 +210,8 @@ - if (fd->got_value != rpnt->loadaddr.got_value) - continue; - -- address = htab_find_slot(rpnt->funcdesc_ht, (void *)fd->entry_point, 0); -+ address = htab_find_slot(rpnt->funcdesc_ht, (void *)fd->entry_point, 0, -+ hash_pointer, eq_pointer); - - if (address && *(struct funcdesc_value *const*)address == fd) { - address = (*(struct funcdesc_value *const*)address)->entry_point; -diff -Nur uClibc-git/ldso/ldso/xtensa/dl-debug.h uClibc-xtensa/ldso/ldso/xtensa/dl-debug.h ---- uClibc-git/ldso/ldso/xtensa/dl-debug.h 2014-06-02 17:40:33.958711675 +0200 -+++ uClibc-xtensa/ldso/ldso/xtensa/dl-debug.h 2014-06-03 12:22:20.032058866 +0200 -@@ -8,54 +8,31 @@ - - static const char * const _dl_reltypes_tab[] = - { -- "R_XTENSA_NONE", -- "R_XTENSA_32", -- "R_XTENSA_RTLD", -- "R_XTENSA_GLOB_DAT", -- "R_XTENSA_JMP_SLOT", -- "R_XTENSA_RELATIVE", -- "R_XTENSA_PLT", -- "R_XTENSA_UNUSED7", -- "R_XTENSA_OP0", -- "R_XTENSA_OP1", -- "R_XTENSA_OP2", -- "R_XTENSA_ASM_EXPAND", -- "R_XTENSA_ASM_SIMPLIFY", -- "R_XTENSA_UNUSED13", -- "R_XTENSA_UNUSED14", -- "R_XTENSA_GNU_VTINHERIT", -- "R_XTENSA_GNU_VTENTRY", -- "R_XTENSA_DIFF8", -- "R_XTENSA_DIFF16", -- "R_XTENSA_DIFF32", -- "R_XTENSA_SLOT0_OP", -- "R_XTENSA_SLOT1_OP", -- "R_XTENSA_SLOT2_OP", -- "R_XTENSA_SLOT3_OP", -- "R_XTENSA_SLOT4_OP", -- "R_XTENSA_SLOT5_OP", -- "R_XTENSA_SLOT6_OP", -- "R_XTENSA_SLOT7_OP", -- "R_XTENSA_SLOT8_OP", -- "R_XTENSA_SLOT9_OP", -- "R_XTENSA_SLOT10_OP", -- "R_XTENSA_SLOT11_OP", -- "R_XTENSA_SLOT12_OP", -- "R_XTENSA_SLOT13_OP", -- "R_XTENSA_SLOT14_OP", -- "R_XTENSA_SLOT0_ALT", -- "R_XTENSA_SLOT1_ALT", -- "R_XTENSA_SLOT2_ALT", -- "R_XTENSA_SLOT3_ALT", -- "R_XTENSA_SLOT4_ALT", -- "R_XTENSA_SLOT5_ALT", -- "R_XTENSA_SLOT6_ALT", -- "R_XTENSA_SLOT7_ALT", -- "R_XTENSA_SLOT8_ALT", -- "R_XTENSA_SLOT9_ALT", -- "R_XTENSA_SLOT10_ALT", -- "R_XTENSA_SLOT11_ALT", -- "R_XTENSA_SLOT12_ALT", -- "R_XTENSA_SLOT13_ALT", -- "R_XTENSA_SLOT14_ALT" -+ [0] "R_XTENSA_NONE", "R_XTENSA_32", -+ [2] "R_XTENSA_RTLD", "R_XTENSA_GLOB_DAT", -+ [4] "R_XTENSA_JMP_SLOT", "R_XTENSA_RELATIVE", -+ [6] "R_XTENSA_PLT", "R_XTENSA_UNUSED7", -+ [8] "R_XTENSA_OP0", "R_XTENSA_OP1", -+ [10] "R_XTENSA_OP2", "R_XTENSA_ASM_EXPAND", -+ [12] "R_XTENSA_ASM_SIMPLIFY", "R_XTENSA_UNUSED13", -+ [14] "R_XTENSA_UNUSED14", "R_XTENSA_GNU_VTINHERIT", -+ [16] "R_XTENSA_GNU_VTENTRY", "R_XTENSA_DIFF8", -+ [18] "R_XTENSA_DIFF16", "R_XTENSA_DIFF32", -+ [20] "R_XTENSA_SLOT0_OP", "R_XTENSA_SLOT1_OP", -+ [22] "R_XTENSA_SLOT2_OP", "R_XTENSA_SLOT3_OP", -+ [24] "R_XTENSA_SLOT4_OP", "R_XTENSA_SLOT5_OP", -+ [26] "R_XTENSA_SLOT6_OP", "R_XTENSA_SLOT7_OP", -+ [28] "R_XTENSA_SLOT8_OP", "R_XTENSA_SLOT9_OP", -+ [30] "R_XTENSA_SLOT10_OP", "R_XTENSA_SLOT11_OP", -+ [32] "R_XTENSA_SLOT12_OP", "R_XTENSA_SLOT13_OP", -+ [34] "R_XTENSA_SLOT14_OP", "R_XTENSA_SLOT0_ALT", -+ [36] "R_XTENSA_SLOT1_ALT", "R_XTENSA_SLOT2_ALT", -+ [38] "R_XTENSA_SLOT3_ALT", "R_XTENSA_SLOT4_ALT", -+ [40] "R_XTENSA_SLOT5_ALT", "R_XTENSA_SLOT6_ALT", -+ [42] "R_XTENSA_SLOT7_ALT", "R_XTENSA_SLOT8_ALT", -+ [44] "R_XTENSA_SLOT9_ALT", "R_XTENSA_SLOT10_ALT", -+ [46] "R_XTENSA_SLOT11_ALT", "R_XTENSA_SLOT12_ALT", -+ [48] "R_XTENSA_SLOT13_ALT", "R_XTENSA_SLOT14_ALT", -+ [50] "R_XTENSA_TLSDESC_FN", "R_XTENSA_TLSDESC_ARG", -+ [52] "R_XTENSA_TLS_TPOFF" - }; -diff -Nur uClibc-git/ldso/ldso/xtensa/dl-startup.h uClibc-xtensa/ldso/ldso/xtensa/dl-startup.h ---- uClibc-git/ldso/ldso/xtensa/dl-startup.h 2014-06-02 17:40:33.958711675 +0200 -+++ uClibc-xtensa/ldso/ldso/xtensa/dl-startup.h 2014-06-03 12:22:20.112059404 +0200 -@@ -11,7 +11,6 @@ - __asm__ ( - " .text\n" - " .align 4\n" -- " .literal_position\n" - " .global _start\n" - " .type _start, @function\n" - " .hidden _start\n" -diff -Nur uClibc-git/ldso/ldso/xtensa/dl-sysdep.h uClibc-xtensa/ldso/ldso/xtensa/dl-sysdep.h ---- uClibc-git/ldso/ldso/xtensa/dl-sysdep.h 2014-06-02 17:40:33.958711675 +0200 -+++ uClibc-xtensa/ldso/ldso/xtensa/dl-sysdep.h 2014-06-03 12:22:20.340060933 +0200 -@@ -78,10 +78,13 @@ - struct elf_resolve; - extern unsigned long _dl_linux_resolver (struct elf_resolve *, int); - --/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so -- undefined references should not be allowed to define the value. */ -+/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or -+ TLS variable, so undefined references should not be allowed to define -+ the value. */ - #define elf_machine_type_class(type) \ -- (((type) == R_XTENSA_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) -+ (((type) == R_XTENSA_JMP_SLOT || (type) == R_XTENSA_TLS_TPOFF \ -+ || (type) == R_XTENSA_TLSDESC_FN || (type) == R_XTENSA_TLSDESC_ARG) \ -+ * ELF_RTYPE_CLASS_PLT) - - /* Return the link-time address of _DYNAMIC. */ - static __always_inline Elf32_Addr -diff -Nur uClibc-git/ldso/ldso/xtensa/dl-tlsdesc.S uClibc-xtensa/ldso/ldso/xtensa/dl-tlsdesc.S ---- uClibc-git/ldso/ldso/xtensa/dl-tlsdesc.S 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-xtensa/ldso/ldso/xtensa/dl-tlsdesc.S 2014-06-03 12:22:20.340060933 +0200 -@@ -0,0 +1,96 @@ -+/* Thread-local storage handling in the ELF dynamic linker. Xtensa version. -+ Copyright (C) 2012-2013 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library. If not, see -+ . */ -+ -+#include -+#include -+#include "tlsdesc.h" -+ -+ -+ .text -+ .align 4 -+ .hidden _dl_tlsdesc_return -+ .global _dl_tlsdesc_return -+ .type _dl_tlsdesc_return, @function -+_dl_tlsdesc_return: -+ entry a1, 16 -+ rur.threadptr a3 -+ add a2, a2, a3 -+ retw -+ .size _dl_tlsdesc_return, .-_dl_tlsdesc_return -+ -+#ifdef SHARED -+ -+ -+ /* This function is used for symbols that need dynamic TLS. -+ -+ The argument passed to this function points to the TLS descriptor. -+ -+ The assembly code that follows is a rendition of the following -+ C code, hand-optimized a little bit. -+ -+ ptrdiff_t -+ _dl_tlsdesc_dynamic(struct tlsdesc_dynamic_arg *td) -+ { -+ dtv_t *dtv = (dtv_t *)THREAD_DTV(); -+ if (td->gen_count <= dtv[0].counter -+ && dtv[td->tlsinfo.ti_module].pointer.val -+ != TLS_DTV_UNALLOCATED) -+ return dtv[td->tlsinfo.ti_module].pointer.val -+ + td->tlsinfo.ti_offset - __builtin_thread_pointer(); -+ return __tls_get_addr (&td->tlsinfo) - __builtin_thread_pointer(); -+ } -+ */ -+ -+ .align 4 -+ .hidden _dl_tlsdesc_dynamic -+ .global _dl_tlsdesc_dynamic -+ .type _dl_tlsdesc_dynamic, @function -+_dl_tlsdesc_dynamic: -+ entry a1, 32 -+ -+ /* dtv_t *dtv = (dtv_t *)THREAD_DTV(); */ -+ rur.threadptr a3 -+ l32i a4, a3, 0 -+ -+ /* if (td->gen_count <= dtv[0].counter */ -+ l32i a6, a2, TLSDESC_GEN_COUNT -+ l32i a7, a4, 0 -+ blt a7, a6, .Lslow -+ -+ /* && dtv[td->tlsinfo.ti_module].pointer.val != TLS_DTV_UNALLOCATED) */ -+ l32i a6, a2, TLSDESC_MODID -+ addx8 a6, a3, a6 -+ l32i a6, a6, 0 -+ beqi a6, -1, .Lslow -+ -+ /* return dtv[td->tlsinfo.ti_module].pointer.val -+ + td->tlsinfo.ti_offset - __builtin_thread_pointer(); */ -+ l32i a6, a2, TLSDESC_MODOFF -+ sub a2, a6, a3 -+ retw -+ -+ /* return __tls_get_addr (&td->tlsinfo) - __builtin_thread_pointer(); */ -+.Lslow: -+ mov a10, a2 -+ movi a8, __tls_get_addr -+ callx8 a8 -+ sub a2, a10, a3 -+ retw -+ .size _dl_tlsdesc_dynamic, .-_dl_tlsdesc_dynamic -+ -+#endif /* SHARED */ -diff -Nur uClibc-git/ldso/ldso/xtensa/elfinterp.c uClibc-xtensa/ldso/ldso/xtensa/elfinterp.c ---- uClibc-git/ldso/ldso/xtensa/elfinterp.c 2014-06-02 17:40:33.958711675 +0200 -+++ uClibc-xtensa/ldso/ldso/xtensa/elfinterp.c 2014-06-03 12:22:20.340060933 +0200 -@@ -31,6 +31,8 @@ - */ - - #include "ldso.h" -+#include "dl-tls.h" -+#include "tlsdeschtab.h" - - unsigned long - _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) -@@ -146,6 +148,9 @@ - int reloc_type; - int symtab_index; - char *symname; -+#if defined USE_TLS && USE_TLS -+ struct elf_resolve *tls_tpnt = NULL; -+#endif - struct symbol_ref sym_ref; - ElfW(Addr) *reloc_addr; - ElfW(Addr) symbol_addr; -@@ -172,15 +177,22 @@ - * here, so all bases should be covered. - */ - if (unlikely (!symbol_addr && -+ ELF_ST_TYPE (sym_ref.sym->st_info) != STT_TLS && - ELF_ST_BIND (sym_ref.sym->st_info) != STB_WEAK)) { -- _dl_dprintf (2, "%s: can't resolve symbol '%s'\n", -- _dl_progname, symname); -- _dl_exit (1); -+ return 1; - } - if (_dl_trace_prelink) { - _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], - &sym_ref, elf_machine_type_class(reloc_type)); - } -+#if defined USE_TLS && USE_TLS -+ tls_tpnt = sym_ref.tpnt; -+#endif -+ } else { -+ symbol_addr =symtab[symtab_index].st_value; -+#if defined USE_TLS && USE_TLS -+ tls_tpnt = tpnt; -+#endif - } - - #if defined (__SUPPORT_LD_DEBUG__) -@@ -198,8 +210,8 @@ - - case R_XTENSA_RTLD: - if (rpnt->r_addend == 1) { -- /* Grab the function pointer stashed at the beginning of the -- GOT by the GOT_INIT function. */ -+ /* Grab the function pointer stashed at the beginning -+ of the GOT by the GOT_INIT function. */ - *reloc_addr = *(ElfW(Addr) *) tpnt->dynamic_info[DT_PLTGOT]; - } else if (rpnt->r_addend == 2) { - /* Store the link map for the object. */ -@@ -213,6 +225,35 @@ - *reloc_addr += tpnt->loadaddr + rpnt->r_addend; - break; - -+#if defined USE_TLS && USE_TLS -+ case R_XTENSA_TLS_TPOFF: -+ CHECK_STATIC_TLS((struct link_map *) tls_tpnt); -+ *reloc_addr = symbol_addr + tls_tpnt->l_tls_offset + rpnt->r_addend; -+ break; -+ case R_XTENSA_TLSDESC_FN: -+#ifndef SHARED -+ CHECK_STATIC_TLS((struct link_map *) tls_tpnt); -+#else -+ if (!TRY_STATIC_TLS ((struct link_map *) tls_tpnt)) -+ *reloc_addr = (ElfW(Addr)) _dl_tlsdesc_dynamic; -+ else -+#endif -+ *reloc_addr = (ElfW(Addr)) _dl_tlsdesc_return; -+ break; -+ case R_XTENSA_TLSDESC_ARG: -+#ifndef SHARED -+ CHECK_STATIC_TLS((struct link_map *) tls_tpnt); -+#else -+ if (!TRY_STATIC_TLS ((struct link_map *) tls_tpnt)) -+ *reloc_addr = (ElfW(Addr)) -+ _dl_make_tlsdesc_dynamic((struct link_map *) tls_tpnt, -+ symbol_addr + *reloc_addr); -+ else -+#endif -+ *reloc_addr += symbol_addr + tls_tpnt->l_tls_offset; -+ break; -+#endif -+ - default: - return -1; /* Calls _dl_exit(1). */ - } -diff -Nur uClibc-git/ldso/ldso/xtensa/resolve.S uClibc-xtensa/ldso/ldso/xtensa/resolve.S ---- uClibc-git/ldso/ldso/xtensa/resolve.S 2014-06-02 17:40:33.958711675 +0200 -+++ uClibc-xtensa/ldso/ldso/xtensa/resolve.S 2014-06-03 12:22:20.344060961 +0200 -@@ -27,7 +27,6 @@ - - .text - .align 4 -- .literal_position - .global _dl_linux_resolve - .type _dl_linux_resolve, @function - _dl_linux_resolve: -diff -Nur uClibc-git/libc/sysdeps/linux/xtensa/clone.S uClibc-xtensa/libc/sysdeps/linux/xtensa/clone.S ---- uClibc-git/libc/sysdeps/linux/xtensa/clone.S 2014-06-02 17:40:34.722715903 +0200 -+++ uClibc-xtensa/libc/sysdeps/linux/xtensa/clone.S 2014-06-03 12:04:16.669187814 +0200 -@@ -1,34 +1,38 @@ --/* Copyright (C) 2001, 2005, 2007 Free Software Foundation, Inc. -+/* Copyright (C) 2001, 2005 Free Software Foundation, Inc. - - The GNU C Library is free software; you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -+ modify it under the terms of the GNU Library General Public License as -+ published by the Free Software Foundation; either version 2 of the -+ License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -+ Library General Public License for more details. - -- You should have received a copy of the GNU Lesser General Public -- License along with the GNU C Library; if not, see -- . */ -+ You should have received a copy of the GNU Library General Public -+ License along with the GNU C Library; see the file COPYING.LIB. If not, -+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ Boston, MA 02111-1307, USA. */ - - /* clone is even more special than fork as it mucks with stacks -- and invokes a function in the right context after it's all over. */ -+ and invokes a function in the right context after its all over. */ - --#include "sysdep.h" --#include -+#include -+#include - #define _ERRNO_H 1 - #include -- --/* int clone (a2 = int (*fn)(void *arg), -- a3 = void *child_stack, -- a4 = int flags, -- a5 = void *arg, -- a6 = pid_t *ptid, -- a7 = struct user_desc *tls, -- 16(sp) = pid_t *ctid) */ -+#ifdef RESET_PID -+#include -+#endif -+#define __ASSEMBLY__ -+#include -+ -+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, -+ a2 a3 a4 a5 -+ pid_t *ptid, struct user_desc *tls, pid_t *ctid) -+ a6 a7 16(sp) -+*/ - - .text - ENTRY (__clone) -@@ -39,7 +43,7 @@ - - /* a2 and a3 are candidates for destruction by system-call return - parameters. We don't need the stack pointer after the system -- call. We trust that the kernel will preserve a7, a9, and a6. */ -+ call. We trust that the kernel will preserve a6, a7 and a9. */ - - mov a9, a5 /* save function argument */ - mov a5, a7 -@@ -48,19 +52,18 @@ - mov a6, a4 - mov a4, a8 - l32i a8, a1, 16 /* child_tid */ -- movi a2, SYS_ify (clone) -+ movi a2, SYS_ify(clone) -+ -+ /* syscall(NR_clone,clone_flags, usp, parent_tid, child_tls, child_tid) -+ a2 a6 a3 a4 a5 a8 -+ */ - -- /* syscall (a2 = NR_clone, -- a6 = clone_flags, -- a3 = usp, -- a4 = parent_tid, -- a5 = child_tls, -- a8 = child_tid) */ - syscall - bltz a2, SYSCALL_ERROR_LABEL - beqz a2, .Lthread_start - -- /* Fall through for parent. */ -+ /* fall through for parent */ -+ - .Lpseudo_end: - retw - -@@ -69,32 +72,38 @@ - j SYSCALL_ERROR_LABEL - - .Lthread_start: -- /* Start child thread. */ -- movi a0, 0 /* terminate the stack frame */ -+ -+#if CLONE_THREAD != 0x00010000 || CLONE_VM != 0x00000100 -+# error invalid values for CLONE_THREAD or CLONE_VM -+#endif - - #ifdef RESET_PID -- /* Check and see if we need to reset the PID. */ -- bbsi.l a6, 16, 1f /* CLONE_THREAD = 0x00010000 */ -+ bbsi.l a6, 16, .Lskip_restore_pid /* CLONE_THREAD = 0x00010000 */ - movi a2, -1 -- bbsi.l a6, 8, 2f /* CLONE_VM = 0x00000100 */ -- movi a2, SYS_ify (getpid) -+ bbsi a6, 8, .Lgotpid /* CLONE_VM = 0x00000100 */ -+ movi a2, SYS_ify(getpid) - syscall --2: rur a3, THREADPTR -- movi a4, PID_OFFSET -- add a4, a4, a3 -- s32i a2, a4, 0 -- movi a4, TID_OFFSET -- add a4, a4, a3 -- s32i a2, a3, 0 --1: --#endif /* RESET_PID */ -+.Lgotpid: -+ rur a3, threadptr -+ movi a0, TLS_PRE_TCB_SIZE -+ sub a3, a3, a0 -+ s32i a2, a3, PID -+ s32i a2, a3, TID -+.Lskip_restore_pid: -+#endif - -+ /* start child thread */ -+ movi a0, 0 /* terminate the stack frame */ - mov a6, a9 /* load up the 'arg' parameter */ - callx4 a7 /* call the user's function */ - - /* Call _exit. Note that any return parameter from the user's -- function in a6 is seen as inputs to _exit. */ -- movi a2, JUMPTARGET(_exit) -+ function in a6 is seen as inputs to _exit. */ -+#ifdef PIC -+ movi a2, _exit@PLT -+#else -+ movi a2, _exit -+#endif - callx4 a2 - - PSEUDO_END (__clone) -diff -Nur uClibc-git/libc/sysdeps/linux/xtensa/fork.c uClibc-xtensa/libc/sysdeps/linux/xtensa/fork.c ---- uClibc-git/libc/sysdeps/linux/xtensa/fork.c 2014-06-02 17:40:34.726715926 +0200 -+++ uClibc-xtensa/libc/sysdeps/linux/xtensa/fork.c 2014-06-03 12:04:16.669187814 +0200 -@@ -20,6 +20,10 @@ - { - return (pid_t) INLINE_SYSCALL(clone, 2, SIGCHLD, 0); - } --lt_strong_alias(fork) --lt_libc_hidden(fork) -+# ifdef __UCLIBC_HAS_THREADS__ -+strong_alias(fork,__libc_fork) -+libc_hidden_weak(fork) -+# else -+libc_hidden_def(fork) -+# endif - #endif -diff -Nur uClibc-git/libc/sysdeps/linux/xtensa/jmpbuf-unwind.h uClibc-xtensa/libc/sysdeps/linux/xtensa/jmpbuf-unwind.h ---- uClibc-git/libc/sysdeps/linux/xtensa/jmpbuf-unwind.h 2014-06-02 17:40:34.726715926 +0200 -+++ uClibc-xtensa/libc/sysdeps/linux/xtensa/jmpbuf-unwind.h 2014-06-03 12:04:16.669187814 +0200 -@@ -1,25 +1,23 @@ --/* Copyright (C) 1997, 1998, 2007 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 -- modify it under the terms of the GNU Lesser General Public -- License as published by the Free Software Foundation; either -- version 2.1 of the License, or (at your option) any later version. -- -- The GNU C Library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with the GNU C Library; if not, see -- . */ -- --/* Test if longjmp to JMPBUF would unwind the frame containing a local -- variable at ADDRESS. */ -- -+/* -+ * Copyright (C) 2000-2006 Erik Andersen -+ * -+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. -+ */ - #include - #include - -+/* Test if longjmp to JMPBUF would unwind the frame -+ containing a local variable at ADDRESS. */ - #define _JMPBUF_UNWINDS(jmpbuf, address) \ - ((void *) (address) < (void *) (jmpbuf)[JB_SP]) -+ -+#ifdef __UCLIBC_HAS_THREADS_NATIVE__ -+#include -+#include -+ -+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \ -+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj) -+ -+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \ -+ ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_SP] - (_adj)) -+#endif -diff -Nur uClibc-git/libc/sysdeps/linux/xtensa/Makefile.arch uClibc-xtensa/libc/sysdeps/linux/xtensa/Makefile.arch ---- uClibc-git/libc/sysdeps/linux/xtensa/Makefile.arch 2014-06-02 17:40:34.686715704 +0200 -+++ uClibc-xtensa/libc/sysdeps/linux/xtensa/Makefile.arch 2014-06-03 12:04:16.669187814 +0200 -@@ -5,7 +5,10 @@ - # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - # - --CSRC-y := brk.c fork.c sigaction.c __syscall_error.c -+CSRC-y := brk.c sigaction.c __syscall_error.c - - SSRC-y := bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S \ - sigrestorer.S syscall.S mmap.S windowspill.S __longjmp.S vfork.S -+ -+CSRC-$(if $(UCLIBC_HAS_THREADS_NATIVE),,y) += fork.c -+SSRC-$(if $(UCLIBC_HAS_THREADS_NATIVE),,y) += clone.S -diff -Nur uClibc-git/libc/sysdeps/linux/xtensa/sys/ptrace.h uClibc-xtensa/libc/sysdeps/linux/xtensa/sys/ptrace.h ---- uClibc-git/libc/sysdeps/linux/xtensa/sys/ptrace.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-xtensa/libc/sysdeps/linux/xtensa/sys/ptrace.h 2014-06-03 11:58:41.563379928 +0200 -@@ -0,0 +1,155 @@ -+/* `ptrace' debugger support interface. Linux version. -+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 -+ 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library; if not, see -+ . */ -+ -+#ifndef _SYS_PTRACE_H -+#define _SYS_PTRACE_H 1 -+ -+#include -+ -+/* Kludge away careless namespace pollution from the kernel. */ -+ -+#undef PTRACE_GETREGS -+#undef PTRACE_SETREGS -+#undef PTRACE_GETFPREGS -+#undef PTRACE_SETFPREGS -+#undef PTRACE_GETFPREGSIZE -+ -+ -+__BEGIN_DECLS -+ -+/* Type of the REQUEST argument to `ptrace.' */ -+enum __ptrace_request -+{ -+ /* Indicate that the process making this request should be traced. -+ All signals received by this process can be intercepted by its -+ parent, and its parent can use the other `ptrace' requests. */ -+ PTRACE_TRACEME = 0, -+#define PT_TRACE_ME PTRACE_TRACEME -+ -+ /* Return the word in the process's text space at address ADDR. */ -+ PTRACE_PEEKTEXT = 1, -+#define PT_READ_I PTRACE_PEEKTEXT -+ -+ /* Return the word in the process's data space at address ADDR. */ -+ PTRACE_PEEKDATA = 2, -+#define PT_READ_D PTRACE_PEEKDATA -+ -+ /* Return the word in the process's user area at offset ADDR. */ -+ PTRACE_PEEKUSER = 3, -+#define PT_READ_U PTRACE_PEEKUSER -+ -+ /* Write the word DATA into the process's text space at address ADDR. */ -+ PTRACE_POKETEXT = 4, -+#define PT_WRITE_I PTRACE_POKETEXT -+ -+ /* Write the word DATA into the process's data space at address ADDR. */ -+ PTRACE_POKEDATA = 5, -+#define PT_WRITE_D PTRACE_POKEDATA -+ -+ /* Write the word DATA into the process's user area at offset ADDR. */ -+ PTRACE_POKEUSER = 6, -+#define PT_WRITE_U PTRACE_POKEUSER -+ -+ /* Continue the process. */ -+ PTRACE_CONT = 7, -+#define PT_CONTINUE PTRACE_CONT -+ -+ /* Kill the process. */ -+ PTRACE_KILL = 8, -+#define PT_KILL PTRACE_KILL -+ -+ /* Single step the process. -+ This is not supported on all machines. */ -+ PTRACE_SINGLESTEP = 9, -+#define PT_STEP PTRACE_SINGLESTEP -+ -+ /* Get all general purpose registers used by a processes. -+ This is not supported on all machines. */ -+ PTRACE_GETREGS = 12, -+#define PT_GETREGS PTRACE_GETREGS -+ -+ /* Set all general purpose registers used by a processes. -+ This is not supported on all machines. */ -+ PTRACE_SETREGS = 13, -+#define PT_SETREGS PTRACE_SETREGS -+ -+ /* Get all floating point registers used by a processes. -+ This is not supported on all machines. */ -+ PTRACE_GETFPREGS = 14, -+#define PT_GETFPREGS PTRACE_GETFPREGS -+ -+ /* Set all floating point registers used by a processes. -+ This is not supported on all machines. */ -+ PTRACE_SETFPREGS = 15, -+#define PT_SETFPREGS PTRACE_SETFPREGS -+ -+ /* Attach to a process that is already running. */ -+ PTRACE_ATTACH = 16, -+#define PT_ATTACH PTRACE_ATTACH -+ -+ /* Detach from a process attached to with PTRACE_ATTACH. */ -+ PTRACE_DETACH = 17, -+#define PT_DETACH PTRACE_DETACH -+ -+ /* Get size required for the buffer holding the floating point registers. -+ This is not supported on all machines. */ -+ PTRACE_GETFPREGSIZE = 18, -+#define PT_GETFPREGSIZE PTRACE_GETFPREGSIZE -+ -+ /* Continue and stop at the next (return from) syscall. */ -+ PTRACE_SYSCALL = 24 -+#define PT_SYSCALL PTRACE_SYSCALL -+}; -+ -+/* Options set using PTRACE_SETOPTIONS. */ -+enum __ptrace_setoptions { -+ PTRACE_O_TRACESYSGOOD = 0x00000001, -+ PTRACE_O_TRACEFORK = 0x00000002, -+ PTRACE_O_TRACEVFORK = 0x00000004, -+ PTRACE_O_TRACECLONE = 0x00000008, -+ PTRACE_O_TRACEEXEC = 0x00000010, -+ PTRACE_O_TRACEVFORKDONE = 0x00000020, -+ PTRACE_O_TRACEEXIT = 0x00000040, -+ PTRACE_O_MASK = 0x0000007f -+}; -+ -+/* Wait extended result codes for the above trace options. */ -+enum __ptrace_eventcodes { -+ PTRACE_EVENT_FORK = 1, -+ PTRACE_EVENT_VFORK = 2, -+ PTRACE_EVENT_CLONE = 3, -+ PTRACE_EVENT_EXEC = 4, -+ PTRACE_EVENT_VFORK_DONE = 5, -+ PTRACE_EVENT_EXIT = 6 -+}; -+ -+/* Perform process tracing functions. REQUEST is one of the values -+ above, and determines the action to be taken. -+ For all requests except PTRACE_TRACEME, PID specifies the process to be -+ traced. -+ -+ PID and the other arguments described above for the various requests should -+ appear (those that are used for the particular request) as: -+ pid_t PID, void *ADDR, int DATA, void *ADDR2 -+ after REQUEST. */ -+extern long int ptrace (enum __ptrace_request __request, ...) __THROW; -+ -+__END_DECLS -+ -+#endif /* _SYS_PTRACE_H */ -diff -Nur uClibc-git/libc/sysdeps/linux/xtensa/sysdep.h uClibc-xtensa/libc/sysdeps/linux/xtensa/sysdep.h ---- uClibc-git/libc/sysdeps/linux/xtensa/sysdep.h 2014-06-02 17:40:34.726715926 +0200 -+++ uClibc-xtensa/libc/sysdeps/linux/xtensa/sysdep.h 2014-06-03 15:24:57.308410770 +0200 -@@ -16,6 +16,10 @@ - License along with the GNU C Library; if not, see - . */ - -+#ifndef _LINUX_XTENSA_SYSDEP_H -+#define _LINUX_XTENSA_SYSDEP_H 1 -+ -+#include - #include - - #ifdef __ASSEMBLER__ -@@ -24,12 +28,6 @@ - #define ASM_TYPE_DIRECTIVE(name, typearg) .type name, typearg - #define ASM_SIZE_DIRECTIVE(name) .size name, . - name - --#ifdef __STDC__ --#define C_LABEL(name) name : --#else --#define C_LABEL(name) name/**/: --#endif -- - #define ENTRY(name) \ - ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ - ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name), @function); \ -@@ -52,6 +50,15 @@ - #undef END - #define END(name) ASM_SIZE_DIRECTIVE(name) - -+/* Local label name for asm code. */ -+#ifndef L -+# ifdef HAVE_ELF -+# define L(name) .L##name -+# else -+# define L(name) name -+# endif -+#endif -+ - /* Define a macro for this directive so it can be removed in a few places. */ - #define LITERAL_POSITION .literal_position - -@@ -123,19 +130,7 @@ - #define PSEUDO_END_ERRVAL(name) \ - END (name) - --#undef ret_ERRVAL --#define ret_ERRVAL retw -- --#if defined RTLD_PRIVATE_ERRNO --# define SYSCALL_ERROR_HANDLER \ --0: movi a4, rtld_errno; \ -- neg a2, a2; \ -- s32i a2, a4, 0; \ -- movi a2, -1; \ -- j .Lpseudo_end; -- --#elif defined _LIBC_REENTRANT -- -+#if defined _LIBC_REENTRANT - # if defined USE___THREAD - # ifndef NOT_IN_libc - # define SYSCALL_ERROR_ERRNO __libc_errno -@@ -170,3 +165,9 @@ - #endif /* _LIBC_REENTRANT */ - - #endif /* __ASSEMBLER__ */ -+ -+/* Pointer mangling is not yet supported for Xtensa. */ -+#define PTR_MANGLE(var) (void) (var) -+#define PTR_DEMANGLE(var) (void) (var) -+ -+#endif /* _LINUX_XTENSA_SYSDEP_H */ -diff -Nur uClibc-git/libc/sysdeps/linux/xtensa/vfork.S uClibc-xtensa/libc/sysdeps/linux/xtensa/vfork.S ---- uClibc-git/libc/sysdeps/linux/xtensa/vfork.S 2014-06-02 17:40:34.726715926 +0200 -+++ uClibc-xtensa/libc/sysdeps/linux/xtensa/vfork.S 2014-06-03 12:04:16.669187814 +0200 -@@ -1,4 +1,4 @@ --/* Copyright (C) 2005, 2007 Free Software Foundation, Inc. -+/* Copyright (C) 2005-2013 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 -@@ -19,72 +19,67 @@ - #include - #define _SIGNAL_H - #include -+#define __ASSEMBLY__ -+#include - - --/* Clone the calling process, but without copying the whole address space. -+/* -+ Clone the calling process, but without copying the whole address space. - The calling process is suspended until the new process exits or is - replaced by a call to `execve'. Return -1 for errors, 0 to the new process, - and the process ID of the new process to the old process. - - Note that it is important that we don't create a new stack frame for the -- caller. */ -+ caller. - -- --/* The following are defined in linux/sched.h, which unfortunately -- is not safe for inclusion in an assembly file. */ --#define CLONE_VM 0x00000100 /* set if VM shared between processes */ --#define CLONE_VFORK 0x00004000 /* set if the parent wants the child to -- wake it up on mm_release */ -+*/ - - #ifndef SAVE_PID --#define SAVE_PID -+#define SAVE_PID(a,b,c,d) - #endif -- - #ifndef RESTORE_PID --#define RESTORE_PID -+#define RESTORE_PID(a,b,c) -+#endif -+#ifndef RESTORE_PID12 -+#define RESTORE_PID12(a,b,c) - #endif - -+/* -+ pid_t vfork(void); -+ Implemented as __clone_syscall(CLONE_VFORK | CLONE_VM | SIGCHLD, 0) -+ */ - --/* pid_t vfork(void); -- Implemented as __clone_syscall(CLONE_VFORK | CLONE_VM | SIGCHLD, 0) */ - - HIDDEN_ENTRY (__vfork) -+ .literal .Ljumptable, 0, .L4, .L8, .L12 - -- movi a6, .Ljumptable -- extui a2, a0, 30, 2 /* call-size: call4/8/12 = 1/2/3 */ -- addx4 a4, a2, a6 /* find return address in jumptable */ -- l32i a4, a4, 0 -- add a4, a4, a6 -- -+ mov a3, a0 # move return address out of the way -+ movi a0, .Ljumptable -+ extui a2, a3, 30, 2 # call-size: call4/8/12 = 1/2/3 -+ addx4 a0, a2, a0 # find return address in jumptable - slli a2, a2, 30 -- xor a3, a0, a2 /* remove call-size from return addr */ -- extui a5, a4, 30, 2 /* get high bits of jump target */ -- slli a5, a5, 30 -- or a3, a3, a5 /* stuff them into the return address */ -- xor a4, a4, a5 /* clear high bits of jump target */ -- or a0, a4, a2 /* create temporary return address */ -- retw /* "return" to .L4, .L8, or .L12 */ -- -- .align 4 --.Ljumptable: -- .word 0 -- .word .L4 - .Ljumptable -- .word .L8 - .Ljumptable -- .word .L12 - .Ljumptable -+ l32i a0, a0, 0 -+ -+ xor a3, a3, a2 # remove call-size from return address -+ or a0, a0, a2 # create temporary return address -+ retw - - /* a7: return address */ -+ - .L4: mov a12, a2 - mov a13, a3 - -- SAVE_PID -+ SAVE_PID(a5,a15,a2,a3) - -- /* Use syscall 'clone'. Set new stack pointer to the same address. */ -- movi a2, SYS_ify (clone) -+ /* use syscall 'clone' and set new stack pointer to the same address */ -+ -+ movi a2, SYS_ify(clone) - movi a3, 0 - movi a6, CLONE_VM | CLONE_VFORK | SIGCHLD -+ - syscall - -- RESTORE_PID -+ RESTORE_PID(a5,a15,a2) - - movi a5, -4096 - -@@ -94,22 +89,24 @@ - - bgeu a6, a5, 1f - jx a7 --1: call4 .Lerr /* returns to original caller */ - -+1: call4 .Lerr - - /* a11: return address */ -+ - .L8: mov a12, a2 - mov a13, a3 - mov a14, a6 - -- SAVE_PID -+ SAVE_PID(a9,a15,a2,a3) - -- movi a2, SYS_ify (clone) -+ movi a2, SYS_ify(clone) - movi a3, 0 - movi a6, CLONE_VM | CLONE_VFORK | SIGCHLD -+ - syscall - -- RESTORE_PID -+ RESTORE_PID(a9,a15,a2) - - movi a9, -4096 - -@@ -120,22 +117,25 @@ - - bgeu a10, a9, 1f - jx a11 --1: call8 .Lerr /* returns to original caller */ -+ -+1: call8 .Lerr - - - /* a15: return address */ -+ - .L12: mov a12, a2 - mov a13, a3 - mov a14, a6 - -- SAVE_PID -+ SAVE_PID (a2,a3,a2,a6) - -- movi a2, SYS_ify (clone) -+ movi a2, SYS_ify(clone) - movi a3, 0 - movi a6, CLONE_VM | CLONE_VFORK | SIGCHLD -+ - syscall - -- RESTORE_PID -+ RESTORE_PID12(a3,a6,a15) - - mov a3, a13 - movi a13, -4096 -@@ -147,18 +147,18 @@ - - bgeu a14, a13, 1f - jx a15 --1: call12 .Lerr /* returns to original caller */ - -+1: call12 .Lerr - - .align 4 -+ - .Lerr: entry a1, 16 - -- /* Restore the return address. */ -- extui a4, a0, 30, 2 /* get the call-size bits */ -+ /* Restore return address */ -+ -+ extui a4, a0, 30, 2 - slli a4, a4, 30 -- slli a3, a3, 2 /* clear high bits of target address */ -- srli a3, a3, 2 -- or a0, a3, a4 /* combine them */ -+ or a0, a3, a4 - - PSEUDO_END (__vfork) - .Lpseudo_end: -diff -Nur uClibc-git/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c uClibc-xtensa/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c ---- uClibc-git/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c 2014-06-02 17:40:35.102718006 +0200 -+++ uClibc-xtensa/libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.c 2014-06-03 12:35:45.097932730 +0200 -@@ -22,8 +22,6 @@ - #include - #include - #include --#include -- - - void - __lll_lock_wait_private (int *futex) -diff -Nur uClibc-git/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/bits/pthreadtypes.h uClibc-xtensa/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/bits/pthreadtypes.h ---- uClibc-git/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/bits/pthreadtypes.h 1970-01-01 01:00:00.000000000 +0100 -+++ uClibc-xtensa/libpthread/nptl/sysdeps/unix/sysv/linux/xtensa/bits/pthreadtypes.h 2014-06-03 12:04:16.669187814 +0200 -@@ -0,0 +1,184 @@ -+/* Copyright (C) 2002-2012 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 -+ modify it under the terms of the GNU Lesser General Public -+ License as published by the Free Software Foundation; either -+ version 2.1 of the License, or (at your option) any later version. -+ -+ The GNU C Library is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public -+ License along with the GNU C Library. If not, see -+ . */ -+ -+#ifndef _BITS_PTHREADTYPES_H -+#define _BITS_PTHREADTYPES_H 1 -+ -+#include -+ -+#define __SIZEOF_PTHREAD_ATTR_T 36 -+#define __SIZEOF_PTHREAD_MUTEX_T 24 -+#define __SIZEOF_PTHREAD_MUTEXATTR_T 4 -+#define __SIZEOF_PTHREAD_COND_T 48 -+#define __SIZEOF_PTHREAD_COND_COMPAT_T 12 -+#define __SIZEOF_PTHREAD_CONDATTR_T 4 -+#define __SIZEOF_PTHREAD_RWLOCK_T 32 -+#define __SIZEOF_PTHREAD_RWLOCKATTR_T 8 -+#define __SIZEOF_PTHREAD_BARRIER_T 20 -+#define __SIZEOF_PTHREAD_BARRIERATTR_T 4 -+ -+ -+/* Thread identifiers. The structure of the attribute type is not -+ exposed on purpose. */ -+typedef unsigned long int pthread_t; -+ -+ -+union pthread_attr_t -+{ -+ char __size[__SIZEOF_PTHREAD_ATTR_T]; -+ long int __align; -+}; -+#ifndef __have_pthread_attr_t -+typedef union pthread_attr_t pthread_attr_t; -+# define __have_p