fix crashes in x32 __tls_get_addr
authorrofl0r <retnyg@gmx.net>
Fri, 13 Jan 2017 10:28:46 +0000 (10:28 +0000)
committerrofl0r <retnyg@gmx.net>
Fri, 13 Jan 2017 10:47:08 +0000 (10:47 +0000)
x32 has another gratuitous difference to all other archs:
it passes an array of 64bit values to __tls_get_addr().
usually it is an array of size_t.

arch/x32/pthread_arch.h
ldso/dynlink.c
src/internal/pthread_impl.h
src/thread/__tls_get_addr.c

index ecb0bbfb04039f77fee354e49bd4858129df10e3..267ad073c79175468941cfb7f7306a1e788f04c4 100644 (file)
@@ -10,3 +10,5 @@ static inline struct pthread *__pthread_self()
 #define MC_PC gregs[REG_RIP]
 
 #define CANARY canary2
+
+#define tls_mod_off_t unsigned long long
index 48dcd1c23d55b998379295db3cd67fe98761b8af..a03f75e3589cc18d366f7f634b868a4ae790dcbe 100644 (file)
@@ -1257,7 +1257,7 @@ void __init_tls(size_t *auxv)
 }
 
 __attribute__((__visibility__("hidden")))
-void *__tls_get_new(size_t *v)
+void *__tls_get_new(tls_mod_off_t *v)
 {
        pthread_t self = __pthread_self();
 
@@ -1769,7 +1769,7 @@ static void *addr2dso(size_t a)
        return 0;
 }
 
-void *__tls_get_addr(size_t *);
+void *__tls_get_addr(tls_mod_off_t *);
 
 static void *do_dlsym(struct dso *p, const char *s, void *ra)
 {
@@ -1787,7 +1787,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra)
                struct symdef def = find_sym(p, s, 0);
                if (!def.sym) goto failed;
                if ((def.sym->st_info&0xf) == STT_TLS)
-                       return __tls_get_addr((size_t []){def.dso->tls_id, def.sym->st_value});
+                       return __tls_get_addr((tls_mod_off_t []){def.dso->tls_id, def.sym->st_value});
                if (DL_FDPIC && (def.sym->st_info&0xf) == STT_FUNC)
                        return def.dso->funcdescs + (def.sym - def.dso->syms);
                return laddr(def.dso, def.sym->st_value);
@@ -1802,7 +1802,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra)
                sym = sysv_lookup(s, h, p);
        }
        if (sym && (sym->st_info&0xf) == STT_TLS)
-               return __tls_get_addr((size_t []){p->tls_id, sym->st_value});
+               return __tls_get_addr((tls_mod_off_t []){p->tls_id, sym->st_value});
        if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC)
                return p->funcdescs + (sym - p->syms);
        if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
@@ -1816,7 +1816,7 @@ static void *do_dlsym(struct dso *p, const char *s, void *ra)
                        sym = sysv_lookup(s, h, p->deps[i]);
                }
                if (sym && (sym->st_info&0xf) == STT_TLS)
-                       return __tls_get_addr((size_t []){p->deps[i]->tls_id, sym->st_value});
+                       return __tls_get_addr((tls_mod_off_t []){p->deps[i]->tls_id, sym->st_value});
                if (DL_FDPIC && sym && sym->st_shndx && (sym->st_info&0xf) == STT_FUNC)
                        return p->deps[i]->funcdescs + (sym - p->deps[i]->syms);
                if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
index 757b86addc3091320f9d8560e213df613730d3e2..ae0ab1c5b665af9a8180d0b9bdb89152806bfbed 100644 (file)
@@ -97,6 +97,10 @@ struct __timer {
 #define DTP_OFFSET 0
 #endif
 
+#ifndef tls_mod_off_t
+#define tls_mod_off_t size_t
+#endif
+
 #define SIGTIMER 32
 #define SIGCANCEL 33
 #define SIGSYNCCALL 34
index 6945faa060d75ca66a5a4d3b01d34f1178b2cc9f..3b6c9b1b2a2b3f1e3f97f226d092be83f9fec24f 100644 (file)
@@ -3,9 +3,9 @@
 #include "libc.h"
 
 __attribute__((__visibility__("hidden")))
-void *__tls_get_new(size_t *);
+void *__tls_get_new(tls_mod_off_t *);
 
-void *__tls_get_addr(size_t *v)
+void *__tls_get_addr(tls_mod_off_t *v)
 {
        pthread_t self = __pthread_self();
        if (v[0]<=(size_t)self->dtv[0])