diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -351,6 +351,10 @@ StringRef segname = osec->parent->name; if (segname == segment_names::text && osec->name == section_names::header) return std::numeric_limits::min(); + // ZeroFill sections must always be the at the end of their segments, + // otherwise subsequent sections may get overwritten with zeroes at runtime. + if (isZeroFill(osec->flags)) + return std::numeric_limits::max(); return 0; } diff --git a/lld/test/MachO/bss.s b/lld/test/MachO/bss.s --- a/lld/test/MachO/bss.s +++ b/lld/test/MachO/bss.s @@ -3,9 +3,27 @@ # RUN: lld -flavor darwinnew -arch x86_64 -o %t %t.o # RUN: llvm-readobj --section-headers --macho-segment %t | FileCheck %s -## Check that __bss takes up zero file size and is at file offset zero. +## Check that __bss takes up zero file size, is at file offset zero, and +## appears at the end of its segment. -# CHECK: Name: __bss +# CHECK: Index: 1 +# CHECK-NEXT: Name: __data +# CHECK-NEXT: Segment: __DATA +# CHECK-NEXT: Address: +# CHECK-NEXT: Size: 0x8 +# CHECK-NEXT: Offset: 4096 +# CHECK-NEXT: Alignment: 0 +# CHECK-NEXT: RelocationOffset: 0x0 +# CHECK-NEXT: RelocationCount: 0 +# CHECK-NEXT: Type: Regular (0x0) +# CHECK-NEXT: Attributes [ (0x0) +# CHECK-NEXT: ] +# CHECK-NEXT: Reserved1: 0x0 +# CHECK-NEXT: Reserved2: 0x0 +# CHECK-NEXT: Reserved3: 0x0 + +# CHECK: Index: 2 +# CHECK-NEXT: Name: __bss # CHECK-NEXT: Segment: __DATA # CHECK-NEXT: Address: # CHECK-NEXT: Size: 0x4 @@ -23,9 +41,9 @@ # CHECK: Name: __DATA # CHECK-NEXT: Size: # CHECK-NEXT: vmaddr: -# CHECK-NEXT: vmsize: 0x4 +# CHECK-NEXT: vmsize: 0xC # CHECK-NEXT: fileoff: -# CHECK-NEXT: filesize: 0 +# CHECK-NEXT: filesize: 8 .globl _main @@ -36,3 +54,6 @@ .bss .zero 4 + +.data +.quad 0x1234