X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/afe874b1634377ecb27057ee76deb04915bb34d7..bee7e226299dacc6d80d9cf6f1585c3d5d0645e0:/src/ld/InputFiles.h diff --git a/src/ld/InputFiles.h b/src/ld/InputFiles.h index 1842c8e..21f878a 100644 --- a/src/ld/InputFiles.h +++ b/src/ld/InputFiles.h @@ -25,6 +25,8 @@ #ifndef __INPUT_FILES_H__ #define __INPUT_FILES_H__ +#define HAVE_PTHREADS 1 + #include #include #include @@ -40,6 +42,9 @@ #include #include #include +#if HAVE_PTHREADS +#include +#endif #include @@ -55,10 +60,10 @@ public: InputFiles(Options& opts, const char** archName); // implementation from ld::dylib::File::DylibHandler - virtual ld::dylib::File* findDylib(const char* installPath, const char* fromPath); + virtual ld::dylib::File* findDylib(const char* installPath, const ld::dylib::File* fromDylib, bool speculative); // iterates all atoms in initial files - bool forEachInitialAtom(ld::File::AtomHandler&) const; + void forEachInitialAtom(ld::File::AtomHandler&, ld::Internal& state); // searches libraries for name bool searchLibraries(const char* name, bool searchDylibs, bool searchArchives, bool dataSymbolOnly, ld::File::AtomHandler&) const; @@ -67,47 +72,87 @@ public: // copy dylibs to link with in command line order void dylibs(ld::Internal& state); - bool inferredArch() const { return _inferredArch; } + void archives(ld::Internal& state); - uint32_t nextInputOrdinal() const { return _nextInputOrdinal++; } + bool inferredArch() const { return _inferredArch; } + void addLinkerOptionLibraries(ld::Internal& state, ld::File::AtomHandler& handler); + void createIndirectDylibs(); + // for -print_statistics - uint64_t _totalObjectSize; - uint64_t _totalArchiveSize; - uint32_t _totalObjectLoaded; - uint32_t _totalArchivesLoaded; - uint32_t _totalDylibsLoaded; + volatile int64_t _totalObjectSize; + volatile int64_t _totalArchiveSize; + volatile int32_t _totalObjectLoaded; + volatile int32_t _totalArchivesLoaded; + volatile int32_t _totalDylibsLoaded; private: void inferArchitecture(Options& opts, const char** archName); const char* fileArch(const uint8_t* p, unsigned len); ld::File* makeFile(const Options::FileInfo& info, bool indirectDylib); - ld::File* addDylib(ld::dylib::File* f, const Options::FileInfo& info, uint64_t mappedLen); - ld::File* addObject(ld::relocatable::File* f, const Options::FileInfo& info, uint64_t mappedLen); - ld::File* addArchive(ld::File* f, const Options::FileInfo& info, uint64_t mappedLen); + ld::File* addDylib(ld::dylib::File* f, const Options::FileInfo& info); void logTraceInfo (const char* format, ...) const; - void logDylib(ld::File*, bool indirect); + void logDylib(ld::File*, bool indirect, bool speculative); void logArchive(ld::File*) const; - void createIndirectDylibs(); + void markExplicitlyLinkedDylibs(); void checkDylibClientRestrictions(ld::dylib::File*); void createOpaqueFileSections(); + bool libraryAlreadyLoaded(const char* path); + bool frameworkAlreadyLoaded(const char* path, const char* frameworkName); - class CStringEquals { - public: - bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } - }; - typedef __gnu_cxx::hash_map, CStringEquals> InstallNameToDylib; + // for pipelined linking + void waitForInputFiles(); + static void waitForInputFiles(InputFiles *inputFiles); + + // for threaded input file processing + void parseWorkerThread(); + static void parseWorkerThread(InputFiles *inputFiles); + void startThread(void (*threadFunc)(InputFiles *)) const; + + typedef std::unordered_map InstallNameToDylib; const Options& _options; std::vector _inputFiles; mutable std::set _archiveFilesLogged; + mutable std::vector _archiveFilePaths; InstallNameToDylib _installPathToDylibs; std::set _allDylibs; ld::dylib::File* _bundleLoader; - mutable uint32_t _nextInputOrdinal; - bool _allDirectDylibsLoaded; bool _inferredArch; + struct strcompclass { + bool operator() (const char *a, const char *b) const { return ::strcmp(a, b) < 0; } + }; + + // for threaded input file processing +#if HAVE_PTHREADS + pthread_mutex_t _parseLock; + pthread_cond_t _parseWorkReady; // used by parse threads to block for work + pthread_cond_t _newFileAvailable; // used by main thread to block for parsed input files + int _availableWorkers; // number of remaining unstarted parse threads + int _idleWorkers; // number of running parse threads that are idle + int _neededFileSlot; // input file the resolver is currently blocked waiting for + int _parseCursor; // slot to begin searching for a file to parse + int _availableInputFiles; // number of input fileinfos with readyToParse==true +#endif + const char * _exception; // passes an exception message from parse thread to main thread + int _remainingInputFiles; // number of input files still to parse + + ld::File::Ordinal _indirectDylibOrdinal; + ld::File::Ordinal _linkerOptionOrdinal; + + class LibraryInfo { + ld::File* _lib; + bool _isDylib; + public: + LibraryInfo(ld::dylib::File* dylib) : _lib(dylib), _isDylib(true) {}; + LibraryInfo(ld::archive::File* dylib) : _lib(dylib), _isDylib(false) {}; + + bool isDylib() const { return _isDylib; } + ld::dylib::File *dylib() const { return (ld::dylib::File*)_lib; } + ld::archive::File *archive() const { return (ld::archive::File*)_lib; } + }; + std::vector _searchLibraries; }; } // namespace tool