diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index b3e1ac457d..939de11876 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -894,10 +894,15 @@ func windynrelocsym(ctxt *Link, rel *loader.SymbolBuilder, s loader.Sym) error { rel.AddUint8(0x90) rel.AddUint8(0x90) case sys.AMD64: + // The relocation symbol might be at an absolute offset + // higher than 32 bits, but the jump instruction can't + // encode more than 32 bit offsets. We use a jump + // relative to the instruction pointer to get around this + // limitation. rel.AddUint8(0xff) - rel.AddUint8(0x24) rel.AddUint8(0x25) - rel.AddAddrPlus4(ctxt.Arch, targ, 0) + rel.AddPCRelPlus(ctxt.Arch, targ, 0) + rel.AddUint8(0x90) rel.AddUint8(0x90) } } else if tplt >= 0 { diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go index 2808644150..fbfd928e87 100644 --- a/src/cmd/link/internal/ld/pe.go +++ b/src/cmd/link/internal/ld/pe.go @@ -1097,18 +1097,10 @@ func Peinit(ctxt *Link) { if ctxt.Arch.PtrSize == 8 { // 64-bit architectures pe64 = true - PEBASE = 1 << 32 - if ctxt.Arch.Family == sys.AMD64 { - // TODO(rsc): For cgo we currently use 32-bit relocations - // that fail when PEBASE is too large. - // We need to fix this, but for now, use a smaller PEBASE. - PEBASE = 1 << 22 - } var oh64 pe.OptionalHeader64 l = binary.Size(&oh64) } else { // 32-bit architectures - PEBASE = 1 << 22 var oh pe.OptionalHeader32 l = binary.Size(&oh) } @@ -1122,6 +1114,13 @@ func Peinit(ctxt *Link) { PEFILEALIGN = 0 // We are creating an object file. The absolute address is irrelevant. PEBASE = 0 + } else { + // Use the same base image address as MSVC and LLVM. + if pe64 { + PEBASE = 0x140000000 + } else { + PEBASE = 0x400000 + } } var sh [16]pe.SectionHeader32 diff --git a/test/nilptr.go b/test/nilptr.go index 7f42e930bd..6a60b18fc1 100644 --- a/test/nilptr.go +++ b/test/nilptr.go @@ -7,8 +7,8 @@ // Test that the implementation catches nil ptr indirection // in a large address space. -// Address space starts at 1<<32 on AIX and on darwin/arm64 and on windows/arm64, so dummy is too far. -//go:build !aix && (!darwin || !arm64) && (!windows || !arm64) +// Address space starts at 1<<32 on AIX and on darwin/arm64 and on windows/[amd64/arm64], so dummy is too far. +//go:build !aix && (!darwin || !arm64) && (!windows || (!amd64 && !arm64)) package main