diff --git a/lld/MachO/Arch/ARM.cpp b/lld/MachO/Arch/ARM.cpp new file mode 100644 --- /dev/null +++ b/lld/MachO/Arch/ARM.cpp @@ -0,0 +1,105 @@ +//===- ARM.cpp ------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "InputFiles.h" +#include "Symbols.h" +#include "SyntheticSections.h" +#include "Target.h" + +#include "lld/Common/ErrorHandler.h" +#include "llvm/BinaryFormat/MachO.h" +#include "llvm/Support/Endian.h" + +using namespace llvm::MachO; +using namespace llvm::support::endian; +using namespace lld; +using namespace lld::macho; + +namespace { + +struct ARM : TargetInfo { + ARM(uint32_t cpuSubtype); + + int64_t getEmbeddedAddend(MemoryBufferRef, uint64_t offset, + const relocation_info) const override; + void relocateOne(uint8_t *loc, const Reloc &, uint64_t va, + uint64_t relocVA) const override; + + void writeStub(uint8_t *buf, const Symbol &) const override; + void writeStubHelperHeader(uint8_t *buf) const override; + void writeStubHelperEntry(uint8_t *buf, const DylibSymbol &, + uint64_t entryAddr) const override; + + void relaxGotLoad(uint8_t *loc, uint8_t type) const override; + const RelocAttrs &getRelocAttrs(uint8_t type) const override; + uint64_t getPageSize() const override { return 4 * 1024; } +}; + +} // namespace + +const RelocAttrs &ARM::getRelocAttrs(uint8_t type) const { + static const std::array relocAttrsArray{{ +#define B(x) RelocAttrBits::x + {"VANILLA", /* FIXME populate this */ B(_0)}, + {"PAIR", /* FIXME populate this */ B(_0)}, + {"SECTDIFF", /* FIXME populate this */ B(_0)}, + {"LOCAL_SECTDIFF", /* FIXME populate this */ B(_0)}, + {"PB_LA_PTR", /* FIXME populate this */ B(_0)}, + {"BR24", /* FIXME populate this */ B(_0)}, + {"BR22", /* FIXME populate this */ B(_0)}, + {"32BIT_BRANCH", /* FIXME populate this */ B(_0)}, + {"HALF", /* FIXME populate this */ B(_0)}, + {"HALF_SECTDIFF", /* FIXME populate this */ B(_0)}, +#undef B + }}; + assert(type < relocAttrsArray.size() && "invalid relocation type"); + if (type >= relocAttrsArray.size()) + return invalidRelocAttrs; + return relocAttrsArray[type]; +} + +int64_t ARM::getEmbeddedAddend(MemoryBufferRef mb, uint64_t offset, + relocation_info rel) const { + fatal("TODO: implement this"); +} + +void ARM::relocateOne(uint8_t *loc, const Reloc &r, uint64_t value, + uint64_t relocVA) const { + fatal("TODO: implement this"); +} + +void ARM::writeStub(uint8_t *buf, const Symbol &sym) const { + fatal("TODO: implement this"); +} + +void ARM::writeStubHelperHeader(uint8_t *buf) const { + fatal("TODO: implement this"); +} + +void ARM::writeStubHelperEntry(uint8_t *buf, const DylibSymbol &sym, + uint64_t entryAddr) const { + fatal("TODO: implement this"); +} + +void ARM::relaxGotLoad(uint8_t *loc, uint8_t type) const { + fatal("TODO: implement this"); +} + +ARM::ARM(uint32_t cpuSubtype) : TargetInfo(ILP32()) { + cpuType = CPU_TYPE_ARM; + this->cpuSubtype = cpuSubtype; + + stubSize = 0 /* FIXME */; + stubHelperHeaderSize = 0 /* FIXME */; + stubHelperEntrySize = 0 /* FIXME */; +} + +TargetInfo *macho::createARMTargetInfo(uint32_t cpuSubtype) { + static ARM t(cpuSubtype); + return &t; +} diff --git a/lld/MachO/CMakeLists.txt b/lld/MachO/CMakeLists.txt --- a/lld/MachO/CMakeLists.txt +++ b/lld/MachO/CMakeLists.txt @@ -5,10 +5,11 @@ include_directories(${LLVM_MAIN_SRC_DIR}/../libunwind/include) add_lld_library(lldMachO2 - Arch/X86_64.cpp + Arch/ARM.cpp Arch/ARM64.cpp Arch/ARM64Common.cpp Arch/ARM64_32.cpp + Arch/X86_64.cpp UnwindInfoSection.cpp Driver.cpp DriverUtils.cpp diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -586,13 +586,19 @@ config->platformInfo.target = MachO::Target(getArchitectureFromName(archName), platform); - switch (getCPUTypeFromArchitecture(config->arch()).first) { + uint32_t cpuType; + uint32_t cpuSubtype; + std::tie(cpuType, cpuSubtype) = getCPUTypeFromArchitecture(config->arch()); + + switch (cpuType) { case CPU_TYPE_X86_64: return createX86_64TargetInfo(); case CPU_TYPE_ARM64: return createARM64TargetInfo(); case CPU_TYPE_ARM64_32: return createARM64_32TargetInfo(); + case CPU_TYPE_ARM: + return createARMTargetInfo(cpuSubtype); default: fatal("missing or unsupported -arch " + archName); } diff --git a/lld/MachO/Target.h b/lld/MachO/Target.h --- a/lld/MachO/Target.h +++ b/lld/MachO/Target.h @@ -80,6 +80,7 @@ TargetInfo *createX86_64TargetInfo(); TargetInfo *createARM64TargetInfo(); TargetInfo *createARM64_32TargetInfo(); +TargetInfo *createARMTargetInfo(uint32_t cpuSubtype); struct LP64 { using mach_header = llvm::MachO::mach_header_64; diff --git a/lld/test/MachO/Inputs/WatchOS.sdk/usr/lib/libSystem.tbd b/lld/test/MachO/Inputs/WatchOS.sdk/usr/lib/libSystem.tbd --- a/lld/test/MachO/Inputs/WatchOS.sdk/usr/lib/libSystem.tbd +++ b/lld/test/MachO/Inputs/WatchOS.sdk/usr/lib/libSystem.tbd @@ -1,6 +1,6 @@ --- !tapi-tbd tbd-version: 4 -targets: [ armv7k-watchos, arm64_32-watchos ] +targets: [ armv7k-watchos, arm64_32-watchos, armv7-watchos ] uuids: - target: armv7k-watchos value: 00000000-0000-0000-0000-000000000001 @@ -9,6 +9,6 @@ install-name: '/usr/lib/libSystem.dylib' current-version: 1.0.0 exports: - - targets: [ arm64_32-watchos, armv7k-watchos ] + - targets: [ arm64_32-watchos, armv7k-watchos, armv7-watchos ] symbols: [ dyld_stub_binder ] ... diff --git a/lld/test/MachO/Inputs/WatchOS.sdk/usr/lib/libc++.tbd b/lld/test/MachO/Inputs/WatchOS.sdk/usr/lib/libc++.tbd --- a/lld/test/MachO/Inputs/WatchOS.sdk/usr/lib/libc++.tbd +++ b/lld/test/MachO/Inputs/WatchOS.sdk/usr/lib/libc++.tbd @@ -1,6 +1,6 @@ --- !tapi-tbd tbd-version: 4 -targets: [ armv7k-watchos, arm64_32-watchos ] +targets: [ armv7k-watchos, arm64_32-watchos, armv7-watchos ] uuids: - target: armv7k-watchos value: 00000000-0000-0000-0000-000000000001 @@ -9,6 +9,6 @@ install-name: '/usr/lib/libc++.dylib' current-version: 1.0.0 reexported-libraries: - - targets: [ arm64_32-watchos, armv7k-watchos ] + - targets: [ arm64_32-watchos, armv7k-watchos, armv7-watchos ] libraries: [ '/usr/lib/libc++abi.dylib' ] ... diff --git a/lld/test/MachO/Inputs/WatchOS.sdk/usr/lib/libc++abi.tbd b/lld/test/MachO/Inputs/WatchOS.sdk/usr/lib/libc++abi.tbd --- a/lld/test/MachO/Inputs/WatchOS.sdk/usr/lib/libc++abi.tbd +++ b/lld/test/MachO/Inputs/WatchOS.sdk/usr/lib/libc++abi.tbd @@ -1,6 +1,6 @@ --- !tapi-tbd tbd-version: 4 -targets: [ armv7k-watchos, arm64_32-watchos ] +targets: [ armv7k-watchos, arm64_32-watchos, armv7-watchos ] uuids: - target: armv7k-watchos value: 00000000-0000-0000-0000-000000000001 @@ -9,6 +9,6 @@ install-name: '/usr/lib/libc++abi.dylib' current-version: 1.0.0 exports: - - targets: [ arm64_32-watchos, armv7k-watchos ] + - targets: [ arm64_32-watchos, armv7k-watchos, armv7-watchos ] symbols: [ ___gxx_personality_v0 ] ... diff --git a/lld/test/MachO/header.s b/lld/test/MachO/header.s --- a/lld/test/MachO/header.s +++ b/lld/test/MachO/header.s @@ -4,16 +4,21 @@ # RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %s -o %t/arm64-test.o # RUN: llvm-mc -filetype=obj -triple=arm64_32-apple-watchos %s -o %t/arm64-32-test.o # RUN: llvm-mc -filetype=obj -triple=arm64_32-apple-watchos %s -o %t/arm64-32-test.o +# RUN: llvm-mc -filetype=obj -triple=armv7-apple-watchos %s -o %t/arm-test.o # RUN: %lld -lSystem -arch x86_64 -o %t/x86-64-executable %t/x86-64-test.o # RUN: %lld -lSystem -arch arm64 -o %t/arm64-executable %t/arm64-test.o # RUN: %lld-watchos -lSystem -o %t/arm64-32-executable %t/arm64-32-test.o +# RUN: %lld-watchos -lSystem -arch armv7 -o %t/arm-executable %t/arm-test.o + # RUN: %lld -arch x86_64 -dylib -o %t/x86-64-dylib %t/x86-64-test.o ## NOTE: recent versions of ld64 don't emit LIB64 for x86-64-executable, maybe we should follow suit # RUN: llvm-objdump --macho --private-header %t/x86-64-executable | FileCheck %s --check-prefix=EXEC -DCPU=X86_64 -DSUBTYPE=ALL -DCAPS=LIB64 # RUN: llvm-objdump --macho --private-header %t/arm64-executable | FileCheck %s --check-prefix=EXEC -DCPU=ARM64 -DSUBTYPE=ALL -DCAPS=0x00 # RUN: llvm-objdump --macho --private-header %t/arm64-32-executable | FileCheck %s --check-prefix=EXEC -DCPU=ARM64_32 -DSUBTYPE=V8 -DCAPS=0x00 +# RUN: llvm-objdump --macho --private-header %t/arm-executable | FileCheck %s --check-prefix=EXEC -DCPU=ARM -DSUBTYPE=V7 -DCAPS=0x00 + # RUN: llvm-objdump --macho --private-header %t/x86-64-dylib | FileCheck %s --check-prefix=DYLIB -DCPU=X86_64 -DSUBTYPE=ALL -DCAPS=0x00 # EXEC: magic cputype cpusubtype caps filetype {{.*}} flags