diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -134,7 +134,10 @@ c->nsects = seg->numNonHiddenSections(); for (OutputSection *osec : seg->getSections()) { - c->filesize += osec->getFileSize(); + // This condition should hold unless we are dealing with a __bss section. + if (osec->fileOff >= seg->fileOff) + c->filesize = std::max( + c->filesize, osec->fileOff + osec->getFileSize() - seg->fileOff); if (osec->isHidden()) continue; @@ -451,6 +454,8 @@ seg->fileOff = fileOff; for (auto *osec : seg->getSections()) { + if (!osec->isNeeded()) + continue; addr = alignTo(addr, osec->align); fileOff = alignTo(fileOff, osec->align); osec->addr = addr; diff --git a/lld/test/MachO/section-headers.s b/lld/test/MachO/section-headers.s --- a/lld/test/MachO/section-headers.s +++ b/lld/test/MachO/section-headers.s @@ -1,7 +1,7 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o # RUN: lld -flavor darwinnew -o %t %t.o -# RUN: llvm-readobj --section-headers %t | FileCheck %s +# RUN: llvm-readobj --section-headers --macho-segment %t | FileCheck %s # CHECK: Name: __text # CHECK-NEXT: Segment: __TEXT @@ -25,11 +25,21 @@ # CHECK: Name: maxlen_16ch_name # CHECK-NEXT: Segment: __TEXT -# CHECK-NOT: } -# CHECK: Alignment: 3 +# CHECK-NEXT: Address: +# CHECK-NEXT: Size: [[#%x, LAST_SEC_SIZE:]] +# CHECK-NEXT: Offset: [[#%u, LAST_SEC_OFF:]] +# CHECK-NEXT: Alignment: 3 # CHECK-NOT: } # CHECK: Type: Regular (0x0) +# CHECK-LABEL: Segment { +# CHECK: Name: __TEXT +# CHECK-NEXT: Size: +# CHECK-NEXT: vmaddr: +# CHECK-NEXT: vmsize: +# CHECK-NEXT: fileoff: 0 +# CHECK-NEXT: filesize: [[#%u, LAST_SEC_SIZE + LAST_SEC_OFF]] + .text .align 1 .global _main