From: Alex Brainman Date: Sat, 19 Oct 2019 06:47:12 +0000 (+1100) Subject: cmd/link: use libmsvcrt.a during internal link X-Git-Tag: go1.14beta1~690 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e4c3925925d9bb93554cc60a29a4d728bb969296;p=gostls13.git cmd/link: use libmsvcrt.a during internal link When using recent versions of gcc with cgo, internal link fails with c:\>go test debug/pe --- FAIL: TestInternalLinkerDWARF (0.94s)     file_test.go:394: building test executable for linktype 2 failed: exit status 2 # command-line-arguments         runtime/cgo(.text): relocation target __acrt_iob_func not defined for ABI0 (but is defined for ABI0)         runtime/cgo(.text): relocation target __acrt_iob_func not defined for ABI0 (but is defined for ABI0)         runtime/cgo(.text): relocation target __acrt_iob_func not defined for ABI0 (but is defined for ABI0) FAIL FAIL    debug/pe        4.572s FAIL It appears that __acrt_iob_func is defined in libmsvcrt.a. And this change adds libmsvcrt.a to the list of libraries always used byi internal linker. libmsvcrt.a also implements __imp___acrt_iob_func. So this change also prevents rewriting __imp___acrt_iob_func name into __acrt_iob_func, otherwise we end up with duplicate __acrt_iob_func symbol error. Fixes #23649 Change-Id: Ie9864cd17e907501e9a8a3672bbc33e02ca20e5c Reviewed-on: https://go-review.googlesource.com/c/go/+/197977 Run-TryBot: Alex Brainman TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 182e5b0769..2c5145e640 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -582,6 +582,11 @@ func (ctxt *Link) loadlib() { if p := ctxt.findLibPath("libmingw32.a"); p != "none" { hostArchive(ctxt, p) } + // Link libmsvcrt.a to resolve '__acrt_iob_func' symbol + // (see https://golang.org/issue/23649 for details). + if p := ctxt.findLibPath("libmsvcrt.a"); p != "none" { + hostArchive(ctxt, p) + } // TODO: maybe do something similar to peimporteddlls to collect all lib names // and try link them all to final exe just like libmingwex.a and libmingw32.a: /* diff --git a/src/cmd/link/internal/loadpe/ldpe.go b/src/cmd/link/internal/loadpe/ldpe.go index f08e1241a7..a41a7901a9 100644 --- a/src/cmd/link/internal/loadpe/ldpe.go +++ b/src/cmd/link/internal/loadpe/ldpe.go @@ -445,9 +445,26 @@ func readpesym(arch *sys.Arch, syms *sym.Symbols, f *pe.File, pesym *pe.COFFSymb name = sectsyms[f.Sections[pesym.SectionNumber-1]].Name } else { name = symname - name = strings.TrimPrefix(name, "__imp_") // __imp_Name => Name - if arch.Family == sys.I386 && name[0] == '_' { - name = name[1:] // _Name => Name + switch arch.Family { + case sys.AMD64: + if name == "__imp___acrt_iob_func" { + // Do not rename __imp___acrt_iob_func into __acrt_iob_func, + // becasue __imp___acrt_iob_func symbol is real + // (see commit b295099 from git://git.code.sf.net/p/mingw-w64/mingw-w64 for detials). + } else { + name = strings.TrimPrefix(name, "__imp_") // __imp_Name => Name + } + case sys.I386: + if name == "__imp____acrt_iob_func" { + // Do not rename __imp____acrt_iob_func into ___acrt_iob_func, + // becasue __imp____acrt_iob_func symbol is real + // (see commit b295099 from git://git.code.sf.net/p/mingw-w64/mingw-w64 for detials). + } else { + name = strings.TrimPrefix(name, "__imp_") // __imp_Name => Name + } + if name[0] == '_' { + name = name[1:] // _Name => Name + } } }