#include "ld.hpp"
#include "Snapshot.h"
+#include "MachOFileAbstraction.hpp"
extern void throwf (const char* format, ...) __attribute__ ((noreturn,format(printf, 1, 2)));
extern void warning(const char* format, ...) __attribute__((format(printf, 1, 2)));
enum CommonsMode { kCommonsIgnoreDylibs, kCommonsOverriddenByDylibs, kCommonsConflictsDylibsError };
enum UUIDMode { kUUIDNone, kUUIDRandom, kUUIDContent };
enum LocalSymbolHandling { kLocalSymbolsAll, kLocalSymbolsNone, kLocalSymbolsSelectiveInclude, kLocalSymbolsSelectiveExclude };
+ enum BitcodeMode { kBitcodeProcess, kBitcodeAsData, kBitcodeMarker, kBitcodeStrip };
enum DebugInfoStripping { kDebugInfoNone, kDebugInfoMinimal, kDebugInfoFull };
+ enum UnalignedPointerTreatment { kUnalignedPointerError, kUnalignedPointerWarning, kUnalignedPointerIgnore };
+#if SUPPORT_APPLE_TV
+ enum Platform { kPlatformUnknown, kPlatformOSX=1, kPlatformiOS=2, kPlatformWatchOS=3, kPlatform_tvOS=4, kPlatform_bridgeOS=5 };
+#else
+ enum Platform { kPlatformUnknown, kPlatformOSX, kPlatformiOS, kPlatformWatchOS };
+#endif
+
+ static Platform platformForLoadCommand(uint32_t lc) {
+ switch (lc) {
+ case LC_VERSION_MIN_MACOSX:
+ return kPlatformOSX;
+ case LC_VERSION_MIN_IPHONEOS:
+ return kPlatformiOS;
+ case LC_VERSION_MIN_WATCHOS:
+ return kPlatformWatchOS;
+ #if SUPPORT_APPLE_TV
+ case LC_VERSION_MIN_TVOS:
+ return kPlatform_tvOS;
+ #endif
+ }
+ assert(!lc && "unknown LC_VERSION_MIN load command");
+ return kPlatformUnknown;
+ }
+
+ static const char* platformName(Platform platform) {
+ switch (platform) {
+ case kPlatformOSX:
+ return "OSX";
+ case kPlatformiOS:
+ return "iOS";
+ case kPlatformWatchOS:
+ return "watchOS";
+ #if SUPPORT_APPLE_TV
+ case kPlatform_tvOS:
+ return "tvOS";
+ #endif
+ case kPlatform_bridgeOS:
+ return "bridgeOS";
+ case kPlatformUnknown:
+ default:
+ return "(unknown)";
+ }
+ }
+
+ static void userReadableSwiftVersion(uint8_t value, char versionString[64])
+ {
+ switch (value) {
+ case 1:
+ strcpy(versionString, "1.0");
+ break;
+ case 2:
+ strcpy(versionString, "1.1");
+ break;
+ case 3:
+ strcpy(versionString, "2.0");
+ break;
+ case 4:
+ strcpy(versionString, "3.0");
+ break;
+ case 5:
+ strcpy(versionString, "4.0");
+ break;
+ default:
+ sprintf(versionString, "unknown ABI version 0x%02X", value);
+ }
+ }
+
class FileInfo {
public:
const char* path;
- uint64_t fileLen;
time_t modTime;
LibraryOptions options;
ld::File::Ordinal ordinal;
// The use pattern for FileInfo is to create one on the stack in a leaf function and return
// it to the calling frame by copy. Therefore the copy constructor steals the path string from
// the source, which dies with the stack frame.
- FileInfo(FileInfo const &other) : path(other.path), fileLen(other.fileLen), modTime(other.modTime), options(other.options), ordinal(other.ordinal), fromFileList(other.fromFileList), inputFileSlot(-1) { ((FileInfo&)other).path = NULL; };
+ FileInfo(FileInfo const &other) : path(other.path), modTime(other.modTime), options(other.options), ordinal(other.ordinal), fromFileList(other.fromFileList), inputFileSlot(-1) { ((FileInfo&)other).path = NULL; };
+
+ FileInfo &operator=(FileInfo other) {
+ std::swap(path, other.path);
+ std::swap(modTime, other.modTime);
+ std::swap(options, other.options);
+ std::swap(ordinal, other.ordinal);
+ std::swap(fromFileList, other.fromFileList);
+ std::swap(inputFileSlot, other.inputFileSlot);
+ std::swap(readyToParse, other.readyToParse);
+ return *this;
+ }
// Create an empty FileInfo. The path can be set implicitly by checkFileExists().
- FileInfo() : path(NULL), fileLen(0), modTime(0), options(), fromFileList(false) {};
+ FileInfo() : path(NULL), modTime(-1), options(), fromFileList(false) {};
// Create a FileInfo for a specific path, but does not stat the file.
- FileInfo(const char *_path) : path(strdup(_path)), fileLen(0), modTime(0), options(), fromFileList(false) {};
+ FileInfo(const char *_path) : path(strdup(_path)), modTime(-1), options(), fromFileList(false) {};
~FileInfo() { if (path) ::free((void*)path); }
// Returns true if a previous call to checkFileExists() succeeded.
// Returns false if the file does not exist of checkFileExists() has never been called.
- bool missing() const { return modTime==0; }
+ bool missing() const { return modTime == -1; }
};
struct ExtraSection {
bool preferSubArchitecture() const { return fHasPreferredSubType; }
cpu_subtype_t subArchitecture() const { return fSubArchitecture; }
bool allowSubArchitectureMismatches() const { return fAllowCpuSubtypeMismatches; }
+ bool enforceDylibSubtypesMatch() const { return fEnforceDylibSubtypesMatch; }
bool forceCpuSubtypeAll() const { return fForceSubtypeAll; }
const char* architectureName() const { return fArchitectureName; }
- void setArchitecture(cpu_type_t, cpu_subtype_t subtype);
+ void setArchitecture(cpu_type_t, cpu_subtype_t subtype, Options::Platform platform);
bool archSupportsThumb2() const { return fArchSupportsThumb2; }
OutputKind outputKind() const { return fOutputKind; }
bool prebind() const { return fPrebind; }
bool allGlobalsAreDeadStripRoots() const;
bool shouldExport(const char*) const;
bool shouldReExport(const char*) const;
+ std::vector<const char*> exportsData() const;
bool ignoreOtherArchInputFiles() const { return fIgnoreOtherArchFiles; }
bool traceDylibs() const { return fTraceDylibs; }
bool traceArchives() const { return fTraceArchives; }
+ bool traceEmitJSON() const { return fTraceEmitJSON; }
bool deadCodeStrip() const { return fDeadStrip; }
UndefinedTreatment undefinedTreatment() const { return fUndefinedTreatment; }
ld::MacVersionMin macosxVersionMin() const { return fMacVersionMin; }
ld::IOSVersionMin iOSVersionMin() const { return fIOSVersionMin; }
+ ld::WatchOSVersionMin watchOSVersionMin() const { return fWatchOSVersionMin; }
+ uint32_t minOSversion() const;
bool minOS(ld::MacVersionMin mac, ld::IOSVersionMin iPhoneOS);
+ bool min_iOS(ld::IOSVersionMin requirediOSMin);
bool messagesPrefixedWithArchitecture();
Treatment picTreatment();
WeakReferenceMismatchTreatment weakReferenceMismatchTreatment() const { return fWeakReferenceMismatchTreatment; }
CommonsMode commonsMode() const { return fCommonsMode; }
bool warnCommons() const { return fWarnCommons; }
bool keepRelocations();
- FileInfo findFile(const char* path) const;
+ FileInfo findFile(const std::string &path, const ld::dylib::File* fromDylib=nullptr) const;
+ bool findFile(const std::string &path, const std::vector<std::string> &tbdExtensions, FileInfo& result) const;
UUIDMode UUIDMode() const { return fUUIDMode; }
bool warnStabs();
bool pauseAtEnd() { return fPause; }
const std::vector<DylibOverride>& dylibOverrides() const { return fDylibOverrides; }
const char* generatedMapPath() const { return fMapPath; }
bool positionIndependentExecutable() const { return fPositionIndependentExecutable; }
- Options::FileInfo findFileUsingPaths(const char* path) const;
+ Options::FileInfo findIndirectDylib(const std::string& installName, const ld::dylib::File* fromDylib) const;
bool deadStripDylibs() const { return fDeadStripDylibs; }
bool allowedUndefined(const char* name) const { return ( fAllowedUndefined.find(name) != fAllowedUndefined.end() ); }
bool someAllowedUndefines() const { return (fAllowedUndefined.size() != 0); }
bool needsUnwindInfoSection() const { return fAddCompactUnwindEncoding; }
const std::vector<const char*>& llvmOptions() const{ return fLLVMOptions; }
const std::vector<const char*>& segmentOrder() const{ return fSegmentOrder; }
+ bool segmentOrderAfterFixedAddressSegment(const char* segName) const;
const std::vector<const char*>* sectionOrder(const char* segName) const;
const std::vector<const char*>& dyldEnvironExtras() const{ return fDyldEnvironExtras; }
const std::vector<const char*>& astFilePaths() const{ return fASTFilePaths; }
bool objcGc() const { return fObjCGc; }
bool objcGcOnly() const { return fObjCGcOnly; }
bool canUseThreadLocalVariables() const { return fTLVSupport; }
- bool addVersionLoadCommand() const { return fVersionLoadCommand; }
+ bool addVersionLoadCommand() const { return fVersionLoadCommand && (fPlatform != kPlatformUnknown); }
+ bool addBuildVersionLoadCommand() const { return fBuildVersionLoadCommand; }
bool addFunctionStarts() const { return fFunctionStartsLoadCommand; }
bool addDataInCodeInfo() const { return fDataInCodeInfoLoadCommand; }
bool canReExportSymbols() const { return fCanReExportSymbols; }
+ const char* ltoCachePath() const { return fLtoCachePath; }
+ int ltoPruneInterval() const { return fLtoPruneInterval; }
+ int ltoPruneAfter() const { return fLtoPruneAfter; }
+ unsigned ltoMaxCacheSize() const { return fLtoMaxCacheSize; }
const char* tempLtoObjectPath() const { return fTempLtoObjectPath; }
const char* overridePathlibLTO() const { return fOverridePathlibLTO; }
const char* mcpuLTO() const { return fLtoCpu; }
bool markAppExtensionSafe() const { return fMarkAppExtensionSafe; }
bool checkDylibsAreAppExtensionSafe() const { return fCheckAppExtensionSafe; }
bool forceLoadSwiftLibs() const { return fForceLoadSwiftLibs; }
+ bool bundleBitcode() const { return fBundleBitcode; }
+ bool hideSymbols() const { return fHideSymbols; }
+ bool verifyBitcode() const { return fVerifyBitcode; }
+ bool renameReverseSymbolMap() const { return fReverseMapUUIDRename; }
+ bool deduplicateFunctions() const { return fDeDupe; }
+ bool verboseDeduplicate() const { return fVerboseDeDupe; }
+ const char* reverseSymbolMapPath() const { return fReverseMapPath; }
+ std::string reverseMapTempPath() const { return fReverseMapTempPath; }
+ bool ltoCodegenOnly() const { return fLTOCodegenOnly; }
+ bool ignoreAutoLink() const { return fIgnoreAutoLink; }
+ bool allowDeadDuplicates() const { return fAllowDeadDups; }
+ bool allowWeakImports() const { return fAllowWeakImports; }
+ bool noInitializers() const { return fNoInitializers; }
+ BitcodeMode bitcodeKind() const { return fBitcodeKind; }
+ bool sharedRegionEncodingV2() const { return fSharedRegionEncodingV2; }
+ bool useDataConstSegment() const { return fUseDataConstSegment; }
+ bool useTextExecSegment() const { return fUseTextExecSegment; }
bool hasWeakBitTweaks() const;
bool forceWeak(const char* symbolName) const;
bool forceNotWeak(const char* symbolName) const;
bool needsThreadLoadCommand() const { return fNeedsThreadLoadCommand; }
bool needsEntryPointLoadCommand() const { return fEntryPointLoadCommand; }
bool needsSourceVersionLoadCommand() const { return fSourceVersionLoadCommand; }
- bool needsDependentDRInfo() const { return fDependentDRInfo; }
bool canUseAbsoluteSymbols() const { return fAbsoluteSymbols; }
bool allowSimulatorToLinkWithMacOSX() const { return fAllowSimulatorToLinkWithMacOSX; }
uint64_t sourceVersion() const { return fSourceVersion; }
const std::vector<SegmentRename>& segmentRenames() const { return fSegmentRenames; }
bool moveRoSymbol(const char* symName, const char* filePath, const char*& seg, bool& wildCardMatch) const;
bool moveRwSymbol(const char* symName, const char* filePath, const char*& seg, bool& wildCardMatch) const;
+ Platform platform() const { return fPlatform; }
+ const std::vector<const char*>& sdkPaths() const { return fSDKPaths; }
+ std::vector<std::string> writeBitcodeLinkOptions() const;
+ std::string getSDKVersionStr() const;
+ std::string getPlatformStr() const;
+ uint8_t maxDefaultCommonAlign() const { return fMaxDefaultCommonAlign; }
+ bool hasDataSymbolMoves() const { return !fSymbolsMovesData.empty(); }
+ bool hasCodeSymbolMoves() const { return !fSymbolsMovesCode.empty(); }
+ void writeToTraceFile(const char* buffer, size_t len) const;
+ UnalignedPointerTreatment unalignedPointerTreatment() const { return fUnalignedPointerTreatment; }
+
+ static uint32_t parseVersionNumber32(const char*);
private:
typedef std::unordered_map<const char*, unsigned int, ld::CStringHash, ld::CStringEquals> NameToOrder;
NameSet::iterator regularBegin() const { return fRegular.begin(); }
NameSet::iterator regularEnd() const { return fRegular.end(); }
void remove(const NameSet&);
+ std::vector<const char*> data() const;
private:
static bool hasWildCards(const char*);
bool wildCardMatch(const char* pattern, const char* candidate) const;
bool checkForFile(const char* format, const char* dir, const char* rootName,
FileInfo& result) const;
uint64_t parseVersionNumber64(const char*);
- uint32_t parseVersionNumber32(const char*);
+ std::string getVersionString32(uint32_t ver) const;
+ std::string getVersionString64(uint64_t ver) const;
+ bool parsePackedVersion32(const std::string& versionStr, uint32_t &result);
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 setUndefinedTreatment(const char* treatment);
void setMacOSXVersionMin(const char* version);
void setIOSVersionMin(const char* version);
+ void setWatchOSVersionMin(const char* version);
void setWeakReferenceMismatchTreatment(const char* treatment);
void addDylibOverride(const char* paths);
void addSectionAlignment(const char* segment, const char* section, const char* alignment);
void addSectionRename(const char* srcSegment, const char* srcSection, const char* dstSegment, const char* dstSection);
void addSegmentRename(const char* srcSegment, const char* dstSegment);
void addSymbolMove(const char* dstSegment, const char* symbolList, std::vector<SymbolsMove>& list, const char* optionName);
+ void cannotBeUsedWithBitcode(const char* arg);
// ObjectFile::ReaderOptions fReaderOptions;
const char* fSegAddrTablePath;
const char* fMapPath;
const char* fDyldInstallPath;
+ const char* fLtoCachePath;
+ int fLtoPruneInterval;
+ int fLtoPruneAfter;
+ unsigned fLtoMaxCacheSize;
const char* fTempLtoObjectPath;
const char* fOverridePathlibLTO;
const char* fLtoCpu;
bool fStatistics;
bool fPrintOptions;
bool fSharedRegionEligible;
+ bool fSharedRegionEligibleForceOff;
bool fPrintOrderFileStatistics;
bool fReadOnlyx86Stubs;
bool fPositionIndependentExecutable;
bool fKextsUseStubs;
bool fUsingLazyDylibLinking;
bool fEncryptable;
+ bool fEncryptableForceOn;
+ bool fEncryptableForceOff;
bool fOrderData;
bool fMarkDeadStrippableDylib;
bool fMakeCompressedDyldInfo;
bool fMakeCompressedDyldInfoForceOff;
bool fNoEHLabels;
bool fAllowCpuSubtypeMismatches;
+ bool fEnforceDylibSubtypesMatch;
bool fUseSimplifiedDylibReExports;
bool fObjCABIVersion2Override;
bool fObjCABIVersion1Override;
bool fTraceDylibs;
bool fTraceIndirectDylibs;
bool fTraceArchives;
+ bool fTraceEmitJSON;
bool fOutputSlidable;
bool fWarnWeakExports;
bool fObjcGcCompaction;
bool fVersionLoadCommand;
bool fVersionLoadCommandForcedOn;
bool fVersionLoadCommandForcedOff;
+ bool fBuildVersionLoadCommand;
bool fFunctionStartsLoadCommand;
bool fFunctionStartsForcedOn;
bool fFunctionStartsForcedOff;
bool fSourceVersionLoadCommand;
bool fSourceVersionLoadCommandForceOn;
bool fSourceVersionLoadCommandForceOff;
- bool fDependentDRInfo;
- bool fDependentDRInfoForcedOn;
- bool fDependentDRInfoForcedOff;
bool fTargetIOSSimulator;
bool fExportDynamic;
bool fAbsoluteSymbols;
bool fMarkAppExtensionSafe;
bool fCheckAppExtensionSafe;
bool fForceLoadSwiftLibs;
+ bool fSharedRegionEncodingV2;
+ bool fUseDataConstSegment;
+ bool fUseDataConstSegmentForceOn;
+ bool fUseDataConstSegmentForceOff;
+ bool fUseTextExecSegment;
+ bool fBundleBitcode;
+ bool fHideSymbols;
+ bool fVerifyBitcode;
+ bool fReverseMapUUIDRename;
+ bool fDeDupe;
+ bool fVerboseDeDupe;
+ const char* fReverseMapPath;
+ std::string fReverseMapTempPath;
+ bool fLTOCodegenOnly;
+ bool fIgnoreAutoLink;
+ bool fAllowDeadDups;
+ bool fAllowWeakImports;
+ bool fNoInitializers;
+ BitcodeMode fBitcodeKind;
+ Platform fPlatform;
DebugInfoStripping fDebugInfoStripping;
const char* fTraceOutputFile;
ld::MacVersionMin fMacVersionMin;
ld::IOSVersionMin fIOSVersionMin;
+ ld::WatchOSVersionMin fWatchOSVersionMin;
std::vector<AliasPair> fAliases;
std::vector<const char*> fInitialUndefines;
NameSet fAllowedUndefined;
- NameSet fWhyLive;
+ SetWithWildcards fWhyLive;
std::vector<ExtraSection> fExtraSections;
std::vector<SectionAlignment> fSectionAlignments;
std::vector<OrderedSymbol> fOrderedSymbols;
std::vector<SegmentRename> fSegmentRenames;
std::vector<SymbolsMove> fSymbolsMovesData;
std::vector<SymbolsMove> fSymbolsMovesCode;
- std::vector<SymbolsMove> fSymbolsMovesZeroFill;
bool fSaveTempFiles;
mutable Snapshot fLinkSnapshot;
bool fSnapshotRequested;
const char* fPipelineFifo;
const char* fDependencyInfoPath;
mutable int fDependencyFileDescriptor;
+ mutable int fTraceFileDescriptor;
+ uint8_t fMaxDefaultCommonAlign;
+ UnalignedPointerTreatment fUnalignedPointerTreatment;
};