// 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);
+}