@@ -245,7 +245,7 @@ func machoCombineDwarf(ctxt *Link, exef *os.File, exem *macho.File, dsym, outexe
245
245
}
246
246
}
247
247
// Do the final update of the DWARF segment's load command.
248
- return machoUpdateDwarfHeader (& reader , ctxt . BuildMode , compressedSects )
248
+ return machoUpdateDwarfHeader (& reader , compressedSects , dwarfsize )
249
249
}
250
250
251
251
// machoCompressSections tries to compress the DWARF segments in dwarfm,
@@ -390,7 +390,7 @@ func machoUpdateSections(r loadCmdReader, seg, sect reflect.Value, deltaOffset,
390
390
}
391
391
392
392
// machoUpdateDwarfHeader updates the DWARF segment load command.
393
- func machoUpdateDwarfHeader (r * loadCmdReader , buildmode BuildMode , compressedSects []* macho.Section ) error {
393
+ func machoUpdateDwarfHeader (r * loadCmdReader , compressedSects []* macho.Section , dwarfsize uint64 ) error {
394
394
var seg , sect interface {}
395
395
cmd , err := r .Next ()
396
396
if err != nil {
@@ -408,32 +408,34 @@ func machoUpdateDwarfHeader(r *loadCmdReader, buildmode BuildMode, compressedSec
408
408
}
409
409
segv := reflect .ValueOf (seg ).Elem ()
410
410
segv .FieldByName ("Offset" ).SetUint (uint64 (dwarfstart ))
411
- segv .FieldByName ("Addr" ).SetUint (uint64 (dwarfaddr ))
412
- segv .FieldByName ("Prot" ).SetUint (0 )
413
411
414
412
if compressedSects != nil {
415
413
var segSize uint64
416
414
for _ , newSect := range compressedSects {
417
415
segSize += newSect .Size
418
416
}
419
417
segv .FieldByName ("Filesz" ).SetUint (segSize )
420
- segv .FieldByName ("Memsz" ).SetUint (uint64 (Rnd (int64 (segSize ), 1 << pageAlign )))
418
+ } else {
419
+ segv .FieldByName ("Filesz" ).SetUint (dwarfsize )
421
420
}
422
421
423
422
deltaOffset := uint64 (dwarfstart ) - realdwarf .Offset
424
423
deltaAddr := uint64 (dwarfaddr ) - realdwarf .Addr
425
424
426
- // If we set Memsz to 0 (and might as well set Addr too),
427
- // then the xnu kernel will bail out halfway through load_segment
428
- // and not apply further sanity checks that we might fail in the future.
429
- // We don't need the DWARF information actually available in memory.
430
- // But if we do this for buildmode=c-shared then the user-space
431
- // dynamic loader complains about memsz < filesz. Sigh.
432
- if buildmode != BuildModeCShared {
433
- segv .FieldByName ("Addr" ).SetUint (0 )
434
- segv .FieldByName ("Memsz" ).SetUint (0 )
435
- deltaAddr = 0
436
- }
425
+ // We want the DWARF segment to be considered non-loadable, so
426
+ // force vmaddr and vmsize to zero. In addition, set the initial
427
+ // protection to zero so as to make the dynamic loader happy,
428
+ // since otherwise it may complain that that the vm size and file
429
+ // size don't match for the segment. See issues 21647 and 32673
430
+ // for more context. Also useful to refer to the Apple dynamic
431
+ // loader source, specifically ImageLoaderMachO::sniffLoadCommands
432
+ // in ImageLoaderMachO.cpp (various versions can be found online, see
433
+ // https://opensource.apple.com/source/dyld/dyld-519.2.2/src/ImageLoaderMachO.cpp.auto.html
434
+ // as one example).
435
+ segv .FieldByName ("Addr" ).SetUint (0 )
436
+ segv .FieldByName ("Memsz" ).SetUint (0 )
437
+ segv .FieldByName ("Prot" ).SetUint (0 )
438
+ deltaAddr = 0
437
439
438
440
if err := r .WriteAt (0 , seg ); err != nil {
439
441
return err
0 commit comments