]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/link: use libmsvcrt.a during internal link
authorAlex Brainman <alex.brainman@gmail.com>
Sat, 19 Oct 2019 06:47:12 +0000 (17:47 +1100)
committerAlex Brainman <alex.brainman@gmail.com>
Sun, 20 Oct 2019 06:38:39 +0000 (06:38 +0000)
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 <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/cmd/link/internal/ld/lib.go
src/cmd/link/internal/loadpe/ldpe.go

index 182e5b0769eae38652bf6f9bf37a747add5bd9b6..2c5145e640d159339662ef17f91a3b3533bd0c7f 100644 (file)
@@ -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:
                                /*
index f08e1241a71290ed19b761647cc35984e66e591f..a41a7901a9a1ad8976de2c5bf4c07eecf37e498e 100644 (file)
@@ -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
+                       }
                }
        }