Page MenuHomeFreeBSD

Make p_vaddr % p_align == p_offset % p_align for TLS segments.
Needs ReviewPublic

Authored by kib on Sun, Aug 4, 10:31 PM.
This revision needs review, but there are no reviewers specified.

Details

Reviewers
None
Summary

See https://sourceware.org/bugzilla/show_bug.cgi?id=24606 for the test case.
See https://reviews.llvm.org/D64930 for the background and more discussion.

Also this fixes another bug in malloc_aligned() where total size of the allocated memory might be not enough to fir the aligned requested block after the initial pointer is incremented by the pointer size.

Diff Detail

Repository
rS FreeBSD src repository
Lint
Lint Skipped
Unit
Unit Tests Skipped
Build Status
Buildable 25683

Event Timeline

kib created this revision.Sun, Aug 4, 10:31 PM
kib edited the summary of this revision. (Show Details)Sun, Aug 4, 10:32 PM
kib edited the summary of this revision. (Show Details)
kib retitled this revision from Make p_vaddr%p_align = p_offset%p_align for TLS segments. to Make p_vaddr % p_align == p_offset % p_align for TLS segments..Sun, Aug 4, 10:39 PM
kib edited the summary of this revision. (Show Details)

Local-Exec TP offsets are link-time constants, and thus contracts between ld and ld.so. It may be worth checking if rtld-elf computed Local-Exec TP offsets match lld.

https://reviews.llvm.org/D64906 series (EM_PPC, EM_PPC64, EM_AARCH64 and EM_386) were committed yesterday. See the changed ELF/InputSection.cpp static int64_t getTlsTpOffset(const Symbol &s) {. The lld formulae should match musl>1.1.22 and glibc. ARM/AArch64 are a bit tricky because there is an optional alignment padding after the 2 reserved words.

Quick instructions to build lld:

git clone git@github.com:llvm/llvm-project.git
cd llvm-project
cmake -Hllvm -BRelease -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS='lld'

# Delete `else if (Out::tlsPhdr && Out::tlsPhdr->firstSec == p->firstSec)` from lld/ELF/Writer.cpp around line 2244
# If sh_addralign(.tdata) < sh_addralign(.tbss), sometimes p_vaddr(PT_TLS)%p_align(PT_TLS)!=0

ninja -C Release lld
# lld is at Release/bin/ld.lld

a.c:

#include <stdio.h>
__thread int a __attribute__((aligned(4))) = 0xb612; // .tdata alignment, try a few numbers, e.g. 1, 2, 4, 8, 16, 32
__asm(".section .tbss,\"awT\"; .align 64"); // try 64, 128, 256, etc
int main() { printf("%p %x\n", &a, a); }
clang a.c -fuse-ld=path/to/ld.lld -o a
./a
# Experiment with a few different alignments