cmd/link: load symbols from .syso in external link mode Fix linking with a package having a .syso file in external link mode, that would otherwise cause an error before executing the external linker because it can't find symbols that are exported in the said .syso file. Fixes #33139 Change-Id: Id3ee737fba1c6f1e37910593dfedf9c84486d398 Reviewed-on: https://go-review.googlesource.com/c/go/+/186417 Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/src/cmd/go/testdata/script/link_syso_issue33139.txt b/src/cmd/go/testdata/script/link_syso_issue33139.txt new file mode 100644 index 0000000..53587e6 --- /dev/null +++ b/src/cmd/go/testdata/script/link_syso_issue33139.txt
@@ -0,0 +1,29 @@ +# Test that we can use the external linker with a host syso file that is +# embedded in a package, that is referenced by a Go assembly stub. +# See issue 33139. +[!gc] stop +cc -c -o syso/objTestImpl.syso syso/src/objTestImpl.c +go build -ldflags='-linkmode=external' ./cmd/main.go + +-- syso/objTest.s -- +#include "textflag.h" + +TEXT ·ObjTest(SB), NOSPLIT, $0 + JMP objTestImpl(SB) + +-- syso/pkg.go -- +package syso + +func ObjTest() + +-- syso/src/objTestImpl.c -- +void objTestImpl() { /* Empty */ } + +-- cmd/main.go -- +package main + +import "syso" + +func main() { + syso.ObjTest() +}
diff --git a/src/cmd/link/internal/arm/asm.go b/src/cmd/link/internal/arm/asm.go index 43d387c..41efd93 100644 --- a/src/cmd/link/internal/arm/asm.go +++ b/src/cmd/link/internal/arm/asm.go
@@ -613,7 +613,7 @@ rs = rs.Outer } - if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil { + if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Type != sym.SUNDEFEXT && rs.Sect == nil { ld.Errorf(s, "missing section for %s", rs.Name) } r.Xsym = rs
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 2266d30..ea67483 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go
@@ -96,7 +96,7 @@ if !r.Type.IsDirectJump() { continue } - if Symaddr(r.Sym) == 0 && r.Sym.Type != sym.SDYNIMPORT { + if Symaddr(r.Sym) == 0 && (r.Sym.Type != sym.SDYNIMPORT && r.Sym.Type != sym.SUNDEFEXT) { if r.Sym.File != s.File { if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) { ctxt.ErrorUnresolved(s, r) @@ -418,6 +418,17 @@ } fallthrough case objabi.R_CALL, objabi.R_PCREL: + if ctxt.LinkMode == LinkExternal && r.Sym != nil && r.Sym.Type == sym.SUNDEFEXT { + // pass through to the external linker. + r.Done = false + r.Xadd = 0 + if ctxt.IsELF { + r.Xadd -= int64(r.Siz) + } + r.Xsym = r.Sym + o = 0 + break + } if ctxt.LinkMode == LinkExternal && r.Sym != nil && r.Sym.Type != sym.SCONST && (r.Sym.Sect != s.Sect || r.Type == objabi.R_GOTPCREL) { r.Done = false
diff --git a/src/cmd/link/internal/ld/go.go b/src/cmd/link/internal/ld/go.go index 80d7ac3..37adeb7 100644 --- a/src/cmd/link/internal/ld/go.go +++ b/src/cmd/link/internal/ld/go.go
@@ -334,6 +334,24 @@ } func (ctxt *Link) addexport() { + // Track undefined external symbols during external link. + if ctxt.LinkMode == LinkExternal { + for _, s := range ctxt.Syms.Allsym { + if !s.Attr.Reachable() || s.Attr.Special() || s.Attr.SubSymbol() { + continue + } + if s.Type != sym.STEXT { + continue + } + for i := range s.R { + r := &s.R[i] + if r.Sym != nil && r.Sym.Type == sym.Sxxx { + r.Sym.Type = sym.SUNDEFEXT + } + } + } + } + // TODO(aix) if ctxt.HeadType == objabi.Hdarwin || ctxt.HeadType == objabi.Haix { return
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 182e5b0..98c5e6c 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go
@@ -2348,7 +2348,7 @@ } put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype) - case sym.SHOSTOBJ: + case sym.SHOSTOBJ, sym.SUNDEFEXT: if ctxt.HeadType == objabi.Hwindows || ctxt.IsELF { put(ctxt, s, s.Name, UndefinedSym, s.Value, nil) }
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go index 7453f37..e9e4876 100644 --- a/src/cmd/link/internal/ld/macho.go +++ b/src/cmd/link/internal/ld/macho.go
@@ -809,7 +809,7 @@ } } - if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ { + if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ || s.Type == sym.SUNDEFEXT { if s.Attr.Reachable() { addsym(ctxt, s, "", DataSym, 0, nil) } @@ -886,7 +886,7 @@ // replace "·" as ".", because DTrace cannot handle it. Addstring(symstr, strings.Replace(s.Extname(), "·", ".", -1)) - if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ { + if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ || s.Type == sym.SUNDEFEXT { symtab.AddUint8(0x01) // type N_EXT, external symbol symtab.AddUint8(0) // no section symtab.AddUint16(ctxt.Arch, 0) // desc
diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go index 12363626..6d4674d 100644 --- a/src/cmd/link/internal/ld/pe.go +++ b/src/cmd/link/internal/ld/pe.go
@@ -685,7 +685,7 @@ // Only windows/386 requires underscore prefix on external symbols. if ctxt.Arch.Family == sys.I386 && ctxt.LinkMode == LinkExternal && - (s.Type == sym.SHOSTOBJ || s.Attr.CgoExport()) { + (s.Type == sym.SHOSTOBJ || s.Type == sym.SUNDEFEXT || s.Attr.CgoExport()) { s.Name = "_" + s.Name }
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index d686a8a..4925eda 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go
@@ -110,7 +110,7 @@ } var elfshnum int - if xo.Type == sym.SDYNIMPORT || xo.Type == sym.SHOSTOBJ { + if xo.Type == sym.SDYNIMPORT || xo.Type == sym.SHOSTOBJ || xo.Type == sym.SUNDEFEXT { elfshnum = SHN_UNDEF } else { if xo.Sect == nil {
diff --git a/src/cmd/link/internal/sym/symkind.go b/src/cmd/link/internal/sym/symkind.go index 4e44d3f..5309e07 100644 --- a/src/cmd/link/internal/sym/symkind.go +++ b/src/cmd/link/internal/sym/symkind.go
@@ -104,6 +104,7 @@ SCONST SDYNIMPORT SHOSTOBJ + SUNDEFEXT // Undefined symbol for resolution by external linker // Sections for debugging information SDWARFSECT
diff --git a/src/cmd/link/internal/sym/symkind_string.go b/src/cmd/link/internal/sym/symkind_string.go index 2732ec7..e48d90c 100644 --- a/src/cmd/link/internal/sym/symkind_string.go +++ b/src/cmd/link/internal/sym/symkind_string.go
@@ -1,4 +1,4 @@ -// Code generated by "stringer -type=SymKind"; DO NOT EDIT. +// Code generated by "stringer -type=SymKind symkind.go"; DO NOT EDIT. package sym @@ -54,17 +54,18 @@ _ = x[SCONST-43] _ = x[SDYNIMPORT-44] _ = x[SHOSTOBJ-45] - _ = x[SDWARFSECT-46] - _ = x[SDWARFINFO-47] - _ = x[SDWARFRANGE-48] - _ = x[SDWARFLOC-49] - _ = x[SDWARFLINES-50] - _ = x[SABIALIAS-51] + _ = x[SUNDEFEXT-46] + _ = x[SDWARFSECT-47] + _ = x[SDWARFINFO-48] + _ = x[SDWARFRANGE-49] + _ = x[SDWARFLOC-50] + _ = x[SDWARFLINES-51] + _ = x[SABIALIAS-52] } -const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSCONSTSDYNIMPORTSHOSTOBJSDWARFSECTSDWARFINFOSDWARFRANGESDWARFLOCSDWARFLINESSABIALIAS" +const _SymKind_name = "SxxxSTEXTSELFRXSECTSTYPESSTRINGSGOSTRINGSGOFUNCSGCBITSSRODATASFUNCTABSELFROSECTSMACHOPLTSTYPERELROSSTRINGRELROSGOSTRINGRELROSGOFUNCRELROSGCBITSRELROSRODATARELROSFUNCTABRELROSTYPELINKSITABLINKSSYMTABSPCLNTABSFirstWritableSBUILDINFOSELFSECTSMACHOSMACHOGOTSWINDOWSSELFGOTSNOPTRDATASINITARRSDATASXCOFFTOCSBSSSNOPTRBSSSTLSBSSSXREFSMACHOSYMSTRSMACHOSYMTABSMACHOINDIRECTPLTSMACHOINDIRECTGOTSFILEPATHSCONSTSDYNIMPORTSHOSTOBJSUNDEFEXTSDWARFSECTSDWARFINFOSDWARFRANGESDWARFLOCSDWARFLINESSABIALIAS" -var _SymKind_index = [...]uint16{0, 4, 9, 19, 24, 31, 40, 47, 54, 61, 69, 79, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 220, 230, 238, 244, 253, 261, 268, 278, 286, 291, 300, 304, 313, 320, 325, 337, 349, 366, 383, 392, 398, 408, 416, 426, 436, 447, 456, 467, 476} +var _SymKind_index = [...]uint16{0, 4, 9, 19, 24, 31, 40, 47, 54, 61, 69, 79, 88, 98, 110, 124, 136, 148, 160, 173, 182, 191, 198, 206, 220, 230, 238, 244, 253, 261, 268, 278, 286, 291, 300, 304, 313, 320, 325, 337, 349, 366, 383, 392, 398, 408, 416, 425, 435, 445, 456, 465, 476, 485} func (i SymKind) String() string { if i >= SymKind(len(_SymKind_index)-1) {