[PATCH] Write alignment of `.tls` into `_tls_used.Characteristics`

Jan Beulich jbeulich@suse.com
Fri Sep 18 11:01:19 GMT 2026


On 18.09.2026 12:12, LIU Hao wrote:
> 在 2026-9-18 17:17, Jan Beulich 写道:
>> IMAGE_SCN_ALIGN_POWER_CONST() spills into higher bits if the input value
>> is too high (which can happen e.g. when linking ELF -> PE). That needs
>> preventing (and imo also warning about).
> 
> Alignment values > 8192 are not encodeable and will be rejected by the assembler (maybe also the 
> compiler); I suspect there's no way to produce a .tls section with more alignment:
> 
>     UCRT64 ~/Desktop
>     $ cat overalign.S
>     .section "dummy", "dr"
>     .p2align 14
>     .long 0
> 
>     UCRT64 ~/Desktop
>     $ as overalign.S  -c
>     C:\MSYS64\ucrt64\bin\as.exe: a.out: section dummy: alignment 2**14 not representable
>     overalign.S: Assembler messages:
>     overalign.S: Fatal error: a.out: nonrepresentable section on output
> 
> 
> So the value always fits in 4 bits: 0x1 for 1-byte alignment, 0x2 for 2, 0x3 for 4, and 0xE for 8192; 0xF 
> seems to be unused.

No, it doesn't. In my earlier reply I gave an example: When linking ELF
objects into a PE binary.

>> I further wonder whether setting too low a value (perhaps anything below
>> target word size) may not be at risk of breaking existing code which
>> doesn't record alignment correctly.
> 
> It's possible to produce 1-byte alignment with LLVM for an MSVC target:
> 
>     CLANG64 ~/Desktop
>     $ echo '#include <stdio.h>
>       thread_local char underaligned = 42; \
>       int main(void) { printf("&underaligned = %p\n", &underaligned); }'  \
>       | '/c/Program Files/LLVM/bin/clang++' -xc++ - \
>     && llvm-readobj --coff-tls-directory a.exe \
>     && ./a.exe
> 
> 
>     File: a.exe
>     Format: COFF-x86-64
>     Arch: x86_64
>     AddressSize: 64bit
>     TLSDirectory {
>       StartAddressOfRawData: 0x140028000
>       EndAddressOfRawData: 0x140028002
>       AddressOfIndex: 0x140023B40
>       AddressOfCallBacks: 0x1400208D8
>       SizeOfZeroFill: 0x0
>       Characteristics [ (0x100000)
>         IMAGE_SCN_ALIGN_1BYTES (0x100000)
>       ]
>     }
>     &underaligned = 000001D944E54F61
> 
> 
> This is not possible with mingw-w64 CRT, since these variables in tlssup.c ensure that the .tls section 
> will be aligned to at least pointer size:
> 
>     /* TLS raw template data start and end.
>        We use here pointer-types for start/end so that tls-data remains
>        aligned on pointer-size-width.  This seems to be required for
>        pe-loader. */
>     _CRTALLOC(".tls") char *_tls_start = NULL;
>     _CRTALLOC(".tls$ZZZ") char *_tls_end = NULL;

Neither this being possible with MSVC nor specific libc behavior on
MinGW addresses my concern. What MSVC does may also not be entirely
right, and people may bypass use of tlssup.c on MinGW.

Jan


More information about the Binutils mailing list