Commit 3f1422c7 authored by Than McIntosh's avatar Than McIntosh

cmd/link: revise previous __DWARF segment protection fix

Tweak the previous fix for issue 32673 (in CL 182958) to work around
problems with c-shared build mode that crop up on some of the builders
(10.11, 10.12).  We now consistently set vmaddr and vmsize to zero
for the DWARF segment regardless of build mode.

Updates #32673

Change-Id: Id1fc213590ad00c28352925e2d754d760e022b5e
Reviewed-on: https://go-review.googlesource.com/c/go/+/183237Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
Reviewed-by: default avatarDavid Chase <drchase@google.com>
parent b3399ac5
...@@ -245,7 +245,7 @@ func machoCombineDwarf(ctxt *Link, exef *os.File, exem *macho.File, dsym, outexe ...@@ -245,7 +245,7 @@ func machoCombineDwarf(ctxt *Link, exef *os.File, exem *macho.File, dsym, outexe
} }
} }
// Do the final update of the DWARF segment's load command. // Do the final update of the DWARF segment's load command.
return machoUpdateDwarfHeader(&reader, ctxt.BuildMode, compressedSects) return machoUpdateDwarfHeader(&reader, compressedSects, dwarfsize)
} }
// machoCompressSections tries to compress the DWARF segments in dwarfm, // machoCompressSections tries to compress the DWARF segments in dwarfm,
...@@ -390,7 +390,7 @@ func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset, ...@@ -390,7 +390,7 @@ func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset,
} }
// machoUpdateDwarfHeader updates the DWARF segment load command. // machoUpdateDwarfHeader updates the DWARF segment load command.
func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode, compressedSects []*macho.Section) error { func machoUpdateDwarfHeader(r *loadCmdReader, compressedSects []*macho.Section, dwarfsize uint64) error {
var seg, sect interface{} var seg, sect interface{}
cmd, err := r.Next() cmd, err := r.Next()
if err != nil { if err != nil {
...@@ -408,8 +408,6 @@ func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode, compressedSec ...@@ -408,8 +408,6 @@ func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode, compressedSec
} }
segv := reflect.ValueOf(seg).Elem() segv := reflect.ValueOf(seg).Elem()
segv.FieldByName("Offset").SetUint(uint64(dwarfstart)) segv.FieldByName("Offset").SetUint(uint64(dwarfstart))
segv.FieldByName("Addr").SetUint(uint64(dwarfaddr))
segv.FieldByName("Prot").SetUint(0)
if compressedSects != nil { if compressedSects != nil {
var segSize uint64 var segSize uint64
...@@ -417,23 +415,27 @@ func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode, compressedSec ...@@ -417,23 +415,27 @@ func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode, compressedSec
segSize += newSect.Size segSize += newSect.Size
} }
segv.FieldByName("Filesz").SetUint(segSize) segv.FieldByName("Filesz").SetUint(segSize)
segv.FieldByName("Memsz").SetUint(uint64(Rnd(int64(segSize), 1<<pageAlign))) } else {
segv.FieldByName("Filesz").SetUint(dwarfsize)
} }
deltaOffset := uint64(dwarfstart) - realdwarf.Offset deltaOffset := uint64(dwarfstart) - realdwarf.Offset
deltaAddr := uint64(dwarfaddr) - realdwarf.Addr deltaAddr := uint64(dwarfaddr) - realdwarf.Addr
// If we set Memsz to 0 (and might as well set Addr too), // We want the DWARF segment to be considered non-loadable, so
// then the xnu kernel will bail out halfway through load_segment // force vmaddr and vmsize to zero. In addition, set the initial
// and not apply further sanity checks that we might fail in the future. // protection to zero so as to make the dynamic loader happy,
// We don't need the DWARF information actually available in memory. // since otherwise it may complain that that the vm size and file
// But if we do this for buildmode=c-shared then the user-space // size don't match for the segment. See issues 21647 and 32673
// dynamic loader complains about memsz < filesz. Sigh. // for more context. Also useful to refer to the Apple dynamic
if buildmode != BuildModeCShared { // loader source, specifically ImageLoaderMachO::sniffLoadCommands
segv.FieldByName("Addr").SetUint(0) // in ImageLoaderMachO.cpp (various versions can be found online, see
segv.FieldByName("Memsz").SetUint(0) // https://opensource.apple.com/source/dyld/dyld-519.2.2/src/ImageLoaderMachO.cpp.auto.html
deltaAddr = 0 // as one example).
} segv.FieldByName("Addr").SetUint(0)
segv.FieldByName("Memsz").SetUint(0)
segv.FieldByName("Prot").SetUint(0)
deltaAddr = 0
if err := r.WriteAt(0, seg); err != nil { if err := r.WriteAt(0, seg); err != nil {
return err return err
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment