https://sourceware.org/bugzilla/show_bug.cgi?id=16821
Bug ID: 16821 Summary: x86_64 PE/COFF: ld truncates addresses of symbols from linker scripts to 32 bit Product: binutils Version: 2.25 (HEAD) Status: NEW Severity: critical Priority: P2 Component: ld Assignee: unassigned at sourceware dot org Reporter: corinna at vinschen dot de I just encountered a serious bug while building the Cygwin DLL for x86_64-pc-cygwin, which I never noticed before (*blush*): The Cygwin DLL is built to be located at the address 0x1:80040000, so it's not located in the lower 32 bits area, but just a tad bit higher. It's also using its own linker script. When I tried to access __image_base__ from the DLL itself, I found to my surprise that __image_base__ was not 0x1:80040000, but instead 0x0:8004000, so it's truncated to 32 bit. The only time __image_base__ occurs in the script is to compute the start of the .text segment: .text __image_base__ + __section_alignment__ : { ... } Further investigation showed that four more symbols were affected: .rdata ALIGN(__section_alignment__) : { *(.rdata) *(SORT(.rdata$*)) *(.rdata_cygwin_nocopy) __rt_psrelocs_start = .; *(.rdata_runtime_pseudo_reloc) __rt_psrelocs_end = .; } __rt_psrelocs_size = __rt_psrelocs_end - __rt_psrelocs_start; ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; __RUNTIME_PSEUDO_RELOC_LIST_END__ = .; ___RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size; __RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size; In this piece of the script, the symbols ___RUNTIME_PSEUDO_RELOC_LIST__ and __RUNTIME_PSEUDO_RELOC_LIST__ have an address which is truncated to 32 bit. If I change this code to .rdata ALIGN(__section_alignment__) : { *(.rdata) *(SORT(.rdata$*)) *(.rdata_cygwin_nocopy) ___RUNTIME_PSEUDO_RELOC_LIST__ = .; __RUNTIME_PSEUDO_RELOC_LIST__ = .; *(.rdata_runtime_pseudo_reloc) ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; __RUNTIME_PSEUDO_RELOC_LIST_END__ = .; } the address of the two symbols is correct. Additionally there are two symbols which are defined with the ABSOLUTE macro: _SYM (_cygheap_start) = ABSOLUTE(.); [...] _SYM (_cygheap_end) = ABSOLUTE(.); Both symbols have the correct address, but again truncated to 32 bit. If I change the script to not use ABSOLUTE _SYM (_cygheap_start) = .; [...] _SYM (_cygheap_end) = .; the 64 bit addresses are correct. So it appears that during certain computations in ld, the addresses of symbols are truncated to 32 bit values. Given that x86_64 Cygwin executables are located at 0x1:00040000 by default, this means that *ALL* Cygwin executables are affected by this bug. Any chance to fix this ASAP? Thanks, Corinna -- You are receiving this mail because: You are on the CC list for the bug. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils