c->nsects = seg->numNonHiddenSections();
for (OutputSection *osec : seg->getSections()) {
- c->filesize += osec->getFileSize();
+ if (!isZeroFill(osec->flags)) {
+ assert(osec->fileOff >= seg->fileOff);
+ c->filesize = std::max(
+ c->filesize, osec->fileOff + osec->getFileSize() - seg->fileOff);
+ }
if (osec->isHidden())
continue;
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;
# 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
# 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
-# REQUIRES: x86
+# REQUIRES: x86, shell
# 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 --macho-segment %t | FileCheck %s
+# RUN: (llvm-readobj --macho-segment %t; echo "Total file size"; wc -c %t) | FileCheck %s
## These two segments must always be present at the start of an executable.
# CHECK-NOT: Segment {
# CHECK: Segment {
-# CHECK: Cmd: LC_SEGMENT_64
-# CHECK: Name: __PAGEZERO
-# CHECK: Size: 72
-# CHECK: vmaddr: 0x0
-# CHECK: vmsize: 0x100000000
-# CHECK: fileoff: 0
-# CHECK: filesize: 0
+# CHECK-NEXT: Cmd: LC_SEGMENT_64
+# CHECK-NEXT: Name: __PAGEZERO
+# CHECK-NEXT: Size: 72
+# CHECK-NEXT: vmaddr: 0x0
+# CHECK-NEXT: vmsize: 0x100000000
+# CHECK-NEXT: fileoff: 0
+# CHECK-NEXT: filesize: 0
## The kernel won't execute a binary with the wrong protections for __PAGEZERO.
-# CHECK: maxprot: ---
-# CHECK: initprot: ---
-# CHECK: nsects: 0
-# CHECK: flags: 0x0
-# CHECK: }
-# CHECK: Segment {
-# CHECK: Cmd: LC_SEGMENT_64
-# CHECK: Name: __TEXT
-# CHECK: Size: 152
-# CHECK: vmaddr: 0x100000000
-# CHECK: vmsize:
+# CHECK-NEXT: maxprot: ---
+# CHECK-NEXT: initprot: ---
+# CHECK-NEXT: nsects: 0
+# CHECK-NEXT: flags: 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: Segment {
+# CHECK-NEXT: Cmd: LC_SEGMENT_64
+# CHECK-NEXT: Name: __TEXT
+# CHECK-NEXT: Size: 152
+# CHECK-NEXT: vmaddr: 0x100000000
+# CHECK-NEXT: vmsize:
## dyld3 assumes that the __TEXT segment starts from the file header
-# CHECK: fileoff: 0
-# CHECK: filesize:
-# CHECK: maxprot: rwx
-# CHECK: initprot: r-x
-# CHECK: nsects: 1
-# CHECK: flags: 0x0
-# CHECK: }
+# CHECK-NEXT: fileoff: 0
+# CHECK-NEXT: filesize:
+# CHECK-NEXT: maxprot: rwx
+# CHECK-NEXT: initprot: r-x
+# CHECK-NEXT: nsects: 1
+# CHECK-NEXT: flags: 0x0
+# CHECK-NEXT: }
## Check that we handle max-length names correctly.
# CHECK: Cmd: LC_SEGMENT_64
# CHECK-NEXT: Name: maxlen_16ch_name
-## This segment must always be present at the end of an executable.
+## This segment must always be present at the end of an executable, and cover
+## its last byte.
# CHECK: Name: __LINKEDIT
-# CHECK: maxprot: rwx
-# CHECK: initprot: r--
+# CHECK-NEXT: Size:
+# CHECK-NEXT: vmaddr:
+# CHECK-NEXT: vmsize:
+# CHECK-NEXT: fileoff: [[#%u, LINKEDIT_OFF:]]
+# CHECK-NEXT: filesize: [[#%u, LINKEDIT_SIZE:]]
+# CHECK-NEXT: maxprot: rwx
+# CHECK-NEXT: initprot: r--
# CHECK-NOT: Cmd: LC_SEGMENT_64
+# CHECK-LABEL: Total file size
+# CHECK-NEXT: [[#%u, LINKEDIT_OFF + LINKEDIT_SIZE]]
+
.text
.global _main
_main: