X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/a645023da60d22e86be13f7b4d97adeff8bc6665..bee7e226299dacc6d80d9cf6f1585c3d5d0645e0:/src/ld/InputFiles.h?ds=sidebyside

diff --git a/src/ld/InputFiles.h b/src/ld/InputFiles.h
index 1565515..21f878a 100644
--- a/src/ld/InputFiles.h
+++ b/src/ld/InputFiles.h
@@ -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>
 
@@ -55,58 +60,99 @@ 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, 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
 	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);
-	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						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<const char*, ld::dylib::File*, __gnu_cxx::hash<const char*>, 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<const char*, ld::dylib::File*, CStringHash, CStringEquals>	InstallNameToDylib;
 
 	const Options&				_options;
 	std::vector<ld::File*>		_inputFiles;
 	mutable std::set<class ld::File*>	_archiveFilesLogged;
+	mutable std::vector<std::string>	_archiveFilePaths;
 	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() 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<LibraryInfo>  _searchLibraries;
 };
 
 } // namespace tool