aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2019-06-20 09:02:05 -0400
committerAlexander Rakoczy <alex@golang.org>2019-07-08 16:55:36 +0000
commitc955c54431f18f407294f86b12b5b39a82ee9ee0 (patch)
treeed7f6b66df622f8314f178540d5fd7869cbfc2b6
parente050fac971440e3e08bb82fb921d63d5851ac3bc (diff)
downloadgo-c955c54431f18f407294f86b12b5b39a82ee9ee0.tar.gz
go-c955c54431f18f407294f86b12b5b39a82ee9ee0.zip
[release-branch.go1.12] 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. Fixes #32697 Change-Id: Id1fc213590ad00c28352925e2d754d760e022b5e Reviewed-on: https://go-review.googlesource.com/c/go/+/183237 Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/183398 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r--src/cmd/link/internal/ld/macho_combine_dwarf.go34
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