var msect *MachoSect
if sect.Rwx&1 == 0 && segname != "__DWARF" && (ctxt.Arch.Family == sys.ARM64 ||
- ctxt.Arch.Family == sys.ARM ||
(ctxt.Arch.Family == sys.AMD64 && ctxt.BuildMode != BuildModeExe)) {
- // Darwin external linker on arm and arm64, and on amd64 in c-shared/c-archive buildmode
+ // Darwin external linker on arm64, and on amd64 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")
if sect.Name == ".got" {
msect.name = "__nl_symbol_ptr"
msect.flag = S_NON_LAZY_SYMBOL_POINTERS
- msect.res1 = uint32(ctxt.Syms.Lookup(".linkedit.plt", 0).Size / 4) /* offset into indirect symbol table */
+ msect.res1 = uint32(ctxt.loader.SymSize(ctxt.ArchSyms.LinkEditPLT2) / 4) /* offset into indirect symbol table */
}
if sect.Name == ".init_array" {
default:
Exitf("unknown macho architecture: %v", ctxt.Arch.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
default:
Exitf("unknown macho architecture: %v", ctxt.Arch.Family)
- case sys.ARM:
- ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 17+2)
- 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(ctxt.Arch, LC_UNIXTHREAD, 42+2)
- ml.data[0] = 4 /* thread type */
- ml.data[1] = 42 /* word count */
- ml.data[2+32] = uint32(Entryvalue(ctxt)) /* start pc */
- ml.data[2+32+1] = uint32(Entryvalue(ctxt) >> 32)
+ ml.data[0] = 4 /* thread type */
+ ml.data[1] = 42 /* word count */
+ ml.data[2+32] = uint32(Entryvalue2(ctxt)) /* start pc */
+ ml.data[2+32+1] = uint32(Entryvalue2(ctxt) >> 32)
case sys.ARM64:
ml := newMachoLoad(ctxt.Arch, LC_UNIXTHREAD, 68+2)
- 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(ctxt.Arch, LC_UNIXTHREAD, 16+2)
- ml.data[0] = 1 /* thread type */
- ml.data[1] = 16 /* word count */
- ml.data[2+10] = uint32(Entryvalue(ctxt)) /* start pc */
+ ml.data[0] = 6 /* thread type */
+ ml.data[1] = 68 /* word count */
+ ml.data[2+64] = uint32(Entryvalue2(ctxt)) /* start pc */
+ ml.data[2+64+1] = uint32(Entryvalue2(ctxt) >> 32)
}
}
if !*FlagD {
+ ldr := ctxt.loader
+
// 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)
+ s1 := ldr.SymSize(ldr.Lookup(".machosymtab", 0))
+ s2 := ldr.SymSize(ctxt.ArchSyms.LinkEditPLT2)
+ s3 := ldr.SymSize(ctxt.ArchSyms.LinkEditGOT2)
+ s4 := ldr.SymSize(ldr.Lookup(".machosymstr", 0))
if ctxt.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.vsize = uint64(s1) + uint64(s2) + uint64(s3) + uint64(s4)
ms.fileoffset = uint64(linkoff)
ms.filesize = ms.vsize
ms.prot1 = 7
}
ml := newMachoLoad(ctxt.Arch, LC_SYMTAB, 4)
- 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 */
+ ml.data[0] = uint32(linkoff) /* symoff */
+ ml.data[1] = uint32(nsortsym) /* nsyms */
+ ml.data[2] = uint32(linkoff + s1 + s2 + s3) /* stroff */
+ ml.data[3] = uint32(s4) /* strsize */
machodysymtab(ctxt)
//
// When dynamically linking, all non-local variables and plugin-exported
// symbols need to be exported.
-func machoShouldExport(ctxt *Link, s *sym.Symbol) bool {
- if !ctxt.DynlinkingGo() || s.Attr.Local() {
+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(s.Extname(), objabi.PathToPrefix(*flagPluginPath)) {
+ if ctxt.BuildMode == BuildModePlugin && strings.HasPrefix(ldr.SymExtname(s), objabi.PathToPrefix(*flagPluginPath)) {
return true
}
- if strings.HasPrefix(s.Name, "go.itab.") {
+ name := ldr.RawSymName(s)
+ if strings.HasPrefix(name, "go.itab.") {
return true
}
- if strings.HasPrefix(s.Name, "type.") && !strings.HasPrefix(s.Name, "type..") {
+ 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(s.Name, "go.link.pkghash") {
+ if strings.HasPrefix(name, "go.link.pkghash") {
return true
}
- return s.Type >= sym.SFirstWritable // only writable sections
+ return ldr.SymType(s) >= sym.SFirstWritable // only writable sections
}
func machosymtab(ctxt *Link) {
- symtab := ctxt.Syms.Lookup(".machosymtab", 0)
- symstr := ctxt.Syms.Lookup(".machosymstr", 0)
+ ldr := ctxt.loader
+ symtab := ldr.CreateSymForUpdate(".machosymtab", 0)
+ symstr := ldr.CreateSymForUpdate(".machosymstr", 0)
- for i := 0; i < nsortsym; i++ {
- s := ctxt.loader.Syms[sortsym[i]]
- symtab.AddUint32(ctxt.Arch, uint32(symstr.Size))
+ for _, s := range sortsym[:nsortsym] {
+ symtab.AddUint32(ctxt.Arch, uint32(symstr.Size()))
- export := machoShouldExport(ctxt, s)
- isGoSymbol := strings.Contains(s.Extname(), ".")
+ export := machoShouldExport(ctxt, ldr, s)
+ isGoSymbol := strings.Contains(ldr.SymExtname(s), ".")
// In normal buildmodes, only add _ to C symbols, as
// Go symbols have dot in the name.
// symbols like crosscall2 are in pclntab and end up
// pointing at the host binary, breaking unwinding.
// See Issue #18190.
- cexport := !isGoSymbol && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(s.Name))
+ cexport := !isGoSymbol && (ctxt.BuildMode != BuildModePlugin || onlycsymbol(ldr.SymName(s)))
if cexport || export || isGoSymbol {
symstr.AddUint8('_')
}
// replace "·" as ".", because DTrace cannot handle it.
- Addstring(symstr, strings.Replace(s.Extname(), "·", ".", -1))
+ symstr.Addstring(strings.Replace(ldr.SymExtname(s), "·", ".", -1))
- if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ || s.Type == sym.SUNDEFEXT {
+ 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 s.Attr.CgoExport() || export {
+ if ldr.AttrCgoExport(s) || export {
symtab.AddUint8(0x0f)
} else {
symtab.AddUint8(0x0e)
}
o := s
- for o.Outer != nil {
- o = o.Outer
+ if outer := ldr.OuterSym(o); outer != 0 {
+ o = outer
}
- if o.Sect == nil {
- Errorf(s, "missing section for symbol")
+ if ldr.SymSect(o) == nil {
+ ldr.Errorf(s, "missing section for symbol")
symtab.AddUint8(0)
} else {
- symtab.AddUint8(uint8(o.Sect.Extnum))
+ symtab.AddUint8(uint8(ldr.SymSect(o).Extnum))
}
symtab.AddUint16(ctxt.Arch, 0) // desc
- symtab.AddUintXX(ctxt.Arch, uint64(Symaddr(s)), ctxt.Arch.PtrSize)
+ symtab.AddUintXX(ctxt.Arch, uint64(ldr.SymAddr(s)), ctxt.Arch.PtrSize)
}
}
}
ml.data[10] = 0 /* extrefsymoff */
ml.data[11] = 0 /* nextrefsyms */
- // must match domacholink below
- s1 := ctxt.Syms.Lookup(".machosymtab", 0)
+ ldr := ctxt.loader
- 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 */
+ // must match domacholink below
+ s1 := ldr.SymSize(ldr.Lookup(".machosymtab", 0))
+ s2 := ldr.SymSize(ctxt.ArchSyms.LinkEditPLT2)
+ s3 := ldr.SymSize(ctxt.ArchSyms.LinkEditGOT2)
+ ml.data[12] = uint32(linkoff + s1) /* indirectsymoff */
+ ml.data[13] = uint32((s2 + s3) / 4) /* nindirectsyms */
ml.data[14] = 0 /* extreloff */
ml.data[15] = 0 /* nextrel */
func Domacholink(ctxt *Link) int64 {
machosymtab(ctxt)
- // write data that will be linkedit section
- s1 := ctxt.Syms.Lookup(".machosymtab", 0)
+ ldr := ctxt.loader
- s2 := ctxt.Syms.Lookup(".linkedit.plt", 0)
- s3 := ctxt.Syms.Lookup(".linkedit.got", 0)
- s4 := ctxt.Syms.Lookup(".machosymstr", 0)
+ // write data that will be linkedit section
+ s1 := ldr.Lookup(".machosymtab", 0)
+ s2 := ctxt.ArchSyms.LinkEditPLT2
+ s3 := ctxt.ArchSyms.LinkEditGOT2
+ s4 := ldr.Lookup(".machosymstr", 0)
// Force the linkedit section to end on a 16-byte
// boundary. This allows pure (non-cgo) Go binaries
// boundary, codesign_allocate will not need to apply
// any alignment padding itself, working around the
// issue.
- for s4.Size%16 != 0 {
- s4.AddUint8(0)
+ s4b := ldr.MakeSymbolUpdater(s4)
+ for s4b.Size()%16 != 0 {
+ s4b.AddUint8(0)
}
- size := int(s1.Size + s2.Size + s3.Size + s4.Size)
+ size := int(ldr.SymSize(s1) + ldr.SymSize(s2) + ldr.SymSize(s3) + ldr.SymSize(s4))
if size > 0 {
linkoff = Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound)) + Rnd(int64(Segdata.Filelen), int64(*FlagRound)) + Rnd(int64(Segdwarf.Filelen), int64(*FlagRound))
ctxt.Out.SeekSet(linkoff)
- ctxt.Out.Write(s1.P[:s1.Size])
- ctxt.Out.Write(s2.P[:s2.Size])
- ctxt.Out.Write(s3.P[:s3.Size])
- ctxt.Out.Write(s4.P[:s4.Size])
+ ctxt.Out.Write(ldr.Data(s1))
+ ctxt.Out.Write(ldr.Data(s2))
+ ctxt.Out.Write(ldr.Data(s3))
+ ctxt.Out.Write(ldr.Data(s4))
}
return Rnd(int64(size), int64(*FlagRound))
}
-func machorelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) {
+func machorelocsect(ctxt *Link, ldr *loader.Loader, 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
sect.Reloff = uint64(ctxt.Out.Offset())
for i, s := range syms {
- if !s.Attr.Reachable() {
+ if !ldr.AttrReachable(s) {
continue
}
- if uint64(s.Value) >= sect.Vaddr {
+ if uint64(ldr.SymValue(s)) >= sect.Vaddr {
syms = syms[i:]
break
}
eaddr := int32(sect.Vaddr + sect.Length)
for _, s := range syms {
- if !s.Attr.Reachable() {
+ if !ldr.AttrReachable(s) {
continue
}
- if s.Value >= int64(eaddr) {
+ if ldr.SymValue(s) >= int64(eaddr) {
break
}
- for ri := range s.R {
- r := &s.R[ri]
- if r.Done {
- continue
- }
- if r.Xsym == nil {
- Errorf(s, "missing xsym in relocation")
+ relocs := ldr.ExtRelocs(s)
+ for ri := 0; ri < relocs.Count(); ri++ {
+ r := relocs.At(ri)
+ if r.Xsym == 0 {
+ ldr.Errorf(s, "missing xsym in relocation")
continue
}
- if !r.Xsym.Attr.Reachable() {
- Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
+ if !ldr.AttrReachable(r.Xsym) {
+ ldr.Errorf(s, "unreachable reloc %d (%s) target %v", r.Type(), sym.RelocName(ctxt.Arch, r.Type()), ldr.SymName(r.Xsym))
}
- if !thearch.Machoreloc1(ctxt.Arch, ctxt.Out, s, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) {
- Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
+ if !thearch.Machoreloc1(ctxt.Arch, ctxt.Out, ldr, s, r, 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()))
}
}
}
ctxt.Out.Write8(0)
}
- machorelocsect(ctxt, Segtext.Sections[0], ctxt.Textp)
+ ldr := ctxt.loader
+ machorelocsect(ctxt, ldr, Segtext.Sections[0], ctxt.Textp2)
for _, sect := range Segtext.Sections[1:] {
- machorelocsect(ctxt, sect, ctxt.datap)
+ machorelocsect(ctxt, ldr, sect, ctxt.datap2)
}
for _, sect := range Segdata.Sections {
- machorelocsect(ctxt, sect, ctxt.datap)
+ machorelocsect(ctxt, ldr, sect, ctxt.datap2)
}
for i := 0; i < len(Segdwarf.Sections); i++ {
sect := Segdwarf.Sections[i]
- si := dwarfp[i]
- if si.secSym() != sect.Sym ||
- si.secSym().Sect != sect {
+ si := dwarfp2[i]
+ if si.secSym() != loader.Sym(sect.Sym2) ||
+ ctxt.loader.SymSect(si.secSym()) != sect {
panic("inconsistency between dwarfp and Segdwarf")
}
- machorelocsect(ctxt, sect, si.syms)
+ machorelocsect(ctxt, ldr, sect, si.syms)
}
}