From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/12835 Path: news.gmane.org!.POSTED!not-for-mail From: Phillip Berndt Newsgroups: gmane.linux.lib.musl.general Subject: TLS issue on aarch64 Date: Fri, 25 May 2018 14:40:14 +0200 Message-ID: Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" X-Trace: blaine.gmane.org 1527251905 12103 195.159.176.226 (25 May 2018 12:38:25 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 25 May 2018 12:38:25 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-12851-gllmg-musl=m.gmane.org@lists.openwall.com Fri May 25 14:38:21 2018 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1fMBzA-00033J-IZ for gllmg-musl@m.gmane.org; Fri, 25 May 2018 14:38:20 +0200 Original-Received: (qmail 1547 invoked by uid 550); 25 May 2018 12:40:27 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 1514 invoked from network); 25 May 2018 12:40:26 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=KJ8QI8DdTj5YVNIHryopVBmsXrl07XMv33R31HalRcM=; b=u2sdGrIODHgo6GCQRFOmviHrg+3gwTnr871yyhK8OKwwnGvdvD0rdtwQKB7mJkk4oq RH/dQ1edh/LdCjtsR2bkv+b81wi1xe080bMiUAt9pVmLfL+J1bd6acljcH0/gDTsmp8Z 8j3Soy/fuoHkG0SPPe5/3pgmTTWsf6kvQriEIIeerhRq3sGeT+bnk0Zou3ClaV9kI/Xo F9LLabLLs9cDudFXD3BzxIHnSn0Wmswc0yz7QJa9poxk65kbA6bg8Vg5DtGSg/Ud1KGO UWOqiEZPFvhwCIALtwvpy0LLiXWWFa+equ726S3VSsbp4GjNWL2++8RL5YjQg+hTQ6lH 0DWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=KJ8QI8DdTj5YVNIHryopVBmsXrl07XMv33R31HalRcM=; b=q4CptJCe4l/TIcFUVbTTP29I/hVGGgbm0PFK6erRY7MVRR7Gh0HOvcRtvP8kZGr8Cm iGNuW1P8M3gB8Eq6FN58+beYLifTlm+4TrtL+Jq9qOc+LOdAwa4itRhyi62ToB7zo5lp 55v4H/RvMbs+9aHTQQLHJeSw83ZaBWyogfVAQ4tETn+LH0TdXgT7WwM7yLaWj+GtHolU yrNsxhEo0E3mjLCCiwo8bFz4BTaL8bwOFhoyhuUlmS0T+J7SbfZ7j6lDgahpe0POK132 Lb9c6C5af34cgtrbGha0Y2JtMAx8WxtH5+ldhW2AYGQFDzOkHmihkabmn2NV0YJcbZ5b P01A== X-Gm-Message-State: ALKqPwef2PeEEcsJE5fUIYGL0LtMJ3pBnKHKNtwvsWcURIYEODJ/KbZd t7hPPYGdzd20gBydbvCEtRoFTx1qKuz7STmq7tGx55cas1PViw== X-Google-Smtp-Source: ADUXVKKYPTyqbgUstJaQBFe7AOz67D42axgDhEjFjJa8jjraZUb2pH8e8YxXo3AN02kJzdBCR1uUcNCEktatlAhq1a4= X-Received: by 2002:a19:5113:: with SMTP id f19-v6mr1421376lfb.13.1527252015166; Fri, 25 May 2018 05:40:15 -0700 (PDT) Xref: news.gmane.org gmane.linux.lib.musl.general:12835 Archived-At: Hi, I'm experiencing a TLS-related error with musl on aarch64. This is my test program: ----8<-------------- #include __thread int foo = 1234; __thread int bar __attribute__((aligned(0x100))) = 5678; int main(int argc, char **argv) { printf("0x%p: %d\n", &foo, foo); printf("0x%p: %d\n", &bar, bar); return 0; } ---->8--------------- I'm compiling this into a static binary with -O2 -static. With glibc and gcc 5.4.0 (tried with 7.2 as well), this gives me the expected output. With musl libc 1.1.19, I instead see ----8<-------------- 0x0x7fa7adf2f0: 0 0x0x7fa7adf3f0: 0 ---->8--------------- Note that this is the wrong address (not aligned), and that the memory has unexpected content as well. I did some initial debugging, but now I'm stuck and need some help. What I've found so far: * GCC apparently emits code that expects the tpidr_el0 register to contain a pointer to the TLS memory, and it expects that the loader unconditionally offsets the first variable by the TLS alignment into said memory: Disassembly of the code that loads &foo: ----8<-------------- 4001a4: d53bd053 mrs x19, tpidr_el0 4001a8: 91400273 add x19, x19, #0x0, lsl #12 4001ac: 91040273 add x19, x19, #0x100 ----8<-------------- (If I align the variable by 0x1000 instead then the code changes acoordingly.) * Musl, on the other hand, in __copy_tls, initializes tpidr_el0 with a pointer 16 bytes from the end of struct pthread, and copies the TLS initializer code directly behind that struct, without adding extra padding. Hence the code tries to access the TLS variables at the wrong location. The following patch fixes the issue, but only if musl is then compiled with optimizations off. With optimizations, the compiler emits the *same* code for both variants. Also, the patch probably has some unexpected side-effects, too - I'm just adding it here as a starting point for further debugging. Any help is greatly appreciated :-) - Phillip ---- diff --git a/arch/aarch64/pthread_arch.h b/arch/aarch64/pthread_arch.h index b2e2d8f..c69f6f1 100644 --- a/arch/aarch64/pthread_arch.h +++ b/arch/aarch64/pthread_arch.h @@ -2,10 +2,10 @@ static inline struct pthread *__pthread_self() { char *self; __asm__ __volatile__ ("mrs %0,tpidr_el0" : "=r"(self)); - return (void*)(self + 16 - sizeof(struct pthread)); + return (void*)(self - sizeof(struct pthread)); } #define TLS_ABOVE_TP -#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) - 16) +#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread)) #define MC_PC pc diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c index b125eb1..3a3c307 100644 --- a/src/env/__init_tls.c +++ b/src/env/__init_tls.c @@ -42,7 +42,7 @@ void *__copy_tls(unsigned char *mem) mem += -((uintptr_t)mem + sizeof(struct pthread)) & (libc.tls_align-1); td = (pthread_t)mem; - mem += sizeof(struct pthread); + mem += sizeof(struct pthread) + libc.tls_align; for (i=1, p=libc.tls_head; p; i++, p=p->next) { dtv[i] = mem + p->offset;