https://sourceware.org/bugzilla/show_bug.cgi?id=31092
Bug ID: 31092 Summary: SECREL32 produces wrong value on x86_64-w64-mingw32 Product: binutils Version: 2.41 Status: UNCONFIRMED Severity: normal Priority: P2 Component: gas Assignee: unassigned at sourceware dot org Reporter: lh_mouse at 126 dot com Target Milestone: --- C source: ``` int printf(const char*, ...) __attribute__((__dllimport__)); void exit(int) __attribute__((__noreturn__, __dllimport__)); __thread int my_value = 42; unsigned int _tls_index; void _start(void) { printf("my_value = %d\n", my_value); exit(0); } __attribute__((__section__(".tls"))) char *_tls_start = 0; __attribute__((__section__(".tls$ZZZ"))) char *_tls_end = 0; typedef struct _IMAGE_TLS_DIRECTORY64 { void* StartAddressOfRawData; void* EndAddressOfRawData; unsigned int* AddressOfIndex; void* AddressOfCallBacks; unsigned int SizeOfZeroFill; unsigned int Characteristics; } IMAGE_TLS_DIRECTORY; __attribute__((used)) const IMAGE_TLS_DIRECTORY _tls_used = { &_tls_start, &_tls_end, &_tls_index, 0, 0, 0 }; ``` Compile it with Clang to get assembly: clang test.s -nostdlib -lmsvcrt -Wl,-e_start ``` .text .def @feat.00; .scl 3; .type 0; .endef .globl @feat.00 .set @feat.00, 0 .file "test.c" .def _start; .scl 2; .type 32; .endef .globl _start # -- Begin function _start .p2align 4, 0x90 _start: # @_start .seh_proc _start # %bb.0: subq $40, %rsp .seh_stackalloc 40 .seh_endprologue movl _tls_index(%rip), %eax movq %gs:88, %rcx movq (%rcx,%rax,8), %rax movl my_value@SECREL32(%rax), %edx leaq .L.str(%rip), %rcx callq *__imp_printf(%rip) xorl %ecx, %ecx callq *__imp_exit(%rip) int3 .seh_endproc # -- End function .section .tls$,"dw" .globl my_value # @my_value .p2align 2, 0x0 my_value: .long 42 # 0x2a .section .rdata,"dr" .L.str: # @.str .asciz "my_value = %d\n" .section .tls,"dw" .globl _tls_start # @_tls_start .p2align 3, 0x0 _tls_start: .quad 0 .section .tls$ZZZ,"dw" .globl _tls_end # @_tls_end .p2align 3, 0x0 _tls_end: .quad 0 .bss .globl _tls_index # @_tls_index .p2align 2, 0x0 _tls_index: .long 0 # 0x0 .section .rdata,"dr" .globl _tls_used # @_tls_used .p2align 3, 0x0 _tls_used: .quad _tls_start .quad _tls_end .quad _tls_index .quad 0 .long 0 # 0x0 .long 0 # 0x0 .addrsig .addrsig_sym _tls_start .addrsig_sym _tls_end .addrsig_sym _tls_index .addrsig_sym _tls_used ``` This can be assembled with clang and produce: ``` $ clang test.s -nostdlib -lmsvcrt -Wl,-e_start && ./a.exe my_value = 42 ``` but that's not part of the issue. GAS doesn't recognize `.addrsig` so let's delete them, then try GAS: ``` $ as --version GNU assembler (GNU Binutils) 2.41.0.20231122 $ as test.s -o test.o && ld test.o -e_start -nostdlib /mingw64/lib/libmsvcrt.a && ./a.exe Segmentation fault ``` Okay let's debug it with x64dbg: ``` 00007FF7FC461000 <a. | 48:83EC 28 | sub rsp, 0x28 00007FF7FC461004 | 8B05 F63F0000 | mov eax, dword ptr ds:[0x7FF7FC465000] 00007FF7FC46100A | 6548:8B0C25 58000000 | mov rcx, qword ptr gs:[0x58] 00007FF7FC461013 | 48:8B04C1 | mov rax, qword ptr ds:[rcx + rax * 8] 00007FF7FC461017 | 8B90 080046BC | mov edx, dword ptr ds:[rax - 0x43B9FFF8] 00007FF7FC46101D | 48:8D0D DC0F0000 | lea rcx, qword ptr ds:[0x7FF7FC462000] 00007FF7FC461024 | FF15 1E500000 | call qword ptr ds:[<printf>] 00007FF7FC46102A | 31C9 | xor ecx, ecx 00007FF7FC46102C | FF15 0E500000 | call qword ptr ds:[<exit>] 00007FF7FC461032 | CC | int3 ``` We can see that `my_value@SECREL32` becomes `0x43B9FFF8` (`080046BC` in little-endian order) and that's not correct. There is another issue: The `@SECREL32` modifier doesn't work in Intel syntax; it gets treated as part of the symbol name. Maybe this is worth another report. -- You are receiving this mail because: You are on the CC list for the bug.