diff options
Diffstat (limited to 'src/cmd/link/internal/ld/macho_combine_dwarf.go')
-rw-r--r-- | src/cmd/link/internal/ld/macho_combine_dwarf.go | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/src/cmd/link/internal/ld/macho_combine_dwarf.go b/src/cmd/link/internal/ld/macho_combine_dwarf.go index 7d33f75b54..8c80576371 100644 --- a/src/cmd/link/internal/ld/macho_combine_dwarf.go +++ b/src/cmd/link/internal/ld/macho_combine_dwarf.go @@ -265,7 +265,7 @@ func machoCombineDwarf(ctxt *Link, inexe, dsym, outexe string) (bool, error) { } } // Do the final update of the DWARF segment's load command. - return false, machoUpdateDwarfHeader(&reader, ctxt.BuildMode, compressedSects) + return false, machoUpdateDwarfHeader(&reader, compressedSects, dwarfsize) } // machoCompressSections tries to compress the DWARF segments in dwarfm, @@ -410,7 +410,7 @@ func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset, } // 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{} cmd, err := r.Next() if err != nil { @@ -428,8 +428,6 @@ func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode, compressedSec } segv := reflect.ValueOf(seg).Elem() segv.FieldByName("Offset").SetUint(uint64(dwarfstart)) - segv.FieldByName("Addr").SetUint(uint64(dwarfaddr)) - segv.FieldByName("Prot").SetUint(0) if compressedSects != nil { var segSize uint64 @@ -437,23 +435,27 @@ func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode, compressedSec segSize += newSect.Size } 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 deltaAddr := uint64(dwarfaddr) - realdwarf.Addr - // If we set Memsz to 0 (and might as well set Addr too), - // then the xnu kernel will bail out halfway through load_segment - // and not apply further sanity checks that we might fail in the future. - // We don't need the DWARF information actually available in memory. - // But if we do this for buildmode=c-shared then the user-space - // dynamic loader complains about memsz < filesz. Sigh. - if buildmode != BuildModeCShared { - segv.FieldByName("Addr").SetUint(0) - segv.FieldByName("Memsz").SetUint(0) - deltaAddr = 0 - } + // We want the DWARF segment to be considered non-loadable, so + // force vmaddr and vmsize to zero. In addition, set the initial + // protection to zero so as to make the dynamic loader happy, + // since otherwise it may complain that that the vm size and file + // size don't match for the segment. See issues 21647 and 32673 + // for more context. Also useful to refer to the Apple dynamic + // loader source, specifically ImageLoaderMachO::sniffLoadCommands + // 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) + deltaAddr = 0 if err := r.WriteAt(0, seg); err != nil { return err |