Bug 17955 - Wrong address difference on 64-bit Windows
Summary: Wrong address difference on 64-bit Windows
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.25
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-02-10 21:40 UTC by fanael4
Modified: 2016-09-26 15:19 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
Proper R_X86_64_PC64 reloc handling (307 bytes, patch)
2016-09-22 15:19 UTC, awson
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description fanael4 2015-02-10 21:40:20 UTC
On 64-bit Windows, when calculating a 64-bit address difference between two labels in different sections, the value will be off.

This program should not abort, but it does:

.text
.intel_syntax noprefix
c: .quad a - mainCRTStartup
.def mainCRTStartup
.scl 2
.type 32
.endef
.globl mainCRTStarup
.extern abort
mainCRTStartup:
  sub rsp, 40
  movabs rax, offset a
  movabs rcx, offset mainCRTStartup
  mov rdx, [c]
  sub rax, rcx
  cmp rax, rdx
  jne 1f
  xor eax, eax
  add rsp, 40
  ret
1:
  call abort
.section .rdata,"dr"
a: .quad 0

The value under "c" is 4092, while the actual difference is 4088.

If "a" is moved to .text, or if "c" is a .long instead of a .quad, the problem disappears.
Comment 1 awson 2016-09-22 15:19:52 UTC
Created attachment 9519 [details]
Proper R_X86_64_PC64 reloc handling

The patch I propose fixes things for me.

Since Microsoft does *not* support R_X86_64_PC64 relocation type for PE-COFF and it is a pure GNU extension, I've decided we can handle it in whatever way we want.

The only known to me high-level language compiler which generates this type of relocations on Windows is GHC (Glasgow Haskell Compiler) via LLVM backend (native codegen backend has workaround to generate R_X86_64_PC32 relocations instead). With no above patch applied ld generates wrong executables for it.
Comment 2 cvs-commit@gcc.gnu.org 2016-09-26 15:17:40 UTC
The master branch has been updated by Nick Clifton <nickc@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=384f7503344b1d07561f801ced7493858cde6164

commit 384f7503344b1d07561f801ced7493858cde6164
Author: Awson <kyrab@mail.ru>
Date:   Mon Sep 26 16:16:25 2016 +0100

    Fix the calculation of AMD64_PCRQUAD relocations.
    
    	PR ld/17955
    	* coff-x86_64.c (coff_amd64_rtype_to_howto): Use an 8 byte offset
    	for R_AMD64_PCRQUAD relocations.
Comment 3 Nick Clifton 2016-09-26 15:19:36 UTC
Thanks for the patch.  I have applied it with one small change - I made the new code conditional upon DONT_EXTEND_AMD64 not being defined.  This is in line with the other uses of R_AMD64_PCRQUAD in the same file.