#ifndef __INPUT_FILES_H__
#define __INPUT_FILES_H__
#define HAVE_PTHREADS 1
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/sysctl.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
#include <mach/mach_time.h>
#include <mach/vm_statistics.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
#include <dlfcn.h>
#include <mach-o/dyld.h>
#if HAVE_PTHREADS
#include <pthread.h>
#endif
#include <vector>
#include "Options.h"
#include "ld.hpp"
namespace ld {
namespace tool {
class InputFiles : public ld::dylib::File::DylibHandler
{
public:
InputFiles(Options& opts, const char** archName);
virtual ld::dylib::File* findDylib(const char* installPath, const char* fromPath);
void forEachInitialAtom(ld::File::AtomHandler&);
bool searchLibraries(const char* name, bool searchDylibs, bool searchArchives,
bool dataSymbolOnly, ld::File::AtomHandler&) const;
bool searchWeakDefInDylib(const char* name) const;
void dylibs(ld::Internal& state);
bool inferredArch() const { return _inferredArch; }
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);
void logTraceInfo (const char* format, ...) const;
void logDylib(ld::File*, bool indirect);
void logArchive(ld::File*) const;
void createIndirectDylibs();
void checkDylibClientRestrictions(ld::dylib::File*);
void createOpaqueFileSections();
void waitForInputFiles();
static void waitForInputFiles(InputFiles *inputFiles);
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;
InstallNameToDylib _installPathToDylibs;
std::set<ld::dylib::File*> _allDylibs;
ld::dylib::File* _bundleLoader;
bool _allDirectDylibsLoaded;
bool _inferredArch;
struct strcompclass {
bool operator() (const char *a, const char *b) const { return ::strcmp(a, b) < 0; }
};
#if HAVE_PTHREADS
pthread_mutex_t _parseLock;
pthread_cond_t _parseWorkReady; pthread_cond_t _newFileAvailable; int _availableWorkers; int _idleWorkers; int _neededFileSlot; int _parseCursor; int _availableInputFiles; #endif
const char * _exception; int _remainingInputFiles;
ld::File::Ordinal _indirectDylibOrdinal;
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;
};
} }
#endif // __INPUT_FILES_H__