#ifndef __OPTIONS__
#define __OPTIONS__
#include <stdint.h>
#include <mach/machine.h>
#include <vector>
#include <ext/hash_set>
#include <ext/hash_map>
#include "ObjectFile.h"
extern void throwf (const char* format, ...) __attribute__ ((noreturn,format(printf, 1, 2)));
extern void warning(const char* format, ...) __attribute__((format(printf, 1, 2)));
class LibraryOptions
{
public:
LibraryOptions() : fWeakImport(false), fReExport(false), fBundleLoader(false), fLazyLoad(false), fForceLoad(false) {}
bool fWeakImport;
bool fReExport;
bool fBundleLoader;
bool fLazyLoad;
bool fForceLoad;
};
class Options
{
public:
Options(int argc, const char* argv[]);
~Options();
enum OutputKind { kDynamicExecutable, kStaticExecutable, kDynamicLibrary, kDynamicBundle, kObjectFile, kDyld, kPreload, kKextBundle };
enum NameSpace { kTwoLevelNameSpace, kFlatNameSpace, kForceFlatNameSpace };
enum Treatment { kError, kWarning, kSuppress, kNULL, kInvalid };
enum UndefinedTreatment { kUndefinedError, kUndefinedWarning, kUndefinedSuppress, kUndefinedDynamicLookup };
enum WeakReferenceMismatchTreatment { kWeakReferenceMismatchError, kWeakReferenceMismatchWeak,
kWeakReferenceMismatchNonWeak };
enum CommonsMode { kCommonsIgnoreDylibs, kCommonsOverriddenByDylibs, kCommonsConflictsDylibsError };
enum DeadStripMode { kDeadStripOff, kDeadStripOn, kDeadStripOnPlusUnusedInits };
enum UUIDMode { kUUIDNone, kUUIDRandom, kUUIDContent };
enum LocalSymbolHandling { kLocalSymbolsAll, kLocalSymbolsNone, kLocalSymbolsSelectiveInclude, kLocalSymbolsSelectiveExclude };
struct FileInfo {
const char* path;
uint64_t fileLen;
time_t modTime;
LibraryOptions options;
};
struct ExtraSection {
const char* segmentName;
const char* sectionName;
const char* path;
const uint8_t* data;
uint64_t dataLen;
};
struct SectionAlignment {
const char* segmentName;
const char* sectionName;
uint8_t alignment;
};
struct OrderedSymbol {
const char* symbolName;
const char* objectFileName;
};
struct SegmentStart {
const char* name;
uint64_t address;
};
struct SegmentSize {
const char* name;
uint64_t size;
};
struct SegmentProtect {
const char* name;
uint32_t max;
uint32_t init;
};
struct DylibOverride {
const char* installName;
const char* useInstead;
};
const ObjectFile::ReaderOptions& readerOptions();
const char* getOutputFilePath();
std::vector<FileInfo>& getInputFiles();
cpu_type_t architecture() { return fArchitecture; }
bool preferSubArchitecture() { return fHasPreferredSubType; }
cpu_subtype_t subArchitecture() { return fSubArchitecture; }
bool allowSubArchitectureMismatches() { return fAllowCpuSubtypeMismatches; }
OutputKind outputKind();
bool prebind();
bool bindAtLoad();
bool fullyLoadArchives();
NameSpace nameSpace();
const char* installPath(); uint32_t currentVersion(); uint32_t compatibilityVersion(); const char* entryName(); const char* executablePath();
uint64_t baseAddress();
bool keepPrivateExterns(); bool needsModuleTable(); bool interposable(const char* name);
bool hasExportRestrictList(); bool hasExportMaskList(); bool hasWildCardExportRestrictList();
bool allGlobalsAreDeadStripRoots();
bool shouldExport(const char*);
bool ignoreOtherArchInputFiles();
bool forceCpuSubtypeAll();
bool traceDylibs();
bool traceArchives();
DeadStripMode deadStrip();
UndefinedTreatment undefinedTreatment();
ObjectFile::ReaderOptions::MacVersionMin macosxVersionMin() { return fReaderOptions.fMacVersionMin; }
ObjectFile::ReaderOptions::IPhoneVersionMin iphoneOSVersionMin() { return fReaderOptions.fIPhoneVersionMin; }
bool minOS(ObjectFile::ReaderOptions::MacVersionMin mac, ObjectFile::ReaderOptions::IPhoneVersionMin iPhoneOS);
bool messagesPrefixedWithArchitecture();
Treatment picTreatment();
WeakReferenceMismatchTreatment weakReferenceMismatchTreatment();
const char* umbrellaName();
std::vector<const char*>& allowableClients();
const char* clientName();
const char* initFunctionName(); const char* dotOutputFile();
uint64_t zeroPageSize();
bool hasCustomStack();
uint64_t customStackSize();
uint64_t customStackAddr();
bool hasExecutableStack();
std::vector<const char*>& initialUndefines();
bool printWhyLive(const char* name);
uint32_t minimumHeaderPad();
uint64_t segmentAlignment() { return fSegmentAlignment; }
bool maxMminimumHeaderPad() { return fMaxMinimumHeaderPad; }
std::vector<ExtraSection>& extraSections();
std::vector<SectionAlignment>& sectionAlignments();
CommonsMode commonsMode();
bool warnCommons();
bool keepRelocations();
FileInfo findFile(const char* path);
UUIDMode getUUIDMode() { return fUUIDMode; }
bool warnStabs();
bool pauseAtEnd() { return fPause; }
bool printStatistics() { return fStatistics; }
bool printArchPrefix() { return fMessagesPrefixedWithArchitecture; }
void gotoClassicLinker(int argc, const char* argv[]);
bool sharedRegionEligible() { return fSharedRegionEligible; }
bool printOrderFileStatistics() { return fPrintOrderFileStatistics; }
const char* dTraceScriptName() { return fDtraceScriptName; }
bool dTrace() { return (fDtraceScriptName != NULL); }
std::vector<OrderedSymbol>& orderedSymbols() { return fOrderedSymbols; }
bool splitSeg() { return fSplitSegs; }
uint64_t baseWritableAddress() { return fBaseWritableAddress; }
std::vector<SegmentStart>& customSegmentAddresses() { return fCustomSegmentAddresses; }
std::vector<SegmentSize>& customSegmentSizes() { return fCustomSegmentSizes; }
std::vector<SegmentProtect>& customSegmentProtections() { return fCustomSegmentProtections; }
bool saveTempFiles() { return fSaveTempFiles; }
const std::vector<const char*>& rpaths() { return fRPaths; }
bool readOnlyx86Stubs() { return fReadOnlyx86Stubs; }
std::vector<DylibOverride>& dylibOverrides() { return fDylibOverrides; }
const char* generatedMapPath() { return fMapPath; }
bool positionIndependentExecutable() { return fPositionIndependentExecutable; }
Options::FileInfo findFileUsingPaths(const char* path);
bool deadStripDylibs() { return fDeadStripDylibs; }
bool allowedUndefined(const char* name) { return ( fAllowedUndefined.find(name) != fAllowedUndefined.end() ); }
bool someAllowedUndefines() { return (fAllowedUndefined.size() != 0); }
LocalSymbolHandling localSymbolHandling() { return fLocalSymbolHandling; }
bool keepLocalSymbol(const char* symbolName);
bool allowTextRelocs() { return fAllowTextRelocs; }
bool warnAboutTextRelocs() { return fWarnTextRelocs; }
bool usingLazyDylibLinking() { return fUsingLazyDylibLinking; }
bool verbose() { return fVerbose; }
bool makeEncryptable() { return fEncryptable; }
bool needsUnwindInfoSection() { return fReaderOptions.fAddCompactUnwindEncoding; }
std::vector<const char*>& llvmOptions() { return fLLVMOptions; }
bool makeClassicDyldInfo() { return fMakeClassicDyldInfo; }
bool makeCompressedDyldInfo() { return fMakeCompressedDyldInfo; }
bool hasExportedSymbolOrder();
bool exportedSymbolOrder(const char* sym, unsigned int* order);
bool orderData() { return fOrderData; }
bool errorOnOtherArchFiles() { return fErrorOnOtherArchFiles; }
bool markAutoDeadStripDylib() { return fMarkDeadStrippableDylib; }
bool removeEHLabels() { return fReaderOptions.fNoEHLabels; }
bool useSimplifiedDylibReExports() { return fUseSimplifiedDylibReExports; }
bool objCABIVersion2POverride() { return fObjCABIVersion2POverride; }
private:
class CStringEquals
{
public:
bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
};
typedef __gnu_cxx::hash_map<const char*, unsigned int, __gnu_cxx::hash<const char*>, CStringEquals> NameToOrder;
typedef __gnu_cxx::hash_set<const char*, __gnu_cxx::hash<const char*>, CStringEquals> NameSet;
enum ExportMode { kExportDefault, kExportSome, kDontExportSome };
enum LibrarySearchMode { kSearchDylibAndArchiveInEachDir, kSearchAllDirsForDylibsThenAllDirsForArchives };
enum InterposeMode { kInterposeNone, kInterposeAllExternal, kInterposeSome };
class SetWithWildcards {
public:
void insert(const char*);
bool contains(const char*);
bool hasWildCards() { return !fWildCard.empty(); }
NameSet::iterator regularBegin() { return fRegular.begin(); }
NameSet::iterator regularEnd() { return fRegular.end(); }
private:
static bool hasWildCards(const char*);
bool wildCardMatch(const char* pattern, const char* candidate);
bool inCharRange(const char*& range, unsigned char c);
NameSet fRegular;
std::vector<const char*> fWildCard;
};
void parse(int argc, const char* argv[]);
void checkIllegalOptionCombinations();
void buildSearchPaths(int argc, const char* argv[]);
void parseArch(const char* architecture);
FileInfo findLibrary(const char* rootName, bool dylibsOnly=false);
FileInfo findFramework(const char* frameworkName);
FileInfo findFramework(const char* rootName, const char* suffix);
bool checkForFile(const char* format, const char* dir, const char* rootName,
FileInfo& result);
uint32_t parseVersionNumber(const char*);
void parseSectionOrderFile(const char* segment, const char* section, const char* path);
void parseOrderFile(const char* path, bool cstring);
void addSection(const char* segment, const char* section, const char* path);
void addSubLibrary(const char* name);
void loadFileList(const char* fileOfPaths);
uint64_t parseAddress(const char* addr);
void loadExportFile(const char* fileOfExports, const char* option, SetWithWildcards& set);
void parseAliasFile(const char* fileOfAliases);
void parsePreCommandLineEnvironmentSettings();
void parsePostCommandLineEnvironmentSettings();
void setUndefinedTreatment(const char* treatment);
void setMacOSXVersionMin(const char* version);
void setIPhoneVersionMin(const char* version);
void setWeakReferenceMismatchTreatment(const char* treatment);
void addDylibOverride(const char* paths);
void addSectionAlignment(const char* segment, const char* section, const char* alignment);
CommonsMode parseCommonsTreatment(const char* mode);
Treatment parseTreatment(const char* treatment);
void reconfigureDefaults();
void checkForClassic(int argc, const char* argv[]);
void parseSegAddrTable(const char* segAddrPath, const char* installPath);
void addLibrary(const FileInfo& info);
void warnObsolete(const char* arg);
uint32_t parseProtection(const char* prot);
void loadSymbolOrderFile(const char* fileOfExports, NameToOrder& orderMapping);
ObjectFile::ReaderOptions fReaderOptions;
const char* fOutputFile;
std::vector<Options::FileInfo> fInputFiles;
cpu_type_t fArchitecture;
cpu_subtype_t fSubArchitecture;
OutputKind fOutputKind;
bool fHasPreferredSubType;
bool fPrebind;
bool fBindAtLoad;
bool fKeepPrivateExterns;
bool fNeedsModuleTable;
bool fIgnoreOtherArchFiles;
bool fErrorOnOtherArchFiles;
bool fForceSubtypeAll;
InterposeMode fInterposeMode;
DeadStripMode fDeadStrip;
NameSpace fNameSpace;
uint32_t fDylibCompatVersion;
uint32_t fDylibCurrentVersion;
const char* fDylibInstallName;
const char* fFinalName;
const char* fEntryName;
uint64_t fBaseAddress;
uint64_t fBaseWritableAddress;
bool fSplitSegs;
SetWithWildcards fExportSymbols;
SetWithWildcards fDontExportSymbols;
SetWithWildcards fInterposeList;
NameToOrder fExportSymbolsOrder;
ExportMode fExportMode;
LibrarySearchMode fLibrarySearchMode;
UndefinedTreatment fUndefinedTreatment;
bool fMessagesPrefixedWithArchitecture;
WeakReferenceMismatchTreatment fWeakReferenceMismatchTreatment;
std::vector<const char*> fSubUmbellas;
std::vector<const char*> fSubLibraries;
std::vector<const char*> fAllowableClients;
std::vector<const char*> fRPaths;
const char* fClientName;
const char* fUmbrellaName;
const char* fInitFunctionName;
const char* fDotOutputFile;
const char* fExecutablePath;
const char* fBundleLoader;
const char* fDtraceScriptName;
const char* fSegAddrTablePath;
const char* fMapPath;
uint64_t fZeroPageSize;
uint64_t fStackSize;
uint64_t fStackAddr;
bool fExecutableStack;
uint32_t fMinimumHeaderPad;
uint64_t fSegmentAlignment;
CommonsMode fCommonsMode;
UUIDMode fUUIDMode;
SetWithWildcards fLocalSymbolsIncluded;
SetWithWildcards fLocalSymbolsExcluded;
LocalSymbolHandling fLocalSymbolHandling;
bool fWarnCommons;
bool fVerbose;
bool fKeepRelocations;
bool fWarnStabs;
bool fTraceDylibSearching;
bool fPause;
bool fStatistics;
bool fPrintOptions;
bool fSharedRegionEligible;
bool fPrintOrderFileStatistics;
bool fReadOnlyx86Stubs;
bool fPositionIndependentExecutable;
bool fDisablePositionIndependentExecutable;
bool fMaxMinimumHeaderPad;
bool fDeadStripDylibs;
bool fAllowTextRelocs;
bool fWarnTextRelocs;
bool fUsingLazyDylibLinking;
bool fEncryptable;
bool fOrderData;
bool fMarkDeadStrippableDylib;
bool fMakeClassicDyldInfo;
bool fMakeCompressedDyldInfo;
bool fNoEHLabels;
bool fAllowCpuSubtypeMismatches;
bool fUseSimplifiedDylibReExports;
bool fObjCABIVersion2POverride;
std::vector<const char*> fInitialUndefines;
NameSet fAllowedUndefined;
NameSet fWhyLive;
std::vector<ExtraSection> fExtraSections;
std::vector<SectionAlignment> fSectionAlignments;
std::vector<OrderedSymbol> fOrderedSymbols;
std::vector<SegmentStart> fCustomSegmentAddresses;
std::vector<SegmentSize> fCustomSegmentSizes;
std::vector<SegmentProtect> fCustomSegmentProtections;
std::vector<DylibOverride> fDylibOverrides;
std::vector<const char*> fLLVMOptions;
std::vector<const char*> fLibrarySearchPaths;
std::vector<const char*> fFrameworkSearchPaths;
std::vector<const char*> fSDKPaths;
bool fSaveTempFiles;
};
#endif // __OPTIONS__