2015-02-27 22:57:28 -05:00
|
|
|
// 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 (
|
2016-04-06 12:01:40 -07:00
|
|
|
"cmd/internal/sys"
|
2015-02-27 22:57:28 -05:00
|
|
|
"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
|
2015-04-10 21:28:09 -04:00
|
|
|
MACHO_CPU_ARM64 = 1<<24 | 12
|
|
|
|
|
MACHO_SUBCPU_ARM64_ALL = 0
|
2015-02-27 22:57:28 -05:00
|
|
|
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
|
2016-04-26 15:17:56 -04:00
|
|
|
MACHO_ARM_RELOC_PAIR = 1
|
|
|
|
|
MACHO_ARM_RELOC_SECTDIFF = 2
|
2015-02-27 22:57:28 -05:00
|
|
|
MACHO_ARM_RELOC_BR24 = 5
|
2015-04-10 21:28:09 -04:00
|
|
|
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
|
2015-02-27 22:57:28 -05:00
|
|
|
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
|
|
|
|
|
|
2016-08-19 11:35:54 -04:00
|
|
|
var sortsym []*Symbol
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
var nsortsym int
|
|
|
|
|
|
|
|
|
|
// Amount of space left for adding load commands
|
2016-03-01 23:21:55 +00:00
|
|
|
// that refer to dynamic libraries. Because these have
|
2015-02-27 22:57:28 -05:00
|
|
|
// to go in the Mach-O header, we can't just pick a
|
2016-03-01 23:21:55 +00:00
|
|
|
// "big enough" header size. The initial header is
|
2015-02-27 22:57:28 -05:00
|
|
|
// one page, the non-dynamic library stuff takes
|
|
|
|
|
// up about 1300 bytes; we overestimate that as 2k.
|
2016-08-22 10:33:13 -04:00
|
|
|
var loadBudget int = INITIAL_MACHO_HEADR - 2*1024
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
func Machoinit() {
|
2016-04-06 12:01:40 -07:00
|
|
|
macho64 = SysArch.RegSize == 8
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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) {
|
2015-04-09 07:37:17 -04:00
|
|
|
Exitf("too many segs")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
s := &seg[nseg]
|
2015-02-27 22:57:28 -05:00
|
|
|
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 {
|
2015-04-09 07:37:17 -04:00
|
|
|
Exitf("too many sects in segment %s", seg.name)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
s := &seg.sect[seg.nsect]
|
2015-02-27 22:57:28 -05:00
|
|
|
seg.nsect++
|
|
|
|
|
s.name = name
|
|
|
|
|
s.segname = segname
|
|
|
|
|
nsect++
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Generic linking code.
|
|
|
|
|
|
|
|
|
|
var dylib []string
|
|
|
|
|
|
|
|
|
|
var linkoff int64
|
|
|
|
|
|
|
|
|
|
func machowrite() int {
|
2016-08-24 20:27:38 +10:00
|
|
|
o1 := coutbuf.Offset()
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
loadsize := 4 * 4 * ndebug
|
|
|
|
|
for i := 0; i < len(load); i++ {
|
2015-02-27 22:57:28 -05:00
|
|
|
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 */
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
var j int
|
|
|
|
|
var s *MachoSeg
|
|
|
|
|
var t *MachoSect
|
|
|
|
|
for i := 0; i < nseg; i++ {
|
2015-02-27 22:57:28 -05:00
|
|
|
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 */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
var l *MachoLoad
|
|
|
|
|
for i := 0; i < len(load); i++ {
|
2015-02-27 22:57:28 -05:00
|
|
|
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])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-24 20:27:38 +10:00
|
|
|
return int(coutbuf.Offset() - o1)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func (ctxt *Link) domacho() {
|
2016-08-21 18:34:24 -04:00
|
|
|
if *FlagD {
|
2015-02-27 22:57:28 -05:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// empirically, string table must begin with " \x00".
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s := ctxt.Syms.Lookup(".machosymstr", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SMACHOSYMSTR
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2016-08-19 22:40:38 -04:00
|
|
|
Adduint8(ctxt, s, ' ')
|
|
|
|
|
Adduint8(ctxt, s, '\x00')
|
2015-02-27 22:57:28 -05:00
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".machosymtab", 0)
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SMACHOSYMTAB
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
if Linkmode != LinkExternal {
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s := ctxt.Syms.Lookup(".plt", 0) // will be __symbol_stub
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SMACHOPLT
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2015-02-27 22:57:28 -05:00
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".got", 0) // will be __nl_symbol_ptr
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SMACHOGOT
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2015-02-27 22:57:28 -05:00
|
|
|
s.Align = 4
|
|
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".linkedit.plt", 0) // indirect table for .plt
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SMACHOINDIRECTPLT
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2015-02-27 22:57:28 -05:00
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s = ctxt.Syms.Lookup(".linkedit.got", 0) // indirect table for .got
|
2017-04-19 15:15:35 +12:00
|
|
|
s.Type = SMACHOINDIRECTGOT
|
2016-03-02 07:59:49 -05:00
|
|
|
s.Attr |= AttrReachable
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Machoadddynlib(lib string) {
|
|
|
|
|
// Will need to store the library name rounded up
|
2016-03-01 23:21:55 +00:00
|
|
|
// and 24 bytes of header metadata. If not enough
|
2015-02-27 22:57:28 -05:00
|
|
|
// space, grab another page of initial space at the
|
|
|
|
|
// beginning of the output file.
|
2016-08-22 10:33:13 -04:00
|
|
|
loadBudget -= (len(lib)+7)/8*8 + 24
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-08-22 10:33:13 -04:00
|
|
|
if loadBudget < 0 {
|
2015-02-27 22:57:28 -05:00
|
|
|
HEADR += 4096
|
2016-08-21 18:34:24 -04:00
|
|
|
*FlagTextAddr += 4096
|
2016-08-22 10:33:13 -04:00
|
|
|
loadBudget += 4096
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dylib = append(dylib, lib)
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func machoshbits(ctxt *Link, mseg *MachoSeg, sect *Section, segname string) {
|
2015-03-02 12:35:15 -05:00
|
|
|
buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2015-04-10 21:28:09 -04:00
|
|
|
var msect *MachoSect
|
2016-04-06 12:01:40 -07:00
|
|
|
if sect.Rwx&1 == 0 && segname != "__DWARF" && (SysArch.Family == sys.ARM64 ||
|
2016-09-19 14:13:07 -04:00
|
|
|
(SysArch.Family == sys.AMD64 && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive || Buildmode == BuildmodePlugin)) ||
|
|
|
|
|
(SysArch.Family == sys.ARM && (Buildmode == BuildmodeCShared || Buildmode == BuildmodeCArchive || Buildmode == BuildmodePlugin))) {
|
2016-04-26 15:17:56 -04:00
|
|
|
// Darwin external linker on arm64 and on amd64 and arm in c-shared/c-archive buildmode
|
2015-06-16 10:07:45 -07:00
|
|
|
// complains about absolute relocs in __TEXT, so if the section is not
|
|
|
|
|
// executable, put it in __DATA segment.
|
2015-04-10 21:28:09 -04:00
|
|
|
msect = newMachoSect(mseg, buf, "__DATA")
|
|
|
|
|
} else {
|
|
|
|
|
msect = newMachoSect(mseg, buf, segname)
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-27 22:57:28 -05:00
|
|
|
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 {
|
2016-09-17 09:39:33 -04:00
|
|
|
Errorf(nil, "macho cannot represent section %s crossing data and bss", sect.Name)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
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 */
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
msect.res1 = uint32(ctxt.Syms.Lookup(".linkedit.plt", 0).Size / 4) /* offset into indirect symbol table */
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2015-04-08 15:11:04 -04:00
|
|
|
|
|
|
|
|
if sect.Name == ".init_array" {
|
|
|
|
|
msect.name = "__mod_init_func"
|
|
|
|
|
msect.flag = 9 // S_MOD_INIT_FUNC_POINTERS
|
|
|
|
|
}
|
2016-03-14 09:23:04 -07:00
|
|
|
|
|
|
|
|
if segname == "__DWARF" {
|
|
|
|
|
msect.flag |= 0x02000000
|
|
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func Asmbmacho(ctxt *Link) {
|
2015-02-27 22:57:28 -05:00
|
|
|
/* apple MACH */
|
2016-08-21 18:34:24 -04:00
|
|
|
va := *FlagTextAddr - int64(HEADR)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
mh := getMachoHdr()
|
2016-04-06 12:01:40 -07:00
|
|
|
switch SysArch.Family {
|
2015-02-27 22:57:28 -05:00
|
|
|
default:
|
2016-04-06 12:01:40 -07:00
|
|
|
Exitf("unknown macho architecture: %v", SysArch.Family)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.ARM:
|
2015-02-27 22:57:28 -05:00
|
|
|
mh.cpu = MACHO_CPU_ARM
|
|
|
|
|
mh.subcpu = MACHO_SUBCPU_ARMV7
|
|
|
|
|
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.AMD64:
|
2015-02-27 22:57:28 -05:00
|
|
|
mh.cpu = MACHO_CPU_AMD64
|
|
|
|
|
mh.subcpu = MACHO_SUBCPU_X86
|
|
|
|
|
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.ARM64:
|
2015-04-10 21:28:09 -04:00
|
|
|
mh.cpu = MACHO_CPU_ARM64
|
|
|
|
|
mh.subcpu = MACHO_SUBCPU_ARM64_ALL
|
|
|
|
|
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.I386:
|
2015-02-27 22:57:28 -05:00
|
|
|
mh.cpu = MACHO_CPU_386
|
|
|
|
|
mh.subcpu = MACHO_SUBCPU_X86
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-02 14:22:05 -05:00
|
|
|
var ms *MachoSeg
|
2015-02-27 22:57:28 -05:00
|
|
|
if Linkmode == LinkExternal {
|
|
|
|
|
/* segment for entire file */
|
|
|
|
|
ms = newMachoSeg("", 40)
|
|
|
|
|
|
|
|
|
|
ms.fileoffset = Segtext.Fileoff
|
2016-04-06 12:01:40 -07:00
|
|
|
if SysArch.Family == sys.ARM || Buildmode == BuildmodeCArchive {
|
2015-06-22 19:59:59 -04:00
|
|
|
ms.filesize = Segdata.Fileoff + Segdata.Filelen - Segtext.Fileoff
|
|
|
|
|
} else {
|
|
|
|
|
ms.filesize = Segdwarf.Fileoff + Segdwarf.Filelen - Segtext.Fileoff
|
2017-03-29 20:50:34 -04:00
|
|
|
ms.vsize = Segdwarf.Vaddr + Segdwarf.Length - Segtext.Vaddr
|
2015-06-22 19:59:59 -04:00
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* segment for zero page */
|
|
|
|
|
if Linkmode != LinkExternal {
|
|
|
|
|
ms = newMachoSeg("__PAGEZERO", 0)
|
|
|
|
|
ms.vsize = uint64(va)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* text */
|
2016-08-21 18:34:24 -04:00
|
|
|
v := Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segtext.Sections {
|
2016-08-19 22:40:38 -04:00
|
|
|
machoshbits(ctxt, ms, sect, "__TEXT")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* data */
|
|
|
|
|
if Linkmode != LinkExternal {
|
2015-03-02 12:35:15 -05:00
|
|
|
w := int64(Segdata.Length)
|
2015-02-27 22:57:28 -05:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segdata.Sections {
|
2016-08-19 22:40:38 -04:00
|
|
|
machoshbits(ctxt, ms, sect, "__DATA")
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-03-14 09:23:04 -07:00
|
|
|
/* dwarf */
|
2016-08-21 18:34:24 -04:00
|
|
|
if !*FlagW {
|
2016-03-14 09:23:04 -07:00
|
|
|
if Linkmode != LinkExternal {
|
|
|
|
|
ms = newMachoSeg("__DWARF", 20)
|
|
|
|
|
ms.vaddr = Segdwarf.Vaddr
|
|
|
|
|
ms.vsize = 0
|
|
|
|
|
ms.fileoffset = Segdwarf.Fileoff
|
|
|
|
|
ms.filesize = Segdwarf.Filelen
|
|
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segdwarf.Sections {
|
2016-08-19 22:40:38 -04:00
|
|
|
machoshbits(ctxt, ms, sect, "__DWARF")
|
2016-03-14 09:23:04 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-27 22:57:28 -05:00
|
|
|
if Linkmode != LinkExternal {
|
2016-04-06 12:01:40 -07:00
|
|
|
switch SysArch.Family {
|
2015-02-27 22:57:28 -05:00
|
|
|
default:
|
2016-04-06 12:01:40 -07:00
|
|
|
Exitf("unknown macho architecture: %v", SysArch.Family)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.ARM:
|
2016-08-19 22:40:38 -04:00
|
|
|
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 */
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.AMD64:
|
2016-08-19 22:40:38 -04:00
|
|
|
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)
|
2015-04-10 21:28:09 -04:00
|
|
|
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.ARM64:
|
2016-08-19 22:40:38 -04:00
|
|
|
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)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-04-06 12:01:40 -07:00
|
|
|
case sys.I386:
|
2016-08-19 22:40:38 -04:00
|
|
|
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 */
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-21 18:34:24 -04:00
|
|
|
if !*FlagD {
|
2015-02-27 22:57:28 -05:00
|
|
|
// must match domacholink below
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
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)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
if Linkmode != LinkExternal {
|
2015-03-02 12:35:15 -05:00
|
|
|
ms := newMachoSeg("__LINKEDIT", 0)
|
2016-08-21 18:34:24 -04:00
|
|
|
ms.vaddr = uint64(va) + uint64(v) + uint64(Rnd(int64(Segdata.Length), int64(*FlagRound)))
|
2015-02-27 22:57:28 -05:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
ml := newMachoLoad(2, 4) /* LC_SYMTAB */
|
2015-02-27 22:57:28 -05:00
|
|
|
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 */
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
machodysymtab(ctxt)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
if Linkmode != LinkExternal {
|
2015-03-02 12:35:15 -05:00
|
|
|
ml := newMachoLoad(14, 6) /* LC_LOAD_DYLINKER */
|
|
|
|
|
ml.data[0] = 12 /* offset to string */
|
2015-02-27 22:57:28 -05:00
|
|
|
stringtouint32(ml.data[1:], "/usr/lib/dyld")
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
for i := 0; i < len(dylib); i++ {
|
2015-02-27 22:57:28 -05:00
|
|
|
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])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-13 09:59:16 -05:00
|
|
|
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
|
2016-02-24 11:55:20 +01:00
|
|
|
// (could be iOS or WatchOS instead).
|
2016-01-13 09:59:16 -05:00
|
|
|
// 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.
|
2016-04-09 15:04:45 +10:00
|
|
|
const LC_VERSION_MIN_MACOSX = 0x24
|
|
|
|
|
|
2016-01-13 09:59:16 -05:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
a := machowrite()
|
2015-02-27 22:57:28 -05:00
|
|
|
if int32(a) > HEADR {
|
2015-04-09 07:37:17 -04:00
|
|
|
Exitf("HEADR too small: %d > %d", a, HEADR)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-19 11:35:54 -04:00
|
|
|
func symkind(s *Symbol) int {
|
2017-04-19 15:15:35 +12:00
|
|
|
if s.Type == SDYNIMPORT {
|
2015-02-27 22:57:28 -05:00
|
|
|
return SymKindUndef
|
|
|
|
|
}
|
2016-03-02 07:59:49 -05:00
|
|
|
if s.Attr.CgoExport() {
|
2015-02-27 22:57:28 -05:00
|
|
|
return SymKindExtdef
|
|
|
|
|
}
|
|
|
|
|
return SymKindLocal
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-16 16:47:28 +12:00
|
|
|
func addsym(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, gotype *Symbol) {
|
2015-02-27 22:57:28 -05:00
|
|
|
if s == nil {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch type_ {
|
|
|
|
|
default:
|
|
|
|
|
return
|
|
|
|
|
|
2016-09-16 16:22:08 +12:00
|
|
|
case DataSym, BSSSym, TextSym:
|
2015-02-27 22:57:28 -05:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if sortsym != nil {
|
|
|
|
|
sortsym[nsortsym] = s
|
|
|
|
|
nkind[symkind(s)]++
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsortsym++
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-19 11:35:54 -04:00
|
|
|
type machoscmp []*Symbol
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
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 {
|
2015-03-02 12:35:15 -05:00
|
|
|
s1 := x[i]
|
|
|
|
|
s2 := x[j]
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
k1 := symkind(s1)
|
|
|
|
|
k2 := symkind(s2)
|
2015-02-27 22:57:28 -05:00
|
|
|
if k1 != k2 {
|
2015-09-24 16:01:50 +02:00
|
|
|
return k1 < k2
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2015-09-24 16:01:50 +02:00
|
|
|
return s1.Extname < s2.Extname
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-09-16 16:22:08 +12:00
|
|
|
func machogenasmsym(ctxt *Link) {
|
|
|
|
|
genasmsym(ctxt, addsym)
|
2016-09-20 14:59:39 +12:00
|
|
|
for _, s := range ctxt.Syms.Allsym {
|
2017-04-19 15:15:35 +12:00
|
|
|
if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
|
2016-03-02 07:59:49 -05:00
|
|
|
if s.Attr.Reachable() {
|
2016-09-16 16:47:28 +12:00
|
|
|
addsym(ctxt, s, "", DataSym, 0, nil)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func machosymorder(ctxt *Link) {
|
2015-02-27 22:57:28 -05:00
|
|
|
// On Mac OS X Mountain Lion, we must sort exported symbols
|
|
|
|
|
// So we sort them here and pre-allocate dynid for them
|
2015-07-10 17:17:11 -06:00
|
|
|
// See https://golang.org/issue/4029
|
2015-03-02 12:35:15 -05:00
|
|
|
for i := 0; i < len(dynexp); i++ {
|
2016-03-02 07:59:49 -05:00
|
|
|
dynexp[i].Attr |= AttrReachable
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-09-16 16:22:08 +12:00
|
|
|
machogenasmsym(ctxt)
|
2016-08-19 11:35:54 -04:00
|
|
|
sortsym = make([]*Symbol, nsortsym)
|
2015-02-27 22:57:28 -05:00
|
|
|
nsortsym = 0
|
2016-09-16 16:22:08 +12:00
|
|
|
machogenasmsym(ctxt)
|
2015-02-27 22:57:28 -05:00
|
|
|
sort.Sort(machoscmp(sortsym[:nsortsym]))
|
2015-03-02 12:35:15 -05:00
|
|
|
for i := 0; i < nsortsym; i++ {
|
2015-02-27 22:57:28 -05:00
|
|
|
sortsym[i].Dynid = int32(i)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-09 12:38:34 -05:00
|
|
|
// 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
|
|
|
|
|
}
|
2016-12-10 13:30:13 -05:00
|
|
|
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
|
|
|
|
|
}
|
2017-04-19 15:15:35 +12:00
|
|
|
return s.Type >= SELFSECT // only writable sections
|
2016-12-09 12:38:34 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func machosymtab(ctxt *Link) {
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
symtab := ctxt.Syms.Lookup(".machosymtab", 0)
|
|
|
|
|
symstr := ctxt.Syms.Lookup(".machosymstr", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
for i := 0; i < nsortsym; i++ {
|
2016-04-14 19:44:55 -07:00
|
|
|
s := sortsym[i]
|
2016-08-19 22:40:38 -04:00
|
|
|
Adduint32(ctxt, symtab, uint32(symstr.Size))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2016-12-09 12:38:34 -05:00
|
|
|
export := machoShouldExport(ctxt, s)
|
|
|
|
|
|
2016-09-19 14:13:07 -04:00
|
|
|
// In normal buildmodes, only add _ to C symbols, as
|
|
|
|
|
// Go symbols have dot in the name.
|
2016-12-10 13:30:13 -05:00
|
|
|
//
|
|
|
|
|
// 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 {
|
2016-08-19 22:40:38 -04:00
|
|
|
Adduint8(ctxt, symstr, '_')
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// replace "·" as ".", because DTrace cannot handle it.
|
2016-09-20 15:31:26 +12:00
|
|
|
Addstring(symstr, strings.Replace(s.Extname, "·", ".", -1))
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2017-04-19 15:15:35 +12:00
|
|
|
if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
|
2016-08-19 22:40:38 -04:00
|
|
|
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
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2016-12-09 12:38:34 -05:00
|
|
|
if s.Attr.CgoExport() || export {
|
2016-08-19 22:40:38 -04:00
|
|
|
Adduint8(ctxt, symtab, 0x0f)
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2016-08-19 22:40:38 -04:00
|
|
|
Adduint8(ctxt, symtab, 0x0e)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-04-14 19:44:55 -07:00
|
|
|
o := s
|
2015-02-27 22:57:28 -05:00
|
|
|
for o.Outer != nil {
|
|
|
|
|
o = o.Outer
|
|
|
|
|
}
|
|
|
|
|
if o.Sect == nil {
|
2016-09-17 09:39:33 -04:00
|
|
|
Errorf(s, "missing section for symbol")
|
2016-08-19 22:40:38 -04:00
|
|
|
Adduint8(ctxt, symtab, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
} else {
|
2016-08-19 22:40:38 -04:00
|
|
|
Adduint8(ctxt, symtab, uint8(o.Sect.Extnum))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2016-08-19 22:40:38 -04:00
|
|
|
Adduint16(ctxt, symtab, 0) // desc
|
2016-09-17 09:39:33 -04:00
|
|
|
adduintxx(ctxt, symtab, uint64(Symaddr(s)), SysArch.PtrSize)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func machodysymtab(ctxt *Link) {
|
2015-03-02 12:35:15 -05:00
|
|
|
ml := newMachoLoad(11, 18) /* LC_DYSYMTAB */
|
2015-02-27 22:57:28 -05:00
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
n := 0
|
2015-02-27 22:57:28 -05:00
|
|
|
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
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s1 := ctxt.Syms.Lookup(".machosymtab", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s2 := ctxt.Syms.Lookup(".linkedit.plt", 0)
|
|
|
|
|
s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
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 */
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func Domacholink(ctxt *Link) int64 {
|
|
|
|
|
machosymtab(ctxt)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// write data that will be linkedit section
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s1 := ctxt.Syms.Lookup(".machosymtab", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
cmd/link: use ctxt.{Lookup,ROLookup} in favour of function versions of same
Done with two eg templates:
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linklookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.Lookup(name, v)
}
package p
import (
"cmd/link/internal/ld"
)
func before(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ld.Linkrlookup(ctxt, name, v)
}
func after(ctxt *ld.Link, name string, v int) *ld.Symbol {
return ctxt.Syms.ROLookup(name, v)
}
Change-Id: I00647dbf62294557bd24c29ad1f108fc786335f1
Reviewed-on: https://go-review.googlesource.com/29343
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-20 15:06:08 +12:00
|
|
|
s2 := ctxt.Syms.Lookup(".linkedit.plt", 0)
|
|
|
|
|
s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
|
|
|
|
|
s4 := ctxt.Syms.Lookup(".machosymstr", 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
// Force the linkedit section to end on a 16-byte
|
2016-03-01 23:21:55 +00:00
|
|
|
// boundary. This allows pure (non-cgo) Go binaries
|
2015-02-27 22:57:28 -05:00
|
|
|
// to be code signed correctly.
|
|
|
|
|
//
|
|
|
|
|
// Apple's codesign_allocate (a helper utility for
|
|
|
|
|
// the codesign utility) can do this fine itself if
|
2016-03-01 23:21:55 +00:00
|
|
|
// it is run on a dynamic Mach-O binary. However,
|
2015-02-27 22:57:28 -05:00
|
|
|
// 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 {
|
2016-08-19 22:40:38 -04:00
|
|
|
Adduint8(ctxt, s4, 0)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
size := int(s1.Size + s2.Size + s3.Size + s4.Size)
|
2015-02-27 22:57:28 -05:00
|
|
|
|
|
|
|
|
if size > 0 {
|
2016-08-21 18:34:24 -04:00
|
|
|
linkoff = Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound)) + Rnd(int64(Segdata.Filelen), int64(*FlagRound)) + Rnd(int64(Segdwarf.Filelen), int64(*FlagRound))
|
2015-02-27 22:57:28 -05:00
|
|
|
Cseek(linkoff)
|
|
|
|
|
|
|
|
|
|
Cwrite(s1.P[:s1.Size])
|
|
|
|
|
Cwrite(s2.P[:s2.Size])
|
|
|
|
|
Cwrite(s3.P[:s3.Size])
|
|
|
|
|
Cwrite(s4.P[:s4.Size])
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-21 18:34:24 -04:00
|
|
|
return Rnd(int64(size), int64(*FlagRound))
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
|
2015-02-27 22:57:28 -05:00
|
|
|
// If main section has no bits, nothing to relocate.
|
|
|
|
|
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-24 20:27:38 +10:00
|
|
|
sect.Reloff = uint64(coutbuf.Offset())
|
2016-04-18 14:50:14 -04:00
|
|
|
for i, s := range syms {
|
|
|
|
|
if !s.Attr.Reachable() {
|
2015-02-27 22:57:28 -05:00
|
|
|
continue
|
|
|
|
|
}
|
2016-04-18 14:50:14 -04:00
|
|
|
if uint64(s.Value) >= sect.Vaddr {
|
|
|
|
|
syms = syms[i:]
|
2015-02-27 22:57:28 -05:00
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-02 12:35:15 -05:00
|
|
|
eaddr := int32(sect.Vaddr + sect.Length)
|
2016-04-18 14:50:14 -04:00
|
|
|
for _, sym := range syms {
|
2016-03-02 07:59:49 -05:00
|
|
|
if !sym.Attr.Reachable() {
|
2015-02-27 22:57:28 -05:00
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
if sym.Value >= int64(eaddr) {
|
|
|
|
|
break
|
|
|
|
|
}
|
2016-04-20 10:36:27 -04:00
|
|
|
for ri := 0; ri < len(sym.R); ri++ {
|
|
|
|
|
r := &sym.R[ri]
|
2015-02-27 22:57:28 -05:00
|
|
|
if r.Done != 0 {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2016-09-17 09:39:33 -04:00
|
|
|
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)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-24 20:27:38 +10:00
|
|
|
sect.Rellen = uint64(coutbuf.Offset()) - sect.Reloff
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
|
|
|
|
|
2016-08-19 22:40:38 -04:00
|
|
|
func Machoemitreloc(ctxt *Link) {
|
2016-08-24 20:27:38 +10:00
|
|
|
for coutbuf.Offset()&7 != 0 {
|
2015-02-27 22:57:28 -05:00
|
|
|
Cput(0)
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-18 21:52:06 +12:00
|
|
|
machorelocsect(ctxt, Segtext.Sections[0], ctxt.Textp)
|
|
|
|
|
for _, sect := range Segtext.Sections[1:] {
|
2016-08-19 22:40:38 -04:00
|
|
|
machorelocsect(ctxt, sect, datap)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segdata.Sections {
|
2016-08-19 22:40:38 -04:00
|
|
|
machorelocsect(ctxt, sect, datap)
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|
2017-04-18 21:52:06 +12:00
|
|
|
for _, sect := range Segdwarf.Sections {
|
2016-04-22 10:31:14 +12:00
|
|
|
machorelocsect(ctxt, sect, dwarfp)
|
2016-03-14 09:23:04 -07:00
|
|
|
}
|
2015-02-27 22:57:28 -05:00
|
|
|
}
|