]> git.saurik.com Git - apple/ld64.git/blobdiff - src/ld/passes/huge.cpp
ld64-274.2.tar.gz
[apple/ld64.git] / src / ld / passes / huge.cpp
index 693976cef69b27c15a3b60e6944b62cf3d5a75d7..3797a23d6c95f9cb9e5e66b197ce705a09a8b17b 100644 (file)
@@ -47,10 +47,53 @@ public:
        }
 };
 
+class DataPadAtom : public ld::Atom {
+public:
+                                                                                       DataPadAtom(ld::Internal& state)
+                                                                                       : ld::Atom(_s_section, ld::Atom::definitionRegular, ld::Atom::combineNever,
+                                                                                                               ld::Atom::scopeTranslationUnit, ld::Atom::typeUnclassified,
+                                                                                                               symbolTableNotIn, false, false, false, ld::Atom::Alignment(3))
+                                                                                       { state.addAtom(*this); }
+
+
+       virtual const ld::File*                                 file() const                                    { return NULL; }
+       virtual const char*                                             name() const                                    { return "padding"; }
+       virtual uint64_t                                                size() const                                    { return 8; }
+       virtual uint64_t                                                objectAddress() const                   { return 0; }
+       virtual void                                                    copyRawContent(uint8_t buffer[]) const { }
+
+protected:
+       virtual                                                                 ~DataPadAtom() {}
+
+       static ld::Section                                              _s_section;
+};
+
+ld::Section DataPadAtom::_s_section("__DATA", "__data", ld::Section::typeUnclassified);
+
+
 void doPass(const Options& opts, ld::Internal& state)
 {
        const bool log = false;
-       
+
+       // <rdar://problem/26015603> add __data section if __DATA segment was gutted by dirty data removal
+       if ( (opts.outputKind() == Options::kDynamicLibrary) && opts.useDataConstSegment() && opts.hasDataSymbolMoves() ) {
+               uint64_t dataAtomsSize = 0;
+               bool foundSegmentDATA_DIRTY = false;
+               for (ld::Internal::FinalSection* sect : state.sections) {
+                       if ( strcmp(sect->segmentName(), "__DATA") == 0 ) {
+                               for (const ld::Atom* atom : sect->atoms) {
+                                       dataAtomsSize += atom->size();
+                               }
+                       }
+                       else if ( strcmp(sect->segmentName(), "__DATA_DIRTY") == 0 ) {
+                               foundSegmentDATA_DIRTY = true;
+                       }
+               }
+               if ( foundSegmentDATA_DIRTY && (dataAtomsSize == 0) ) {
+                       new DataPadAtom(state);
+               }
+       }
+
        // only make make __huge section in final linked images
        if ( opts.outputKind() == Options::kObjectFile )
                return;