// Filter out useless linker warnings caused by bugs outside Go.
// See also cmd/link/internal/ld's hostlink method.
var save [][]byte
+ var skipLines int
for _, line := range bytes.SplitAfter(out, []byte("\n")) {
// golang.org/issue/26073 - Apple Xcode bug
if bytes.Contains(line, []byte("ld: warning: text-based stub file")) {
continue
}
+
+ if skipLines > 0 {
+ skipLines--
+ continue
+ }
+
+ // Remove duplicate main symbol with runtime/cgo on AIX.
+ // With runtime/cgo, two main are available:
+ // One is generated by cgo tool with {return 0;}.
+ // The other one is the main calling runtime.rt0_go
+ // in runtime/cgo.
+ // The second can't be used by cgo programs because
+ // runtime.rt0_go is unknown to them.
+ // Therefore, we let ld remove this main version
+ // and used the cgo generated one.
+ if p.ImportPath == "runtime/cgo" && bytes.Contains(line, []byte("ld: 0711-224 WARNING: Duplicate symbol: .main")) {
+ skipLines = 1
+ continue
+ }
+
save = append(save, line)
}
out = bytes.Join(save, nil)
argv = append(argv, filepath.Join(*flagTmpdir, "go.o"))
argv = append(argv, hostobjCopy()...)
+ if ctxt.HeadType == objabi.Haix {
+ // We want to have C files after Go files to remove
+ // trampolines csects made by ld.
+ argv = append(argv, "-nostartfiles")
+ argv = append(argv, "/lib/crt0_64.o")
+
+ extld := ctxt.extld()
+ // Get starting files.
+ getPathFile := func(file string) string {
+ args := []string{"-maix64", "--print-file-name=" + file}
+ out, err := exec.Command(extld, args...).CombinedOutput()
+ if err != nil {
+ log.Fatalf("running %s failed: %v\n%s", extld, err, out)
+ }
+ return strings.Trim(string(out), "\n")
+ }
+ argv = append(argv, getPathFile("crtcxa.o"))
+ argv = append(argv, getPathFile("crtdbase.o"))
+ }
if ctxt.linkShared {
seenDirs := make(map[string]bool)
// onlycsymbol reports whether this is a symbol that is referenced by C code.
func onlycsymbol(s *sym.Symbol) bool {
switch s.Name {
- case "_cgo_topofstack", "_cgo_panic", "crosscall2":
+ case "_cgo_topofstack", "__cgo_topofstack", "_cgo_panic", "crosscall2":
return true
}
if strings.HasPrefix(s.Name, "_cgoexp_") {
}
if ctxt.LinkMode == LinkExternal {
- // Change main name to match __start code.
- main := ctxt.Syms.ROLookup("_main", 0)
- main.Name = ".main"
+ // Change rt0_go name to match name in runtime/cgo:main().
+ rt0 := ctxt.Syms.ROLookup("runtime.rt0_go", 0)
+ ctxt.Syms.Rename(rt0.Name, "runtime_rt0_go", 0, ctxt.Reachparent)
for _, s := range ctxt.Syms.Allsym {
if !s.Attr.CgoExport() {
TEXT runtime·asminit(SB),NOSPLIT|NOFRAME,$0-0
RET
+// Any changes must be reflected to runtime/cgo/gcc_aix_ppc64.S:.crosscall_ppc64
TEXT _cgo_reginit(SB),NOSPLIT|NOFRAME,$0-0
// crosscall_ppc64 and crosscall2 need to reginit, but can't
// get at the 'runtime.reginit' symbol.
// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
// Must obey the gcc calling convention.
+#ifdef GOOS_aix
+// On AIX, _cgo_topofstack is defined in runtime/cgo, because it must
+// be a longcall in order to prevent trampolines from ld.
+TEXT __cgo_topofstack(SB),NOSPLIT|NOFRAME,$0
+#else
TEXT _cgo_topofstack(SB),NOSPLIT|NOFRAME,$0
+#endif
// g (R30) and R31 are callee-save in the C ABI, so save them
MOVD g, R4
MOVD R31, R5
--- /dev/null
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cgo
+
+// These functions must be exported in order to perform
+// longcall on cgo programs (cf gcc_aix_ppc64.c).
+// go:cgo_export_static __cgo_topofstack
+// go:cgo_export_static runtime.rt0_go
stdu 1, -296(1)
// Set up Go ABI constant registers
- bl ._cgo_reginit
- nop
+ // Must match _cgo_reginit in runtime package.
+ xor 0, 0, 0
// Restore g pointer (r30 in Go ABI, which may have been clobbered by C)
mr 30, 4
--- /dev/null
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build aix
+// +build ppc64 ppc64le
+
+/*
+ * On AIX, call to _cgo_topofstack and Go main are forced to be a longcall.
+ * Without it, ld might add trampolines in the middle of .text section
+ * to reach these functions which are normally declared in runtime package.
+ */
+extern int __attribute__((longcall)) __cgo_topofstack(void);
+extern int __attribute__((longcall)) runtime_rt0_go(int argc, char **argv);
+
+int _cgo_topofstack(void) {
+ return __cgo_topofstack();
+}
+
+int main(int argc, char **argv) {
+ return runtime_rt0_go(argc, argv);
+}