]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link,cmd/internal/objabi: support ADDR32NB relocations on windows
authorqmuntal <quimmuntal@gmail.com>
Thu, 12 Jan 2023 10:19:12 +0000 (11:19 +0100)
committerQuim Muntal <quimmuntal@gmail.com>
Wed, 29 Mar 2023 05:01:03 +0000 (05:01 +0000)
This CL updates the linker to support
IMAGE_REL_[I386|AMD64|ARM|ARM64]_ADDR32NB relocations via the new
R_PEIMAGEOFF relocation type. This relocation type references symbols
using RVAs instead of VA, so it can use 4-byte offsets to reference
symbols that would normally require 8-byte offsets.

This new relocation is still not used, but will be useful when
generating Structured Exception Handling (SEH) metadata, which
needs to reference functions only using 4-byte addresses, thus
using RVAs instead of VA is of great help.

Updates #57302

Change-Id: I28d73e97d5cb78a3bc7194dc7d2fcb4a03f9f4d0
Reviewed-on: https://go-review.googlesource.com/c/go/+/461737
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Run-TryBot: Quim Muntal <quimmuntal@gmail.com>
Reviewed-by: Davis Goodin <dagood@microsoft.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/internal/objabi/reloctype.go
src/cmd/internal/objabi/reloctype_string.go
src/cmd/link/internal/amd64/asm.go
src/cmd/link/internal/arm/asm.go
src/cmd/link/internal/arm64/asm.go
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/pe.go
src/cmd/link/internal/loader/loader_test.go
src/cmd/link/internal/loader/symbolbuilder.go
src/cmd/link/internal/x86/asm.go

index 2bc7b2dd7a32cf7f902a7d7470f8cc71f590ff07..84b0aecc4a610cacfe4b3ee91212ee4253c1c2d9 100644 (file)
@@ -333,6 +333,10 @@ const (
        // in a symbol and target any symbols.
        R_XCOFFREF
 
+       // R_PEIMAGEOFF resolves to a 32-bit offset from the start address of where
+       // the executable file is mapped in memory.
+       R_PEIMAGEOFF
+
        // R_WEAK marks the relocation as a weak reference.
        // A weak relocation does not make the symbol it refers to reachable,
        // and is only honored by the linker if the symbol is in some other way
index 9ce37d00dea942245a338da59ab36bfadf39aa41..b4b741e0205b9ba6ba9b99e0d674883b272407bc 100644 (file)
@@ -85,11 +85,12 @@ func _() {
        _ = x[R_ADDRCUOFF-75]
        _ = x[R_WASMIMPORT-76]
        _ = x[R_XCOFFREF-77]
+       _ = x[R_PEIMAGEOFF-78]
 }
 
-const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USEGENERICIFACEMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_CALLR_RISCV_CALL_TRAMPR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRLOONG64R_ADDRLOONG64UR_ADDRLOONG64TLSR_ADDRLOONG64TLSUR_CALLLOONG64R_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREF"
+const _RelocType_name = "R_ADDRR_ADDRPOWERR_ADDRARM64R_ADDRMIPSR_ADDROFFR_SIZER_CALLR_CALLARMR_CALLARM64R_CALLINDR_CALLPOWERR_CALLMIPSR_CONSTR_PCRELR_TLS_LER_TLS_IER_GOTOFFR_PLT0R_PLT1R_PLT2R_USEFIELDR_USETYPER_USEIFACER_USEIFACEMETHODR_USEGENERICIFACEMETHODR_METHODOFFR_KEEPR_POWER_TOCR_GOTPCRELR_JMPMIPSR_DWARFSECREFR_DWARFFILEREFR_ARM64_TLS_LER_ARM64_TLS_IER_ARM64_GOTPCRELR_ARM64_GOTR_ARM64_PCRELR_ARM64_PCREL_LDST8R_ARM64_PCREL_LDST16R_ARM64_PCREL_LDST32R_ARM64_PCREL_LDST64R_ARM64_LDST8R_ARM64_LDST16R_ARM64_LDST32R_ARM64_LDST64R_ARM64_LDST128R_POWER_TLS_LER_POWER_TLS_IER_POWER_TLSR_POWER_TLS_IE_PCREL34R_POWER_TLS_LE_TPREL34R_ADDRPOWER_DSR_ADDRPOWER_GOTR_ADDRPOWER_GOT_PCREL34R_ADDRPOWER_PCRELR_ADDRPOWER_TOCRELR_ADDRPOWER_TOCREL_DSR_ADDRPOWER_D34R_ADDRPOWER_PCREL34R_RISCV_CALLR_RISCV_CALL_TRAMPR_RISCV_PCREL_ITYPER_RISCV_PCREL_STYPER_RISCV_TLS_IE_ITYPER_RISCV_TLS_IE_STYPER_PCRELDBLR_ADDRLOONG64R_ADDRLOONG64UR_ADDRLOONG64TLSR_ADDRLOONG64TLSUR_CALLLOONG64R_JMPLOONG64R_ADDRMIPSUR_ADDRMIPSTLSR_ADDRCUOFFR_WASMIMPORTR_XCOFFREFR_PEIMAGEOFF"
 
-var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 233, 244, 250, 261, 271, 280, 293, 307, 321, 335, 351, 362, 375, 394, 414, 434, 454, 467, 481, 495, 509, 524, 538, 552, 563, 585, 607, 621, 636, 659, 676, 694, 715, 730, 749, 761, 779, 798, 817, 837, 857, 867, 880, 894, 910, 927, 940, 952, 963, 976, 987, 999, 1009}
+var _RelocType_index = [...]uint16{0, 6, 17, 28, 38, 47, 53, 59, 68, 79, 88, 99, 109, 116, 123, 131, 139, 147, 153, 159, 165, 175, 184, 194, 210, 233, 244, 250, 261, 271, 280, 293, 307, 321, 335, 351, 362, 375, 394, 414, 434, 454, 467, 481, 495, 509, 524, 538, 552, 563, 585, 607, 621, 636, 659, 676, 694, 715, 730, 749, 761, 779, 798, 817, 837, 857, 867, 880, 894, 910, 927, 940, 952, 963, 976, 987, 999, 1009, 1021}
 
 func (i RelocType) String() string {
        i -= 1
index f4832efcf73694f397ead033430709e4f4f40770..c91e37584c63d869baa57172cbb6bc4188f9d0ac 100644 (file)
@@ -532,6 +532,9 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
                        v = ld.IMAGE_REL_AMD64_ADDR32
                }
 
+       case objabi.R_PEIMAGEOFF:
+               v = ld.IMAGE_REL_AMD64_ADDR32NB
+
        case objabi.R_CALL,
                objabi.R_PCREL:
                v = ld.IMAGE_REL_AMD64_REL32
index 4574f2d5f9f9bb2f9cd28d3e69d61eaedb43f046..b432da89d43abfb3215190fe0389369dff578860 100644 (file)
@@ -356,6 +356,9 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
 
        case objabi.R_ADDR:
                v = ld.IMAGE_REL_ARM_ADDR32
+
+       case objabi.R_PEIMAGEOFF:
+               v = ld.IMAGE_REL_ARM_ADDR32NB
        }
 
        out.Write16(uint16(v))
index 7109d84fa32b81148f1b52cf24e02b65ee1b591d..312ee27aa6e0037a0528b206d28298fb8f4de9ca 100644 (file)
@@ -679,6 +679,9 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
                        out.Write16(ld.IMAGE_REL_ARM64_ADDR32)
                }
 
+       case objabi.R_PEIMAGEOFF:
+               out.Write16(ld.IMAGE_REL_ARM64_ADDR32NB)
+
        case objabi.R_ADDRARM64:
                // Note: r.Xadd has been taken care of below, in archreloc.
                out.Write32(uint32(sectoff))
index 01f9bc7099f037fdd1703bb3b54521fce821ea2e..66e97c69dbe3009e23d7fb82e8ffd52f67c35dfb 100644 (file)
@@ -345,7 +345,7 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                        } else {
                                log.Fatalf("cannot handle R_TLS_IE (sym %s) when linking internally", ldr.SymName(s))
                        }
-               case objabi.R_ADDR:
+               case objabi.R_ADDR, objabi.R_PEIMAGEOFF:
                        if weak && !ldr.AttrReachable(rs) {
                                // Redirect it to runtime.unreachableMethod, which will throw if called.
                                rs = syms.unreachableMethod
@@ -398,6 +398,11 @@ func (st *relocSymState) relocsym(s loader.Sym, P []byte) {
                        }
 
                        o = ldr.SymValue(rs) + r.Add()
+                       if rt == objabi.R_PEIMAGEOFF {
+                               // The R_PEIMAGEOFF offset is a RVA, so subtract
+                               // the base address for the executable.
+                               o -= PEBASE
+                       }
 
                        // On amd64, 4-byte offsets will be sign-extended, so it is impossible to
                        // access more than 2GB of static data; fail at link time is better than
@@ -639,7 +644,7 @@ func extreloc(ctxt *Link, ldr *loader.Loader, s loader.Sym, r loader.Reloc) (loa
                }
                return rr, false
 
-       case objabi.R_ADDR:
+       case objabi.R_ADDR, objabi.R_PEIMAGEOFF:
                // set up addend for eventual relocation via outer symbol.
                rs := r.Sym()
                if r.Weak() && !ldr.AttrReachable(rs) {
index 08e5b976b6b0751e0f4a682ba9aee3bb9f328408..27f2b0305adac03cbde6496502b0c5e6563bf255 100644 (file)
@@ -105,14 +105,16 @@ const (
        IMAGE_SYM_CLASS_EXTERNAL = 2
        IMAGE_SYM_CLASS_STATIC   = 3
 
-       IMAGE_REL_I386_DIR32  = 0x0006
-       IMAGE_REL_I386_SECREL = 0x000B
-       IMAGE_REL_I386_REL32  = 0x0014
-
-       IMAGE_REL_AMD64_ADDR64 = 0x0001
-       IMAGE_REL_AMD64_ADDR32 = 0x0002
-       IMAGE_REL_AMD64_REL32  = 0x0004
-       IMAGE_REL_AMD64_SECREL = 0x000B
+       IMAGE_REL_I386_DIR32   = 0x0006
+       IMAGE_REL_I386_DIR32NB = 0x0007
+       IMAGE_REL_I386_SECREL  = 0x000B
+       IMAGE_REL_I386_REL32   = 0x0014
+
+       IMAGE_REL_AMD64_ADDR64   = 0x0001
+       IMAGE_REL_AMD64_ADDR32   = 0x0002
+       IMAGE_REL_AMD64_ADDR32NB = 0x0003
+       IMAGE_REL_AMD64_REL32    = 0x0004
+       IMAGE_REL_AMD64_SECREL   = 0x000B
 
        IMAGE_REL_ARM_ABSOLUTE = 0x0000
        IMAGE_REL_ARM_ADDR32   = 0x0001
index 7d1031e9dc6187c912aab71eb64aab9ebd1f0c18..8ee4be033b7f76be49c5e48b7d32ac3683f7139d 100644 (file)
@@ -338,6 +338,17 @@ func TestAddDataMethods(t *testing.T) {
                        expKind: sym.SDATA,
                        expRel:  []Reloc{mkReloc(ldr, objabi.R_ADDRCUOFF, 0, 8, 7, 8)},
                },
+               {
+                       which: "AddPEImageRelativeAddrPlus",
+                       addDataFunc: func(l *Loader, s Sym, s2 Sym) Sym {
+                               sb := l.MakeSymbolUpdater(s)
+                               sb.AddPEImageRelativeAddrPlus(arch, s2, 3)
+                               return s
+                       },
+                       expData: []byte{0, 0, 0, 0},
+                       expKind: sym.SDATA,
+                       expRel:  []Reloc{mkReloc(ldr, objabi.R_PEIMAGEOFF, 0, 4, 3, 9)},
+               },
        }
 
        var pmi Sym
index 558c0a7dfffbdf3fd89d3f5a15254be41c8f08fc..1744df2784e744c751e4e35920a8ca13eb744fde 100644 (file)
@@ -387,6 +387,10 @@ func (sb *SymbolBuilder) AddAddr(arch *sys.Arch, tgt Sym) int64 {
        return sb.AddAddrPlus(arch, tgt, 0)
 }
 
+func (sb *SymbolBuilder) AddPEImageRelativeAddrPlus(arch *sys.Arch, tgt Sym, add int64) int64 {
+       return sb.addSymRef(tgt, add, objabi.R_PEIMAGEOFF, 4)
+}
+
 func (sb *SymbolBuilder) AddPCRelPlus(arch *sys.Arch, tgt Sym, add int64) int64 {
        return sb.addSymRef(tgt, add, objabi.R_PCREL, 4)
 }
index 3a33201fd9403e65e9f0186599130cdbc179d0dd..fa5ad672286e8983befa6a97782d09c5e5d9ee7f 100644 (file)
@@ -399,6 +399,9 @@ func pereloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym,
        case objabi.R_ADDR:
                v = ld.IMAGE_REL_I386_DIR32
 
+       case objabi.R_PEIMAGEOFF:
+               v = ld.IMAGE_REL_I386_DIR32NB
+
        case objabi.R_CALL,
                objabi.R_PCREL:
                v = ld.IMAGE_REL_I386_REL32