// 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 (
	"cmd/internal/obj"
	"cmd/internal/sys"
	"sort"
	"strings"
)

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
}

type MachoLoad struct {
	type_ uint32
	data  []uint32
}

/*
 * 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
	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_ADDEND      = 10
	MACHO_GENERIC_RELOC_VANILLA   = 0
	MACHO_FAKE_GOTPCREL           = 100
)

// 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.

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

var macho64 bool

var machohdr MachoHdr

var load []MachoLoad

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 []*Symbol

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 int = INITIAL_MACHO_HEADR - 2*1024

func Machoinit() {
	macho64 = SysArch.RegSize == 8
}

func getMachoHdr() *MachoHdr {
	return &machohdr
}

func newMachoLoad(type_ uint32, ndata uint32) *MachoLoad {
	if macho64 && (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() int {
	o1 := coutbuf.Offset()

	loadsize := 4 * 4 * ndebug
	for i := 0; i < len(load); i++ {
		loadsize += 4 * (len(load[i].data) + 2)
	}
	if macho64 {
		loadsize += 18 * 4 * nseg
		loadsize += 20 * 4 * nsect
	} else {
		loadsize += 14 * 4 * nseg
		loadsize += 17 * 4 * nsect
	}

	if macho64 {
		Thearch.Lput(0xfeedfacf)
	} else {
		Thearch.Lput(0xfeedface)
	}
	Thearch.Lput(machohdr.cpu)
	Thearch.Lput(machohdr.subcpu)
	if Linkmode == LinkExternal {
		Thearch.Lput(1) /* file type - mach object */
	} else {
		Thearch.Lput(2) /* file type - mach executable */
	}
	Thearch.Lput(uint32(len(load)) + uint32(nseg) + uint32(ndebug))
	Thearch.Lput(uint32(loadsize))
	Thearch.Lput(1) /* flags - no undefines */
	if macho64 {
		Thearch.Lput(0) /* reserved */
	}

	var j int
	var s *MachoSeg
	var t *MachoSect
	for i := 0; i < nseg; i++ {
		s = &seg[i]
		if macho64 {
			Thearch.Lput(25) /* segment 64 */
			Thearch.Lput(72 + 80*s.nsect)
			strnput(s.name, 16)
			Thearch.Vput(s.vaddr)
			Thearch.Vput(s.vsize)
			Thearch.Vput(s.fileoffset)
			Thearch.Vput(s.filesize)
			Thearch.Lput(s.prot1)
			Thearch.Lput(s.prot2)
			Thearch.Lput(s.nsect)
			Thearch.Lput(s.flag)
		} else {
			Thearch.Lput(1) /* segment 32 */
			Thearch.Lput(56 + 68*s.nsect)
			strnput(s.name, 16)
			Thearch.Lput(uint32(s.vaddr))
			Thearch.Lput(uint32(s.vsize))
			Thearch.Lput(uint32(s.fileoffset))
			Thearch.Lput(uint32(s.filesize))
			Thearch.Lput(s.prot1)
			Thearch.Lput(s.prot2)
			Thearch.Lput(s.nsect)
			Thearch.Lput(s.flag)
		}

		for j = 0; uint32(j) < s.nsect; j++ {
			t = &s.sect[j]
			if macho64 {
				strnput(t.name, 16)
				strnput(t.segname, 16)
				Thearch.Vput(t.addr)
				Thearch.Vput(t.size)
				Thearch.Lput(t.off)
				Thearch.Lput(t.align)
				Thearch.Lput(t.reloc)
				Thearch.Lput(t.nreloc)
				Thearch.Lput(t.flag)
				Thearch.Lput(t.res1) /* reserved */
				Thearch.Lput(t.res2) /* reserved */
				Thearch.Lput(0)      /* reserved */
			} else {
				strnput(t.name, 16)
				strnput(t.segname, 16)
				Thearch.Lput(uint32(t.addr))
				Thearch.Lput(uint32(t.size))
				Thearch.Lput(t.off)
				Thearch.Lput(t.align)
				Thearch.Lput(t.reloc)
				Thearch.Lput(t.nreloc)
				Thearch.Lput(t.flag)
				Thearch.Lput(t.res1) /* reserved */
				Thearch.Lput(t.res2) /* reserved */
			}
		}
	}

	var l *MachoLoad
	for i := 0; i < len(load); i++ {
		l = &load[i]
		Thearch.Lput(l.type_)
		Thearch.Lput(4 * (uint32(len(l.data)) + 2))
		for j = 0; j < len(l.data); j++ {
			Thearch.Lput(l.data[j])
		}
	}

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

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

	// empirically, string table must begin with " \x00".
	s := ctxt.Syms.Lookup(".machosymstr", 0)

	s.Type = obj.SMACHOSYMSTR
	s.Attr |= AttrReachable
	Adduint8(ctxt, s, ' ')
	Adduint8(ctxt, s, '\x00')

	s = ctxt.Syms.Lookup(".machosymtab", 0)
	s.Type = obj.SMACHOSYMTAB
	s.Attr |= AttrReachable

	if Linkmode != LinkExternal {
		s := ctxt.Syms.Lookup(".plt", 0) // will be __symbol_stub
		s.Type = obj.SMACHOPLT
		s.Attr |= AttrReachable

		s = ctxt.Syms.Lookup(".got", 0) // will be __nl_symbol_ptr
		s.Type = obj.SMACHOGOT
		s.Attr |= AttrReachable
		s.Align = 4

		s = ctxt.Syms.Lookup(".linkedit.plt", 0) // indirect table for .plt
		s.Type = obj.SMACHOINDIRECTPLT
		s.Attr |= AttrReachable

		s = ctxt.Syms.Lookup(".linkedit.got", 0) // indirect table for .got
		s.Type = obj.SMACHOINDIRECTGOT
		s.Attr |= AttrReachable
	}
}

func Machoadddynlib(lib string) {
	// 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 *Section, segname string) {
	buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)

	var msect *MachoSect
	if sect.Rwx&1 == 0 && segname != "__DWARF" && (SysArch.Family == sys.ARM64 ||
		(SysArch.Family == sys.AMD64 && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive || Buildmode == BuildmodePlugin)) ||
		(SysArch.Family == sys.ARM && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive || Buildmode == BuildmodePlugin))) {
		// Darwin external linker on arm64 and on amd64 and arm in c-shared/c-archive buildmode
		// complains about absolute relocs in __TEXT, so if the section is not
		// executable, put it in __DATA segment.
		msect = newMachoSect(mseg, buf, "__DATA")
	} else {
		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 {
		// zero fill
		msect.off = 0

		msect.flag |= 1
	}

	if sect.Rwx&1 != 0 {
		msect.flag |= 0x400 /* has instructions */
	}

	if sect.Name == ".plt" {
		msect.name = "__symbol_stub1"
		msect.flag = 0x80000408 /* only instructions, code, symbol stubs */
		msect.res1 = 0          //nkind[SymKindLocal];
		msect.res2 = 6
	}

	if sect.Name == ".got" {
		msect.name = "__nl_symbol_ptr"
		msect.flag = 6                                                     /* section with nonlazy symbol pointers */
		msect.res1 = uint32(ctxt.Syms.Lookup(".linkedit.plt", 0).Size / 4) /* offset into indirect symbol table */
	}

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

	if segname == "__DWARF" {
		msect.flag |= 0x02000000
	}
}

func Asmbmacho(ctxt *Link) {
	/* apple MACH */
	va := *FlagTextAddr - int64(HEADR)

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

	case sys.ARM:
		mh.cpu = MACHO_CPU_ARM
		mh.subcpu = MACHO_SUBCPU_ARMV7

	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

	case sys.I386:
		mh.cpu = MACHO_CPU_386
		mh.subcpu = MACHO_SUBCPU_X86
	}

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

		ms.fileoffset = Segtext.Fileoff
		if SysArch.Family == sys.ARM || Buildmode == BuildmodeCArchive {
			ms.filesize = Segdata.Fileoff + Segdata.Filelen - Segtext.Fileoff
		} else {
			ms.filesize = Segdwarf.Fileoff + Segdwarf.Filelen - Segtext.Fileoff
			ms.vsize = ms.filesize
		}
	}

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

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

	if 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
	}

	for sect := Segtext.Sect; sect != nil; sect = sect.Next {
		machoshbits(ctxt, ms, sect, "__TEXT")
	}

	/* data */
	if Linkmode != LinkExternal {
		w := int64(Segdata.Length)
		ms = newMachoSeg("__DATA", 20)
		ms.vaddr = uint64(va) + uint64(v)
		ms.vsize = uint64(w)
		ms.fileoffset = uint64(v)
		ms.filesize = Segdata.Filelen
		ms.prot1 = 3
		ms.prot2 = 3
	}

	for sect := Segdata.Sect; sect != nil; sect = sect.Next {
		machoshbits(ctxt, ms, sect, "__DATA")
	}

	/* dwarf */
	if !*FlagW {
		if Linkmode != LinkExternal {
			ms = newMachoSeg("__DWARF", 20)
			ms.vaddr = Segdwarf.Vaddr
			ms.vsize = 0
			ms.fileoffset = Segdwarf.Fileoff
			ms.filesize = Segdwarf.Filelen
		}
		for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
			machoshbits(ctxt, ms, sect, "__DWARF")
		}
	}

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

		case sys.ARM:
			ml := newMachoLoad(5, 17+2)              /* unix thread */
			ml.data[0] = 1                           /* thread type */
			ml.data[1] = 17                          /* word count */
			ml.data[2+15] = uint32(Entryvalue(ctxt)) /* start pc */

		case sys.AMD64:
			ml := newMachoLoad(5, 42+2)              /* unix thread */
			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(5, 68+2)              /* unix thread */
			ml.data[0] = 6                           /* thread type */
			ml.data[1] = 68                          /* word count */
			ml.data[2+64] = uint32(Entryvalue(ctxt)) /* start pc */
			ml.data[2+64+1] = uint32(Entryvalue(ctxt) >> 32)

		case sys.I386:
			ml := newMachoLoad(5, 16+2)              /* unix thread */
			ml.data[0] = 1                           /* thread type */
			ml.data[1] = 16                          /* word count */
			ml.data[2+10] = uint32(Entryvalue(ctxt)) /* start pc */
		}
	}

	if !*FlagD {
		// must match domacholink below
		s1 := ctxt.Syms.Lookup(".machosymtab", 0)
		s2 := ctxt.Syms.Lookup(".linkedit.plt", 0)
		s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
		s4 := ctxt.Syms.Lookup(".machosymstr", 0)

		if Linkmode != LinkExternal {
			ms := newMachoSeg("__LINKEDIT", 0)
			ms.vaddr = uint64(va) + uint64(v) + uint64(Rnd(int64(Segdata.Length), int64(*FlagRound)))
			ms.vsize = uint64(s1.Size) + uint64(s2.Size) + uint64(s3.Size) + uint64(s4.Size)
			ms.fileoffset = uint64(linkoff)
			ms.filesize = ms.vsize
			ms.prot1 = 7
			ms.prot2 = 3
		}

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

		machodysymtab(ctxt)

		if Linkmode != LinkExternal {
			ml := newMachoLoad(14, 6) /* LC_LOAD_DYLINKER */
			ml.data[0] = 12           /* offset to string */
			stringtouint32(ml.data[1:], "/usr/lib/dyld")

			for i := 0; i < len(dylib); i++ {
				ml = newMachoLoad(12, 4+(uint32(len(dylib[i]))+1+7)/8*2) /* LC_LOAD_DYLIB */
				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:], dylib[i])
			}
		}
	}

	if Linkmode == LinkInternal {
		// For lldb, must say LC_VERSION_MIN_MACOSX or else
		// it won't know that this Mach-O binary is from OS X
		// (could be iOS or WatchOS instead).
		// Go on iOS uses linkmode=external, and linkmode=external
		// adds this itself. So we only need this code for linkmode=internal
		// and we can assume OS X.
		//
		// See golang.org/issues/12941.
		const LC_VERSION_MIN_MACOSX = 0x24

		ml := newMachoLoad(LC_VERSION_MIN_MACOSX, 2)
		ml.data[0] = 10<<16 | 7<<8 | 0<<0 // OS X version 10.7.0
		ml.data[1] = 10<<16 | 7<<8 | 0<<0 // SDK 10.7.0
	}

	a := machowrite()
	if int32(a) > HEADR {
		Exitf("HEADR too small: %d > %d", a, HEADR)
	}
}

func symkind(s *Symbol) int {
	if s.Type == obj.SDYNIMPORT {
		return SymKindUndef
	}
	if s.Attr.CgoExport() {
		return SymKindExtdef
	}
	return SymKindLocal
}

func addsym(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, gotype *Symbol) {
	if s == nil {
		return
	}

	switch type_ {
	default:
		return

	case DataSym, BSSSym, TextSym:
		break
	}

	if sortsym != nil {
		sortsym[nsortsym] = s
		nkind[symkind(s)]++
	}

	nsortsym++
}

type machoscmp []*Symbol

func (x machoscmp) Len() int {
	return len(x)
}

func (x machoscmp) Swap(i, j int) {
	x[i], x[j] = x[j], x[i]
}

func (x machoscmp) Less(i, j int) bool {
	s1 := x[i]
	s2 := x[j]

	k1 := symkind(s1)
	k2 := symkind(s2)
	if k1 != k2 {
		return k1 < k2
	}

	return s1.Extname < s2.Extname
}

func machogenasmsym(ctxt *Link) {
	genasmsym(ctxt, addsym)
	for _, s := range ctxt.Syms.Allsym {
		if s.Type == obj.SDYNIMPORT || s.Type == obj.SHOSTOBJ {
			if s.Attr.Reachable() {
				addsym(ctxt, s, "", DataSym, 0, nil)
			}
		}
	}
}

func machosymorder(ctxt *Link) {
	// 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 i := 0; i < len(dynexp); i++ {
		dynexp[i].Attr |= AttrReachable
	}
	machogenasmsym(ctxt)
	sortsym = make([]*Symbol, nsortsym)
	nsortsym = 0
	machogenasmsym(ctxt)
	sort.Sort(machoscmp(sortsym[:nsortsym]))
	for i := 0; i < nsortsym; i++ {
		sortsym[i].Dynid = int32(i)
	}
}

// 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, s *Symbol) bool {
	if !ctxt.DynlinkingGo() || s.Attr.Local() {
		return false
	}
	if Buildmode == BuildmodePlugin && strings.HasPrefix(s.Extname, *flagPluginPath) {
		return true
	}
	if strings.HasPrefix(s.Name, "type.") && !strings.HasPrefix(s.Name, "type..") {
		// reduce runtime typemap pressure, but do not
		// export alg functions (type..*), as these
		// appear in pclntable.
		return true
	}
	if strings.HasPrefix(s.Name, "go.link.pkghash") {
		return true
	}
	return s.Type >= obj.SELFSECT // only writable sections
}

func machosymtab(ctxt *Link) {
	symtab := ctxt.Syms.Lookup(".machosymtab", 0)
	symstr := ctxt.Syms.Lookup(".machosymstr", 0)

	for i := 0; i < nsortsym; i++ {
		s := sortsym[i]
		Adduint32(ctxt, symtab, uint32(symstr.Size))

		export := machoShouldExport(ctxt, s)

		// In normal buildmodes, only add _ to C symbols, as
		// Go symbols have dot in the name.
		//
		// Do not export C symbols in plugins, as runtime C
		// symbols like crosscall2 are in pclntab and end up
		// pointing at the host binary, breaking unwinding.
		// See Issue #18190.
		cexport := !strings.Contains(s.Extname, ".") && (Buildmode != BuildmodePlugin || onlycsymbol(s))
		if cexport || export {
			Adduint8(ctxt, symstr, '_')
		}

		// replace "·" as ".", because DTrace cannot handle it.
		Addstring(symstr, strings.Replace(s.Extname, "·", ".", -1))

		if s.Type == obj.SDYNIMPORT || s.Type == obj.SHOSTOBJ {
			Adduint8(ctxt, symtab, 0x01)                // type N_EXT, external symbol
			Adduint8(ctxt, symtab, 0)                   // no section
			Adduint16(ctxt, symtab, 0)                  // desc
			adduintxx(ctxt, symtab, 0, SysArch.PtrSize) // no value
		} else {
			if s.Attr.CgoExport() || export {
				Adduint8(ctxt, symtab, 0x0f)
			} else {
				Adduint8(ctxt, symtab, 0x0e)
			}
			o := s
			for o.Outer != nil {
				o = o.Outer
			}
			if o.Sect == nil {
				Errorf(s, "missing section for symbol")
				Adduint8(ctxt, symtab, 0)
			} else {
				Adduint8(ctxt, symtab, uint8(o.Sect.Extnum))
			}
			Adduint16(ctxt, symtab, 0) // desc
			adduintxx(ctxt, symtab, uint64(Symaddr(s)), SysArch.PtrSize)
		}
	}
}

func machodysymtab(ctxt *Link) {
	ml := newMachoLoad(11, 18) /* LC_DYSYMTAB */

	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 */

	// must match domacholink below
	s1 := ctxt.Syms.Lookup(".machosymtab", 0)

	s2 := ctxt.Syms.Lookup(".linkedit.plt", 0)
	s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
	ml.data[12] = uint32(linkoff + s1.Size)       /* indirectsymoff */
	ml.data[13] = uint32((s2.Size + s3.Size) / 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)

	// write data that will be linkedit section
	s1 := ctxt.Syms.Lookup(".machosymtab", 0)

	s2 := ctxt.Syms.Lookup(".linkedit.plt", 0)
	s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
	s4 := ctxt.Syms.Lookup(".machosymstr", 0)

	// 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.
	for s4.Size%16 != 0 {
		Adduint8(ctxt, s4, 0)
	}

	size := int(s1.Size + s2.Size + s3.Size + s4.Size)

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

		Cwrite(s1.P[:s1.Size])
		Cwrite(s2.P[:s2.Size])
		Cwrite(s3.P[:s3.Size])
		Cwrite(s4.P[:s4.Size])
	}

	return Rnd(int64(size), int64(*FlagRound))
}

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

	sect.Reloff = uint64(coutbuf.Offset())
	for i, s := range syms {
		if !s.Attr.Reachable() {
			continue
		}
		if uint64(s.Value) >= sect.Vaddr {
			syms = syms[i:]
			break
		}
	}

	eaddr := int32(sect.Vaddr + sect.Length)
	for _, sym := range syms {
		if !sym.Attr.Reachable() {
			continue
		}
		if sym.Value >= int64(eaddr) {
			break
		}
		for ri := 0; ri < len(sym.R); ri++ {
			r := &sym.R[ri]
			if r.Done != 0 {
				continue
			}
			if r.Xsym == nil {
				Errorf(sym, "missing xsym in relocation")
				continue
			}
			if !r.Xsym.Attr.Reachable() {
				Errorf(sym, "unreachable reloc %v target %v", r.Type, r.Xsym.Name)
			}
			if Thearch.Machoreloc1(sym, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) < 0 {
				Errorf(sym, "unsupported obj reloc %v/%d to %s", r.Type, r.Siz, r.Sym.Name)
			}
		}
	}

	sect.Rellen = uint64(coutbuf.Offset()) - sect.Reloff
}

func Machoemitreloc(ctxt *Link) {
	for coutbuf.Offset()&7 != 0 {
		Cput(0)
	}

	machorelocsect(ctxt, Segtext.Sect, ctxt.Textp)
	for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
		machorelocsect(ctxt, sect, datap)
	}
	for sect := Segdata.Sect; sect != nil; sect = sect.Next {
		machorelocsect(ctxt, sect, datap)
	}
	for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
		machorelocsect(ctxt, sect, dwarfp)
	}
}
