isec->file = this;
isec->name = StringRef(sec.sectname, strnlen(sec.sectname, 16));
isec->segname = StringRef(sec.segname, strnlen(sec.segname, 16));
- isec->data = {buf + sec.offset, static_cast<size_t>(sec.size)};
+ isec->data = {isZeroFill(sec.flags) ? nullptr : buf + sec.offset,
+ static_cast<size_t>(sec.size)};
if (sec.align >= 32)
error("alignment " + std::to_string(sec.align) + " of section " +
isec->name + " is too large");
uint64_t InputSection::getVA() const { return parent->addr + outSecOff; }
void InputSection::writeTo(uint8_t *buf) {
- if (!data.empty())
- memcpy(buf, data.data(), data.size());
+ if (getFileSize() == 0)
+ return;
+
+ memcpy(buf, data.data(), data.size());
for (Reloc &r : relocs) {
uint64_t va = 0;
llvm::PointerUnion<Symbol *, InputSection *> target;
};
+inline bool isZeroFill(uint8_t flags) {
+ return (flags & llvm::MachO::SECTION_TYPE) == llvm::MachO::S_ZEROFILL;
+}
+
class InputSection {
public:
virtual ~InputSection() = default;
virtual uint64_t getSize() const { return data.size(); }
- virtual uint64_t getFileSize() const { return getSize(); }
+ virtual uint64_t getFileSize() const {
+ return isZeroFill(flags) ? 0 : getSize();
+ }
uint64_t getFileOffset() const;
uint64_t getVA() const;
#include "Writer.h"
#include "lld/Common/ErrorHandler.h"
+#include "lld/Common/Memory.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/LEB128.h"
ImageLoaderCacheSection::ImageLoaderCacheSection() {
segname = segment_names::data;
name = "__data";
+ uint8_t *arr = bAlloc.Allocate<uint8_t>(WordSize);
+ memset(arr, 0, WordSize);
+ data = {arr, WordSize};
}
LazyPointerSection::LazyPointerSection()
addr = alignTo(addr, section->align);
fileOff = alignTo(fileOff, section->align);
section->addr = addr;
- section->fileOff = fileOff;
+ section->fileOff = isZeroFill(section->flags) ? 0 : fileOff;
section->finalize();
addr += section->getSize();
--- /dev/null
+# 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 --macho-segment %t | FileCheck %s
+
+## Check that __bss takes up zero file size and is at file offset zero.
+
+# CHECK: Name: __bss
+# CHECK-NEXT: Segment: __DATA
+# CHECK-NEXT: Address:
+# CHECK-NEXT: Size: 0x4
+# CHECK-NEXT: Offset: 0
+# CHECK-NEXT: Alignment: 0
+# CHECK-NEXT: RelocationOffset: 0x0
+# CHECK-NEXT: RelocationCount: 0
+# CHECK-NEXT: Type: ZeroFill (0x1)
+# CHECK-NEXT: Attributes [ (0x0)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Reserved1: 0x0
+# CHECK-NEXT: Reserved2: 0x0
+# CHECK-NEXT: Reserved3: 0x0
+
+# CHECK: Name: __DATA
+# CHECK-NEXT: Size:
+# CHECK-NEXT: vmaddr:
+# CHECK-NEXT: vmsize: 0x4
+# CHECK-NEXT: fileoff:
+# CHECK-NEXT: filesize: 0
+
+.globl _main
+
+.text
+_main:
+ movq $0, %rax
+ retq
+
+.bss
+.zero 4