// Copyright 2009 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 ld

import (
	"bytes"
	"cmd/internal/codesign"
	"cmd/internal/objabi"
	"cmd/internal/sys"
	"cmd/link/internal/loader"
	"cmd/link/internal/sym"
	"debug/macho"
	"encoding/binary"
	"fmt"
	"internal/buildcfg"
	"io"
	"os"
	"sort"
	"strings"
	"unsafe"
)

type MachoHdr struct {
	cpu    uint32
	subcpu uint32
}

type MachoSect struct {
	name    string
	segname string
	addr    uint64
	size    uint64
	off     uint32
	align   uint32
	reloc   uint32
	nreloc  uint32
	flag    uint32
	res1    uint32
	res2    uint32
}

type MachoSeg struct {
	name       string
	vsize      uint64
	vaddr      uint64
	fileoffset uint64
	filesize   uint64
	prot1      uint32
	prot2      uint32
	nsect      uint32
	msect      uint32
	sect       []MachoSect
	flag       uint32
}

// MachoPlatformLoad represents a LC_VERSION_MIN_* or
// LC_BUILD_VERSION load command.
type MachoPlatformLoad struct {
	platform MachoPlatform // One of PLATFORM_* constants.
	cmd      MachoLoad
}

type MachoLoad struct {
	type_ uint32
	data  []uint32
}

type MachoPlatform int

/*
 * Total amount of space to reserve at the start of the file
 * for Header, PHeaders, and SHeaders.
 * May waste some.
 */
const (
	INITIAL_MACHO_HEADR = 4 * 1024
)

const (
	MACHO_CPU_AMD64                      = 1<<24 | 7
	MACHO_CPU_386                        = 7
	MACHO_SUBCPU_X86                     = 3
	MACHO_CPU_ARM                        = 12
	MACHO_SUBCPU_ARM                     = 0
	MACHO_SUBCPU_ARMV7                   = 9
	MACHO_CPU_ARM64                      = 1<<24 | 12
	MACHO_SUBCPU_ARM64_ALL               = 0
	MACHO_SUBCPU_ARM64_V8                = 1
	MACHO_SUBCPU_ARM64E                  = 2
	MACHO32SYMSIZE                       = 12
	MACHO64SYMSIZE                       = 16
	MACHO_X86_64_RELOC_UNSIGNED          = 0
	MACHO_X86_64_RELOC_SIGNED            = 1
	MACHO_X86_64_RELOC_BRANCH            = 2
	MACHO_X86_64_RELOC_GOT_LOAD          = 3
	MACHO_X86_64_RELOC_GOT               = 4
	MACHO_X86_64_RELOC_SUBTRACTOR        = 5
	MACHO_X86_64_RELOC_SIGNED_1          = 6
	MACHO_X86_64_RELOC_SIGNED_2          = 7
	MACHO_X86_64_RELOC_SIGNED_4          = 8
	MACHO_ARM_RELOC_VANILLA              = 0
	MACHO_ARM_RELOC_PAIR                 = 1
	MACHO_ARM_RELOC_SECTDIFF             = 2
	MACHO_ARM_RELOC_BR24                 = 5
	MACHO_ARM64_RELOC_UNSIGNED           = 0
	MACHO_ARM64_RELOC_BRANCH26           = 2
	MACHO_ARM64_RELOC_PAGE21             = 3
	MACHO_ARM64_RELOC_PAGEOFF12          = 4
	MACHO_ARM64_RELOC_GOT_LOAD_PAGE21    = 5
	MACHO_ARM64_RELOC_GOT_LOAD_PAGEOFF12 = 6
	MACHO_ARM64_RELOC_ADDEND             = 10
	MACHO_GENERIC_RELOC_VANILLA          = 0
	MACHO_FAKE_GOTPCREL                  = 100
)

const (
	MH_MAGIC    = 0xfeedface
	MH_MAGIC_64 = 0xfeedfacf

	MH_OBJECT  = 0x1
	MH_EXECUTE = 0x2

	MH_NOUNDEFS = 0x1
	MH_DYLDLINK = 0x4
	MH_PIE      = 0x200000
)

const (
	LC_SEGMENT                  = 0x1
	LC_SYMTAB                   = 0x2
	LC_SYMSEG                   = 0x3
	LC_THREAD                   = 0x4
	LC_UNIXTHREAD               = 0x5
	LC_LOADFVMLIB               = 0x6
	LC_IDFVMLIB                 = 0x7
	LC_IDENT                    = 0x8
	LC_FVMFILE                  = 0x9
	LC_PREPAGE                  = 0xa
	LC_DYSYMTAB                 = 0xb
	LC_LOAD_DYLIB               = 0xc
	LC_ID_DYLIB                 = 0xd
	LC_LOAD_DYLINKER            = 0xe
	LC_ID_DYLINKER              = 0xf
	LC_PREBOUND_DYLIB           = 0x10
	LC_ROUTINES                 = 0x11
	LC_SUB_FRAMEWORK            = 0x12
	LC_SUB_UMBRELLA             = 0x13
	LC_SUB_CLIENT               = 0x14
	LC_SUB_LIBRARY              = 0x15
	LC_TWOLEVEL_HINTS           = 0x16
	LC_PREBIND_CKSUM            = 0x17
	LC_LOAD_WEAK_DYLIB          = 0x80000018
	LC_SEGMENT_64               = 0x19
	LC_ROUTINES_64              = 0x1a
	LC_UUID                     = 0x1b
	LC_RPATH                    = 0x8000001c
	LC_CODE_SIGNATURE           = 0x1d
	LC_SEGMENT_SPLIT_INFO       = 0x1e
	LC_REEXPORT_DYLIB           = 0x8000001f
	LC_LAZY_LOAD_DYLIB          = 0x20
	LC_ENCRYPTION_INFO          = 0x21
	LC_DYLD_INFO                = 0x22
	LC_DYLD_INFO_ONLY           = 0x80000022
	LC_LOAD_UPWARD_DYLIB        = 0x80000023
	LC_VERSION_MIN_MACOSX       = 0x24
	LC_VERSION_MIN_IPHONEOS     = 0x25
	LC_FUNCTION_STARTS          = 0x26
	LC_DYLD_ENVIRONMENT         = 0x27
	LC_MAIN                     = 0x80000028
	LC_DATA_IN_CODE             = 0x29
	LC_SOURCE_VERSION           = 0x2A
	LC_DYLIB_CODE_SIGN_DRS      = 0x2B
	LC_ENCRYPTION_INFO_64       = 0x2C
	LC_LINKER_OPTION            = 0x2D
	LC_LINKER_OPTIMIZATION_HINT = 0x2E
	LC_VERSION_MIN_TVOS         = 0x2F
	LC_VERSION_MIN_WATCHOS      = 0x30
	LC_VERSION_NOTE             = 0x31
	LC_BUILD_VERSION            = 0x32
	LC_DYLD_EXPORTS_TRIE        = 0x80000033
	LC_DYLD_CHAINED_FIXUPS      = 0x80000034
)

const (
	S_REGULAR                  = 0x0
	S_ZEROFILL                 = 0x1
	S_NON_LAZY_SYMBOL_POINTERS = 0x6
	S_SYMBOL_STUBS             = 0x8
	S_MOD_INIT_FUNC_POINTERS   = 0x9
	S_ATTR_PURE_INSTRUCTIONS   = 0x80000000
	S_ATTR_DEBUG               = 0x02000000
	S_ATTR_SOME_INSTRUCTIONS   = 0x00000400
)

const (
	PLATFORM_MACOS    MachoPlatform = 1
	PLATFORM_IOS      MachoPlatform = 2
	PLATFORM_TVOS     MachoPlatform = 3
	PLATFORM_WATCHOS  MachoPlatform = 4
	PLATFORM_BRIDGEOS MachoPlatform = 5
)

// rebase table opcode
const (
	REBASE_TYPE_POINTER         = 1
	REBASE_TYPE_TEXT_ABSOLUTE32 = 2
	REBASE_TYPE_TEXT_PCREL32    = 3

	REBASE_OPCODE_MASK                               = 0xF0
	REBASE_IMMEDIATE_MASK                            = 0x0F
	REBASE_OPCODE_DONE                               = 0x00
	REBASE_OPCODE_SET_TYPE_IMM                       = 0x10
	REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB        = 0x20
	REBASE_OPCODE_ADD_ADDR_ULEB                      = 0x30
	REBASE_OPCODE_ADD_ADDR_IMM_SCALED                = 0x40
	REBASE_OPCODE_DO_REBASE_IMM_TIMES                = 0x50
	REBASE_OPCODE_DO_REBASE_ULEB_TIMES               = 0x60
	REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB            = 0x70
	REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB = 0x80
)

// bind table opcode
const (
	BIND_TYPE_POINTER         = 1
	BIND_TYPE_TEXT_ABSOLUTE32 = 2
	BIND_TYPE_TEXT_PCREL32    = 3

	BIND_SPECIAL_DYLIB_SELF            = 0
	BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1
	BIND_SPECIAL_DYLIB_FLAT_LOOKUP     = -2
	BIND_SPECIAL_DYLIB_WEAK_LOOKUP     = -3

	BIND_OPCODE_MASK                                         = 0xF0
	BIND_IMMEDIATE_MASK                                      = 0x0F
	BIND_OPCODE_DONE                                         = 0x00
	BIND_OPCODE_SET_DYLIB_ORDINAL_IMM                        = 0x10
	BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB                       = 0x20
	BIND_OPCODE_SET_DYLIB_SPECIAL_IMM                        = 0x30
	BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM                = 0x40
	BIND_OPCODE_SET_TYPE_IMM                                 = 0x50
	BIND_OPCODE_SET_ADDEND_SLEB                              = 0x60
	BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB                  = 0x70
	BIND_OPCODE_ADD_ADDR_ULEB                                = 0x80
	BIND_OPCODE_DO_BIND                                      = 0x90
	BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB                        = 0xA0
	BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED                  = 0xB0
	BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB             = 0xC0
	BIND_OPCODE_THREADED                                     = 0xD0
	BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB = 0x00
	BIND_SUBOPCODE_THREADED_APPLY                            = 0x01
)

const machoHeaderSize64 = 8 * 4 // size of 64-bit Mach-O header

// Mach-O file writing
// https://developer.apple.com/mac/library/DOCUMENTATION/DeveloperTools/Conceptual/MachORuntime/Reference/reference.html

var machohdr MachoHdr

var load []MachoLoad

var machoPlatform MachoPlatform

var seg [16]MachoSeg

var nseg int

var ndebug int

var nsect int

const (
	SymKindLocal = 0 + iota
	SymKindExtdef
	SymKindUndef
	NumSymKind
)

var nkind [NumSymKind]int

var sortsym []loader.Sym

var nsortsym int

// Amount of space left for adding load commands
// that refer to dynamic libraries. Because these have
// to go in the Mach-O header, we can't just pick a
// "big enough" header size. The initial header is
// one page, the non-dynamic library stuff takes
// up about 1300 bytes; we overestimate that as 2k.
var loadBudget = INITIAL_MACHO_HEADR - 2*1024

func getMachoHdr() *MachoHdr {
	return &machohdr
}

func newMachoLoad(arch *sys.Arch, type_ uint32, ndata uint32) *MachoLoad {
	if arch.PtrSize == 8 && (ndata&1 != 0) {
		ndata++
	}

	load = append(load, MachoLoad{})
	l := &load[len(load)-1]
	l.type_ = type_
	l.data = make([]uint32, ndata)
	return l
}

func newMachoSeg(name string, msect int) *MachoSeg {
	if nseg >= len(seg) {
		Exitf("too many segs")
	}

	s := &seg[nseg]
	nseg++
	s.name = name
	s.msect = uint32(msect)
	s.sect = make([]MachoSect, msect)
	return s
}

func newMachoSect(seg *MachoSeg, name string, segname string) *MachoSect {
	if seg.nsect >= seg.msect {
		Exitf("too many sects in segment %s", seg.name)
	}

	s := &seg.sect[seg.nsect]
	seg.nsect++
	s.name = name
	s.segname = segname
	nsect++
	return s
}

// Generic linking code.

var dylib []string

var linkoff int64

func machowrite(ctxt *Link, arch *sys.Arch, out *OutBuf, linkmode LinkMode) int {
	o1 := out.Offset()

	loadsize := 4 * 4 * ndebug
	for i := range load {
		loadsize += 4 * (len(load[i].data) + 2)
	}
	if arch.PtrSize == 8 {
		loadsize += 18 * 4 * nseg
		loadsize += 20 * 4 * nsect
	} else {
		loadsize += 14 * 4 * nseg
		loadsize += 17 * 4 * nsect
	}

	if arch.PtrSize == 8 {
		out.Write32(MH_MAGIC_64)
	} else {
		out.Write32(MH_MAGIC)
	}
	out.Write32(machohdr.cpu)
	out.Write32(machohdr.subcpu)
	if linkmode == LinkExternal {
		out.Write32(MH_OBJECT) /* file type - mach object */
	} else {
		out.Write32(MH_EXECUTE) /* file type - mach executable */
	}
	out.Write32(uint32(len(load)) + uint32(nseg) + uint32(ndebug))
	out.Write32(uint32(loadsize))
	flags := uint32(0)
	if nkind[SymKindUndef] == 0 {
		flags |= MH_NOUNDEFS
	}
	if ctxt.IsPIE() && linkmode == LinkInternal {
		flags |= MH_PIE | MH_DYLDLINK
	}
	out.Write32(flags) /* flags */
	if arch.PtrSize == 8 {
		out.Write32(0) /* reserved */
	}

	for i := 0; i < nseg; i++ {
		s := &seg[i]
		if arch.PtrSize == 8 {
			out.Write32(LC_SEGMENT_64)
			out.Write32(72 + 80*s.nsect)
			out.WriteStringN(s.name, 16)
			out.Write64(s.vaddr)
			out.Write64(s.vsize)
			out.Write64(s.fileoffset)
			out.Write64(s.filesize)
			out.Write32(s.prot1)
			out.Write32(s.prot2)
			out.Write32(s.nsect)
			out.Write32(s.flag)
		} else {
			out.Write32(LC_SEGMENT)
			out.Write32(56 + 68*s.nsect)
			out.WriteStringN(s.name, 16)
			out.Write32(uint32(s.vaddr))
			out.Write32(uint32(s.vsize))
			out.Write32(uint32(s.fileoffset))
			out.Write32(uint32(s.filesize))
			out.Write32(s.prot1)
			out.Write32(s.prot2)
			out.Write32(s.nsect)
			out.Write32(s.flag)
		}

		for j := uint32(0); j < s.nsect; j++ {
			t := &s.sect[j]
			if arch.PtrSize == 8 {
				out.WriteStringN(t.name, 16)
				out.WriteStringN(t.segname, 16)
				out.Write64(t.addr)
				out.Write64(t.size)
				out.Write32(t.off)
				out.Write32(t.align)
				out.Write32(t.reloc)
				out.Write32(t.nreloc)
				out.Write32(t.flag)
				out.Write32(t.res1) /* reserved */
				out.Write32(t.res2) /* reserved */
				out.Write32(0)      /* reserved */
			} else {
				out.WriteStringN(t.name, 16)
				out.WriteStringN(t.segname, 16)
				out.Write32(uint32(t.addr))
				out.Write32(uint32(t.size))
				out.Write32(t.off)
				out.Write32(t.align)
				out.Write32(t.reloc)
				out.Write32(t.nreloc)
				out.Write32(t.flag)
				out.Write32(t.res1) /* reserved */
				out.Write32(t.res2) /* reserved */
			}
		}
	}

	for i := range load {
		l := &load[i]
		out.Write32(l.type_)
		out.Write32(4 * (uint32(len(l.data)) + 2))
		for j := 0; j < len(l.data); j++ {
			out.Write32(l.data[j])
		}
	}

	return int(out.Offset() - o1)
}

func (ctxt *Link) domacho() {
	if *FlagD {
		return
	}

	// Copy platform load command.
	for _, h := range hostobj {
		load, err := hostobjMachoPlatform(&h)
		if err != nil {
			Exitf("%v", err)
		}
		if load != nil {
			machoPlatform = load.platform
			ml := newMachoLoad(ctxt.Arch, load.cmd.type_, uint32(len(load.cmd.data)))
			copy(ml.data, load.cmd.data)
			break
		}
	}
	if machoPlatform == 0 {
		machoPlatform = PLATFORM_MACOS
		if buildcfg.GOOS == "ios" {
			machoPlatform = PLATFORM_IOS
		}
		if ctxt.LinkMode == LinkInternal && machoPlatform == PLATFORM_MACOS {
			var version uint32
			switch ctxt.Arch.Family {
			case sys.AMD64:
				// This must be fairly recent for Apple signing (go.dev/issue/30488).
				// Having too old a version here was also implicated in some problems
				// calling into macOS libraries (go.dev/issue/56784).
				// In general this can be the most recent supported macOS version.
				version = 10<<16 | 13<<8 | 0<<0 // 10.13.0
			case sys.ARM64:
				version = 11<<16 | 0<<8 | 0<<0 // 11.0.0
			}
			ml := newMachoLoad(ctxt.Arch, LC_BUILD_VERSION, 4)
			ml.data[0] = uint32(machoPlatform)
			ml.data[1] = version // OS version
			ml.data[2] = version // SDK version
			ml.data[3] = 0       // ntools
		}
	}

	// empirically, string table must begin with " \x00".
	s := ctxt.loader.LookupOrCreateSym(".machosymstr", 0)
	sb := ctxt.loader.MakeSymbolUpdater(s)

	sb.SetType(sym.SMACHOSYMSTR)
	sb.SetReachable(true)
	sb.AddUint8(' ')
	sb.AddUint8('\x00')

	s = ctxt.loader.LookupOrCreateSym(".machosymtab", 0)
	sb = ctxt.loader.MakeSymbolUpdater(s)
	sb.SetType(sym.SMACHOSYMTAB)
	sb.SetReachable(true)

	if ctxt.IsInternal() {
		s = ctxt.loader.LookupOrCreateSym(".plt", 0) // will be __symbol_stub
		sb = ctxt.loader.MakeSymbolUpdater(s)
		sb.SetType(sym.SMACHOPLT)
		sb.SetReachable(true)

		s = ctxt.loader.LookupOrCreateSym(".got", 0) // will be __nl_symbol_ptr
		sb = ctxt.loader.MakeSymbolUpdater(s)
		sb.SetType(sym.SMACHOGOT)
		sb.SetReachable(true)
		sb.SetAlign(4)

		s = ctxt.loader.LookupOrCreateSym(".linkedit.plt", 0) // indirect table for .plt
		sb = ctxt.loader.MakeSymbolUpdater(s)
		sb.SetType(sym.SMACHOINDIRECTPLT)
		sb.SetReachable(true)

		s = ctxt.loader.LookupOrCreateSym(".linkedit.got", 0) // indirect table for .got
		sb = ctxt.loader.MakeSymbolUpdater(s)
		sb.SetType(sym.SMACHOINDIRECTGOT)
		sb.SetReachable(true)
	}

	// Add a dummy symbol that will become the __asm marker section.
	if ctxt.IsExternal() {
		s = ctxt.loader.LookupOrCreateSym(".llvmasm", 0)
		sb = ctxt.loader.MakeSymbolUpdater(s)
		sb.SetType(sym.SMACHO)
		sb.SetReachable(true)
		sb.AddUint8(0)
	}

	// Un-export runtime symbols from plugins. Since the runtime
	// is included in both the main binary and each plugin, these
	// symbols appear in both images. If we leave them exported in
	// the plugin, then the dynamic linker will resolve
	// relocations to these functions in the plugin's functab to
	// point to the main image, causing the runtime to think the
	// plugin's functab is corrupted. By unexporting them, these
	// become static references, which are resolved to the
	// plugin's text.
	//
	// It would be better to omit the runtime from plugins. (Using
	// relative PCs in the functab instead of relocations would
	// also address this.)
	//
	// See issue #18190.
	if ctxt.BuildMode == BuildModePlugin {
		for _, name := range []string{"_cgo_topofstack", "__cgo_topofstack", "_cgo_panic", "crosscall2"} {
			// Most of these are data symbols or C
			// symbols, so they have symbol version 0.
			ver := 0
			// _cgo_panic is a Go function, so it uses ABIInternal.
			if name == "_cgo_panic" {
				ver = abiInternalVer
			}
			s := ctxt.loader.Lookup(name, ver)
			if s != 0 {
				ctxt.loader.SetAttrCgoExportDynamic(s, false)
			}
		}
	}
}

func machoadddynlib(lib string, linkmode LinkMode) {
	if seenlib[lib] || linkmode == LinkExternal {
		return
	}
	seenlib[lib] = true

	// Will need to store the library name rounded up
	// and 24 bytes of header metadata. If not enough
	// space, grab another page of initial space at the
	// beginning of the output file.
	loadBudget -= (len(lib)+7)/8*8 + 24

	if loadBudget < 0 {
		HEADR += 4096
		*FlagTextAddr += 4096
		loadBudget += 4096
	}

	dylib = append(dylib, lib)
}

func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string) {
	buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)

	msect := newMachoSect(mseg, buf, segname)

	if sect.Rellen > 0 {
		msect.reloc = uint32(sect.Reloff)
		msect.nreloc = uint32(sect.Rellen / 8)
	}

	for 1<<msect.align < sect.Align {
		msect.align++
	}
	msect.addr = sect.Vaddr
	msect.size = sect.Length

	if sect.Vaddr < sect.Seg.Vaddr+sect.Seg.Filelen {
		// data in file
		if sect.Length > sect.Seg.Vaddr+sect.Seg.Filelen-sect.Vaddr {
			Errorf(nil, "macho cannot represent section %s crossing data and bss", sect.Name)
		}
		msect.off = uint32(sect.Seg.Fileoff + sect.Vaddr - sect.Seg.Vaddr)
	} else {
		msect.off = 0
		msect.flag |= S_ZEROFILL
	}

	if sect.Rwx&1 != 0 {
		msect.flag |= S_ATTR_SOME_INSTRUCTIONS
	}

	if sect.Name == ".text" {
		msect.flag |= S_ATTR_PURE_INSTRUCTIONS
	}

	if sect.Name == ".plt" {
		msect.name = "__symbol_stub1"
		msect.flag = S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS | S_SYMBOL_STUBS
		msect.res1 = 0 //nkind[SymKindLocal];
		msect.res2 = 6
	}

	if sect.Name == ".got" {
		msect.name = "__nl_symbol_ptr"
		msect.flag = S_NON_LAZY_SYMBOL_POINTERS
		msect.res1 = uint32(ctxt.loader.SymSize(ctxt.ArchSyms.LinkEditPLT) / 4) /* offset into indirect symbol table */
	}

	if sect.Name == ".init_array" {
		msect.name = "__mod_init_func"
		msect.flag = S_MOD_INIT_FUNC_POINTERS
	}

	// Some platforms such as watchOS and tvOS require binaries with
	// bitcode enabled. The Go toolchain can't output bitcode, so use
	// a marker section in the __LLVM segment, "__asm", to tell the Apple
	// toolchain that the Go text came from assembler and thus has no
	// bitcode. This is not true, but Kotlin/Native, Rust and Flutter
	// are also using this trick.
	if sect.Name == ".llvmasm" {
		msect.name = "__asm"
		msect.segname = "__LLVM"
	}

	if segname == "__DWARF" {
		msect.flag |= S_ATTR_DEBUG
	}
}

func asmbMacho(ctxt *Link) {
	machlink := doMachoLink(ctxt)
	if ctxt.IsExternal() {
		symo := int64(Segdwarf.Fileoff + uint64(Rnd(int64(Segdwarf.Filelen), *FlagRound)) + uint64(machlink))
		ctxt.Out.SeekSet(symo)
		machoEmitReloc(ctxt)
	}
	ctxt.Out.SeekSet(0)

	ldr := ctxt.loader

	/* apple MACH */
	va := *FlagTextAddr - int64(HEADR)

	mh := getMachoHdr()
	switch ctxt.Arch.Family {
	default:
		Exitf("unknown macho architecture: %v", ctxt.Arch.Family)

	case sys.AMD64:
		mh.cpu = MACHO_CPU_AMD64
		mh.subcpu = MACHO_SUBCPU_X86

	case sys.ARM64:
		mh.cpu = MACHO_CPU_ARM64
		mh.subcpu = MACHO_SUBCPU_ARM64_ALL
	}

	var ms *MachoSeg
	if ctxt.LinkMode == LinkExternal {
		/* segment for entire file */
		ms = newMachoSeg("", 40)

		ms.fileoffset = Segtext.Fileoff
		ms.filesize = Segdwarf.Fileoff + Segdwarf.Filelen - Segtext.Fileoff
		ms.vsize = Segdwarf.Vaddr + Segdwarf.Length - Segtext.Vaddr
	}

	/* segment for zero page */
	if ctxt.LinkMode != LinkExternal {
		ms = newMachoSeg("__PAGEZERO", 0)
		ms.vsize = uint64(va)
	}

	/* text */
	v := Rnd(int64(uint64(HEADR)+Segtext.Length), *FlagRound)

	var mstext *MachoSeg
	if ctxt.LinkMode != LinkExternal {
		ms = newMachoSeg("__TEXT", 20)
		ms.vaddr = uint64(va)
		ms.vsize = uint64(v)
		ms.fileoffset = 0
		ms.filesize = uint64(v)
		ms.prot1 = 7
		ms.prot2 = 5
		mstext = ms
	}

	for _, sect := range Segtext.Sections {
		machoshbits(ctxt, ms, sect, "__TEXT")
	}

	/* rodata */
	if ctxt.LinkMode != LinkExternal && Segrelrodata.Length > 0 {
		ms = newMachoSeg("__DATA_CONST", 20)
		ms.vaddr = Segrelrodata.Vaddr
		ms.vsize = Segrelrodata.Length
		ms.fileoffset = Segrelrodata.Fileoff
		ms.filesize = Segrelrodata.Filelen
		ms.prot1 = 3
		ms.prot2 = 3
		ms.flag = 0x10 // SG_READ_ONLY
	}

	for _, sect := range Segrelrodata.Sections {
		machoshbits(ctxt, ms, sect, "__DATA_CONST")
	}

	/* data */
	if ctxt.LinkMode != LinkExternal {
		ms = newMachoSeg("__DATA", 20)
		ms.vaddr = Segdata.Vaddr
		ms.vsize = Segdata.Length
		ms.fileoffset = Segdata.Fileoff
		ms.filesize = Segdata.Filelen
		ms.prot1 = 3
		ms.prot2 = 3
	}

	for _, sect := range Segdata.Sections {
		machoshbits(ctxt, ms, sect, "__DATA")
	}

	/* dwarf */
	if !*FlagW {
		if ctxt.LinkMode != LinkExternal {
			ms = newMachoSeg("__DWARF", 20)
			ms.vaddr = Segdwarf.Vaddr
			ms.vsize = 0
			ms.fileoffset = Segdwarf.Fileoff
			ms.filesize = Segdwarf.Filelen
		}
		for _, sect := range Segdwarf.Sections {
			machoshbits(ctxt, ms, sect, "__DWARF")
		}
	}

	if ctxt.LinkMode != LinkExternal {
		switch ctxt.Arch.Family {
		default:
			Exitf("unknown macho architecture: %v", ctxt.Arch.Family)

		case sys.AMD64:
			ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 42+2)
			ml.data[0] = 4                           /* thread type */
			ml.data[1] = 42                          /* word count */
			ml.data[2+32] = uint32(Entryvalue(ctxt)) /* start pc */
			ml.data[2+32+1] = uint32(Entryvalue(ctxt) >> 32)

		case sys.ARM64:
			ml := newMachoLoad(ctxt.Arch, LC_MAIN, 4)
			ml.data[0] = uint32(uint64(Entryvalue(ctxt)) - (Segtext.Vaddr - uint64(HEADR)))
			ml.data[1] = uint32((uint64(Entryvalue(ctxt)) - (Segtext.Vaddr - uint64(HEADR))) >> 32)
		}
	}

	var codesigOff int64
	if !*FlagD {
		// must match doMachoLink below
		s1 := ldr.SymSize(ldr.Lookup(".machorebase", 0))
		s2 := ldr.SymSize(ldr.Lookup(".machobind", 0))
		s3 := ldr.SymSize(ldr.Lookup(".machosymtab", 0))
		s4 := ldr.SymSize(ctxt.ArchSyms.LinkEditPLT)
		s5 := ldr.SymSize(ctxt.ArchSyms.LinkEditGOT)
		s6 := ldr.SymSize(ldr.Lookup(".machosymstr", 0))
		s7 := ldr.SymSize(ldr.Lookup(".machocodesig", 0))

		if ctxt.LinkMode != LinkExternal {
			ms := newMachoSeg("__LINKEDIT", 0)
			ms.vaddr = uint64(Rnd(int64(Segdata.Vaddr+Segdata.Length), *FlagRound))
			ms.vsize = uint64(s1 + s2 + s3 + s4 + s5 + s6 + s7)
			ms.fileoffset = uint64(linkoff)
			ms.filesize = ms.vsize
			ms.prot1 = 1
			ms.prot2 = 1

			codesigOff = linkoff + s1 + s2 + s3 + s4 + s5 + s6
		}

		if ctxt.LinkMode != LinkExternal && ctxt.IsPIE() {
			ml := newMachoLoad(ctxt.Arch, LC_DYLD_INFO_ONLY, 10)
			ml.data[0] = uint32(linkoff)      // rebase off
			ml.data[1] = uint32(s1)           // rebase size
			ml.data[2] = uint32(linkoff + s1) // bind off
			ml.data[3] = uint32(s2)           // bind size
			ml.data[4] = 0                    // weak bind off
			ml.data[5] = 0                    // weak bind size
			ml.data[6] = 0                    // lazy bind off
			ml.data[7] = 0                    // lazy bind size
			ml.data[8] = 0                    // export
			ml.data[9] = 0                    // export size
		}

		ml := newMachoLoad(ctxt.Arch, LC_SYMTAB, 4)
		ml.data[0] = uint32(linkoff + s1 + s2)                /* symoff */
		ml.data[1] = uint32(nsortsym)                         /* nsyms */
		ml.data[2] = uint32(linkoff + s1 + s2 + s3 + s4 + s5) /* stroff */
		ml.data[3] = uint32(s6)                               /* strsize */

		if ctxt.LinkMode != LinkExternal {
			machodysymtab(ctxt, linkoff+s1+s2)

			ml := newMachoLoad(ctxt.Arch, LC_LOAD_DYLINKER, 6)
			ml.data[0] = 12 /* offset to string */
			stringtouint32(ml.data[1:], "/usr/lib/dyld")

			for _, lib := range dylib {
				ml = newMachoLoad(ctxt.Arch, LC_LOAD_DYLIB, 4+(uint32(len(lib))+1+7)/8*2)
				ml.data[0] = 24 /* offset of string from beginning of load */
				ml.data[1] = 0  /* time stamp */
				ml.data[2] = 0  /* version */
				ml.data[3] = 0  /* compatibility version */
				stringtouint32(ml.data[4:], lib)
			}
		}

		if ctxt.IsInternal() && ctxt.NeedCodeSign() {
			ml := newMachoLoad(ctxt.Arch, LC_CODE_SIGNATURE, 2)
			ml.data[0] = uint32(codesigOff)
			ml.data[1] = uint32(s7)
		}
	}

	a := machowrite(ctxt, ctxt.Arch, ctxt.Out, ctxt.LinkMode)
	if int32(a) > HEADR {
		Exitf("HEADR too small: %d > %d", a, HEADR)
	}

	// Now we have written everything. Compute the code signature (which
	// is a hash of the file content, so it must be done at last.)
	if ctxt.IsInternal() && ctxt.NeedCodeSign() {
		cs := ldr.Lookup(".machocodesig", 0)
		data := ctxt.Out.Data()
		if int64(len(data)) != codesigOff {
			panic("wrong size")
		}
		codesign.Sign(ldr.Data(cs), bytes.NewReader(data), "a.out", codesigOff, int64(mstext.fileoffset), int64(mstext.filesize), ctxt.IsExe() || ctxt.IsPIE())
		ctxt.Out.SeekSet(codesigOff)
		ctxt.Out.Write(ldr.Data(cs))
	}
}

func symkind(ldr *loader.Loader, s loader.Sym) int {
	if t := ldr.SymType(s); t == sym.SDYNIMPORT || t == sym.SHOSTOBJ || t == sym.SUNDEFEXT {
		return SymKindUndef
	}
	if ldr.AttrCgoExport(s) {
		return SymKindExtdef
	}
	return SymKindLocal
}

func collectmachosyms(ctxt *Link) {
	ldr := ctxt.loader

	addsym := func(s loader.Sym) {
		sortsym = append(sortsym, s)
		nkind[symkind(ldr, s)]++
	}

	// On Mach-O, even with -s, we still need to keep dynamically exported and
	// referenced symbols. We can strip defined local text and data symbols.
	// So *FlagS is applied based on symbol type.

	// Add special runtime.text and runtime.etext symbols (which are local).
	// We've already included this symbol in Textp on darwin if ctxt.DynlinkingGo().
	// See data.go:/textaddress
	if !*FlagS {
		if !ctxt.DynlinkingGo() {
			s := ldr.Lookup("runtime.text", 0)
			if ldr.SymType(s) == sym.STEXT {
				addsym(s)
			}
			for n := range Segtext.Sections[1:] {
				s := ldr.Lookup(fmt.Sprintf("runtime.text.%d", n+1), 0)
				if s != 0 {
					addsym(s)
				} else {
					break
				}
			}
			s = ldr.Lookup("runtime.etext", 0)
			if ldr.SymType(s) == sym.STEXT {
				addsym(s)
			}
		}
	}

	// Add text symbols.
	for _, s := range ctxt.Textp {
		if *FlagS && !ldr.AttrCgoExportDynamic(s) {
			continue
		}
		addsym(s)
	}

	shouldBeInSymbolTable := func(s loader.Sym) bool {
		if ldr.AttrNotInSymbolTable(s) {
			return false
		}
		name := ldr.SymName(s) // TODO: try not to read the name
		if name == "" || name[0] == '.' {
			return false
		}
		return true
	}

	// Add data symbols and external references.
	for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
		if !ldr.AttrReachable(s) {
			continue
		}
		t := ldr.SymType(s)
		if t >= sym.SELFRXSECT && t < sym.SXREF { // data sections handled in dodata
			if t == sym.STLSBSS {
				// TLSBSS is not used on darwin. See data.go:allocateDataSections
				continue
			}
			if !shouldBeInSymbolTable(s) {
				continue
			}
			if *FlagS && !ldr.AttrCgoExportDynamic(s) {
				continue
			}
			addsym(s)
			continue
		}

		switch t {
		case sym.SDYNIMPORT, sym.SHOSTOBJ, sym.SUNDEFEXT:
			// Keep dynamic symbol references even if *FlagS.
			addsym(s)
		}

		// Some 64-bit functions have a "$INODE64" or "$INODE64$UNIX2003" suffix.
		if t == sym.SDYNIMPORT && ldr.SymDynimplib(s) == "/usr/lib/libSystem.B.dylib" {
			// But only on macOS.
			if machoPlatform == PLATFORM_MACOS {
				switch n := ldr.SymExtname(s); n {
				case "fdopendir":
					switch buildcfg.GOARCH {
					case "amd64":
						ldr.SetSymExtname(s, n+"$INODE64")
					}
				case "readdir_r", "getfsstat":
					switch buildcfg.GOARCH {
					case "amd64":
						ldr.SetSymExtname(s, n+"$INODE64")
					}
				}
			}
		}
	}

	nsortsym = len(sortsym)
}

func machosymorder(ctxt *Link) {
	ldr := ctxt.loader

	// On Mac OS X Mountain Lion, we must sort exported symbols
	// So we sort them here and pre-allocate dynid for them
	// See https://golang.org/issue/4029
	for _, s := range ctxt.dynexp {
		if !ldr.AttrReachable(s) {
			panic("dynexp symbol is not reachable")
		}
	}
	collectmachosyms(ctxt)
	sort.Slice(sortsym[:nsortsym], func(i, j int) bool {
		s1 := sortsym[i]
		s2 := sortsym[j]
		k1 := symkind(ldr, s1)
		k2 := symkind(ldr, s2)
		if k1 != k2 {
			return k1 < k2
		}
		return ldr.SymExtname(s1) < ldr.SymExtname(s2) // Note: unnamed symbols are not added in collectmachosyms
	})
	for i, s := range sortsym {
		ldr.SetSymDynid(s, int32(i))
	}
}

// AddMachoSym adds s to Mach-O symbol table, used in GenSymLate.
// Currently only used on ARM64 when external linking.
func AddMachoSym(ldr *loader.Loader, s loader.Sym) {
	ldr.SetSymDynid(s, int32(nsortsym))
	sortsym = append(sortsym, s)
	nsortsym++
	nkind[symkind(ldr, s)]++
}

// machoShouldExport reports whether a symbol needs to be exported.
//
// When dynamically linking, all non-local variables and plugin-exported
// symbols need to be exported.
func machoShouldExport(ctxt *Link, ldr *loader.Loader, s loader.Sym) bool {
	if !ctxt.DynlinkingGo() || ldr.AttrLocal(s) {
		return false
	}
	if ctxt.BuildMode == BuildModePlugin && strings.HasPrefix(ldr.SymExtname(s), objabi.PathToPrefix(*flagPluginPath)) {
		return true
	}
	name := ldr.SymName(s)
	if strings.HasPrefix(name, "go:itab.") {
		return true
	}
	if strings.HasPrefix(name, "type:") && !strings.HasPrefix(name, "type:.") {
		// reduce runtime typemap pressure, but do not
		// export alg functions (type:.*), as these
		// appear in pclntable.
		return true
	}
	if strings.HasPrefix(name, "go:link.pkghash") {
		return true
	}
	return ldr.SymType(s) >= sym.SFirstWritable // only writable sections
}

func machosymtab(ctxt *Link) {
	ldr := ctxt.loader
	symtab := ldr.CreateSymForUpdate(".machosymtab", 0)
	symstr := ldr.CreateSymForUpdate(".machosymstr", 0)

	for _, s := range sortsym[:nsortsym] {
		symtab.AddUint32(ctxt.Arch, uint32(symstr.Size()))

		export := machoShouldExport(ctxt, ldr, s)

		// Prefix symbol names with "_" to match the system toolchain.
		// (We used to only prefix C symbols, which is all required for the build.
		// But some tools don't recognize Go symbols as symbols, so we prefix them
		// as well.)
		symstr.AddUint8('_')

		// replace "·" as ".", because DTrace cannot handle it.
		name := strings.Replace(ldr.SymExtname(s), "·", ".", -1)

		name = mangleABIName(ctxt, ldr, s, name)
		symstr.Addstring(name)

		if t := ldr.SymType(s); t == sym.SDYNIMPORT || t == sym.SHOSTOBJ || t == sym.SUNDEFEXT {
			symtab.AddUint8(0x01)                             // type N_EXT, external symbol
			symtab.AddUint8(0)                                // no section
			symtab.AddUint16(ctxt.Arch, 0)                    // desc
			symtab.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) // no value
		} else {
			if export || ldr.AttrCgoExportDynamic(s) {
				symtab.AddUint8(0x0f) // N_SECT | N_EXT
			} else if ldr.AttrCgoExportStatic(s) {
				// Only export statically, not dynamically. (N_PEXT is like hidden visibility)
				symtab.AddUint8(0x1f) // N_SECT | N_EXT | N_PEXT
			} else {
				symtab.AddUint8(0x0e) // N_SECT
			}
			o := s
			if outer := ldr.OuterSym(o); outer != 0 {
				o = outer
			}
			if ldr.SymSect(o) == nil {
				ldr.Errorf(s, "missing section for symbol")
				symtab.AddUint8(0)
			} else {
				symtab.AddUint8(uint8(ldr.SymSect(o).Extnum))
			}
			symtab.AddUint16(ctxt.Arch, 0) // desc
			symtab.AddUintXX(ctxt.Arch, uint64(ldr.SymAddr(s)), ctxt.Arch.PtrSize)
		}
	}
}

func machodysymtab(ctxt *Link, base int64) {
	ml := newMachoLoad(ctxt.Arch, LC_DYSYMTAB, 18)

	n := 0
	ml.data[0] = uint32(n)                   /* ilocalsym */
	ml.data[1] = uint32(nkind[SymKindLocal]) /* nlocalsym */
	n += nkind[SymKindLocal]

	ml.data[2] = uint32(n)                    /* iextdefsym */
	ml.data[3] = uint32(nkind[SymKindExtdef]) /* nextdefsym */
	n += nkind[SymKindExtdef]

	ml.data[4] = uint32(n)                   /* iundefsym */
	ml.data[5] = uint32(nkind[SymKindUndef]) /* nundefsym */

	ml.data[6] = 0  /* tocoffset */
	ml.data[7] = 0  /* ntoc */
	ml.data[8] = 0  /* modtaboff */
	ml.data[9] = 0  /* nmodtab */
	ml.data[10] = 0 /* extrefsymoff */
	ml.data[11] = 0 /* nextrefsyms */

	ldr := ctxt.loader

	// must match domacholink below
	s1 := ldr.SymSize(ldr.Lookup(".machosymtab", 0))
	s2 := ldr.SymSize(ctxt.ArchSyms.LinkEditPLT)
	s3 := ldr.SymSize(ctxt.ArchSyms.LinkEditGOT)
	ml.data[12] = uint32(base + s1)     /* indirectsymoff */
	ml.data[13] = uint32((s2 + s3) / 4) /* nindirectsyms */

	ml.data[14] = 0 /* extreloff */
	ml.data[15] = 0 /* nextrel */
	ml.data[16] = 0 /* locreloff */
	ml.data[17] = 0 /* nlocrel */
}

func doMachoLink(ctxt *Link) int64 {
	machosymtab(ctxt)
	machoDyldInfo(ctxt)

	ldr := ctxt.loader

	// write data that will be linkedit section
	s1 := ldr.Lookup(".machorebase", 0)
	s2 := ldr.Lookup(".machobind", 0)
	s3 := ldr.Lookup(".machosymtab", 0)
	s4 := ctxt.ArchSyms.LinkEditPLT
	s5 := ctxt.ArchSyms.LinkEditGOT
	s6 := ldr.Lookup(".machosymstr", 0)

	size := ldr.SymSize(s1) + ldr.SymSize(s2) + ldr.SymSize(s3) + ldr.SymSize(s4) + ldr.SymSize(s5) + ldr.SymSize(s6)

	// Force the linkedit section to end on a 16-byte
	// boundary. This allows pure (non-cgo) Go binaries
	// to be code signed correctly.
	//
	// Apple's codesign_allocate (a helper utility for
	// the codesign utility) can do this fine itself if
	// it is run on a dynamic Mach-O binary. However,
	// when it is run on a pure (non-cgo) Go binary, where
	// the linkedit section is mostly empty, it fails to
	// account for the extra padding that it itself adds
	// when adding the LC_CODE_SIGNATURE load command
	// (which must be aligned on a 16-byte boundary).
	//
	// By forcing the linkedit section to end on a 16-byte
	// boundary, codesign_allocate will not need to apply
	// any alignment padding itself, working around the
	// issue.
	if size%16 != 0 {
		n := 16 - size%16
		s6b := ldr.MakeSymbolUpdater(s6)
		s6b.Grow(s6b.Size() + n)
		s6b.SetSize(s6b.Size() + n)
		size += n
	}

	if size > 0 {
		linkoff = Rnd(int64(uint64(HEADR)+Segtext.Length), *FlagRound) + Rnd(int64(Segrelrodata.Filelen), *FlagRound) + Rnd(int64(Segdata.Filelen), *FlagRound) + Rnd(int64(Segdwarf.Filelen), *FlagRound)
		ctxt.Out.SeekSet(linkoff)

		ctxt.Out.Write(ldr.Data(s1))
		ctxt.Out.Write(ldr.Data(s2))
		ctxt.Out.Write(ldr.Data(s3))
		ctxt.Out.Write(ldr.Data(s4))
		ctxt.Out.Write(ldr.Data(s5))
		ctxt.Out.Write(ldr.Data(s6))

		// Add code signature if necessary. This must be the last.
		s7 := machoCodeSigSym(ctxt, linkoff+size)
		size += ldr.SymSize(s7)
	}

	return Rnd(size, *FlagRound)
}

func machorelocsect(ctxt *Link, out *OutBuf, sect *sym.Section, syms []loader.Sym) {
	// If main section has no bits, nothing to relocate.
	if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
		return
	}
	ldr := ctxt.loader

	for i, s := range syms {
		if !ldr.AttrReachable(s) {
			continue
		}
		if uint64(ldr.SymValue(s)) >= sect.Vaddr {
			syms = syms[i:]
			break
		}
	}

	eaddr := sect.Vaddr + sect.Length
	for _, s := range syms {
		if !ldr.AttrReachable(s) {
			continue
		}
		if ldr.SymValue(s) >= int64(eaddr) {
			break
		}

		// Compute external relocations on the go, and pass to Machoreloc1
		// to stream out.
		relocs := ldr.Relocs(s)
		for ri := 0; ri < relocs.Count(); ri++ {
			r := relocs.At(ri)
			rr, ok := extreloc(ctxt, ldr, s, r)
			if !ok {
				continue
			}
			if rr.Xsym == 0 {
				ldr.Errorf(s, "missing xsym in relocation")
				continue
			}
			if !ldr.AttrReachable(rr.Xsym) {
				ldr.Errorf(s, "unreachable reloc %d (%s) target %v", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymName(rr.Xsym))
			}
			if !thearch.Machoreloc1(ctxt.Arch, out, ldr, s, rr, int64(uint64(ldr.SymValue(s)+int64(r.Off()))-sect.Vaddr)) {
				ldr.Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), r.Siz(), ldr.SymName(r.Sym()))
			}
		}
	}

	// sanity check
	if uint64(out.Offset()) != sect.Reloff+sect.Rellen {
		panic("machorelocsect: size mismatch")
	}
}

func machoEmitReloc(ctxt *Link) {
	for ctxt.Out.Offset()&7 != 0 {
		ctxt.Out.Write8(0)
	}

	sizeExtRelocs(ctxt, thearch.MachorelocSize)
	relocSect, wg := relocSectFn(ctxt, machorelocsect)

	relocSect(ctxt, Segtext.Sections[0], ctxt.Textp)
	for _, sect := range Segtext.Sections[1:] {
		if sect.Name == ".text" {
			relocSect(ctxt, sect, ctxt.Textp)
		} else {
			relocSect(ctxt, sect, ctxt.datap)
		}
	}
	for _, sect := range Segrelrodata.Sections {
		relocSect(ctxt, sect, ctxt.datap)
	}
	for _, sect := range Segdata.Sections {
		relocSect(ctxt, sect, ctxt.datap)
	}
	for i := 0; i < len(Segdwarf.Sections); i++ {
		sect := Segdwarf.Sections[i]
		si := dwarfp[i]
		if si.secSym() != loader.Sym(sect.Sym) ||
			ctxt.loader.SymSect(si.secSym()) != sect {
			panic("inconsistency between dwarfp and Segdwarf")
		}
		relocSect(ctxt, sect, si.syms)
	}
	wg.Wait()
}

// hostobjMachoPlatform returns the first platform load command found
// in the host object, if any.
func hostobjMachoPlatform(h *Hostobj) (*MachoPlatformLoad, error) {
	f, err := os.Open(h.file)
	if err != nil {
		return nil, fmt.Errorf("%s: failed to open host object: %v\n", h.file, err)
	}
	defer f.Close()
	sr := io.NewSectionReader(f, h.off, h.length)
	m, err := macho.NewFile(sr)
	if err != nil {
		// Not a valid Mach-O file.
		return nil, nil
	}
	return peekMachoPlatform(m)
}

// peekMachoPlatform returns the first LC_VERSION_MIN_* or LC_BUILD_VERSION
// load command found in the Mach-O file, if any.
func peekMachoPlatform(m *macho.File) (*MachoPlatformLoad, error) {
	for _, cmd := range m.Loads {
		raw := cmd.Raw()
		ml := MachoLoad{
			type_: m.ByteOrder.Uint32(raw),
		}
		// Skip the type and command length.
		data := raw[8:]
		var p MachoPlatform
		switch ml.type_ {
		case LC_VERSION_MIN_IPHONEOS:
			p = PLATFORM_IOS
		case LC_VERSION_MIN_MACOSX:
			p = PLATFORM_MACOS
		case LC_VERSION_MIN_WATCHOS:
			p = PLATFORM_WATCHOS
		case LC_VERSION_MIN_TVOS:
			p = PLATFORM_TVOS
		case LC_BUILD_VERSION:
			p = MachoPlatform(m.ByteOrder.Uint32(data))
		default:
			continue
		}
		ml.data = make([]uint32, len(data)/4)
		r := bytes.NewReader(data)
		if err := binary.Read(r, m.ByteOrder, &ml.data); err != nil {
			return nil, err
		}
		return &MachoPlatformLoad{
			platform: p,
			cmd:      ml,
		}, nil
	}
	return nil, nil
}

// A rebase entry tells the dynamic linker the data at sym+off needs to be
// relocated when the in-memory image moves. (This is somewhat like, say,
// ELF R_X86_64_RELATIVE).
// For now, the only kind of entry we support is that the data is an absolute
// address. That seems all we need.
// In the binary it uses a compact stateful bytecode encoding. So we record
// entries as we go and build the table at the end.
type machoRebaseRecord struct {
	sym loader.Sym
	off int64
}

var machorebase []machoRebaseRecord

func MachoAddRebase(s loader.Sym, off int64) {
	machorebase = append(machorebase, machoRebaseRecord{s, off})
}

// A bind entry tells the dynamic linker the data at GOT+off should be bound
// to the address of the target symbol, which is a dynamic import.
// For now, the only kind of entry we support is that the data is an absolute
// address, and the source symbol is always the GOT. That seems all we need.
// In the binary it uses a compact stateful bytecode encoding. So we record
// entries as we go and build the table at the end.
type machoBindRecord struct {
	off  int64
	targ loader.Sym
}

var machobind []machoBindRecord

func MachoAddBind(off int64, targ loader.Sym) {
	machobind = append(machobind, machoBindRecord{off, targ})
}

// Generate data for the dynamic linker, used in LC_DYLD_INFO_ONLY load command.
// See mach-o/loader.h, struct dyld_info_command, for the encoding.
// e.g. https://opensource.apple.com/source/xnu/xnu-6153.81.5/EXTERNAL_HEADERS/mach-o/loader.h
func machoDyldInfo(ctxt *Link) {
	ldr := ctxt.loader
	rebase := ldr.CreateSymForUpdate(".machorebase", 0)
	bind := ldr.CreateSymForUpdate(".machobind", 0)

	if !(ctxt.IsPIE() && ctxt.IsInternal()) {
		return
	}

	segId := func(seg *sym.Segment) uint8 {
		switch seg {
		case &Segtext:
			return 1
		case &Segrelrodata:
			return 2
		case &Segdata:
			if Segrelrodata.Length > 0 {
				return 3
			}
			return 2
		}
		panic("unknown segment")
	}

	dylibId := func(s loader.Sym) int {
		slib := ldr.SymDynimplib(s)
		for i, lib := range dylib {
			if lib == slib {
				return i + 1
			}
		}
		return BIND_SPECIAL_DYLIB_FLAT_LOOKUP // don't know where it is from
	}

	// Rebase table.
	// TODO: use more compact encoding. The encoding is stateful, and
	// we can use delta encoding.
	rebase.AddUint8(REBASE_OPCODE_SET_TYPE_IMM | REBASE_TYPE_POINTER)
	for _, r := range machorebase {
		seg := ldr.SymSect(r.sym).Seg
		off := uint64(ldr.SymValue(r.sym)+r.off) - seg.Vaddr
		rebase.AddUint8(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | segId(seg))
		rebase.AddUleb(off)

		rebase.AddUint8(REBASE_OPCODE_DO_REBASE_IMM_TIMES | 1)
	}
	rebase.AddUint8(REBASE_OPCODE_DONE)
	sz := Rnd(rebase.Size(), 8)
	rebase.Grow(sz)
	rebase.SetSize(sz)

	// Bind table.
	// TODO: compact encoding, as above.
	// TODO: lazy binding?
	got := ctxt.GOT
	seg := ldr.SymSect(got).Seg
	gotAddr := ldr.SymValue(got)
	bind.AddUint8(BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER)
	for _, r := range machobind {
		off := uint64(gotAddr+r.off) - seg.Vaddr
		bind.AddUint8(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | segId(seg))
		bind.AddUleb(off)

		d := dylibId(r.targ)
		if d > 0 && d < 128 {
			bind.AddUint8(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | uint8(d)&0xf)
		} else if d >= 128 {
			bind.AddUint8(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB)
			bind.AddUleb(uint64(d))
		} else { // d <= 0
			bind.AddUint8(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | uint8(d)&0xf)
		}

		bind.AddUint8(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM)
		// target symbol name as a C string, with _ prefix
		bind.AddUint8('_')
		bind.Addstring(ldr.SymExtname(r.targ))

		bind.AddUint8(BIND_OPCODE_DO_BIND)
	}
	bind.AddUint8(BIND_OPCODE_DONE)
	sz = Rnd(bind.Size(), 16) // make it 16-byte aligned, see the comment in doMachoLink
	bind.Grow(sz)
	bind.SetSize(sz)

	// TODO: export table.
	// The symbols names are encoded as a trie. I'm really too lazy to do that
	// for now.
	// Without it, the symbols are not dynamically exported, so they cannot be
	// e.g. dlsym'd. But internal linking is not the default in that case, so
	// it is fine.
}

// machoCodeSigSym creates and returns a symbol for code signature.
// The symbol context is left as zeros, which will be generated at the end
// (as it depends on the rest of the file).
func machoCodeSigSym(ctxt *Link, codeSize int64) loader.Sym {
	ldr := ctxt.loader
	cs := ldr.CreateSymForUpdate(".machocodesig", 0)
	if !ctxt.NeedCodeSign() || ctxt.IsExternal() {
		return cs.Sym()
	}
	sz := codesign.Size(codeSize, "a.out")
	cs.Grow(sz)
	cs.SetSize(sz)
	return cs.Sym()
}

// machoCodeSign code-signs Mach-O file fname with an ad-hoc signature.
// This is used for updating an external linker generated binary.
func machoCodeSign(ctxt *Link, fname string) error {
	f, err := os.OpenFile(fname, os.O_RDWR, 0)
	if err != nil {
		return err
	}
	defer f.Close()

	mf, err := macho.NewFile(f)
	if err != nil {
		return err
	}
	if mf.Magic != macho.Magic64 {
		Exitf("not 64-bit Mach-O file: %s", fname)
	}

	// Find existing LC_CODE_SIGNATURE and __LINKEDIT segment
	var sigOff, sigSz, csCmdOff, linkeditOff int64
	var linkeditSeg, textSeg *macho.Segment
	loadOff := int64(machoHeaderSize64)
	get32 := mf.ByteOrder.Uint32
	for _, l := range mf.Loads {
		data := l.Raw()
		cmd, sz := get32(data), get32(data[4:])
		if cmd == LC_CODE_SIGNATURE {
			sigOff = int64(get32(data[8:]))
			sigSz = int64(get32(data[12:]))
			csCmdOff = loadOff
		}
		if seg, ok := l.(*macho.Segment); ok {
			switch seg.Name {
			case "__LINKEDIT":
				linkeditSeg = seg
				linkeditOff = loadOff
			case "__TEXT":
				textSeg = seg
			}
		}
		loadOff += int64(sz)
	}

	if sigOff == 0 {
		// The C linker doesn't generate a signed binary, for some reason.
		// Skip.
		return nil
	}

	fi, err := f.Stat()
	if err != nil {
		return err
	}
	if sigOff+sigSz != fi.Size() {
		// We don't expect anything after the signature (this will invalidate
		// the signature anyway.)
		return fmt.Errorf("unexpected content after code signature")
	}

	sz := codesign.Size(sigOff, "a.out")
	if sz != sigSz {
		// Update the load command,
		var tmp [8]byte
		mf.ByteOrder.PutUint32(tmp[:4], uint32(sz))
		_, err = f.WriteAt(tmp[:4], csCmdOff+12)
		if err != nil {
			return err
		}

		// Uodate the __LINKEDIT segment.
		segSz := sigOff + sz - int64(linkeditSeg.Offset)
		mf.ByteOrder.PutUint64(tmp[:8], uint64(segSz))
		_, err = f.WriteAt(tmp[:8], int64(linkeditOff)+int64(unsafe.Offsetof(macho.Segment64{}.Memsz)))
		if err != nil {
			return err
		}
		_, err = f.WriteAt(tmp[:8], int64(linkeditOff)+int64(unsafe.Offsetof(macho.Segment64{}.Filesz)))
		if err != nil {
			return err
		}
	}

	cs := make([]byte, sz)
	codesign.Sign(cs, f, "a.out", sigOff, int64(textSeg.Offset), int64(textSeg.Filesz), ctxt.IsExe() || ctxt.IsPIE())
	_, err = f.WriteAt(cs, sigOff)
	if err != nil {
		return err
	}
	err = f.Truncate(sigOff + sz)
	return err
}
