bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gas/31092] New: SECREL32 produces wrong value on x86_64-w64-mingw32


From: lh_mouse at 126 dot com
Subject: [Bug gas/31092] New: SECREL32 produces wrong value on x86_64-w64-mingw32
Date: Tue, 28 Nov 2023 14:50:55 +0000

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.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]