summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp')
-rw-r--r--lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp68
1 files changed, 42 insertions, 26 deletions
diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
index d46cf2ce386..0eb2b11eaaa 100644
--- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
+++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
@@ -317,6 +317,10 @@ MachOFileLayout::MachOFileLayout(const NormalizedFile &file)
+ file.sections.size() * sectsSize
+ sizeof(symtab_command);
_countOfLoadCommands = 2;
+ if (file.hasMinVersionLoadCommand) {
+ _endOfLoadCommands += sizeof(version_min_command);
+ _countOfLoadCommands++;
+ }
if (!_file.dataInCode.empty()) {
_endOfLoadCommands += sizeof(linkedit_data_command);
_countOfLoadCommands++;
@@ -738,6 +742,38 @@ std::error_code MachOFileLayout::writeSegmentLoadCommands(uint8_t *&lc) {
return std::error_code();
}
+static void writeVersionMinLoadCommand(const NormalizedFile &_file,
+ bool _swap,
+ uint8_t *&lc) {
+ if (!_file.hasMinVersionLoadCommand)
+ return;
+ version_min_command *vm = reinterpret_cast<version_min_command*>(lc);
+ switch (_file.os) {
+ case MachOLinkingContext::OS::unknown:
+ vm->cmd = _file.minOSVersionKind;
+ vm->cmdsize = sizeof(version_min_command);
+ vm->version = _file.minOSverson;
+ vm->sdk = 0;
+ break;
+ case MachOLinkingContext::OS::macOSX:
+ vm->cmd = LC_VERSION_MIN_MACOSX;
+ vm->cmdsize = sizeof(version_min_command);
+ vm->version = _file.minOSverson;
+ vm->sdk = _file.sdkVersion;
+ break;
+ case MachOLinkingContext::OS::iOS:
+ case MachOLinkingContext::OS::iOS_simulator:
+ vm->cmd = LC_VERSION_MIN_IPHONEOS;
+ vm->cmdsize = sizeof(version_min_command);
+ vm->version = _file.minOSverson;
+ vm->sdk = _file.sdkVersion;
+ break;
+ }
+ if (_swap)
+ swapStruct(*vm);
+ lc += sizeof(version_min_command);
+}
+
std::error_code MachOFileLayout::writeLoadCommands() {
std::error_code ec;
uint8_t *lc = &_buffer[_startOfLoadCommands];
@@ -759,6 +795,11 @@ std::error_code MachOFileLayout::writeLoadCommands() {
if (_swap)
swapStruct(*st);
lc += sizeof(symtab_command);
+
+ // Add LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS,
+ // LC_VERSION_MIN_WATCHOS, LC_VERSION_MIN_TVOS
+ writeVersionMinLoadCommand(_file, _swap, lc);
+
// Add LC_DATA_IN_CODE if needed.
if (_dataInCodeSize != 0) {
linkedit_data_command* dl = reinterpret_cast<linkedit_data_command*>(lc);
@@ -872,32 +913,7 @@ std::error_code MachOFileLayout::writeLoadCommands() {
// Add LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_WATCHOS,
// LC_VERSION_MIN_TVOS
- if (_file.hasMinVersionLoadCommand) {
- version_min_command *vm = reinterpret_cast<version_min_command*>(lc);
- switch (_file.os) {
- case MachOLinkingContext::OS::unknown:
- // TODO: We need to emit the load command if we managed to derive
- // a platform from one of the files we are linking.
- llvm_unreachable("Version commands for unknown OS aren't supported");
- break;
- case MachOLinkingContext::OS::macOSX:
- vm->cmd = LC_VERSION_MIN_MACOSX;
- vm->cmdsize = sizeof(version_min_command);
- vm->version = _file.minOSverson;
- vm->sdk = _file.sdkVersion;
- break;
- case MachOLinkingContext::OS::iOS:
- case MachOLinkingContext::OS::iOS_simulator:
- vm->cmd = LC_VERSION_MIN_MACOSX;
- vm->cmdsize = sizeof(version_min_command);
- vm->version = _file.minOSverson;
- vm->sdk = _file.sdkVersion;
- break;
- }
- if (_swap)
- swapStruct(*vm);
- lc += sizeof(version_min_command);
- }
+ writeVersionMinLoadCommand(_file, _swap, lc);
// If main executable, add LC_MAIN.
if (_file.fileType == llvm::MachO::MH_EXECUTE) {
OpenPOWER on IntegriCloud