Commit 5e514b76 authored by John Papandriopoulos's avatar John Papandriopoulos Committed by Ian Lance Taylor

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/+/186417Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 27cf81e1
# 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()
}
...@@ -613,7 +613,7 @@ func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val int64) (int64, bo ...@@ -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
......
...@@ -96,7 +96,7 @@ func trampoline(ctxt *Link, s *sym.Symbol) { ...@@ -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) { ...@@ -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
......
...@@ -334,6 +334,24 @@ func fieldtrack(ctxt *Link) { ...@@ -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
......
...@@ -2348,7 +2348,7 @@ func genasmsym(ctxt *Link, put func(*Link, *sym.Symbol, string, SymbolType, int6 ...@@ -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)
} }
......
...@@ -809,7 +809,7 @@ func machogenasmsym(ctxt *Link) { ...@@ -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) { ...@@ -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
......
...@@ -685,7 +685,7 @@ func (f *peFile) writeSymbols(ctxt *Link) { ...@@ -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
} }
......
...@@ -110,7 +110,7 @@ func putelfsym(ctxt *Link, x *sym.Symbol, s string, t SymbolType, addr int64, go ...@@ -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 {
......
...@@ -104,6 +104,7 @@ const ( ...@@ -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
......
// 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 _() { ...@@ -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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment