summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/include/lld/ReaderWriter/MachOLinkingContext.h4
-rw-r--r--lld/lib/ReaderWriter/MachO/File.h14
-rw-r--r--lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp16
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFile.h16
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp4
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp12
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp4
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp4
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp34
-rw-r--r--lld/test/mach-o/dylib-install-names.yaml6
-rw-r--r--lld/test/mach-o/lazy-bind-x86_64.yaml40
11 files changed, 125 insertions, 29 deletions
diff --git a/lld/include/lld/ReaderWriter/MachOLinkingContext.h b/lld/include/lld/ReaderWriter/MachOLinkingContext.h
index ef4de3b47c8..e1822a028a4 100644
--- a/lld/include/lld/ReaderWriter/MachOLinkingContext.h
+++ b/lld/include/lld/ReaderWriter/MachOLinkingContext.h
@@ -254,6 +254,10 @@ public:
/// search paths to allow indirect dylibs to be overridden.
mach_o::MachODylibFile* findIndirectDylib(StringRef path);
+ uint32_t dylibCurrentVersion(StringRef installName) const;
+
+ uint32_t dylibCompatVersion(StringRef installName) const;
+
/// Creates a copy (owned by this MachOLinkingContext) of a string.
StringRef copy(StringRef str) { return str.copy(_allocator); }
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);
diff --git a/lld/test/mach-o/dylib-install-names.yaml b/lld/test/mach-o/dylib-install-names.yaml
index 5f4fde8deee..a79581c0e26 100644
--- a/lld/test/mach-o/dylib-install-names.yaml
+++ b/lld/test/mach-o/dylib-install-names.yaml
@@ -1,5 +1,6 @@
# Check we accept -install_name correctly:
# RUN: lld -flavor darwin -arch x86_64 -install_name libwibble.dylib -dylib \
+# RUN: -compatibility_version 2.0 -current_version 5.3 \
# RUN: %p/Inputs/libSystem.yaml %s -o %t.dylib
# RUN: macho-dump %t.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE
@@ -9,12 +10,14 @@
# Check we default the install-name to the output file:
# RUN: lld -flavor darwin -arch x86_64 -dylib %s -o libwibble.dylib \
+# RUN: -compatibility_version 2.0 -current_version 5.3 \
# RUN: %p/Inputs/libSystem.yaml
# RUN: macho-dump libwibble.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE
# RUN: rm -f libwibble.dylib
# Check -single_module does nothing
# RUN: lld -flavor darwin -arch x86_64 -dylib %s -install_name libwibble.dylib \
+# RUN: -compatibility_version 2.0 -current_version 5.3 \
# RUN: -single_module -o %t2.dylib %p/Inputs/libSystem.yaml
# RUN: macho-dump %t2.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE
@@ -51,6 +54,9 @@ global-symbols:
# CHECK-BINARY-WRITE: (('command', 13)
# CHECK-BINARY-WRITE-NEXT: ('size', 40)
# CHECK-BINARY-WRITE-NEXT: ('install_name', 'libwibble.dylib')
+# CHECK-BINARY-WRITE-NEXT: ('timestamp,
+# CHECK-BINARY-WRITE-NEXT: ('cur_version, 328448)
+# CHECK-BINARY-WRITE-NEXT: ('compat_version, 131072)
# CHECK-BINARY-READ: shared-library-atoms:
# CHECK-BINARY-READ: - name: _myGlobal
diff --git a/lld/test/mach-o/lazy-bind-x86_64.yaml b/lld/test/mach-o/lazy-bind-x86_64.yaml
index 0a474ffe5f8..a6800098823 100644
--- a/lld/test/mach-o/lazy-bind-x86_64.yaml
+++ b/lld/test/mach-o/lazy-bind-x86_64.yaml
@@ -3,6 +3,7 @@
# RUN: llvm-objdump -lazy-bind %t | FileCheck %s
# RUN: llvm-nm -m %t | FileCheck --check-prefix=CHECK-NM %s
# RUN: llvm-objdump -disassemble %t | FileCheck --check-prefix=CHECK-HELPERS %s
+# RUN: llvm-objdump -private-headers %t | FileCheck --check-prefix=CHECK-DYLIBS %s
#
# Test that correct two-level namespace ordinals are used for lazy bindings.
#
@@ -61,23 +62,29 @@ undefined-symbols:
value: 0x0000000000000000
--- !mach-o
-arch: x86_64
-file-type: MH_DYLIB
-install-name: /usr/lib/libbar.dylib
+arch: x86_64
+file-type: MH_DYLIB
+install-name: /usr/lib/libbar.dylib
+compat-version: 1.0
+current-version: 2.3
exports:
- name: _bar
--- !mach-o
-arch: x86_64
-file-type: MH_DYLIB
-install-name: /usr/lib/libfoo.dylib
+arch: x86_64
+file-type: MH_DYLIB
+install-name: /usr/lib/libfoo.dylib
+compat-version: 2.0
+current-version: 3.4
exports:
- name: _foo
--- !mach-o
-arch: x86_64
-file-type: MH_DYLIB
-install-name: /usr/lib/libbaz.dylib
+arch: x86_64
+file-type: MH_DYLIB
+install-name: /usr/lib/libbaz.dylib
+compat-version: 3.0
+current-version: 4.5
exports:
- name: _baz
@@ -99,3 +106,18 @@ exports:
# CHECK-HELPERS: 68 10 00 00 00 pushq $16
# CHECK-HELPERS: 68 20 00 00 00 pushq $32
+
+# CHECK-DYLIBS: cmd LC_LOAD_DYLIB
+# CHECK-DYLIBS: name /usr/lib/libbar.dylib (offset 24)
+# CHECK-DYLIBS: current version 2.3.0
+# CHECK-DYLIBS: compatibility version 1.0.0
+# CHECK-DYLIBS: cmd LC_LOAD_DYLIB
+# CHECK-DYLIBS: name /usr/lib/libfoo.dylib (offset 24)
+# CHECK-DYLIBS: current version 3.4.0
+# CHECK-DYLIBS: compatibility version 2.0.0
+# CHECK-DYLIBS: cmd LC_LOAD_DYLIB
+# CHECK-DYLIBS: name /usr/lib/libbaz.dylib (offset 24)
+# CHECK-DYLIBS: current version 4.5.0
+# CHECK-DYLIBS: compatibility version 3.0.0
+
+
OpenPOWER on IntegriCloud