Index: lib/ReaderWriter/MachO/File.h =================================================================== --- lib/ReaderWriter/MachO/File.h +++ lib/ReaderWriter/MachO/File.h @@ -187,6 +187,10 @@ visitor(offAndAtom.atom, offAndAtom.offset); } + bool subsectionsViaSymbols() const { + return _flags & llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS; + } + protected: std::error_code doParse() override { // Convert binary file to normalized mach-o. @@ -197,6 +201,7 @@ if (std::error_code ec = normalized::normalizedObjectToAtoms( this, **normFile, false)) return ec; + _flags = normFile.get()->flags; return std::error_code(); } @@ -219,7 +224,8 @@ std::unique_ptr _mb; MachOLinkingContext *_ctx; SectionToAtoms _sectionAtoms; - NameToAtom _undefAtoms; + NameToAtom _undefAtoms; + normalized::FileFlags _flags; }; class MachODylibFile : public SharedLibraryFile { Index: lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp =================================================================== --- lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -105,10 +105,12 @@ public: Util(const MachOLinkingContext &ctxt) : _ctx(ctxt), _archHandler(ctxt.archHandler()), _entryAtom(nullptr), - _hasTLVDescriptors(false) {} + _hasTLVDescriptors(false), _subsectionsViaSymbols(true) {} ~Util(); - void assignAtomsToSections(const lld::File &atomFile); + void processDefinedAtoms(const lld::File &atomFile); + void processAtomAttributes(const DefinedAtom *atom); + void assignAtomToSection(const DefinedAtom *atom); void organizeSections(); void assignAddressesToSections(const NormalizedFile &file); uint32_t fileFlags(); @@ -180,6 +182,7 @@ AtomToIndex _atomToSymbolIndex; std::vector _machHeaderAliasAtoms; bool _hasTLVDescriptors; + bool _subsectionsViaSymbols; }; Util::~Util() { @@ -366,15 +369,28 @@ sect->size = offset + atom->size(); } -void Util::assignAtomsToSections(const lld::File &atomFile) { +void Util::processDefinedAtoms(const lld::File &atomFile) { for (const DefinedAtom *atom : atomFile.defined()) { - if (atom->contentType() == DefinedAtom::typeMachHeader) - _machHeaderAliasAtoms.push_back(atom); - else - appendAtom(sectionForAtom(atom), atom); + processAtomAttributes(atom); + assignAtomToSection(atom); } } +void Util::processAtomAttributes(const DefinedAtom *atom) { + auto *machoFile = static_cast(&atom->file()); + // If the file doesn't use subsections via symbols, then make sure we don't + // add that flag to the final output file if we have a relocatable file. + if (!machoFile->subsectionsViaSymbols()) + _subsectionsViaSymbols = false; +} + +void Util::assignAtomToSection(const DefinedAtom *atom) { + if (atom->contentType() == DefinedAtom::typeMachHeader) + _machHeaderAliasAtoms.push_back(atom); + else + appendAtom(sectionForAtom(atom), atom); +} + SegmentInfo *Util::segmentForName(StringRef segName) { for (SegmentInfo *si : _segmentInfos) { if ( si->name.equals(segName) ) @@ -1183,7 +1199,7 @@ uint32_t Util::fileFlags() { // FIXME: these need to determined at runtime. if (_ctx.outputMachOType() == MH_OBJECT) { - return MH_SUBSECTIONS_VIA_SYMBOLS; + return _subsectionsViaSymbols ? MH_SUBSECTIONS_VIA_SYMBOLS : 0; } else { uint32_t flags = MH_DYLDLINK; if (!_ctx.useFlatNamespace()) @@ -1208,7 +1224,7 @@ const MachOLinkingContext &context) { // The util object buffers info until the normalized file can be made. Util util(context); - util.assignAtomsToSections(atomFile); + util.processDefinedAtoms(atomFile); util.organizeSections(); std::unique_ptr f(new NormalizedFile()); Index: test/mach-o/parse-data-relocs-x86_64.yaml =================================================================== --- test/mach-o/parse-data-relocs-x86_64.yaml +++ test/mach-o/parse-data-relocs-x86_64.yaml @@ -323,4 +323,5 @@ # CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ] # CHECK: section-choice: custom-required # CHECK: section-name: __DATA/__custom +# CHECK: dead-strip: never