]> git.saurik.com Git - apple/ld64.git/blobdiff - src/ld/InputFiles.h
ld64-253.3.tar.gz
[apple/ld64.git] / src / ld / InputFiles.h
index 1565515bf84e8148ca8c4f9ba95195145e275bb8..608ce39f41f20349a0ec035a1a2eea7a26851219 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-*
  *
- * Copyright (c) 2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
@@ -25,6 +25,8 @@
 #ifndef __INPUT_FILES_H__
 #define __INPUT_FILES_H__
 
+#define HAVE_PTHREADS 1
+
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -40,6 +42,9 @@
 #include <mach/mach_host.h>
 #include <dlfcn.h>
 #include <mach-o/dyld.h>
+#if HAVE_PTHREADS
+#include <pthread.h>
+#endif
 
 #include <vector>
 
@@ -58,9 +63,10 @@ public:
        virtual ld::dylib::File*        findDylib(const char* installPath, const char* fromPath);
        
        // 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, ld::File::AtomHandler&) const;
+       bool                                            searchLibraries(const char* name, bool searchDylibs, bool searchArchives,  
+                                                                                                                                 bool dataSymbolOnly, ld::File::AtomHandler&) const;
        // see if any linked dylibs export a weak def of symbol
        bool                                            searchWeakDefInDylib(const char* name) const;
        // copy dylibs to link with in command line order
@@ -68,35 +74,40 @@ public:
        
        bool                                            inferredArch() const { return _inferredArch; }
        
-       uint32_t                                        nextInputOrdinal() const  { return _nextInputOrdinal++; }
-       
+       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);
-       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*                                       makeFile(const Options::FileInfo& info, bool indirectDylib);
+       ld::File*                                       addDylib(ld::dylib::File* f,        const Options::FileInfo& info);
        void                                            logTraceInfo (const char* format, ...) const;
        void                                            logDylib(ld::File*, bool indirect);
        void                                            logArchive(ld::File*) const;
-       void                                            createIndirectDylibs();
+       void                                            markExplicitlyLinkedDylibs();
        void                                            checkDylibClientRestrictions(ld::dylib::File*);
        void                                            createOpaqueFileSections();
+       bool                                            libraryAlreadyLoaded(const char* path);
+       
+       // 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;
 
-       class CStringEquals {
-       public:
-               bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
-       };
-       typedef __gnu_cxx::hash_map<const char*, ld::dylib::File*, __gnu_cxx::hash<const char*>, CStringEquals> InstallNameToDylib;
+       typedef std::unordered_map<const char*, ld::dylib::File*, CStringHash, CStringEquals>   InstallNameToDylib;
 
        const Options&                          _options;
        std::vector<ld::File*>          _inputFiles;
@@ -104,9 +115,40 @@ private:
        InstallNameToDylib                      _installPathToDylibs;
        std::set<ld::dylib::File*>      _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() { return _isDylib; }
+        ld::dylib::File *dylib() { return (ld::dylib::File*)_lib; }
+        ld::archive::File *archive() { return (ld::archive::File*)_lib; }
+    };
+    std::vector<LibraryInfo>  _searchLibraries;
 };
 
 } // namespace tool