aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link/internal/ld
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/link/internal/ld')
-rw-r--r--src/cmd/link/internal/ld/data.go24
-rw-r--r--src/cmd/link/internal/ld/deadcode.go2
-rw-r--r--src/cmd/link/internal/ld/lib.go44
-rw-r--r--src/cmd/link/internal/ld/macho.go41
-rw-r--r--src/cmd/link/internal/ld/macho_combine_dwarf.go112
-rw-r--r--src/cmd/link/internal/ld/symtab.go4
-rw-r--r--src/cmd/link/internal/ld/target.go6
7 files changed, 111 insertions, 122 deletions
diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go
index dc7096ea8c..a730125cf2 100644
--- a/src/cmd/link/internal/ld/data.go
+++ b/src/cmd/link/internal/ld/data.go
@@ -930,7 +930,7 @@ func writeBlock(ctxt *Link, out *OutBuf, ldr *loader.Loader, syms []loader.Sym,
break
}
if val < addr {
- ldr.Errorf(s, "phase error: addr=%#x but sym=%#x type=%d", addr, val, ldr.SymType(s))
+ ldr.Errorf(s, "phase error: addr=%#x but sym=%#x type=%v sect=%v", addr, val, ldr.SymType(s), ldr.SymSect(s).Name)
errorexit()
}
if addr < val {
@@ -1308,9 +1308,9 @@ func (state *dodataState) makeRelroForSharedLib(target *Link) {
// relro Type before it reaches here.
isRelro = true
case sym.SFUNCTAB:
- if target.IsAIX() && ldr.SymName(s) == "runtime.etypes" {
+ if ldr.SymName(s) == "runtime.etypes" {
// runtime.etypes must be at the end of
- // the relro datas.
+ // the relro data.
isRelro = true
}
}
@@ -1706,7 +1706,7 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
ldr.SetSymSect(ldr.LookupOrCreateSym("runtime.ebss", 0), sect)
bssGcEnd := state.datsize - int64(sect.Vaddr)
- // Emit gcdata for bcc symbols now that symbol values have been assigned.
+ // Emit gcdata for bss symbols now that symbol values have been assigned.
gcsToEmit := []struct {
symName string
symKind sym.SymKind
@@ -1786,7 +1786,8 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
culprit := ldr.SymName(state.data[sym.STEXT][0])
Errorf(nil, "dodata found an sym.STEXT symbol: %s", culprit)
}
- state.allocateSingleSymSections(&Segtext, sym.SELFRXSECT, sym.SRODATA, 04)
+ state.allocateSingleSymSections(&Segtext, sym.SELFRXSECT, sym.SRODATA, 05)
+ state.allocateSingleSymSections(&Segtext, sym.SMACHOPLT, sym.SRODATA, 05)
/* read-only data */
sect = state.allocateNamedDataSection(segro, ".rodata", sym.ReadOnly, 04)
@@ -1810,7 +1811,6 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
/* read-only ELF, Mach-O sections */
state.allocateSingleSymSections(segro, sym.SELFROSECT, sym.SRODATA, 04)
- state.allocateSingleSymSections(segro, sym.SMACHOPLT, sym.SRODATA, 04)
// There is some data that are conceptually read-only but are written to by
// relocations. On GNU systems, we can arrange for the dynamic linker to
@@ -1826,13 +1826,16 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
const fallbackPerm = 04
relroSecPerm := fallbackPerm
genrelrosecname := func(suffix string) string {
+ if suffix == "" {
+ return ".rodata"
+ }
return suffix
}
seg := segro
if ctxt.UseRelro() {
segrelro := &Segrelrodata
- if ctxt.LinkMode == LinkExternal && ctxt.HeadType != objabi.Haix {
+ if ctxt.LinkMode == LinkExternal && !ctxt.IsAIX() && !ctxt.IsDarwin() {
// Using a separate segment with an external
// linker results in some programs moving
// their data sections unexpectedly, which
@@ -1845,9 +1848,12 @@ func (state *dodataState) allocateDataSections(ctxt *Link) {
state.datsize = 0
}
- genrelrosecname = func(suffix string) string {
- return ".data.rel.ro" + suffix
+ if !ctxt.IsDarwin() { // We don't need the special names on darwin.
+ genrelrosecname = func(suffix string) string {
+ return ".data.rel.ro" + suffix
+ }
}
+
relroReadOnly := []sym.SymKind{}
for _, symnro := range sym.ReadOnly {
symn := sym.RelROMap[symnro]
diff --git a/src/cmd/link/internal/ld/deadcode.go b/src/cmd/link/internal/ld/deadcode.go
index 0269429723..35545f950e 100644
--- a/src/cmd/link/internal/ld/deadcode.go
+++ b/src/cmd/link/internal/ld/deadcode.go
@@ -209,7 +209,7 @@ func (d *deadcodePass) mark(symIdx, parent loader.Sym) {
if symIdx != 0 && !d.ldr.AttrReachable(symIdx) {
d.wq.push(symIdx)
d.ldr.SetAttrReachable(symIdx, true)
- if objabi.Fieldtrack_enabled != 0 {
+ if objabi.Fieldtrack_enabled != 0 && d.ldr.Reachparent[symIdx] == 0 {
d.ldr.Reachparent[symIdx] = parent
}
if *flagDumpDep {
diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go
index 09c7bbfb53..4295b2a660 100644
--- a/src/cmd/link/internal/ld/lib.go
+++ b/src/cmd/link/internal/ld/lib.go
@@ -775,14 +775,6 @@ func (ctxt *Link) linksetup() {
sb.SetSize(0)
sb.AddUint8(uint8(objabi.GOARM))
}
-
- if objabi.Framepointer_enabled(objabi.GOOS, objabi.GOARCH) {
- fpe := ctxt.loader.LookupOrCreateSym("runtime.framepointer_enabled", 0)
- sb := ctxt.loader.MakeSymbolUpdater(fpe)
- sb.SetType(sym.SNOPTRDATA)
- sb.SetSize(0)
- sb.AddUint8(1)
- }
} else {
// If OTOH the module does not contain the runtime package,
// create a local symbol for the moduledata.
@@ -1246,15 +1238,23 @@ func (ctxt *Link) hostlink() {
}
}
+ // On darwin, whether to combine DWARF into executable.
+ // Only macOS supports unmapped segments such as our __DWARF segment.
+ combineDwarf := ctxt.IsDarwin() && !*FlagS && !*FlagW && !debug_s && machoPlatform == PLATFORM_MACOS
+
switch ctxt.HeadType {
case objabi.Hdarwin:
- if machoPlatform == PLATFORM_MACOS {
+ if combineDwarf {
+ // Leave room for DWARF combining.
// -headerpad is incompatible with -fembed-bitcode.
argv = append(argv, "-Wl,-headerpad,1144")
}
if ctxt.DynlinkingGo() && !ctxt.Arch.InFamily(sys.ARM, sys.ARM64) {
argv = append(argv, "-Wl,-flat_namespace")
}
+ if !combineDwarf {
+ argv = append(argv, "-Wl,-S") // suppress STAB (symbolic debugging) symbols
+ }
case objabi.Hopenbsd:
argv = append(argv, "-Wl,-nopie")
case objabi.Hwindows:
@@ -1288,7 +1288,7 @@ func (ctxt *Link) hostlink() {
switch ctxt.BuildMode {
case BuildModeExe:
if ctxt.HeadType == objabi.Hdarwin {
- if machoPlatform == PLATFORM_MACOS {
+ if machoPlatform == PLATFORM_MACOS && ctxt.IsAMD64() {
argv = append(argv, "-Wl,-no_pie")
argv = append(argv, "-Wl,-pagezero_size,4000000")
}
@@ -1525,7 +1525,7 @@ func (ctxt *Link) hostlink() {
// does not work, the resulting programs will not run. See
// issue #17847. To avoid this problem pass -no-pie to the
// toolchain if it is supported.
- if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared {
+ if ctxt.BuildMode == BuildModeExe && !ctxt.linkShared && !(ctxt.IsDarwin() && ctxt.IsARM64()) {
// GCC uses -no-pie, clang uses -nopie.
for _, nopie := range []string{"-no-pie", "-nopie"} {
if linkerFlagSupported(argv[0], altLinker, nopie) {
@@ -1594,11 +1594,16 @@ func (ctxt *Link) hostlink() {
ctxt.Logf("%s", out)
}
- if !*FlagS && !*FlagW && !debug_s && ctxt.HeadType == objabi.Hdarwin {
+ if combineDwarf {
dsym := filepath.Join(*flagTmpdir, "go.dwarf")
if out, err := exec.Command("dsymutil", "-f", *flagOutfile, "-o", dsym).CombinedOutput(); err != nil {
Exitf("%s: running dsymutil failed: %v\n%s", os.Args[0], err, out)
}
+ // Remove STAB (symbolic debugging) symbols after we are done with them (by dsymutil).
+ // They contain temporary file paths and make the build not reproducible.
+ if out, err := exec.Command("strip", "-S", *flagOutfile).CombinedOutput(); err != nil {
+ Exitf("%s: running strip failed: %v\n%s", os.Args[0], err, out)
+ }
// Skip combining if `dsymutil` didn't generate a file. See #11994.
if _, err := os.Stat(dsym); os.IsNotExist(err) {
return
@@ -1614,15 +1619,12 @@ func (ctxt *Link) hostlink() {
if err != nil {
Exitf("%s: parsing Mach-O header failed: %v", os.Args[0], err)
}
- // Only macOS supports unmapped segments such as our __DWARF segment.
- if machoPlatform == PLATFORM_MACOS {
- if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil {
- Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
- }
- os.Remove(*flagOutfile)
- if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
- Exitf("%s: %v", os.Args[0], err)
- }
+ if err := machoCombineDwarf(ctxt, exef, exem, dsym, combinedOutput); err != nil {
+ Exitf("%s: combining dwarf failed: %v", os.Args[0], err)
+ }
+ os.Remove(*flagOutfile)
+ if err := os.Rename(combinedOutput, *flagOutfile); err != nil {
+ Exitf("%s: %v", os.Args[0], err)
}
}
}
diff --git a/src/cmd/link/internal/ld/macho.go b/src/cmd/link/internal/ld/macho.go
index f6356729a6..9765ce18d3 100644
--- a/src/cmd/link/internal/ld/macho.go
+++ b/src/cmd/link/internal/ld/macho.go
@@ -499,16 +499,7 @@ func machoadddynlib(lib string, linkmode LinkMode) {
func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string) {
buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
- var msect *MachoSect
- if sect.Rwx&1 == 0 && segname != "__DWARF" && (ctxt.Arch.Family == sys.ARM64 ||
- (ctxt.Arch.Family == sys.AMD64 && ctxt.BuildMode != BuildModeExe)) {
- // 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")
- } else {
- msect = newMachoSect(mseg, buf, segname)
- }
+ msect := newMachoSect(mseg, buf, segname)
if sect.Rellen > 0 {
msect.reloc = uint32(sect.Reloff)
@@ -633,13 +624,28 @@ func asmbMacho(ctxt *Link) {
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 {
- w := int64(Segdata.Length)
ms = newMachoSeg("__DATA", 20)
- ms.vaddr = uint64(va) + uint64(v)
- ms.vsize = uint64(w)
- ms.fileoffset = uint64(v)
+ ms.vaddr = Segdata.Vaddr
+ ms.vsize = Segdata.Length
+ ms.fileoffset = Segdata.Fileoff
ms.filesize = Segdata.Filelen
ms.prot1 = 3
ms.prot2 = 3
@@ -695,7 +701,7 @@ func asmbMacho(ctxt *Link) {
if ctxt.LinkMode != LinkExternal {
ms := newMachoSeg("__LINKEDIT", 0)
- ms.vaddr = uint64(va) + uint64(v) + uint64(Rnd(int64(Segdata.Length), int64(*FlagRound)))
+ ms.vaddr = uint64(Rnd(int64(Segdata.Vaddr+Segdata.Length), int64(*FlagRound)))
ms.vsize = uint64(s1) + uint64(s2) + uint64(s3) + uint64(s4)
ms.fileoffset = uint64(linkoff)
ms.filesize = ms.vsize
@@ -1008,7 +1014,7 @@ func doMachoLink(ctxt *Link) int64 {
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))
+ linkoff = Rnd(int64(uint64(HEADR)+Segtext.Length), int64(*FlagRound)) + Rnd(int64(Segrelrodata.Filelen), int64(*FlagRound)) + Rnd(int64(Segdata.Filelen), int64(*FlagRound)) + Rnd(int64(Segdwarf.Filelen), int64(*FlagRound))
ctxt.Out.SeekSet(linkoff)
ctxt.Out.Write(ldr.Data(s1))
@@ -1086,6 +1092,9 @@ func machoEmitReloc(ctxt *Link) {
for _, sect := range Segtext.Sections[1:] {
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)
}
diff --git a/src/cmd/link/internal/ld/macho_combine_dwarf.go b/src/cmd/link/internal/ld/macho_combine_dwarf.go
index 9d9f916b8e..77ee8a4d62 100644
--- a/src/cmd/link/internal/ld/macho_combine_dwarf.go
+++ b/src/cmd/link/internal/ld/macho_combine_dwarf.go
@@ -16,10 +16,6 @@ import (
"unsafe"
)
-const (
- pageAlign = 12 // 4096 = 1 << 12
-)
-
type loadCmd struct {
Cmd macho.LoadCmd
Len uint32
@@ -138,7 +134,7 @@ func machoCombineDwarf(ctxt *Link, exef *os.File, exem *macho.File, dsym, outexe
// Now copy the dwarf data into the output.
// Kernel requires all loaded segments to be page-aligned in the file,
// even though we mark this one as being 0 bytes of virtual address space.
- dwarfstart := machoCalcStart(realdwarf.Offset, linkseg.Offset, pageAlign)
+ dwarfstart := Rnd(int64(linkseg.Offset), int64(*FlagRound))
if _, err := outf.Seek(dwarfstart, 0); err != nil {
return err
}
@@ -166,7 +162,7 @@ func machoCombineDwarf(ctxt *Link, exef *os.File, exem *macho.File, dsym, outexe
if _, err := exef.Seek(int64(linkseg.Offset), 0); err != nil {
return err
}
- linkstart := machoCalcStart(linkseg.Offset, uint64(dwarfstart)+dwarfsize, pageAlign)
+ linkstart := Rnd(dwarfstart+int64(dwarfsize), int64(*FlagRound))
if _, err := outf.Seek(linkstart, 0); err != nil {
return err
}
@@ -217,9 +213,9 @@ func machoCombineDwarf(ctxt *Link, exef *os.File, exem *macho.File, dsym, outexe
linkoffset := uint64(linkstart) - linkseg.Offset
switch cmd.Cmd {
case macho.LoadCmdSegment64:
- err = machoUpdateSegment(reader, linkseg, linkoffset, &macho.Segment64{}, &macho.Section64{})
+ err = machoUpdateSegment(reader, linkseg, linkoffset)
case macho.LoadCmdSegment:
- err = machoUpdateSegment(reader, linkseg, linkoffset, &macho.Segment32{}, &macho.Section32{})
+ panic("unexpected 32-bit segment")
case LC_DYLD_INFO, LC_DYLD_INFO_ONLY:
err = machoUpdateLoadCommand(reader, linkseg, linkoffset, &dyldInfoCmd{}, "RebaseOff", "BindOff", "WeakBindOff", "LazyBindOff", "ExportOff")
case macho.LoadCmdSymtab:
@@ -313,70 +309,56 @@ func machoCompressSection(sectBytes []byte) (compressed bool, contents []byte, e
// machoUpdateSegment updates the load command for a moved segment.
// Only the linkedit segment should move, and it should have 0 sections.
-// seg should be a macho.Segment32 or macho.Segment64 as appropriate.
-// sect should be a macho.Section32 or macho.Section64 as appropriate.
-func machoUpdateSegment(r loadCmdReader, linkseg *macho.Segment, linkoffset uint64, seg, sect interface{}) error {
- if err := r.ReadAt(0, seg); err != nil {
+func machoUpdateSegment(r loadCmdReader, linkseg *macho.Segment, linkoffset uint64) error {
+ var seg macho.Segment64
+ if err := r.ReadAt(0, &seg); err != nil {
return err
}
- segValue := reflect.ValueOf(seg)
- offset := reflect.Indirect(segValue).FieldByName("Offset")
// Only the linkedit segment moved, anything before that is fine.
- if offset.Uint() < linkseg.Offset {
+ if seg.Offset < linkseg.Offset {
return nil
}
- offset.SetUint(offset.Uint() + linkoffset)
- if err := r.WriteAt(0, seg); err != nil {
+ seg.Offset += linkoffset
+ if err := r.WriteAt(0, &seg); err != nil {
return err
}
// There shouldn't be any sections, but just to make sure...
- return machoUpdateSections(r, segValue, reflect.ValueOf(sect), linkoffset, nil)
+ return machoUpdateSections(r, &seg, linkoffset, nil)
}
-func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset uint64, compressedSects []*macho.Section) error {
- iseg := reflect.Indirect(seg)
- nsect := iseg.FieldByName("Nsect").Uint()
+func machoUpdateSections(r loadCmdReader, seg *macho.Segment64, deltaOffset uint64, compressedSects []*macho.Section) error {
+ nsect := seg.Nsect
if nsect == 0 {
return nil
}
- sectOffset := int64(iseg.Type().Size())
-
- isect := reflect.Indirect(sect)
- offsetField := isect.FieldByName("Offset")
- reloffField := isect.FieldByName("Reloff")
- addrField := isect.FieldByName("Addr")
- nameField := isect.FieldByName("Name")
- sizeField := isect.FieldByName("Size")
- sectSize := int64(isect.Type().Size())
- for i := uint64(0); i < nsect; i++ {
- if err := r.ReadAt(sectOffset, sect.Interface()); err != nil {
+ sectOffset := int64(unsafe.Sizeof(*seg))
+
+ var sect macho.Section64
+ sectSize := int64(unsafe.Sizeof(sect))
+ for i := uint32(0); i < nsect; i++ {
+ if err := r.ReadAt(sectOffset, &sect); err != nil {
return err
}
if compressedSects != nil {
cSect := compressedSects[i]
- var name [16]byte
- copy(name[:], []byte(cSect.Name))
- nameField.Set(reflect.ValueOf(name))
- sizeField.SetUint(cSect.Size)
+ copy(sect.Name[:], cSect.Name)
+ sect.Size = cSect.Size
if cSect.Offset != 0 {
- offsetField.SetUint(uint64(cSect.Offset) + deltaOffset)
+ sect.Offset = cSect.Offset + uint32(deltaOffset)
}
if cSect.Addr != 0 {
- addrField.SetUint(cSect.Addr)
+ sect.Addr = cSect.Addr
}
} else {
- if offsetField.Uint() != 0 {
- offsetField.SetUint(offsetField.Uint() + deltaOffset)
- }
- if reloffField.Uint() != 0 {
- reloffField.SetUint(reloffField.Uint() + deltaOffset)
+ if sect.Offset != 0 {
+ sect.Offset += uint32(deltaOffset)
}
- if addrField.Uint() != 0 {
- addrField.SetUint(addrField.Uint())
+ if sect.Reloff != 0 {
+ sect.Reloff += uint32(deltaOffset)
}
}
- if err := r.WriteAt(sectOffset, sect.Interface()); err != nil {
+ if err := r.WriteAt(sectOffset, &sect); err != nil {
return err
}
sectOffset += sectSize
@@ -386,32 +368,27 @@ func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset u
// machoUpdateDwarfHeader updates the DWARF segment load command.
func machoUpdateDwarfHeader(r *loadCmdReader, compressedSects []*macho.Section, dwarfsize uint64, dwarfstart int64, realdwarf *macho.Segment) error {
- var seg, sect interface{}
cmd, err := r.Next()
if err != nil {
return err
}
- if cmd.Cmd == macho.LoadCmdSegment64 {
- seg = new(macho.Segment64)
- sect = new(macho.Section64)
- } else {
- seg = new(macho.Segment32)
- sect = new(macho.Section32)
+ if cmd.Cmd != macho.LoadCmdSegment64 {
+ panic("not a Segment64")
}
- if err := r.ReadAt(0, seg); err != nil {
+ var seg macho.Segment64
+ if err := r.ReadAt(0, &seg); err != nil {
return err
}
- segv := reflect.ValueOf(seg).Elem()
- segv.FieldByName("Offset").SetUint(uint64(dwarfstart))
+ seg.Offset = uint64(dwarfstart)
if compressedSects != nil {
var segSize uint64
for _, newSect := range compressedSects {
segSize += newSect.Size
}
- segv.FieldByName("Filesz").SetUint(segSize)
+ seg.Filesz = segSize
} else {
- segv.FieldByName("Filesz").SetUint(dwarfsize)
+ seg.Filesz = dwarfsize
}
// We want the DWARF segment to be considered non-loadable, so
@@ -424,14 +401,14 @@ func machoUpdateDwarfHeader(r *loadCmdReader, compressedSects []*macho.Section,
// in ImageLoaderMachO.cpp (various versions can be found online, see
// https://opensource.apple.com/source/dyld/dyld-519.2.2/src/ImageLoaderMachO.cpp.auto.html
// as one example).
- segv.FieldByName("Addr").SetUint(0)
- segv.FieldByName("Memsz").SetUint(0)
- segv.FieldByName("Prot").SetUint(0)
+ seg.Addr = 0
+ seg.Memsz = 0
+ seg.Prot = 0
- if err := r.WriteAt(0, seg); err != nil {
+ if err := r.WriteAt(0, &seg); err != nil {
return err
}
- return machoUpdateSections(*r, segv, reflect.ValueOf(sect), uint64(dwarfstart)-realdwarf.Offset, compressedSects)
+ return machoUpdateSections(*r, &seg, uint64(dwarfstart)-realdwarf.Offset, compressedSects)
}
func machoUpdateLoadCommand(r loadCmdReader, linkseg *macho.Segment, linkoffset uint64, cmd interface{}, fields ...string) error {
@@ -451,12 +428,3 @@ func machoUpdateLoadCommand(r loadCmdReader, linkseg *macho.Segment, linkoffset
}
return nil
}
-
-func machoCalcStart(origAddr, newAddr uint64, alignExp uint32) int64 {
- align := uint64(1 << alignExp)
- origMod, newMod := origAddr%align, newAddr%align
- if origMod == newMod {
- return int64(newAddr)
- }
- return int64(newAddr + align + origMod - newMod)
-}
diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go
index bc880955b8..56363cdaae 100644
--- a/src/cmd/link/internal/ld/symtab.go
+++ b/src/cmd/link/internal/ld/symtab.go
@@ -681,8 +681,8 @@ func (ctxt *Link) symtab(pcln *pclntab) []sym.SymKind {
itablinkSym := ldr.Lookup("runtime.itablink", 0)
nitablinks := uint64(ldr.SymSize(itablinkSym)) / uint64(ctxt.Arch.PtrSize)
moduledata.AddAddr(ctxt.Arch, itablinkSym)
- moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
- moduledata.AddUint(ctxt.Arch, uint64(nitablinks))
+ moduledata.AddUint(ctxt.Arch, nitablinks)
+ moduledata.AddUint(ctxt.Arch, nitablinks)
// The ptab slice
if ptab := ldr.Lookup("go.plugin.tabs", 0); ptab != 0 && ldr.AttrReachable(ptab) {
ldr.SetAttrLocal(ptab, true)
diff --git a/src/cmd/link/internal/ld/target.go b/src/cmd/link/internal/ld/target.go
index 102b6c5436..f68de8fff1 100644
--- a/src/cmd/link/internal/ld/target.go
+++ b/src/cmd/link/internal/ld/target.go
@@ -74,8 +74,12 @@ func (t *Target) IsDynlinkingGo() bool {
func (t *Target) UseRelro() bool {
switch t.BuildMode {
case BuildModeCArchive, BuildModeCShared, BuildModeShared, BuildModePIE, BuildModePlugin:
- return t.IsELF || t.HeadType == objabi.Haix
+ return t.IsELF || t.HeadType == objabi.Haix || t.HeadType == objabi.Hdarwin
default:
+ if t.HeadType == objabi.Hdarwin && t.IsARM64() {
+ // On darwin/ARM64, everything is PIE.
+ return true
+ }
return t.linkShared || (t.HeadType == objabi.Haix && t.LinkMode == LinkExternal)
}
}