// 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/hash"
	imacho "cmd/internal/macho"
	"cmd/internal/objabi"
	"cmd/internal/sys"
	"cmd/link/internal/loader"
	"cmd/link/internal/sym"
	"debug/macho"
	"encoding/binary"
	"fmt"
	"internal/buildcfg"
	"io"
	"os"
	"sort"
	"strconv"
	"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_SUBTRACTOR         = 1
	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_POINTER_TO_GOT     = 7
	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 (
	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
	PLATFORM_MACCATALYST MachoPlatform = 6
)

// 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_SYMBOL_FLAGS_WEAK_IMPORT = 0x1

	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
}

// Create a new Mach-O load command. ndata is the number of 32-bit words for
// the data (not including the load command header).
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(imacho.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(imacho.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)
}

type macVersionFlag [3]byte

func (f *macVersionFlag) String() string {
	return fmt.Sprintf("%d.%d.%d", f[0], f[1], f[2])
}

func (f *macVersionFlag) Set(s string) error {
	var parsed macVersionFlag
	nums := strings.Split(s, ".")
	if len(nums) > 3 {
		goto Error
	}
	for i, num := range nums {
		n, err := strconv.Atoi(num)
		if err != nil || n < 0 || n > 0xFF {
			goto Error
		}
		parsed[i] = byte(n)
	}
	// success, now modify f
	*f = parsed
	return nil

Error:
	return fmt.Errorf("invalid version %q", s)
}

func (f *macVersionFlag) version() uint32 {
	return uint32(f[0])<<16 | uint32(f[1])<<8 | uint32(f[2])
}

var (
	// On advice from Apple engineers, we keep macOS set to the
	// oldest supported macOS version but keep macSDK to the newest
	// tested OS/SDK version. If these defaults are not good enough,
	// the -macos and -macsdk linker flags can override them.
	// For past problems involving these values, see
	//	go.dev/issue/30488
	//	go.dev/issue/56784
	//	go.dev/issue/77917
	macOS  = macVersionFlag{13, 0, 0}
	macSDK = macVersionFlag{26, 2, 0}
)

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 && load.platform != PLATFORM_MACOS {
			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 load == nil && machoPlatform == PLATFORM_MACOS {
			ml := newMachoLoad(ctxt.Arch, imacho.LC_BUILD_VERSION, 4)
			ml.data[0] = uint32(machoPlatform)
			ml.data[1] = macOS.version()
			ml.data[2] = macSDK.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 __got
		sb = ctxt.loader.MakeSymbolUpdater(s)
		if ctxt.UseRelro() {
			sb.SetType(sym.SMACHORELROSECT)
		} else {
			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.ReplaceAll(sect.Name[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("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 = "__got"
		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, imacho.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, imacho.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, imacho.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, imacho.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, imacho.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, imacho.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() && *flagHostBuildid != "none" {
			ml := newMachoLoad(ctxt.Arch, imacho.LC_UUID, 4)
			var uuid [16]byte
			if len(buildinfo) >= 16 {
				copy(uuid[:], buildinfo)
			} else {
				// Note: When setting macSDK to 26.2, dyld refuses to run any
				// binary without an LC_UUID, which makes bootstrap fail.
				// To work around that situation, if buildinfo is missing we
				// construct a hash of the binary written so far and use that.
				// Using -B none will bypass this if desired,
				// but the resulting binary may not be runnable.
				copy(uuid[:], uuidFromHash(hash.Sum32(ctxt.Out.Data())))
			}
			ml.data[0] = ctxt.Arch.ByteOrder.Uint32(uuid[0:])
			ml.data[1] = ctxt.Arch.ByteOrder.Uint32(uuid[4:])
			ml.data[2] = ctxt.Arch.ByteOrder.Uint32(uuid[8:])
			ml.data[3] = ctxt.Arch.ByteOrder.Uint32(uuid[12:])
		}

		if ctxt.IsInternal() && ctxt.NeedCodeSign() {
			ml := newMachoLoad(ctxt.Arch, imacho.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.NewBuffer(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
	// NOTE: runtime.text.N symbols (if we split text sections) are not added, though,
	// so we handle them here.
	if !*FlagS {
		if !ctxt.DynlinkingGo() {
			s := ldr.Lookup("runtime.text", 0)
			if ldr.SymType(s).IsText() {
				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
			}
		}
		if !ctxt.DynlinkingGo() {
			s := ldr.Lookup("runtime.etext", 0)
			if ldr.SymType(s).IsText() {
				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.SFirstUnallocated { // 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 || machoPlatform == PLATFORM_MACCATALYST {
				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.ReplaceAll(ldr.SymExtname(s), "·", ".")

		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, imacho.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() != 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 imacho.LC_VERSION_MIN_IPHONEOS:
			p = PLATFORM_IOS
		case imacho.LC_VERSION_MIN_MACOSX:
			p = PLATFORM_MACOS
		case imacho.LC_VERSION_MIN_WATCHOS:
			p = PLATFORM_WATCHOS
		case imacho.LC_VERSION_MIN_TVOS:
			p = PLATFORM_TVOS
		case imacho.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 sym+off should be bound
// to the address of the target symbol, which is a dynamic import.
// sym is the symbol containing the pointer (e.g. the GOT or a data symbol),
// off is the offset within that symbol, and targ is the dynamic import target.
// 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 machoBindRecord struct {
	sym  loader.Sym
	off  int64
	targ loader.Sym
}

var machobind []machoBindRecord

func MachoAddBind(sym loader.Sym, off int64, targ loader.Sym) {
	machobind = append(machobind, machoBindRecord{sym, 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?
	bind.AddUint8(BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER)
	for _, r := range machobind {
		seg := ldr.SymSect(r.sym).Seg
		off := uint64(ldr.SymValue(r.sym)+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)
		}

		flags := uint8(0)
		if ldr.SymWeakBinding(r.targ) {
			flags |= BIND_SYMBOL_FLAGS_WEAK_IMPORT
		}
		bind.AddUint8(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | flags)
		// 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 == imacho.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], linkeditOff+int64(unsafe.Offsetof(macho.Segment64{}.Memsz)))
		if err != nil {
			return err
		}
		_, err = f.WriteAt(tmp[:8], 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
}
