mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/link: pass-through undefined call targets in external link mode
Allows Go asm calls referencing a function in a .syso file to be passed through to the external linker, that would have otherwise raised a "relocation target X not defined" error in cmd/link. Fixes #33139 Change-Id: I2a8eb6063ebcd05fac96f141acf7652cf9189766 Reviewed-on: https://go-review.googlesource.com/c/go/+/198798 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
81d6ec204f
commit
59a6847039
12 changed files with 97 additions and 18 deletions
43
src/cmd/go/testdata/script/link_syso_issue33139.txt
vendored
Normal file
43
src/cmd/go/testdata/script/link_syso_issue33139.txt
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
# 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 function.
|
||||||
|
# See issue 33139.
|
||||||
|
[!gc] skip
|
||||||
|
[!exec:cc] skip
|
||||||
|
|
||||||
|
# External linking is not supported on linux/ppc64.
|
||||||
|
# See: https://github.com/golang/go/issues/8912
|
||||||
|
[linux] [ppc64] skip
|
||||||
|
|
||||||
|
# External linking is not supported on darwin/386 (10.14+).
|
||||||
|
# See: https://github.com/golang/go/issues/31751
|
||||||
|
[darwin] [386] skip
|
||||||
|
|
||||||
|
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
|
||||||
|
// We do not actually execute this function in the test above, thus
|
||||||
|
// there is no stack frame setup here.
|
||||||
|
// We only care about Go build and/or link errors when referencing
|
||||||
|
// the objTestImpl symbol in the syso file.
|
||||||
|
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
|
||||||
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) {
|
||||||
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)
|
||||||
|
|
@ -298,7 +298,7 @@ func relocsym(ctxt *Link, s *sym.Symbol) {
|
||||||
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 {
|
||||||
Errorf(s, "missing section for relocation target %s", rs.Name)
|
Errorf(s, "missing section for relocation target %s", rs.Name)
|
||||||
}
|
}
|
||||||
r.Xsym = rs
|
r.Xsym = rs
|
||||||
|
|
@ -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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -2369,6 +2369,11 @@ 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.SUNDEFEXT:
|
||||||
|
if ctxt.HeadType == objabi.Hwindows || ctxt.HeadType == objabi.Haix || ctxt.IsELF {
|
||||||
|
put(ctxt, s, s.Name, UndefinedSym, s.Value, nil)
|
||||||
|
}
|
||||||
|
|
||||||
case sym.SHOSTOBJ:
|
case sym.SHOSTOBJ:
|
||||||
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) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
|
|
||||||
|
|
@ -955,7 +955,7 @@ func putaixsym(ctxt *Link, x *sym.Symbol, str string, t SymbolType, addr int64,
|
||||||
syms = append(syms, a4)
|
syms = append(syms, a4)
|
||||||
|
|
||||||
case UndefinedSym:
|
case UndefinedSym:
|
||||||
if x.Type != sym.SDYNIMPORT && x.Type != sym.SHOSTOBJ {
|
if x.Type != sym.SDYNIMPORT && x.Type != sym.SHOSTOBJ && x.Type != sym.SUNDEFEXT {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s := &XcoffSymEnt64{
|
s := &XcoffSymEnt64{
|
||||||
|
|
|
||||||
|
|
@ -801,7 +801,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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue