bug-binutils
[Top][All Lists]
Advanced

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

[Bug ld/16821] New: x86_64 PE/COFF: ld truncates addresses of symbols fr


From: corinna at vinschen dot de
Subject: [Bug ld/16821] New: x86_64 PE/COFF: ld truncates addresses of symbols from linker scripts to 32 bit
Date: Tue, 08 Apr 2014 14:10:39 +0000

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.



reply via email to

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