diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -22,6 +22,7 @@ #include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" #include "llvm/BinaryFormat/MachO.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" @@ -248,6 +249,38 @@ // different location. const StringRef path = "/usr/lib/dyld"; }; + +class LCBuildVersion : public LoadCommand { +public: + LCBuildVersion(const PlatformInfo &platform) : platform(platform) {} + + const int ntools = 1; + + uint32_t getSize() const override { + return sizeof(build_version_command) + ntools * sizeof(build_tool_version); + } + + void writeTo(uint8_t *buf) const override { + auto *c = reinterpret_cast(buf); + c->cmd = LC_BUILD_VERSION; + c->cmdsize = getSize(); + c->platform = static_cast(platform.kind); + c->minos = ((platform.minimum.getMajor() << 020) | + (platform.minimum.getMinor().getValueOr(0) << 010) | + platform.minimum.getSubminor().getValueOr(0)); + c->sdk = ((platform.sdk.getMajor() << 020) | + (platform.sdk.getMinor().getValueOr(0) << 010) | + platform.sdk.getSubminor().getValueOr(0)); + c->ntools = ntools; + auto *t = reinterpret_cast(&c[1]); + t->tool = TOOL_LD; + t->version = (LLVM_VERSION_MAJOR << 020) | (LLVM_VERSION_MINOR << 010) | + LLVM_VERSION_PATCH; + } + + const PlatformInfo &platform; +}; + } // namespace void Writer::scanRelocations() { @@ -282,6 +315,8 @@ llvm_unreachable("unhandled output file type"); } + in.header->addLoadCommand(make(config->platform)); + uint8_t segIndex = 0; for (OutputSegment *seg : outputSegments) { in.header->addLoadCommand(make(seg->name, seg)); diff --git a/lld/test/MachO/headerpad.s b/lld/test/MachO/headerpad.s --- a/lld/test/MachO/headerpad.s +++ b/lld/test/MachO/headerpad.s @@ -11,8 +11,8 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o # RUN: lld -flavor darwinnew -o %t %t.o -headerpad 0 # RUN: llvm-objdump --macho --all-headers %t | FileCheck %s --check-prefix=PAD0 -# PAD0: magic cputype cpusubtype caps filetype ncmds sizeofcmds -# PAD0-NEXT: MH_MAGIC_64 X86_64 ALL LIB64 EXECUTE 8 [[#%u, CMDSIZE:]] {{.*}} +# PAD0: magic cputype cpusubtype caps filetype ncmds sizeofcmds flags +# PAD0-NEXT: MH_MAGIC_64 X86_64 ALL LIB64 EXECUTE 9 [[#%u, CMDSIZE:]] {{.*}} # PAD0: sectname __text # PAD0-NEXT: segname __TEXT # PAD0-NEXT: addr @@ -21,8 +21,8 @@ # RUN: lld -flavor darwinnew -o %t %t.o -headerpad 11 # RUN: llvm-objdump --macho --all-headers %t | FileCheck %s --check-prefix=PAD11 -# PAD11: magic cputype cpusubtype caps filetype ncmds sizeofcmds -# PAD11-NEXT: MH_MAGIC_64 X86_64 ALL LIB64 EXECUTE 8 [[#%u, CMDSIZE:]] {{.*}} +# PAD11: magic cputype cpusubtype caps filetype ncmds sizeofcmds flags +# PAD11-NEXT: MH_MAGIC_64 X86_64 ALL LIB64 EXECUTE 9 [[#%u, CMDSIZE:]] {{.*}} # PAD11: sectname __text # PAD11-NEXT: segname __TEXT # PAD11-NEXT: addr diff --git a/lld/test/MachO/lc-build-version.s b/lld/test/MachO/lc-build-version.s new file mode 100644 --- /dev/null +++ b/lld/test/MachO/lc-build-version.s @@ -0,0 +1,20 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o +# RUN: lld -flavor darwinnew -Z -platform_version macos 10.14.1 10.15 -o %t %t.o +# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s + +# CHECK: cmd LC_BUILD_VERSION +# CHECK-NEXT: cmdsize 32 +# CHECK-NEXT: platform macos +# CHECK-NEXT: sdk 10.15 +# CHECK-NEXT: minos 10.14.1 +# CHECK-NEXT: ntools 1 +# CHECK-NEXT: tool ld +# CHECK-NEXT: version {{[1-9][0-9]\.[0-9]+}} +# CHECK-NEXT: Load command [[#]] + +.text +.global _main +_main: + mov $0, %eax + ret diff --git a/lld/test/MachO/local-got.s b/lld/test/MachO/local-got.s --- a/lld/test/MachO/local-got.s +++ b/lld/test/MachO/local-got.s @@ -12,12 +12,12 @@ ## address offset and the contents at that address very similarly, so am using ## --match-full-lines to make sure we match on the right thing. # CHECK: Contents of section __cstring: -# CHECK-NEXT: 1000003ec {{.*}} +# CHECK-NEXT: 10000040c {{.*}} ## 1st 8 bytes refer to the start of __cstring + 0xe, 2nd 8 bytes refer to the ## start of __cstring # CHECK: Contents of section __got: -# CHECK-NEXT: [[#%X,ADDR:]] fa030000 01000000 ec030000 01000000 {{.*}} +# CHECK-NEXT: [[#%X,ADDR:]] 1a040000 01000000 0c040000 01000000 {{.*}} # CHECK-NEXT: [[#ADDR + 16]] 00000000 00000000 {{.*}} ## Check that a non-locally-defined symbol is still bound at the correct offset: diff --git a/lld/test/MachO/relocations.s b/lld/test/MachO/relocations.s --- a/lld/test/MachO/relocations.s +++ b/lld/test/MachO/relocations.s @@ -19,9 +19,9 @@ # CHECK: leaq [[#%u, LSTR_OFF:]](%rip), %rsi # CHECK-NEXT: [[#%x, CSTRING_ADDR + 22 - LSTR_OFF]] -# RUN: llvm-objdump --section=__const --full-contents -d %t | FileCheck %s --check-prefix=NONPCREL +# RUN: llvm-objdump --section=__const --full-contents %t | FileCheck %s --check-prefix=NONPCREL # NONPCREL: Contents of section __const: -# NONPCREL-NEXT: 100001000 d0030000 01000000 d0030000 01000000 +# NONPCREL-NEXT: 100001000 f0030000 01000000 f0030000 01000000 .section __TEXT,__text .globl _main, _f