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>
This commit is contained in:
John Papandriopoulos 2019-09-29 16:59:56 -07:00 committed by Ian Lance Taylor
parent 27cf81e1b4
commit 5e514b76e2
10 changed files with 76 additions and 16 deletions

View File

@ -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()
}

View File

@ -613,7 +613,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo
rs = rs.Outer 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) ld.Errorf(s, "missing section for %s", rs.Name)
} }
r.Xsym = rs r.Xsym = rs

View File

@ -96,7 +96,7 @@ func trampoline(ctxt *Link, s *sym.Symbol) {
if !r.Type.IsDirectJump() { if !r.Type.IsDirectJump() {
continue 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 r.Sym.File != s.File {
if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) { if !isRuntimeDepPkg(s.File) || !isRuntimeDepPkg(r.Sym.File) {
ctxt.ErrorUnresolved(s, r) ctxt.ErrorUnresolved(s, r)
@ -418,6 +418,17 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
} }
fallthrough fallthrough
case objabi.R_CALL, objabi.R_PCREL: 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) { 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 r.Done = false

View File

@ -334,6 +334,24 @@ func fieldtrack(ctxt *Link) {
} }
func (ctxt *Link) addexport() { 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) // TODO(aix)
if ctxt.HeadType == objabi.Hdarwin || ctxt.HeadType == objabi.Haix { if ctxt.HeadType == objabi.Hdarwin || ctxt.HeadType == objabi.Haix {
return return

View File

@ -2348,7 +2348,7 @@ func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int6
} }
put(ctxt, s, s.Name, BSSSym, Symaddr(s), s.Gotype) 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 { if ctxt.HeadType == objabi.Hwindows || ctxt.IsELF {
put(ctxt, s, s.Name, UndefinedSym, s.Value, nil) put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
} }

View File

@ -809,7 +809,7 @@ func machogenasmsym(ctxt *Link) {
} }
} }
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() { if s.Attr.Reachable() {
addsym(ctxt, s, "", DataSym, 0, nil) addsym(ctxt, s, "", DataSym, 0, nil)
} }
@ -886,7 +886,7 @@ func machosymtab(ctxt *Link) {
// replace "·" as ".", because DTrace cannot handle it. // replace "·" as ".", because DTrace cannot handle it.
Addstring(symstr, strings.Replace(s.Extname(), "·", ".", -1)) 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(0x01) // type N_EXT, external symbol
symtab.AddUint8(0) // no section symtab.AddUint8(0) // no section
symtab.AddUint16(ctxt.Arch, 0) // desc symtab.AddUint16(ctxt.Arch, 0) // desc

View File

@ -685,7 +685,7 @@ func (f *peFile) writeSymbols(ctxt *Link) {
// Only windows/386 requires underscore prefix on external symbols. // Only windows/386 requires underscore prefix on external symbols.
if ctxt.Arch.Family == sys.I386 && if ctxt.Arch.Family == sys.I386 &&
ctxt.LinkMode == LinkExternal && 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 s.Name = "_" + s.Name
} }

View File

@ -110,7 +110,7 @@ func putelfsym(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64, go
} }
var elfshnum int 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 elfshnum = SHN_UNDEF
} else { } else {
if xo.Sect == nil { if xo.Sect == nil {

View File

@ -104,6 +104,7 @@ const (
SCONST SCONST
SDYNIMPORT SDYNIMPORT
SHOSTOBJ SHOSTOBJ
SUNDEFEXT // Undefined symbol for resolution by external linker
// Sections for debugging information // Sections for debugging information
SDWARFSECT SDWARFSECT

View File

@ -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 package sym
@ -54,17 +54,18 @@ func _() {
_ = x[SCONST-43] _ = x[SCONST-43]
_ = x[SDYNIMPORT-44] _ = x[SDYNIMPORT-44]
_ = x[SHOSTOBJ-45] _ = x[SHOSTOBJ-45]
_ = x[SDWARFSECT-46] _ = x[SUNDEFEXT-46]
_ = x[SDWARFINFO-47] _ = x[SDWARFSECT-47]
_ = x[SDWARFRANGE-48] _ = x[SDWARFINFO-48]
_ = x[SDWARFLOC-49] _ = x[SDWARFRANGE-49]
_ = x[SDWARFLINES-50] _ = x[SDWARFLOC-50]
_ = x[SABIALIAS-51] _ = 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 { func (i SymKind) String() string {
if i >= SymKind(len(_SymKind_index)-1) { if i >= SymKind(len(_SymKind_index)-1) {