diff options
Diffstat (limited to 'lld/lib')
8 files changed, 84 insertions, 20 deletions
diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h index cc98cd51f57..7d0292d0e93 100644 --- a/lld/lib/ReaderWriter/MachO/File.h +++ b/lld/lib/ReaderWriter/MachO/File.h @@ -198,8 +198,10 @@ private: class MachODylibFile : public SharedLibraryFile { public: - MachODylibFile(StringRef path, StringRef installName) - : SharedLibraryFile(path), _installName(installName) { + MachODylibFile(StringRef path, StringRef installName, uint32_t compatVersion, + uint32_t currentVersion) + : SharedLibraryFile(path), _installName(installName), + _currentVersion(currentVersion), _compatVersion(compatVersion) { } const SharedLibraryAtom *exports(StringRef name, @@ -243,6 +245,10 @@ public: StringRef installName() { return _installName; } + uint32_t currentVersion() { return _currentVersion; } + + uint32_t compatVersion() { return _compatVersion; } + typedef std::function<MachODylibFile *(StringRef)> FindDylib; void loadReExportedDylibs(FindDylib find) { @@ -292,7 +298,9 @@ private: bool weakDef; }; - StringRef _installName; + StringRef _installName; + uint32_t _currentVersion; + uint32_t _compatVersion; atom_collection_vector<DefinedAtom> _definedAtoms; atom_collection_vector<UndefinedAtom> _undefinedAtoms; atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms; diff --git a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp index 8bdee4e446a..3e91e4a56b3 100644 --- a/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp +++ b/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp @@ -652,6 +652,22 @@ MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) { return nullptr; } +uint32_t MachOLinkingContext::dylibCurrentVersion(StringRef installName) const { + auto pos = _pathToDylibMap.find(installName); + if (pos != _pathToDylibMap.end()) + return pos->second->currentVersion(); + else + return 0x1000; // 1.0 +} + +uint32_t MachOLinkingContext::dylibCompatVersion(StringRef installName) const { + auto pos = _pathToDylibMap.find(installName); + if (pos != _pathToDylibMap.end()) + return pos->second->compatVersion(); + else + return 0x1000; // 1.0 +} + bool MachOLinkingContext::createImplicitFiles( std::vector<std::unique_ptr<File> > &result) { // Add indirect dylibs by asking each linked dylib to add its indirects. diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h b/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h index 29d2fc8ea01..64b8231eb2b 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h @@ -1,4 +1,4 @@ -//===- lib/ReaderWriter/MachO/NormalizedFile.h ----------------------===// +//===- lib/ReaderWriter/MachO/MachONormalizedFile.h -----------------------===// // // The LLVM Linker // @@ -145,6 +145,9 @@ struct Symbol { /// A typedef so that YAML I/O can (de/en)code the protection bits of a segment. LLVM_YAML_STRONG_TYPEDEF(uint32_t, VMProtect) +/// A typedef to hold verions X.Y.X packed into 32-bit xxxx.yy.zz +LLVM_YAML_STRONG_TYPEDEF(uint32_t, PackedVersion) + /// Segments are only used in normalized final linked images (not in relocatable /// object files). They specify how a range of the file is loaded. struct Segment { @@ -159,6 +162,8 @@ struct Segment { struct DependentDylib { StringRef path; LoadCommandType kind; + PackedVersion compatVersion; + PackedVersion currentVersion; }; /// A normalized rebasing entry. Only used in normalized final linked images. @@ -203,7 +208,6 @@ struct DataInCode { /// A typedef so that YAML I/O can encode/decode mach_header.flags. LLVM_YAML_STRONG_TYPEDEF(uint32_t, FileFlags) - /// struct NormalizedFile { NormalizedFile() : arch(MachOLinkingContext::arch_unknown), @@ -225,14 +229,16 @@ struct NormalizedFile { // Maps to load commands with no LINKEDIT content (final linked images only). std::vector<DependentDylib> dependentDylibs; - StringRef installName; + StringRef installName; // dylibs only + PackedVersion compatVersion; // dylibs only + PackedVersion currentVersion; // dylibs only bool hasUUID; std::vector<StringRef> rpaths; Hex64 entryAddress; MachOLinkingContext::OS os; Hex64 sourceVersion; - Hex32 minOSverson; - Hex32 sdkVersion; + PackedVersion minOSverson; + PackedVersion sdkVersion; // Maps to load commands with LINKEDIT content (final linked images only). Hex32 pageSize; diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp index 042cca7125d..a05fa750326 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp @@ -455,8 +455,10 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, DependentDylib entry; entry.path = lc + read32(&dl->dylib.name, isBig); entry.kind = LoadCommandType(cmd); + entry.compatVersion = read32(&dl->dylib.compatibility_version, isBig); + entry.currentVersion = read32(&dl->dylib.current_version, isBig); f->dependentDylibs.push_back(entry); - } + } break; case LC_DYLD_INFO: case LC_DYLD_INFO_ONLY: diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp index 3bc341ffa3a..71643bda02c 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp @@ -734,9 +734,9 @@ std::error_code MachOFileLayout::writeLoadCommands() { dc->cmd = LC_ID_DYLIB; dc->cmdsize = size; dc->dylib.name = sizeof(dylib_command); // offset - dc->dylib.timestamp = 0; // FIXME - dc->dylib.current_version = 0; // FIXME - dc->dylib.compatibility_version = 0; // FIXME + dc->dylib.timestamp = 2; + dc->dylib.current_version = _file.currentVersion; + dc->dylib.compatibility_version = _file.compatVersion; if (_swap) swapStruct(*dc); memcpy(lc + sizeof(dylib_command), path.begin(), path.size()); @@ -834,9 +834,9 @@ std::error_code MachOFileLayout::writeLoadCommands() { dc->cmd = dep.kind; dc->cmdsize = size; dc->dylib.name = sizeof(dylib_command); // offset - dc->dylib.timestamp = 0; // FIXME - dc->dylib.current_version = 0; // FIXME - dc->dylib.compatibility_version = 0; // FIXME + dc->dylib.timestamp = 2; + dc->dylib.current_version = dep.currentVersion; + dc->dylib.compatibility_version = dep.compatVersion; if (_swap) swapStruct(*dc); memcpy(lc+sizeof(dylib_command), dep.path.begin(), dep.path.size()); diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index a668dadb129..19a7e45b4df 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -941,6 +941,8 @@ void Util::addDependentDylibs(const lld::File &atomFile,NormalizedFile &nFile) { DependentDylib depInfo; depInfo.path = loadPath; depInfo.kind = llvm::MachO::LC_LOAD_DYLIB; + depInfo.currentVersion = _context.dylibCurrentVersion(loadPath); + depInfo.compatVersion = _context.dylibCompatVersion(loadPath); nFile.dependentDylibs.push_back(depInfo); } else { if ( slAtom->canBeNullAtRuntime() ) @@ -1188,6 +1190,8 @@ normalizedFromAtoms(const lld::File &atomFile, normFile.fileType = context.outputMachOType(); normFile.flags = util.fileFlags(); normFile.installName = context.installName(); + normFile.currentVersion = context.currentVersion(); + normFile.compatVersion = context.compatibilityVersion(); normFile.pageSize = context.pageSize(); util.addDependentDylibs(atomFile, normFile); util.copySegmentInfo(normFile); diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp index a94329e50f9..7465fb2e613 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -820,7 +820,9 @@ normalizedDylibToAtoms(const NormalizedFile &normalizedFile, StringRef path, bool copyRefs) { // Instantiate SharedLibraryFile object. std::unique_ptr<MachODylibFile> file( - new MachODylibFile(path, normalizedFile.installName)); + new MachODylibFile(path, normalizedFile.installName, + normalizedFile.compatVersion, + normalizedFile.currentVersion)); // Tell MachODylibFile object about all symbols it exports. if (!normalizedFile.exportInfo.empty()) { // If exports trie exists, use it instead of traditional symbol table. diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp index af4fc587484..ae14d755e2b 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp @@ -25,6 +25,7 @@ #include "llvm/ADT/Twine.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" #include "llvm/Support/MachO.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" @@ -529,8 +530,13 @@ struct ScalarEnumerationTraits<LoadCommandType> { template <> struct MappingTraits<DependentDylib> { static void mapping(IO &io, DependentDylib& dylib) { - io.mapRequired("path", dylib.path); - io.mapOptional("kind", dylib.kind, llvm::MachO::LC_LOAD_DYLIB); + io.mapRequired("path", dylib.path); + io.mapOptional("kind", dylib.kind, + llvm::MachO::LC_LOAD_DYLIB); + io.mapOptional("compat-version", dylib.compatVersion, + PackedVersion(0x10000)); + io.mapOptional("current-version", dylib.currentVersion, + PackedVersion(0x10000)); } }; @@ -650,6 +656,24 @@ struct MappingTraits<DataInCode> { } }; +template <> +struct ScalarTraits<PackedVersion> { + static void output(const PackedVersion &value, void*, raw_ostream &out) { + out << llvm::format("%d.%d", (value >> 16), (value >> 8) & 0xFF); + if (value & 0xFF) { + out << llvm::format(".%d", (value & 0xFF)); + } + } + static StringRef input(StringRef scalar, void*, PackedVersion &result) { + uint32_t value; + if (lld::MachOLinkingContext::parsePackedVersion(scalar, value)) + return "malformed version number"; + result = value; + // Return the empty string on success, + return StringRef(); + } + static bool mustQuote(StringRef) { return false; } +}; template <> struct MappingTraits<NormalizedFile> { @@ -659,13 +683,15 @@ struct MappingTraits<NormalizedFile> { io.mapOptional("flags", file.flags); io.mapOptional("dependents", file.dependentDylibs); io.mapOptional("install-name", file.installName, StringRef()); + io.mapOptional("compat-version", file.compatVersion, PackedVersion(0x10000)); + io.mapOptional("current-version", file.currentVersion, PackedVersion(0x10000)); io.mapOptional("has-UUID", file.hasUUID, true); io.mapOptional("rpaths", file.rpaths); io.mapOptional("entry-point", file.entryAddress, Hex64(0)); io.mapOptional("source-version", file.sourceVersion, Hex64(0)); io.mapOptional("OS", file.os); - io.mapOptional("min-os-version", file.minOSverson, Hex32(0)); - io.mapOptional("sdk-version", file.sdkVersion, Hex32(0)); + io.mapOptional("min-os-version", file.minOSverson, PackedVersion(0)); + io.mapOptional("sdk-version", file.sdkVersion, PackedVersion(0)); io.mapOptional("segments", file.segments); io.mapOptional("sections", file.sections); io.mapOptional("local-symbols", file.localSymbols); |

