diff --git a/lld/lib/ReaderWriter/MachO/Atoms.h b/lld/lib/ReaderWriter/MachO/Atoms.h index b21a1ac5005c..0d41d609cfbe 100644 --- a/lld/lib/ReaderWriter/MachO/Atoms.h +++ b/lld/lib/ReaderWriter/MachO/Atoms.h @@ -16,24 +16,36 @@ namespace lld { namespace mach_o { class MachODefinedAtom : public SimpleDefinedAtom { public: - // FIXME: This constructor should also take the ContentType. - MachODefinedAtom(const File &f, const StringRef name, - const ArrayRef content, Scope scope) - : SimpleDefinedAtom(f), _name(name), _content(content), _scope(scope) {} + MachODefinedAtom(const File &f, const StringRef name, Scope scope, + ContentType type, const ArrayRef content) + : SimpleDefinedAtom(f), _name(name), _content(content), + _contentType(type), _scope(scope) {} - uint64_t size() const override { return rawContent().size(); } + // Constructor for zero-fill content + MachODefinedAtom(const File &f, const StringRef name, Scope scope, + uint64_t size) + : SimpleDefinedAtom(f), _name(name), + _content(ArrayRef(nullptr, size)), + _contentType(DefinedAtom::typeZeroFill), _scope(scope) {} - ContentType contentType() const override { return DefinedAtom::typeCode; } + uint64_t size() const override { return _content.size(); } + + ContentType contentType() const override { return _contentType; } StringRef name() const override { return _name; } Scope scope() const override { return _scope; } - ArrayRef rawContent() const override { return _content; } + ArrayRef rawContent() const override { + // Zerofill atoms have a content pointer which is null. + assert(_content.data() != nullptr); + return _content; + } private: const StringRef _name; const ArrayRef _content; + const ContentType _contentType; const Scope _scope; }; diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h index 767d5230cf62..755dedf0a3e5 100644 --- a/lld/lib/ReaderWriter/MachO/File.h +++ b/lld/lib/ReaderWriter/MachO/File.h @@ -21,15 +21,27 @@ class MachOFile : public SimpleFile { public: MachOFile(StringRef path) : SimpleFile(path) {} - void addDefinedAtom(StringRef name, ArrayRef content, - Atom::Scope scope, bool copyRefs) { + void addDefinedAtom(StringRef name, Atom::Scope scope, + DefinedAtom::ContentType type, + ArrayRef content, bool copyRefs) { if (copyRefs) { // Make a copy of the atom's name and content that is owned by this file. name = name.copy(_allocator); content = content.copy(_allocator); } MachODefinedAtom *atom = - new (_allocator) MachODefinedAtom(*this, name, content, scope); + new (_allocator) MachODefinedAtom(*this, name, scope, type, content); + addAtom(*atom); + } + + void addZeroFillDefinedAtom(StringRef name, Atom::Scope scope, uint64_t size, + bool copyRefs) { + if (copyRefs) { + // Make a copy of the atom's name and content that is owned by this file. + name = name.copy(_allocator); + } + MachODefinedAtom *atom = + new (_allocator) MachODefinedAtom(*this, name, scope, size); addAtom(*atom); } diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp index 59452fbc3ddc..ab29f858b4ec 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -74,6 +74,11 @@ static Atom::Scope atomScope(uint8_t scope) { llvm_unreachable("unknown scope value!"); } +static DefinedAtom::ContentType atomTypeFromSection(const Section §ion) { + // FIX ME + return DefinedAtom::typeCode; +} + static void processSymbol(const NormalizedFile &normalizedFile, MachOFile &file, const Symbol &sym, bool copyRefs) { // Mach-O symbol table does have size in it, so need to scan ahead @@ -81,8 +86,13 @@ static void processSymbol(const NormalizedFile &normalizedFile, MachOFile &file, const Section §ion = normalizedFile.sections[sym.sect - 1]; uint64_t offset = sym.value - section.address; uint64_t size = nextSymbolAddress(normalizedFile, sym) - sym.value; - ArrayRef atomContent = section.content.slice(offset, size); - file.addDefinedAtom(sym.name, atomContent, atomScope(sym.scope), copyRefs); + if (section.type == llvm::MachO::S_ZEROFILL){ + file.addZeroFillDefinedAtom(sym.name, atomScope(sym.scope), size, copyRefs); + } else { + ArrayRef atomContent = section.content.slice(offset, size); + file.addDefinedAtom(sym.name, atomScope(sym.scope), + atomTypeFromSection(section), atomContent, copyRefs); + } } diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp index fb63cac227e9..691a1bc1eeaa 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp @@ -278,9 +278,19 @@ struct MappingTraits
{ io.mapOptional("attributes", sect.attributes); io.mapOptional("alignment", sect.alignment, 0U); io.mapRequired("address", sect.address); - MappingNormalization> content( + if (sect.type == llvm::MachO::S_ZEROFILL) { + // S_ZEROFILL sections use "size:" instead of "content:" + uint64_t size = sect.content.size(); + io.mapOptional("size", size); + if (!io.outputting()) { + uint8_t *bytes = nullptr; + sect.content = makeArrayRef(bytes, size); + } + } else { + MappingNormalization> content( io, sect.content); - io.mapOptional("content", content->_normalizedContent); + io.mapOptional("content", content->_normalizedContent); + } io.mapOptional("relocations", sect.relocations); io.mapOptional("indirect-syms", sect.indirectSymbols); } diff --git a/lld/test/mach-o/parse-data.yaml b/lld/test/mach-o/parse-data.yaml index c09162798d29..d280750f7b7f 100644 --- a/lld/test/mach-o/parse-data.yaml +++ b/lld/test/mach-o/parse-data.yaml @@ -33,7 +33,7 @@ sections: attributes: [ ] alignment: 2 address: 0x0000000000000014 - content: [ 0x00, 0x00, 0x00, 0x00 ] + size: 4 local-symbols: - name: _s1 type: N_SECT @@ -62,6 +62,11 @@ global-symbols: ... # CHECK: defined-atoms: + +# CHECK: - name: _s1 +# CHECK: type: zero-fill +# CHECK: size: 4 + # CHECK: - name: _a # CHECK: scope: global # CHECK: content: [ 01, 02, 03, 04, 05, 06, 07, 08 ] @@ -74,8 +79,5 @@ global-symbols: # CHECK: scope: global # CHECK: content: [ 21, 22, 23, 24 ] -# CHECK: - name: _s1 -# CHECK: content: [ 00, 00, 00, 00 ] - # CHECK: - name: _s2 # CHECK: content: [ 31, 32, 33, 34 ]