From 1f53e7d00c375efb32e2e468f91a42668653d5f0 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Fri, 13 Jan 2017 10:28:46 +0000 Subject: [PATCH] fix crashes in x32 __tls_get_addr 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 | 2 ++ ldso/dynlink.c | 10 +++++----- src/internal/pthread_impl.h | 4 ++++ src/thread/__tls_get_addr.c | 4 ++-- 4 files changed, 13 insertions(+), 7 deletions(-) diff --git a/arch/x32/pthread_arch.h b/arch/x32/pthread_arch.h index ecb0bbfb..267ad073 100644 --- a/arch/x32/pthread_arch.h +++ b/arch/x32/pthread_arch.h @@ -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 diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 48dcd1c2..a03f75e3 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -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)) diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index 757b86ad..ae0ab1c5 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -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 diff --git a/src/thread/__tls_get_addr.c b/src/thread/__tls_get_addr.c index 6945faa0..3b6c9b1b 100644 --- a/src/thread/__tls_get_addr.c +++ b/src/thread/__tls_get_addr.c @@ -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])