From 359fb4a9afe273c1ef5600c0c7308dc167c0d4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chigot?= Date: Wed, 20 Feb 2019 16:26:54 +0100 Subject: [PATCH] cmd/link: on AIX generate export file for host linker Change-Id: I6638cb0f9ed751c76a29cae62a93a923f18f14f3 Reviewed-on: https://go-review.googlesource.com/c/go/+/164005 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/cmd/link/internal/ld/lib.go | 4 +++ src/cmd/link/internal/ld/xcoff.go | 57 ++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index e99c81aeb7..44befc9637 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -1266,6 +1266,10 @@ func (ctxt *Link) hostlink() { if ctxt.IsELF { argv = append(argv, "-rdynamic") } + if ctxt.HeadType == objabi.Haix { + fileName := xcoffCreateExportFile(ctxt) + argv = append(argv, "-Wl,-bE:"+fileName) + } if strings.Contains(argv[0], "clang") { argv = append(argv, "-Qunused-arguments") diff --git a/src/cmd/link/internal/ld/xcoff.go b/src/cmd/link/internal/ld/xcoff.go index 30a27d2b18..ee375bfe03 100644 --- a/src/cmd/link/internal/ld/xcoff.go +++ b/src/cmd/link/internal/ld/xcoff.go @@ -9,7 +9,9 @@ import ( "cmd/internal/objabi" "cmd/link/internal/sym" "encoding/binary" + "io/ioutil" "math/bits" + "path/filepath" "sort" "strings" ) @@ -771,7 +773,7 @@ func (f *xcoffFile) writeSymbolFunc(ctxt *Link, x *sym.Symbol) []xcoffSym { s := &XcoffSymEnt64{ Nsclass: C_EXT, - Noffset: uint32(xfile.stringTable.add(x.Name)), + Noffset: uint32(xfile.stringTable.add(x.Extname())), Nvalue: uint64(x.Value), Nscnum: f.getXCOFFscnum(x.Sect), Ntype: SYM_TYPE_FUNC, @@ -1182,6 +1184,26 @@ func (ctxt *Link) doxcoff() { // Change main name to match __start code. main := ctxt.Syms.ROLookup("_main", 0) main.Name = ".main" + + for _, s := range ctxt.Syms.Allsym { + if !s.Attr.CgoExport() { + continue + } + + name := s.Extname() + if s.Type == sym.STEXT { + // On AIX, a exported function must have two symbols: + // - a .text symbol which must start with a ".". + // - a .data symbol which is a function descriptor. + ctxt.Syms.Rename(s.Name, "."+name, 0, ctxt.Reachparent) + + desc := ctxt.Syms.Lookup(name, 0) + desc.Type = sym.SNOPTRDATA + desc.AddAddr(ctxt.Arch, s) + desc.AddAddr(ctxt.Arch, toc) + desc.AddUint64(ctxt.Arch, 0) + } + } } } @@ -1614,3 +1636,36 @@ func (f *xcoffFile) emitRelocations(ctxt *Link, fileoff int64) { // TODO(aix): DWARF relocations } + +// xcoffCreateExportFile creates a file with exported symbols for +// -Wl,-bE option. +// ld won't export symbols unless they are listed in an export file. +func xcoffCreateExportFile(ctxt *Link) (fname string) { + fname = filepath.Join(*flagTmpdir, "export_file.exp") + var buf bytes.Buffer + + for _, s := range ctxt.Syms.Allsym { + if !s.Attr.CgoExport() { + continue + } + if !strings.HasPrefix(s.String(), "_cgoexp_") { + continue + } + + // Retrieve the name of the initial symbol + // exported by cgo. + // The corresponding Go symbol is: + // _cgoexp_hashcode_symname. + name := strings.SplitN(s.Extname(), "_", 4)[3] + + buf.Write([]byte(name + "\n")) + } + + err := ioutil.WriteFile(fname, buf.Bytes(), 0666) + if err != nil { + Errorf(nil, "WriteFile %s failed: %v", fname, err) + } + + return fname + +}