7bf0075934
The content of this branch was automatically imported from Fedora ELN with the following as its source: https://src.fedoraproject.org/rpms/lld#5baec8dff67c12abc0448e72ca11142f76c03089
7987 lines
277 KiB
Diff
7987 lines
277 KiB
Diff
From c81a0aa7794dab5420165e47eebd6337b0da5891 Mon Sep 17 00:00:00 2001
|
|
From: Tom Stellard <tstellar@redhat.com>
|
|
Date: Mon, 10 Aug 2020 16:44:53 -0700
|
|
Subject: [PATCH] Revert "[lld] Initial commit for new Mach-O backend"
|
|
|
|
This reverts commit 03f43b3aca363e16c45d8733400fd0083b1af4d8.
|
|
---
|
|
lld/CMakeLists.txt | 1 -
|
|
lld/MachO/Arch/X86_64.cpp | 286 ----
|
|
lld/MachO/CMakeLists.txt | 36 -
|
|
lld/MachO/Config.h | 57 -
|
|
lld/MachO/Driver.cpp | 451 ------
|
|
lld/MachO/Driver.h | 36 -
|
|
lld/MachO/ExportTrie.cpp | 283 ----
|
|
lld/MachO/ExportTrie.h | 47 -
|
|
lld/MachO/InputFiles.cpp | 433 ------
|
|
lld/MachO/InputFiles.h | 121 --
|
|
lld/MachO/InputSection.cpp | 48 -
|
|
lld/MachO/InputSection.h | 74 -
|
|
lld/MachO/MachOStructs.h | 36 -
|
|
lld/MachO/MergedOutputSection.cpp | 74 -
|
|
lld/MachO/MergedOutputSection.h | 56 -
|
|
lld/MachO/Options.td | 1297 -----------------
|
|
lld/MachO/OutputSection.cpp | 18 -
|
|
lld/MachO/OutputSection.h | 74 -
|
|
lld/MachO/OutputSegment.cpp | 67 -
|
|
lld/MachO/OutputSegment.h | 62 -
|
|
lld/MachO/SymbolTable.cpp | 87 --
|
|
lld/MachO/SymbolTable.h | 50 -
|
|
lld/MachO/Symbols.cpp | 23 -
|
|
lld/MachO/Symbols.h | 138 --
|
|
lld/MachO/SyntheticSections.cpp | 409 ------
|
|
lld/MachO/SyntheticSections.h | 290 ----
|
|
lld/MachO/Target.cpp | 14 -
|
|
lld/MachO/Target.h | 75 -
|
|
lld/MachO/Writer.cpp | 542 -------
|
|
lld/MachO/Writer.h | 31 -
|
|
lld/include/lld/Common/Driver.h | 5 -
|
|
.../Inputs/MacOSX.sdk/usr/lib/libSystem.tbd | 42 -
|
|
.../iPhoneSimulator.sdk/usr/lib/libSystem.tbd | 23 -
|
|
lld/test/MachO/Inputs/libfunction.s | 6 -
|
|
lld/test/MachO/Inputs/libgoodbye.s | 14 -
|
|
lld/test/MachO/Inputs/libhello.s | 17 -
|
|
lld/test/MachO/arch.s | 11 -
|
|
lld/test/MachO/archive.s | 35 -
|
|
lld/test/MachO/bss.s | 59 -
|
|
lld/test/MachO/dylib.s | 35 -
|
|
lld/test/MachO/dylink-lazy.s | 62 -
|
|
lld/test/MachO/dylink.s | 69 -
|
|
lld/test/MachO/entry-symbol.s | 28 -
|
|
lld/test/MachO/export-trie.s | 44 -
|
|
lld/test/MachO/fat-arch.s | 16 -
|
|
.../MachO/invalid/alignment-too-large.yaml | 58 -
|
|
lld/test/MachO/invalid/archive-no-index.s | 17 -
|
|
lld/test/MachO/invalid/bad-archive.s | 11 -
|
|
lld/test/MachO/invalid/duplicate-symbol.s | 12 -
|
|
lld/test/MachO/invalid/invalid-executable.s | 11 -
|
|
lld/test/MachO/invalid/invalid-fat-narch.s | 12 -
|
|
lld/test/MachO/invalid/invalid-fat-offset.s | 22 -
|
|
.../invalid/invalid-relocation-length.yaml | 99 --
|
|
.../invalid/invalid-relocation-pcrel.yaml | 99 --
|
|
lld/test/MachO/invalid/missing-dylib.s | 5 -
|
|
lld/test/MachO/invalid/no-id-dylink.yaml | 166 ---
|
|
lld/test/MachO/invalid/no-such-file.s | 4 -
|
|
.../MachO/invalid/order-file-bad-arch.test | 9 -
|
|
.../MachO/invalid/order-file-bad-objfile.test | 10 -
|
|
.../MachO/invalid/reserved-section-name.s | 14 -
|
|
lld/test/MachO/invalid/stub-link.s | 15 -
|
|
lld/test/MachO/invalid/undefined-symbol.s | 11 -
|
|
lld/test/MachO/link-search-order.s | 43 -
|
|
lld/test/MachO/load-commands.s | 22 -
|
|
lld/test/MachO/local-got.s | 58 -
|
|
lld/test/MachO/no-exports-dylib.s | 6 -
|
|
lld/test/MachO/order-file.s | 131 --
|
|
lld/test/MachO/platform-version.test | 17 -
|
|
lld/test/MachO/relocations.s | 66 -
|
|
lld/test/MachO/resolution.s | 44 -
|
|
lld/test/MachO/search-paths-darwin.test | 20 -
|
|
lld/test/MachO/search-paths.test | 15 -
|
|
lld/test/MachO/section-headers.s | 46 -
|
|
lld/test/MachO/section-merge.s | 26 -
|
|
lld/test/MachO/segments.s | 53 -
|
|
lld/test/MachO/silent-ignore.test | 9 -
|
|
lld/test/MachO/static-link.s | 30 -
|
|
lld/test/MachO/stub-link.s | 21 -
|
|
lld/test/MachO/sub-library.s | 74 -
|
|
lld/test/MachO/subsections-section-relocs.s | 47 -
|
|
lld/test/MachO/subsections-symbol-relocs.s | 55 -
|
|
lld/test/MachO/symbol-order.s | 46 -
|
|
lld/test/MachO/symtab.s | 54 -
|
|
lld/test/MachO/x86-64-reloc-signed.s | 64 -
|
|
lld/test/MachO/x86-64-reloc-unsigned.s | 31 -
|
|
lld/tools/lld/CMakeLists.txt | 1 -
|
|
lld/tools/lld/lld.cpp | 12 +-
|
|
87 files changed, 4 insertions(+), 7244 deletions(-)
|
|
delete mode 100644 lld/MachO/Arch/X86_64.cpp
|
|
delete mode 100644 lld/MachO/CMakeLists.txt
|
|
delete mode 100644 lld/MachO/Config.h
|
|
delete mode 100644 lld/MachO/Driver.cpp
|
|
delete mode 100644 lld/MachO/Driver.h
|
|
delete mode 100644 lld/MachO/ExportTrie.cpp
|
|
delete mode 100644 lld/MachO/ExportTrie.h
|
|
delete mode 100644 lld/MachO/InputFiles.cpp
|
|
delete mode 100644 lld/MachO/InputFiles.h
|
|
delete mode 100644 lld/MachO/InputSection.cpp
|
|
delete mode 100644 lld/MachO/InputSection.h
|
|
delete mode 100644 lld/MachO/MachOStructs.h
|
|
delete mode 100644 lld/MachO/MergedOutputSection.cpp
|
|
delete mode 100644 lld/MachO/MergedOutputSection.h
|
|
delete mode 100644 lld/MachO/Options.td
|
|
delete mode 100644 lld/MachO/OutputSection.cpp
|
|
delete mode 100644 lld/MachO/OutputSection.h
|
|
delete mode 100644 lld/MachO/OutputSegment.cpp
|
|
delete mode 100644 lld/MachO/OutputSegment.h
|
|
delete mode 100644 lld/MachO/SymbolTable.cpp
|
|
delete mode 100644 lld/MachO/SymbolTable.h
|
|
delete mode 100644 lld/MachO/Symbols.cpp
|
|
delete mode 100644 lld/MachO/Symbols.h
|
|
delete mode 100644 lld/MachO/SyntheticSections.cpp
|
|
delete mode 100644 lld/MachO/SyntheticSections.h
|
|
delete mode 100644 lld/MachO/Target.cpp
|
|
delete mode 100644 lld/MachO/Target.h
|
|
delete mode 100644 lld/MachO/Writer.cpp
|
|
delete mode 100644 lld/MachO/Writer.h
|
|
delete mode 100644 lld/test/MachO/Inputs/MacOSX.sdk/usr/lib/libSystem.tbd
|
|
delete mode 100644 lld/test/MachO/Inputs/iPhoneSimulator.sdk/usr/lib/libSystem.tbd
|
|
delete mode 100644 lld/test/MachO/Inputs/libfunction.s
|
|
delete mode 100644 lld/test/MachO/Inputs/libgoodbye.s
|
|
delete mode 100644 lld/test/MachO/Inputs/libhello.s
|
|
delete mode 100644 lld/test/MachO/arch.s
|
|
delete mode 100644 lld/test/MachO/archive.s
|
|
delete mode 100644 lld/test/MachO/bss.s
|
|
delete mode 100644 lld/test/MachO/dylib.s
|
|
delete mode 100644 lld/test/MachO/dylink-lazy.s
|
|
delete mode 100644 lld/test/MachO/dylink.s
|
|
delete mode 100644 lld/test/MachO/entry-symbol.s
|
|
delete mode 100644 lld/test/MachO/export-trie.s
|
|
delete mode 100644 lld/test/MachO/fat-arch.s
|
|
delete mode 100644 lld/test/MachO/invalid/alignment-too-large.yaml
|
|
delete mode 100644 lld/test/MachO/invalid/archive-no-index.s
|
|
delete mode 100644 lld/test/MachO/invalid/bad-archive.s
|
|
delete mode 100644 lld/test/MachO/invalid/duplicate-symbol.s
|
|
delete mode 100644 lld/test/MachO/invalid/invalid-executable.s
|
|
delete mode 100644 lld/test/MachO/invalid/invalid-fat-narch.s
|
|
delete mode 100644 lld/test/MachO/invalid/invalid-fat-offset.s
|
|
delete mode 100644 lld/test/MachO/invalid/invalid-relocation-length.yaml
|
|
delete mode 100644 lld/test/MachO/invalid/invalid-relocation-pcrel.yaml
|
|
delete mode 100644 lld/test/MachO/invalid/missing-dylib.s
|
|
delete mode 100644 lld/test/MachO/invalid/no-id-dylink.yaml
|
|
delete mode 100644 lld/test/MachO/invalid/no-such-file.s
|
|
delete mode 100644 lld/test/MachO/invalid/order-file-bad-arch.test
|
|
delete mode 100644 lld/test/MachO/invalid/order-file-bad-objfile.test
|
|
delete mode 100644 lld/test/MachO/invalid/reserved-section-name.s
|
|
delete mode 100644 lld/test/MachO/invalid/stub-link.s
|
|
delete mode 100644 lld/test/MachO/invalid/undefined-symbol.s
|
|
delete mode 100644 lld/test/MachO/link-search-order.s
|
|
delete mode 100644 lld/test/MachO/load-commands.s
|
|
delete mode 100644 lld/test/MachO/local-got.s
|
|
delete mode 100644 lld/test/MachO/no-exports-dylib.s
|
|
delete mode 100644 lld/test/MachO/order-file.s
|
|
delete mode 100644 lld/test/MachO/platform-version.test
|
|
delete mode 100644 lld/test/MachO/relocations.s
|
|
delete mode 100644 lld/test/MachO/resolution.s
|
|
delete mode 100644 lld/test/MachO/search-paths-darwin.test
|
|
delete mode 100644 lld/test/MachO/search-paths.test
|
|
delete mode 100644 lld/test/MachO/section-headers.s
|
|
delete mode 100644 lld/test/MachO/section-merge.s
|
|
delete mode 100644 lld/test/MachO/segments.s
|
|
delete mode 100644 lld/test/MachO/silent-ignore.test
|
|
delete mode 100644 lld/test/MachO/static-link.s
|
|
delete mode 100644 lld/test/MachO/stub-link.s
|
|
delete mode 100644 lld/test/MachO/sub-library.s
|
|
delete mode 100644 lld/test/MachO/subsections-section-relocs.s
|
|
delete mode 100644 lld/test/MachO/subsections-symbol-relocs.s
|
|
delete mode 100644 lld/test/MachO/symbol-order.s
|
|
delete mode 100644 lld/test/MachO/symtab.s
|
|
delete mode 100644 lld/test/MachO/x86-64-reloc-signed.s
|
|
delete mode 100644 lld/test/MachO/x86-64-reloc-unsigned.s
|
|
|
|
diff --git a/lld/CMakeLists.txt b/lld/CMakeLists.txt
|
|
index 5090c935e75..a0f2132c0f5 100644
|
|
--- a/lld/CMakeLists.txt
|
|
+++ b/lld/CMakeLists.txt
|
|
@@ -223,7 +223,6 @@ endif()
|
|
add_subdirectory(docs)
|
|
add_subdirectory(COFF)
|
|
add_subdirectory(ELF)
|
|
-add_subdirectory(MachO)
|
|
add_subdirectory(MinGW)
|
|
add_subdirectory(wasm)
|
|
|
|
diff --git a/lld/MachO/Arch/X86_64.cpp b/lld/MachO/Arch/X86_64.cpp
|
|
deleted file mode 100644
|
|
index 36f686ca2f1..00000000000
|
|
--- a/lld/MachO/Arch/X86_64.cpp
|
|
+++ /dev/null
|
|
@@ -1,286 +0,0 @@
|
|
-//===- X86_64.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 X86_64 : TargetInfo {
|
|
- X86_64();
|
|
-
|
|
- uint64_t getImplicitAddend(MemoryBufferRef, const section_64 &,
|
|
- const relocation_info &) const override;
|
|
- void relocateOne(uint8_t *loc, const Reloc &, uint64_t val) const override;
|
|
-
|
|
- void writeStub(uint8_t *buf, const DylibSymbol &) const override;
|
|
- void writeStubHelperHeader(uint8_t *buf) const override;
|
|
- void writeStubHelperEntry(uint8_t *buf, const DylibSymbol &,
|
|
- uint64_t entryAddr) const override;
|
|
-
|
|
- void prepareSymbolRelocation(lld::macho::Symbol &, const InputSection *,
|
|
- const Reloc &) override;
|
|
- uint64_t getSymbolVA(const lld::macho::Symbol &, uint8_t type) const override;
|
|
-};
|
|
-
|
|
-} // namespace
|
|
-
|
|
-static std::string getErrorLocation(MemoryBufferRef mb, const section_64 &sec,
|
|
- const relocation_info &rel) {
|
|
- return ("invalid relocation at offset " + std::to_string(rel.r_address) +
|
|
- " of " + sec.segname + "," + sec.sectname + " in " +
|
|
- mb.getBufferIdentifier())
|
|
- .str();
|
|
-}
|
|
-
|
|
-static void validateLength(MemoryBufferRef mb, const section_64 &sec,
|
|
- const relocation_info &rel,
|
|
- const std::vector<uint8_t> &validLengths) {
|
|
- if (std::find(validLengths.begin(), validLengths.end(), rel.r_length) !=
|
|
- validLengths.end())
|
|
- return;
|
|
-
|
|
- std::string msg = getErrorLocation(mb, sec, rel) + ": relocations of type " +
|
|
- std::to_string(rel.r_type) + " must have r_length of ";
|
|
- bool first = true;
|
|
- for (uint8_t length : validLengths) {
|
|
- if (!first)
|
|
- msg += " or ";
|
|
- first = false;
|
|
- msg += std::to_string(length);
|
|
- }
|
|
- fatal(msg);
|
|
-}
|
|
-
|
|
-uint64_t X86_64::getImplicitAddend(MemoryBufferRef mb, const section_64 &sec,
|
|
- const relocation_info &rel) const {
|
|
- auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart());
|
|
- const uint8_t *loc = buf + sec.offset + rel.r_address;
|
|
- switch (rel.r_type) {
|
|
- case X86_64_RELOC_BRANCH:
|
|
- // XXX: ld64 also supports r_length = 0 here but I'm not sure when such a
|
|
- // relocation will actually be generated.
|
|
- validateLength(mb, sec, rel, {2});
|
|
- break;
|
|
- case X86_64_RELOC_SIGNED:
|
|
- case X86_64_RELOC_SIGNED_1:
|
|
- case X86_64_RELOC_SIGNED_2:
|
|
- case X86_64_RELOC_SIGNED_4:
|
|
- case X86_64_RELOC_GOT_LOAD:
|
|
- case X86_64_RELOC_GOT:
|
|
- if (!rel.r_pcrel)
|
|
- fatal(getErrorLocation(mb, sec, rel) + ": relocations of type " +
|
|
- std::to_string(rel.r_type) + " must be pcrel");
|
|
- validateLength(mb, sec, rel, {2});
|
|
- break;
|
|
- case X86_64_RELOC_UNSIGNED:
|
|
- if (rel.r_pcrel)
|
|
- fatal(getErrorLocation(mb, sec, rel) + ": relocations of type " +
|
|
- std::to_string(rel.r_type) + " must not be pcrel");
|
|
- validateLength(mb, sec, rel, {2, 3});
|
|
- break;
|
|
- default:
|
|
- error("TODO: Unhandled relocation type " + std::to_string(rel.r_type));
|
|
- return 0;
|
|
- }
|
|
-
|
|
- switch (rel.r_length) {
|
|
- case 0:
|
|
- return *loc;
|
|
- case 1:
|
|
- return read16le(loc);
|
|
- case 2:
|
|
- return read32le(loc);
|
|
- case 3:
|
|
- return read64le(loc);
|
|
- default:
|
|
- llvm_unreachable("invalid r_length");
|
|
- }
|
|
-}
|
|
-
|
|
-void X86_64::relocateOne(uint8_t *loc, const Reloc &r, uint64_t val) const {
|
|
- switch (r.type) {
|
|
- case X86_64_RELOC_BRANCH:
|
|
- case X86_64_RELOC_SIGNED:
|
|
- case X86_64_RELOC_SIGNED_1:
|
|
- case X86_64_RELOC_SIGNED_2:
|
|
- case X86_64_RELOC_SIGNED_4:
|
|
- case X86_64_RELOC_GOT_LOAD:
|
|
- case X86_64_RELOC_GOT:
|
|
- // These types are only used for pc-relative relocations, so offset by 4
|
|
- // since the RIP has advanced by 4 at this point. This is only valid when
|
|
- // r_length = 2, which is enforced by validateLength().
|
|
- val -= 4;
|
|
- break;
|
|
- case X86_64_RELOC_UNSIGNED:
|
|
- break;
|
|
- default:
|
|
- llvm_unreachable(
|
|
- "getImplicitAddend should have flagged all unhandled relocation types");
|
|
- }
|
|
-
|
|
- switch (r.length) {
|
|
- case 0:
|
|
- *loc = val;
|
|
- break;
|
|
- case 1:
|
|
- write16le(loc, val);
|
|
- break;
|
|
- case 2:
|
|
- write32le(loc, val);
|
|
- break;
|
|
- case 3:
|
|
- write64le(loc, val);
|
|
- break;
|
|
- default:
|
|
- llvm_unreachable("invalid r_length");
|
|
- }
|
|
-}
|
|
-
|
|
-// The following methods emit a number of assembly sequences with RIP-relative
|
|
-// addressing. Note that RIP-relative addressing on X86-64 has the RIP pointing
|
|
-// to the next instruction, not the current instruction, so we always have to
|
|
-// account for the current instruction's size when calculating offsets.
|
|
-// writeRipRelative helps with that.
|
|
-//
|
|
-// bufAddr: The virtual address corresponding to buf[0].
|
|
-// bufOff: The offset within buf of the next instruction.
|
|
-// destAddr: The destination address that the current instruction references.
|
|
-static void writeRipRelative(uint8_t *buf, uint64_t bufAddr, uint64_t bufOff,
|
|
- uint64_t destAddr) {
|
|
- uint64_t rip = bufAddr + bufOff;
|
|
- // For the instructions we care about, the RIP-relative address is always
|
|
- // stored in the last 4 bytes of the instruction.
|
|
- write32le(buf + bufOff - 4, destAddr - rip);
|
|
-}
|
|
-
|
|
-static constexpr uint8_t stub[] = {
|
|
- 0xff, 0x25, 0, 0, 0, 0, // jmpq *__la_symbol_ptr(%rip)
|
|
-};
|
|
-
|
|
-void X86_64::writeStub(uint8_t *buf, const DylibSymbol &sym) const {
|
|
- memcpy(buf, stub, 2); // just copy the two nonzero bytes
|
|
- uint64_t stubAddr = in.stubs->addr + sym.stubsIndex * sizeof(stub);
|
|
- writeRipRelative(buf, stubAddr, sizeof(stub),
|
|
- in.lazyPointers->addr + sym.stubsIndex * WordSize);
|
|
-}
|
|
-
|
|
-static constexpr uint8_t stubHelperHeader[] = {
|
|
- 0x4c, 0x8d, 0x1d, 0, 0, 0, 0, // 0x0: leaq ImageLoaderCache(%rip), %r11
|
|
- 0x41, 0x53, // 0x7: pushq %r11
|
|
- 0xff, 0x25, 0, 0, 0, 0, // 0x9: jmpq *dyld_stub_binder@GOT(%rip)
|
|
- 0x90, // 0xf: nop
|
|
-};
|
|
-
|
|
-static constexpr uint8_t stubHelperEntry[] = {
|
|
- 0x68, 0, 0, 0, 0, // 0x0: pushq <bind offset>
|
|
- 0xe9, 0, 0, 0, 0, // 0x5: jmp <__stub_helper>
|
|
-};
|
|
-
|
|
-void X86_64::writeStubHelperHeader(uint8_t *buf) const {
|
|
- memcpy(buf, stubHelperHeader, sizeof(stubHelperHeader));
|
|
- writeRipRelative(buf, in.stubHelper->addr, 7, in.imageLoaderCache->getVA());
|
|
- writeRipRelative(buf, in.stubHelper->addr, 0xf,
|
|
- in.got->addr +
|
|
- in.stubHelper->stubBinder->gotIndex * WordSize);
|
|
-}
|
|
-
|
|
-void X86_64::writeStubHelperEntry(uint8_t *buf, const DylibSymbol &sym,
|
|
- uint64_t entryAddr) const {
|
|
- memcpy(buf, stubHelperEntry, sizeof(stubHelperEntry));
|
|
- write32le(buf + 1, sym.lazyBindOffset);
|
|
- writeRipRelative(buf, entryAddr, sizeof(stubHelperEntry),
|
|
- in.stubHelper->addr);
|
|
-}
|
|
-
|
|
-void X86_64::prepareSymbolRelocation(lld::macho::Symbol &sym,
|
|
- const InputSection *isec, const Reloc &r) {
|
|
- switch (r.type) {
|
|
- case X86_64_RELOC_GOT_LOAD:
|
|
- // TODO: implement mov -> lea relaxation for non-dynamic symbols
|
|
- case X86_64_RELOC_GOT:
|
|
- in.got->addEntry(sym);
|
|
- break;
|
|
- case X86_64_RELOC_BRANCH: {
|
|
- if (auto *dysym = dyn_cast<DylibSymbol>(&sym))
|
|
- in.stubs->addEntry(*dysym);
|
|
- break;
|
|
- }
|
|
- case X86_64_RELOC_UNSIGNED: {
|
|
- if (auto *dysym = dyn_cast<DylibSymbol>(&sym)) {
|
|
- if (r.length != 3) {
|
|
- error("X86_64_RELOC_UNSIGNED referencing the dynamic symbol " +
|
|
- dysym->getName() + " must have r_length = 3");
|
|
- return;
|
|
- }
|
|
- in.binding->addEntry(dysym, isec, r.offset, r.addend);
|
|
- }
|
|
- break;
|
|
- }
|
|
- case X86_64_RELOC_SIGNED:
|
|
- case X86_64_RELOC_SIGNED_1:
|
|
- case X86_64_RELOC_SIGNED_2:
|
|
- case X86_64_RELOC_SIGNED_4:
|
|
- break;
|
|
- case X86_64_RELOC_SUBTRACTOR:
|
|
- case X86_64_RELOC_TLV:
|
|
- fatal("TODO: handle relocation type " + std::to_string(r.type));
|
|
- break;
|
|
- default:
|
|
- llvm_unreachable("unexpected relocation type");
|
|
- }
|
|
-}
|
|
-
|
|
-uint64_t X86_64::getSymbolVA(const lld::macho::Symbol &sym,
|
|
- uint8_t type) const {
|
|
- switch (type) {
|
|
- case X86_64_RELOC_GOT_LOAD:
|
|
- case X86_64_RELOC_GOT:
|
|
- return in.got->addr + sym.gotIndex * WordSize;
|
|
- case X86_64_RELOC_BRANCH:
|
|
- if (auto *dysym = dyn_cast<DylibSymbol>(&sym))
|
|
- return in.stubs->addr + dysym->stubsIndex * sizeof(stub);
|
|
- return sym.getVA();
|
|
- case X86_64_RELOC_UNSIGNED:
|
|
- case X86_64_RELOC_SIGNED:
|
|
- case X86_64_RELOC_SIGNED_1:
|
|
- case X86_64_RELOC_SIGNED_2:
|
|
- case X86_64_RELOC_SIGNED_4:
|
|
- return sym.getVA();
|
|
- case X86_64_RELOC_SUBTRACTOR:
|
|
- case X86_64_RELOC_TLV:
|
|
- fatal("TODO: handle relocation type " + std::to_string(type));
|
|
- default:
|
|
- llvm_unreachable("Unexpected relocation type");
|
|
- }
|
|
-}
|
|
-
|
|
-X86_64::X86_64() {
|
|
- cpuType = CPU_TYPE_X86_64;
|
|
- cpuSubtype = CPU_SUBTYPE_X86_64_ALL;
|
|
-
|
|
- stubSize = sizeof(stub);
|
|
- stubHelperHeaderSize = sizeof(stubHelperHeader);
|
|
- stubHelperEntrySize = sizeof(stubHelperEntry);
|
|
-}
|
|
-
|
|
-TargetInfo *macho::createX86_64TargetInfo() {
|
|
- static X86_64 t;
|
|
- return &t;
|
|
-}
|
|
diff --git a/lld/MachO/CMakeLists.txt b/lld/MachO/CMakeLists.txt
|
|
deleted file mode 100644
|
|
index 6fe356f5158..00000000000
|
|
--- a/lld/MachO/CMakeLists.txt
|
|
+++ /dev/null
|
|
@@ -1,36 +0,0 @@
|
|
-set(LLVM_TARGET_DEFINITIONS Options.td)
|
|
-tablegen(LLVM Options.inc -gen-opt-parser-defs)
|
|
-add_public_tablegen_target(MachOOptionsTableGen)
|
|
-
|
|
-add_lld_library(lldMachO2
|
|
- Arch/X86_64.cpp
|
|
- Driver.cpp
|
|
- ExportTrie.cpp
|
|
- InputFiles.cpp
|
|
- InputSection.cpp
|
|
- MergedOutputSection.cpp
|
|
- OutputSection.cpp
|
|
- OutputSegment.cpp
|
|
- SymbolTable.cpp
|
|
- Symbols.cpp
|
|
- SyntheticSections.cpp
|
|
- Target.cpp
|
|
- Writer.cpp
|
|
-
|
|
- LINK_COMPONENTS
|
|
- ${LLVM_TARGETS_TO_BUILD}
|
|
- BinaryFormat
|
|
- Core
|
|
- Object
|
|
- Option
|
|
- Support
|
|
- TextAPI
|
|
-
|
|
- LINK_LIBS
|
|
- lldCommon
|
|
- ${LLVM_PTHREAD_LIB}
|
|
-
|
|
- DEPENDS
|
|
- MachOOptionsTableGen
|
|
- ${tablegen_deps}
|
|
- )
|
|
diff --git a/lld/MachO/Config.h b/lld/MachO/Config.h
|
|
deleted file mode 100644
|
|
index 79812a43356..00000000000
|
|
--- a/lld/MachO/Config.h
|
|
+++ /dev/null
|
|
@@ -1,57 +0,0 @@
|
|
-//===- Config.h -------------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_CONFIG_H
|
|
-#define LLD_MACHO_CONFIG_H
|
|
-
|
|
-#include "llvm/ADT/DenseMap.h"
|
|
-#include "llvm/ADT/StringRef.h"
|
|
-#include "llvm/BinaryFormat/MachO.h"
|
|
-#include "llvm/TextAPI/MachO/Architecture.h"
|
|
-
|
|
-#include <vector>
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-class Symbol;
|
|
-struct SymbolPriorityEntry;
|
|
-
|
|
-struct Configuration {
|
|
- Symbol *entry;
|
|
- bool hasReexports = false;
|
|
- llvm::StringRef installName;
|
|
- llvm::StringRef outputFile;
|
|
- llvm::MachO::Architecture arch;
|
|
- llvm::MachO::HeaderFileType outputType;
|
|
- std::vector<llvm::StringRef> librarySearchPaths;
|
|
- // TODO: use the framework search paths
|
|
- std::vector<llvm::StringRef> frameworkSearchPaths;
|
|
- llvm::DenseMap<llvm::StringRef, SymbolPriorityEntry> priorities;
|
|
-};
|
|
-
|
|
-// The symbol with the highest priority should be ordered first in the output
|
|
-// section (modulo input section contiguity constraints). Using priority
|
|
-// (highest first) instead of order (lowest first) has the convenient property
|
|
-// that the default-constructed zero priority -- for symbols/sections without a
|
|
-// user-defined order -- naturally ends up putting them at the end of the
|
|
-// output.
|
|
-struct SymbolPriorityEntry {
|
|
- // The priority given to a matching symbol, regardless of which object file
|
|
- // it originated from.
|
|
- size_t anyObjectFile = 0;
|
|
- // The priority given to a matching symbol from a particular object file.
|
|
- llvm::DenseMap<llvm::StringRef, size_t> objectFiles;
|
|
-};
|
|
-
|
|
-extern Configuration *config;
|
|
-
|
|
-} // namespace macho
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
|
|
deleted file mode 100644
|
|
index 2a3b0042162..00000000000
|
|
--- a/lld/MachO/Driver.cpp
|
|
+++ /dev/null
|
|
@@ -1,451 +0,0 @@
|
|
-//===- Driver.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 "Driver.h"
|
|
-#include "Config.h"
|
|
-#include "InputFiles.h"
|
|
-#include "OutputSection.h"
|
|
-#include "OutputSegment.h"
|
|
-#include "SymbolTable.h"
|
|
-#include "Symbols.h"
|
|
-#include "Target.h"
|
|
-#include "Writer.h"
|
|
-
|
|
-#include "lld/Common/Args.h"
|
|
-#include "lld/Common/Driver.h"
|
|
-#include "lld/Common/ErrorHandler.h"
|
|
-#include "lld/Common/LLVM.h"
|
|
-#include "lld/Common/Memory.h"
|
|
-#include "lld/Common/Version.h"
|
|
-#include "llvm/ADT/DenseSet.h"
|
|
-#include "llvm/ADT/StringExtras.h"
|
|
-#include "llvm/ADT/StringRef.h"
|
|
-#include "llvm/BinaryFormat/MachO.h"
|
|
-#include "llvm/BinaryFormat/Magic.h"
|
|
-#include "llvm/Object/Archive.h"
|
|
-#include "llvm/Option/ArgList.h"
|
|
-#include "llvm/Option/Option.h"
|
|
-#include "llvm/Support/Host.h"
|
|
-#include "llvm/Support/MemoryBuffer.h"
|
|
-#include "llvm/Support/Path.h"
|
|
-
|
|
-using namespace llvm;
|
|
-using namespace llvm::MachO;
|
|
-using namespace llvm::sys;
|
|
-using namespace llvm::opt;
|
|
-using namespace lld;
|
|
-using namespace lld::macho;
|
|
-
|
|
-Configuration *lld::macho::config;
|
|
-
|
|
-// Create prefix string literals used in Options.td
|
|
-#define PREFIX(NAME, VALUE) const char *NAME[] = VALUE;
|
|
-#include "Options.inc"
|
|
-#undef PREFIX
|
|
-
|
|
-// Create table mapping all options defined in Options.td
|
|
-static const opt::OptTable::Info optInfo[] = {
|
|
-#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
|
|
- {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \
|
|
- X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
|
|
-#include "Options.inc"
|
|
-#undef OPTION
|
|
-};
|
|
-
|
|
-MachOOptTable::MachOOptTable() : OptTable(optInfo) {}
|
|
-
|
|
-opt::InputArgList MachOOptTable::parse(ArrayRef<const char *> argv) {
|
|
- // Make InputArgList from string vectors.
|
|
- unsigned missingIndex;
|
|
- unsigned missingCount;
|
|
- SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size());
|
|
-
|
|
- opt::InputArgList args = ParseArgs(vec, missingIndex, missingCount);
|
|
-
|
|
- if (missingCount)
|
|
- error(Twine(args.getArgString(missingIndex)) + ": missing argument");
|
|
-
|
|
- for (opt::Arg *arg : args.filtered(OPT_UNKNOWN))
|
|
- error("unknown argument: " + arg->getSpelling());
|
|
- return args;
|
|
-}
|
|
-
|
|
-void MachOOptTable::printHelp(const char *argv0, bool showHidden) const {
|
|
- PrintHelp(lld::outs(), (std::string(argv0) + " [options] file...").c_str(),
|
|
- "LLVM Linker", showHidden);
|
|
- lld::outs() << "\n";
|
|
-}
|
|
-
|
|
-static Optional<std::string> findLibrary(StringRef name) {
|
|
- std::string stub = (llvm::Twine("lib") + name + ".tbd").str();
|
|
- std::string shared = (llvm::Twine("lib") + name + ".dylib").str();
|
|
- std::string archive = (llvm::Twine("lib") + name + ".a").str();
|
|
- llvm::SmallString<260> location;
|
|
-
|
|
- for (StringRef dir : config->librarySearchPaths) {
|
|
- for (StringRef library : {stub, shared, archive}) {
|
|
- location = dir;
|
|
- llvm::sys::path::append(location, library);
|
|
- if (fs::exists(location))
|
|
- return location.str().str();
|
|
- }
|
|
- }
|
|
- return {};
|
|
-}
|
|
-
|
|
-static TargetInfo *createTargetInfo(opt::InputArgList &args) {
|
|
- StringRef arch = args.getLastArgValue(OPT_arch, "x86_64");
|
|
- config->arch = llvm::MachO::getArchitectureFromName(
|
|
- args.getLastArgValue(OPT_arch, arch));
|
|
- switch (config->arch) {
|
|
- case llvm::MachO::AK_x86_64:
|
|
- case llvm::MachO::AK_x86_64h:
|
|
- return createX86_64TargetInfo();
|
|
- default:
|
|
- fatal("missing or unsupported -arch " + arch);
|
|
- }
|
|
-}
|
|
-
|
|
-static bool isDirectory(StringRef option, StringRef path) {
|
|
- if (!fs::exists(path)) {
|
|
- warn("directory not found for option -" + option + path);
|
|
- return false;
|
|
- } else if (!fs::is_directory(path)) {
|
|
- warn("option -" + option + path + " references a non-directory path");
|
|
- return false;
|
|
- }
|
|
- return true;
|
|
-}
|
|
-
|
|
-static void getSearchPaths(std::vector<StringRef> &paths, unsigned optionCode,
|
|
- opt::InputArgList &args,
|
|
- const SmallVector<StringRef, 2> &systemPaths) {
|
|
- StringRef optionLetter{(optionCode == OPT_F ? "F" : "L")};
|
|
- for (auto const &path : args::getStrings(args, optionCode)) {
|
|
- if (isDirectory(optionLetter, path))
|
|
- paths.push_back(path);
|
|
- }
|
|
- if (!args.hasArg(OPT_Z) && Triple(sys::getProcessTriple()).isOSDarwin()) {
|
|
- for (auto const &path : systemPaths) {
|
|
- if (isDirectory(optionLetter, path))
|
|
- paths.push_back(path);
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-static void getLibrarySearchPaths(std::vector<StringRef> &paths,
|
|
- opt::InputArgList &args) {
|
|
- getSearchPaths(paths, OPT_L, args, {"/usr/lib", "/usr/local/lib"});
|
|
-}
|
|
-
|
|
-static void getFrameworkSearchPaths(std::vector<StringRef> &paths,
|
|
- opt::InputArgList &args) {
|
|
- getSearchPaths(paths, OPT_F, args,
|
|
- {"/Library/Frameworks", "/System/Library/Frameworks"});
|
|
-}
|
|
-
|
|
-static void addFile(StringRef path) {
|
|
- Optional<MemoryBufferRef> buffer = readFile(path);
|
|
- if (!buffer)
|
|
- return;
|
|
- MemoryBufferRef mbref = *buffer;
|
|
-
|
|
- switch (identify_magic(mbref.getBuffer())) {
|
|
- case file_magic::archive: {
|
|
- std::unique_ptr<object::Archive> file = CHECK(
|
|
- object::Archive::create(mbref), path + ": failed to parse archive");
|
|
-
|
|
- if (!file->isEmpty() && !file->hasSymbolTable())
|
|
- error(path + ": archive has no index; run ranlib to add one");
|
|
-
|
|
- inputFiles.push_back(make<ArchiveFile>(std::move(file)));
|
|
- break;
|
|
- }
|
|
- case file_magic::macho_object:
|
|
- inputFiles.push_back(make<ObjFile>(mbref));
|
|
- break;
|
|
- case file_magic::macho_dynamically_linked_shared_lib:
|
|
- inputFiles.push_back(make<DylibFile>(mbref));
|
|
- break;
|
|
- case file_magic::tapi_file: {
|
|
- llvm::Expected<std::unique_ptr<llvm::MachO::InterfaceFile>> result =
|
|
- TextAPIReader::get(mbref);
|
|
- if (!result)
|
|
- return;
|
|
-
|
|
- inputFiles.push_back(make<DylibFile>(std::move(*result)));
|
|
- break;
|
|
- }
|
|
- default:
|
|
- error(path + ": unhandled file type");
|
|
- }
|
|
-}
|
|
-
|
|
-static std::array<StringRef, 6> archNames{"arm", "arm64", "i386",
|
|
- "x86_64", "ppc", "ppc64"};
|
|
-static bool isArchString(StringRef s) {
|
|
- static DenseSet<StringRef> archNamesSet(archNames.begin(), archNames.end());
|
|
- return archNamesSet.find(s) != archNamesSet.end();
|
|
-}
|
|
-
|
|
-// An order file has one entry per line, in the following format:
|
|
-//
|
|
-// <arch>:<object file>:<symbol name>
|
|
-//
|
|
-// <arch> and <object file> are optional. If not specified, then that entry
|
|
-// matches any symbol of that name.
|
|
-//
|
|
-// If a symbol is matched by multiple entries, then it takes the lowest-ordered
|
|
-// entry (the one nearest to the front of the list.)
|
|
-//
|
|
-// The file can also have line comments that start with '#'.
|
|
-void parseOrderFile(StringRef path) {
|
|
- Optional<MemoryBufferRef> buffer = readFile(path);
|
|
- if (!buffer) {
|
|
- error("Could not read order file at " + path);
|
|
- return;
|
|
- }
|
|
-
|
|
- MemoryBufferRef mbref = *buffer;
|
|
- size_t priority = std::numeric_limits<size_t>::max();
|
|
- for (StringRef rest : args::getLines(mbref)) {
|
|
- StringRef arch, objectFile, symbol;
|
|
-
|
|
- std::array<StringRef, 3> fields;
|
|
- uint8_t fieldCount = 0;
|
|
- while (rest != "" && fieldCount < 3) {
|
|
- std::pair<StringRef, StringRef> p = getToken(rest, ": \t\n\v\f\r");
|
|
- StringRef tok = p.first;
|
|
- rest = p.second;
|
|
-
|
|
- // Check if we have a comment
|
|
- if (tok == "" || tok[0] == '#')
|
|
- break;
|
|
-
|
|
- fields[fieldCount++] = tok;
|
|
- }
|
|
-
|
|
- switch (fieldCount) {
|
|
- case 3:
|
|
- arch = fields[0];
|
|
- objectFile = fields[1];
|
|
- symbol = fields[2];
|
|
- break;
|
|
- case 2:
|
|
- (isArchString(fields[0]) ? arch : objectFile) = fields[0];
|
|
- symbol = fields[1];
|
|
- break;
|
|
- case 1:
|
|
- symbol = fields[0];
|
|
- break;
|
|
- case 0:
|
|
- break;
|
|
- default:
|
|
- llvm_unreachable("too many fields in order file");
|
|
- }
|
|
-
|
|
- if (!arch.empty()) {
|
|
- if (!isArchString(arch)) {
|
|
- error("invalid arch \"" + arch + "\" in order file: expected one of " +
|
|
- llvm::join(archNames, ", "));
|
|
- continue;
|
|
- }
|
|
-
|
|
- // TODO: Update when we extend support for other archs
|
|
- if (arch != "x86_64")
|
|
- continue;
|
|
- }
|
|
-
|
|
- if (!objectFile.empty() && !objectFile.endswith(".o")) {
|
|
- error("invalid object file name \"" + objectFile +
|
|
- "\" in order file: should end with .o");
|
|
- continue;
|
|
- }
|
|
-
|
|
- if (!symbol.empty()) {
|
|
- SymbolPriorityEntry &entry = config->priorities[symbol];
|
|
- if (!objectFile.empty())
|
|
- entry.objectFiles.insert(std::make_pair(objectFile, priority));
|
|
- else
|
|
- entry.anyObjectFile = std::max(entry.anyObjectFile, priority);
|
|
- }
|
|
-
|
|
- --priority;
|
|
- }
|
|
-}
|
|
-
|
|
-// We expect sub-library names of the form "libfoo", which will match a dylib
|
|
-// with a path of .*/libfoo.dylib.
|
|
-static bool markSubLibrary(StringRef searchName) {
|
|
- for (InputFile *file : inputFiles) {
|
|
- if (auto *dylibFile = dyn_cast<DylibFile>(file)) {
|
|
- StringRef filename = path::filename(dylibFile->getName());
|
|
- if (filename.consume_front(searchName) && filename == ".dylib") {
|
|
- dylibFile->reexport = true;
|
|
- return true;
|
|
- }
|
|
- }
|
|
- }
|
|
- return false;
|
|
-}
|
|
-
|
|
-static void handlePlatformVersion(const opt::Arg *arg) {
|
|
- // TODO: implementation coming very soon ...
|
|
-}
|
|
-
|
|
-static void warnIfDeprecatedOption(const opt::Option &opt) {
|
|
- if (!opt.getGroup().isValid())
|
|
- return;
|
|
- if (opt.getGroup().getID() == OPT_grp_deprecated) {
|
|
- warn("Option `" + opt.getPrefixedName() + "' is deprecated in ld64:");
|
|
- warn(opt.getHelpText());
|
|
- }
|
|
-}
|
|
-
|
|
-static void warnIfUnimplementedOption(const opt::Option &opt) {
|
|
- if (!opt.getGroup().isValid())
|
|
- return;
|
|
- switch (opt.getGroup().getID()) {
|
|
- case OPT_grp_deprecated:
|
|
- // warn about deprecated options elsewhere
|
|
- break;
|
|
- case OPT_grp_undocumented:
|
|
- warn("Option `" + opt.getPrefixedName() +
|
|
- "' is undocumented. Should lld implement it?");
|
|
- break;
|
|
- case OPT_grp_obsolete:
|
|
- warn("Option `" + opt.getPrefixedName() +
|
|
- "' is obsolete. Please modernize your usage.");
|
|
- break;
|
|
- case OPT_grp_ignored:
|
|
- warn("Option `" + opt.getPrefixedName() + "' is ignored.");
|
|
- break;
|
|
- default:
|
|
- warn("Option `" + opt.getPrefixedName() +
|
|
- "' is not yet implemented. Stay tuned...");
|
|
- break;
|
|
- }
|
|
-}
|
|
-
|
|
-bool macho::link(llvm::ArrayRef<const char *> argsArr, bool canExitEarly,
|
|
- raw_ostream &stdoutOS, raw_ostream &stderrOS) {
|
|
- lld::stdoutOS = &stdoutOS;
|
|
- lld::stderrOS = &stderrOS;
|
|
-
|
|
- stderrOS.enable_colors(stderrOS.has_colors());
|
|
- // TODO: Set up error handler properly, e.g. the errorLimitExceededMsg
|
|
-
|
|
- MachOOptTable parser;
|
|
- opt::InputArgList args = parser.parse(argsArr.slice(1));
|
|
-
|
|
- if (args.hasArg(OPT_help_hidden)) {
|
|
- parser.printHelp(argsArr[0], /*showHidden=*/true);
|
|
- return true;
|
|
- } else if (args.hasArg(OPT_help)) {
|
|
- parser.printHelp(argsArr[0], /*showHidden=*/false);
|
|
- return true;
|
|
- }
|
|
-
|
|
- config = make<Configuration>();
|
|
- symtab = make<SymbolTable>();
|
|
- target = createTargetInfo(args);
|
|
-
|
|
- config->entry = symtab->addUndefined(args.getLastArgValue(OPT_e, "_main"));
|
|
- config->outputFile = args.getLastArgValue(OPT_o, "a.out");
|
|
- config->installName =
|
|
- args.getLastArgValue(OPT_install_name, config->outputFile);
|
|
- getLibrarySearchPaths(config->librarySearchPaths, args);
|
|
- getFrameworkSearchPaths(config->frameworkSearchPaths, args);
|
|
- config->outputType = args.hasArg(OPT_dylib) ? MH_DYLIB : MH_EXECUTE;
|
|
-
|
|
- if (args.hasArg(OPT_v)) {
|
|
- message(getLLDVersion());
|
|
- message(StringRef("Library search paths:") +
|
|
- (config->librarySearchPaths.size()
|
|
- ? "\n\t" + llvm::join(config->librarySearchPaths, "\n\t")
|
|
- : ""));
|
|
- message(StringRef("Framework search paths:") +
|
|
- (config->frameworkSearchPaths.size()
|
|
- ? "\n\t" + llvm::join(config->frameworkSearchPaths, "\n\t")
|
|
- : ""));
|
|
- freeArena();
|
|
- return !errorCount();
|
|
- }
|
|
-
|
|
- for (const auto &arg : args) {
|
|
- const auto &opt = arg->getOption();
|
|
- warnIfDeprecatedOption(opt);
|
|
- switch (arg->getOption().getID()) {
|
|
- case OPT_INPUT:
|
|
- addFile(arg->getValue());
|
|
- break;
|
|
- case OPT_l: {
|
|
- StringRef name = arg->getValue();
|
|
- if (Optional<std::string> path = findLibrary(name)) {
|
|
- addFile(*path);
|
|
- break;
|
|
- }
|
|
- error("library not found for -l" + name);
|
|
- break;
|
|
- }
|
|
- case OPT_platform_version:
|
|
- handlePlatformVersion(arg);
|
|
- break;
|
|
- case OPT_o:
|
|
- case OPT_dylib:
|
|
- case OPT_e:
|
|
- case OPT_L:
|
|
- case OPT_Z:
|
|
- case OPT_arch:
|
|
- // handled elsewhere
|
|
- break;
|
|
- default:
|
|
- warnIfUnimplementedOption(opt);
|
|
- break;
|
|
- }
|
|
- }
|
|
-
|
|
- // Now that all dylibs have been loaded, search for those that should be
|
|
- // re-exported.
|
|
- for (opt::Arg *arg : args.filtered(OPT_sub_library)) {
|
|
- config->hasReexports = true;
|
|
- StringRef searchName = arg->getValue();
|
|
- if (!markSubLibrary(searchName))
|
|
- error("-sub_library " + searchName + " does not match a supplied dylib");
|
|
- }
|
|
-
|
|
- StringRef orderFile = args.getLastArgValue(OPT_order_file);
|
|
- if (!orderFile.empty())
|
|
- parseOrderFile(orderFile);
|
|
-
|
|
- if (config->outputType == MH_EXECUTE && !isa<Defined>(config->entry)) {
|
|
- error("undefined symbol: " + config->entry->getName());
|
|
- return false;
|
|
- }
|
|
-
|
|
- createSyntheticSections();
|
|
-
|
|
- // Initialize InputSections.
|
|
- for (InputFile *file : inputFiles) {
|
|
- for (SubsectionMap &map : file->subsections) {
|
|
- for (auto &p : map) {
|
|
- InputSection *isec = p.second;
|
|
- inputSections.push_back(isec);
|
|
- }
|
|
- }
|
|
- }
|
|
-
|
|
- // Write to an output file.
|
|
- writeResult();
|
|
-
|
|
- if (canExitEarly)
|
|
- exitLld(errorCount() ? 1 : 0);
|
|
-
|
|
- freeArena();
|
|
- return !errorCount();
|
|
-}
|
|
diff --git a/lld/MachO/Driver.h b/lld/MachO/Driver.h
|
|
deleted file mode 100644
|
|
index 2233740d1db..00000000000
|
|
--- a/lld/MachO/Driver.h
|
|
+++ /dev/null
|
|
@@ -1,36 +0,0 @@
|
|
-//===- Driver.h -------------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_DRIVER_H
|
|
-#define LLD_MACHO_DRIVER_H
|
|
-
|
|
-#include "lld/Common/LLVM.h"
|
|
-#include "llvm/Option/OptTable.h"
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-class MachOOptTable : public llvm::opt::OptTable {
|
|
-public:
|
|
- MachOOptTable();
|
|
- llvm::opt::InputArgList parse(ArrayRef<const char *> argv);
|
|
- void printHelp(const char *argv0, bool showHidden) const;
|
|
-};
|
|
-
|
|
-// Create enum with OPT_xxx values for each option in Options.td
|
|
-enum {
|
|
- OPT_INVALID = 0,
|
|
-#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
|
|
-#include "Options.inc"
|
|
-#undef OPTION
|
|
-};
|
|
-
|
|
-} // namespace macho
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/ExportTrie.cpp b/lld/MachO/ExportTrie.cpp
|
|
deleted file mode 100644
|
|
index 7cc81bcfd5f..00000000000
|
|
--- a/lld/MachO/ExportTrie.cpp
|
|
+++ /dev/null
|
|
@@ -1,283 +0,0 @@
|
|
-//===- ExportTrie.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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-//
|
|
-// This is a partial implementation of the Mach-O export trie format. It's
|
|
-// essentially a symbol table encoded as a compressed prefix trie, meaning that
|
|
-// the common prefixes of each symbol name are shared for a more compact
|
|
-// representation. The prefixes are stored on the edges of the trie, and one
|
|
-// edge can represent multiple characters. For example, given two exported
|
|
-// symbols _bar and _baz, we will have a trie like this (terminal nodes are
|
|
-// marked with an asterisk):
|
|
-//
|
|
-// +-+-+
|
|
-// | | // root node
|
|
-// +-+-+
|
|
-// |
|
|
-// | _ba
|
|
-// |
|
|
-// +-+-+
|
|
-// | |
|
|
-// +-+-+
|
|
-// r / \ z
|
|
-// / \
|
|
-// +-+-+ +-+-+
|
|
-// | * | | * |
|
|
-// +-+-+ +-+-+
|
|
-//
|
|
-// More documentation of the format can be found in
|
|
-// llvm/tools/obj2yaml/macho2yaml.cpp.
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#include "ExportTrie.h"
|
|
-#include "Symbols.h"
|
|
-
|
|
-#include "lld/Common/ErrorHandler.h"
|
|
-#include "lld/Common/Memory.h"
|
|
-#include "llvm/ADT/Optional.h"
|
|
-#include "llvm/BinaryFormat/MachO.h"
|
|
-#include "llvm/Support/LEB128.h"
|
|
-
|
|
-using namespace llvm;
|
|
-using namespace llvm::MachO;
|
|
-using namespace lld;
|
|
-using namespace lld::macho;
|
|
-
|
|
-namespace {
|
|
-
|
|
-struct Edge {
|
|
- Edge(StringRef s, TrieNode *node) : substring(s), child(node) {}
|
|
-
|
|
- StringRef substring;
|
|
- struct TrieNode *child;
|
|
-};
|
|
-
|
|
-struct ExportInfo {
|
|
- uint64_t address;
|
|
- // TODO: Add proper support for re-exports & stub-and-resolver flags.
|
|
-};
|
|
-
|
|
-} // namespace
|
|
-
|
|
-struct macho::TrieNode {
|
|
- std::vector<Edge> edges;
|
|
- Optional<ExportInfo> info;
|
|
- // Estimated offset from the start of the serialized trie to the current node.
|
|
- // This will converge to the true offset when updateOffset() is run to a
|
|
- // fixpoint.
|
|
- size_t offset = 0;
|
|
-
|
|
- // Returns whether the new estimated offset differs from the old one.
|
|
- bool updateOffset(size_t &nextOffset);
|
|
- void writeTo(uint8_t *buf) const;
|
|
-};
|
|
-
|
|
-bool TrieNode::updateOffset(size_t &nextOffset) {
|
|
- // Size of the whole node (including the terminalSize and the outgoing edges.)
|
|
- // In contrast, terminalSize only records the size of the other data in the
|
|
- // node.
|
|
- size_t nodeSize;
|
|
- if (info) {
|
|
- uint64_t flags = 0;
|
|
- uint32_t terminalSize =
|
|
- getULEB128Size(flags) + getULEB128Size(info->address);
|
|
- // Overall node size so far is the uleb128 size of the length of the symbol
|
|
- // info + the symbol info itself.
|
|
- nodeSize = terminalSize + getULEB128Size(terminalSize);
|
|
- } else {
|
|
- nodeSize = 1; // Size of terminalSize (which has a value of 0)
|
|
- }
|
|
- // Compute size of all child edges.
|
|
- ++nodeSize; // Byte for number of children.
|
|
- for (Edge &edge : edges) {
|
|
- nodeSize += edge.substring.size() + 1 // String length.
|
|
- + getULEB128Size(edge.child->offset); // Offset len.
|
|
- }
|
|
- // On input, 'nextOffset' is the new preferred location for this node.
|
|
- bool result = (offset != nextOffset);
|
|
- // Store new location in node object for use by parents.
|
|
- offset = nextOffset;
|
|
- nextOffset += nodeSize;
|
|
- return result;
|
|
-}
|
|
-
|
|
-void TrieNode::writeTo(uint8_t *buf) const {
|
|
- buf += offset;
|
|
- if (info) {
|
|
- // TrieNodes with Symbol info: size, flags address
|
|
- uint64_t flags = 0; // TODO: emit proper flags
|
|
- uint32_t terminalSize =
|
|
- getULEB128Size(flags) + getULEB128Size(info->address);
|
|
- buf += encodeULEB128(terminalSize, buf);
|
|
- buf += encodeULEB128(flags, buf);
|
|
- buf += encodeULEB128(info->address, buf);
|
|
- } else {
|
|
- // TrieNode with no Symbol info.
|
|
- *buf++ = 0; // terminalSize
|
|
- }
|
|
- // Add number of children. TODO: Handle case where we have more than 256.
|
|
- assert(edges.size() < 256);
|
|
- *buf++ = edges.size();
|
|
- // Append each child edge substring and node offset.
|
|
- for (const Edge &edge : edges) {
|
|
- memcpy(buf, edge.substring.data(), edge.substring.size());
|
|
- buf += edge.substring.size();
|
|
- *buf++ = '\0';
|
|
- buf += encodeULEB128(edge.child->offset, buf);
|
|
- }
|
|
-}
|
|
-
|
|
-TrieNode *TrieBuilder::makeNode() {
|
|
- auto *node = make<TrieNode>();
|
|
- nodes.emplace_back(node);
|
|
- return node;
|
|
-}
|
|
-
|
|
-static int charAt(const Symbol *sym, size_t pos) {
|
|
- StringRef str = sym->getName();
|
|
- if (pos >= str.size())
|
|
- return -1;
|
|
- return str[pos];
|
|
-}
|
|
-
|
|
-// Build the trie by performing a three-way radix quicksort: We start by sorting
|
|
-// the strings by their first characters, then sort the strings with the same
|
|
-// first characters by their second characters, and so on recursively. Each
|
|
-// time the prefixes diverge, we add a node to the trie.
|
|
-//
|
|
-// node: The most recently created node along this path in the trie (i.e.
|
|
-// the furthest from the root.)
|
|
-// lastPos: The prefix length of the most recently created node, i.e. the number
|
|
-// of characters along its path from the root.
|
|
-// pos: The string index we are currently sorting on. Note that each symbol
|
|
-// S contained in vec has the same prefix S[0...pos).
|
|
-void TrieBuilder::sortAndBuild(MutableArrayRef<const Symbol *> vec,
|
|
- TrieNode *node, size_t lastPos, size_t pos) {
|
|
-tailcall:
|
|
- if (vec.empty())
|
|
- return;
|
|
-
|
|
- // Partition items so that items in [0, i) are less than the pivot,
|
|
- // [i, j) are the same as the pivot, and [j, vec.size()) are greater than
|
|
- // the pivot.
|
|
- const Symbol *pivotSymbol = vec[vec.size() / 2];
|
|
- int pivot = charAt(pivotSymbol, pos);
|
|
- size_t i = 0;
|
|
- size_t j = vec.size();
|
|
- for (size_t k = 0; k < j;) {
|
|
- int c = charAt(vec[k], pos);
|
|
- if (c < pivot)
|
|
- std::swap(vec[i++], vec[k++]);
|
|
- else if (c > pivot)
|
|
- std::swap(vec[--j], vec[k]);
|
|
- else
|
|
- k++;
|
|
- }
|
|
-
|
|
- bool isTerminal = pivot == -1;
|
|
- bool prefixesDiverge = i != 0 || j != vec.size();
|
|
- if (lastPos != pos && (isTerminal || prefixesDiverge)) {
|
|
- TrieNode *newNode = makeNode();
|
|
- node->edges.emplace_back(pivotSymbol->getName().slice(lastPos, pos),
|
|
- newNode);
|
|
- node = newNode;
|
|
- lastPos = pos;
|
|
- }
|
|
-
|
|
- sortAndBuild(vec.slice(0, i), node, lastPos, pos);
|
|
- sortAndBuild(vec.slice(j), node, lastPos, pos);
|
|
-
|
|
- if (isTerminal) {
|
|
- assert(j - i == 1); // no duplicate symbols
|
|
- node->info = {pivotSymbol->getVA()};
|
|
- } else {
|
|
- // This is the tail-call-optimized version of the following:
|
|
- // sortAndBuild(vec.slice(i, j - i), node, lastPos, pos + 1);
|
|
- vec = vec.slice(i, j - i);
|
|
- ++pos;
|
|
- goto tailcall;
|
|
- }
|
|
-}
|
|
-
|
|
-size_t TrieBuilder::build() {
|
|
- if (exported.empty())
|
|
- return 0;
|
|
-
|
|
- TrieNode *root = makeNode();
|
|
- sortAndBuild(exported, root, 0, 0);
|
|
-
|
|
- // Assign each node in the vector an offset in the trie stream, iterating
|
|
- // until all uleb128 sizes have stabilized.
|
|
- size_t offset;
|
|
- bool more;
|
|
- do {
|
|
- offset = 0;
|
|
- more = false;
|
|
- for (TrieNode *node : nodes)
|
|
- more |= node->updateOffset(offset);
|
|
- } while (more);
|
|
-
|
|
- return offset;
|
|
-}
|
|
-
|
|
-void TrieBuilder::writeTo(uint8_t *buf) const {
|
|
- for (TrieNode *node : nodes)
|
|
- node->writeTo(buf);
|
|
-}
|
|
-
|
|
-namespace {
|
|
-
|
|
-// Parse a serialized trie and invoke a callback for each entry.
|
|
-class TrieParser {
|
|
-public:
|
|
- TrieParser(const uint8_t *buf, size_t size, const TrieEntryCallback &callback)
|
|
- : start(buf), end(start + size), callback(callback) {}
|
|
-
|
|
- void parse(const uint8_t *buf, const Twine &cumulativeString);
|
|
-
|
|
- void parse() { parse(start, ""); }
|
|
-
|
|
- const uint8_t *start;
|
|
- const uint8_t *end;
|
|
- const TrieEntryCallback &callback;
|
|
-};
|
|
-
|
|
-} // namespace
|
|
-
|
|
-void TrieParser::parse(const uint8_t *buf, const Twine &cumulativeString) {
|
|
- if (buf >= end)
|
|
- fatal("Node offset points outside export section");
|
|
-
|
|
- unsigned ulebSize;
|
|
- uint64_t terminalSize = decodeULEB128(buf, &ulebSize);
|
|
- buf += ulebSize;
|
|
- uint64_t flags = 0;
|
|
- size_t offset;
|
|
- if (terminalSize != 0) {
|
|
- flags = decodeULEB128(buf, &ulebSize);
|
|
- callback(cumulativeString, flags);
|
|
- }
|
|
- buf += terminalSize;
|
|
- uint8_t numEdges = *buf++;
|
|
- for (uint8_t i = 0; i < numEdges; ++i) {
|
|
- const char *cbuf = reinterpret_cast<const char *>(buf);
|
|
- StringRef substring = StringRef(cbuf, strnlen(cbuf, end - buf));
|
|
- buf += substring.size() + 1;
|
|
- offset = decodeULEB128(buf, &ulebSize);
|
|
- buf += ulebSize;
|
|
- parse(start + offset, cumulativeString + substring);
|
|
- }
|
|
-}
|
|
-
|
|
-void macho::parseTrie(const uint8_t *buf, size_t size,
|
|
- const TrieEntryCallback &callback) {
|
|
- if (size == 0)
|
|
- return;
|
|
-
|
|
- TrieParser(buf, size, callback).parse();
|
|
-}
|
|
diff --git a/lld/MachO/ExportTrie.h b/lld/MachO/ExportTrie.h
|
|
deleted file mode 100644
|
|
index 2bd8c33db9a..00000000000
|
|
--- a/lld/MachO/ExportTrie.h
|
|
+++ /dev/null
|
|
@@ -1,47 +0,0 @@
|
|
-//===- ExportTrie.h ---------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_EXPORT_TRIE_H
|
|
-#define LLD_MACHO_EXPORT_TRIE_H
|
|
-
|
|
-#include "llvm/ADT/ArrayRef.h"
|
|
-#include "llvm/ADT/STLExtras.h"
|
|
-
|
|
-#include <vector>
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-struct TrieNode;
|
|
-class Symbol;
|
|
-
|
|
-class TrieBuilder {
|
|
-public:
|
|
- void addSymbol(const Symbol &sym) { exported.push_back(&sym); }
|
|
- // Returns the size in bytes of the serialized trie.
|
|
- size_t build();
|
|
- void writeTo(uint8_t *buf) const;
|
|
-
|
|
-private:
|
|
- TrieNode *makeNode();
|
|
- void sortAndBuild(llvm::MutableArrayRef<const Symbol *> vec, TrieNode *node,
|
|
- size_t lastPos, size_t pos);
|
|
-
|
|
- std::vector<const Symbol *> exported;
|
|
- std::vector<TrieNode *> nodes;
|
|
-};
|
|
-
|
|
-using TrieEntryCallback =
|
|
- llvm::function_ref<void(const llvm::Twine & /*name*/, uint64_t /*flags*/)>;
|
|
-
|
|
-void parseTrie(const uint8_t *buf, size_t size, const TrieEntryCallback &);
|
|
-
|
|
-} // namespace macho
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
|
|
deleted file mode 100644
|
|
index 46fe82f9882..00000000000
|
|
--- a/lld/MachO/InputFiles.cpp
|
|
+++ /dev/null
|
|
@@ -1,433 +0,0 @@
|
|
-//===- InputFiles.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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-//
|
|
-// This file contains functions to parse Mach-O object files. In this comment,
|
|
-// we describe the Mach-O file structure and how we parse it.
|
|
-//
|
|
-// Mach-O is not very different from ELF or COFF. The notion of symbols,
|
|
-// sections and relocations exists in Mach-O as it does in ELF and COFF.
|
|
-//
|
|
-// Perhaps the notion that is new to those who know ELF/COFF is "subsections".
|
|
-// In ELF/COFF, sections are an atomic unit of data copied from input files to
|
|
-// output files. When we merge or garbage-collect sections, we treat each
|
|
-// section as an atomic unit. In Mach-O, that's not the case. Sections can
|
|
-// consist of multiple subsections, and subsections are a unit of merging and
|
|
-// garbage-collecting. Therefore, Mach-O's subsections are more similar to
|
|
-// ELF/COFF's sections than Mach-O's sections are.
|
|
-//
|
|
-// A section can have multiple symbols. A symbol that does not have the
|
|
-// N_ALT_ENTRY attribute indicates a beginning of a subsection. Therefore, by
|
|
-// definition, a symbol is always present at the beginning of each subsection. A
|
|
-// symbol with N_ALT_ENTRY attribute does not start a new subsection and can
|
|
-// point to a middle of a subsection.
|
|
-//
|
|
-// The notion of subsections also affects how relocations are represented in
|
|
-// Mach-O. All references within a section need to be explicitly represented as
|
|
-// relocations if they refer to different subsections, because we obviously need
|
|
-// to fix up addresses if subsections are laid out in an output file differently
|
|
-// than they were in object files. To represent that, Mach-O relocations can
|
|
-// refer to an unnamed location via its address. Scattered relocations (those
|
|
-// with the R_SCATTERED bit set) always refer to unnamed locations.
|
|
-// Non-scattered relocations refer to an unnamed location if r_extern is not set
|
|
-// and r_symbolnum is zero.
|
|
-//
|
|
-// Without the above differences, I think you can use your knowledge about ELF
|
|
-// and COFF for Mach-O.
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#include "InputFiles.h"
|
|
-#include "Config.h"
|
|
-#include "ExportTrie.h"
|
|
-#include "InputSection.h"
|
|
-#include "MachOStructs.h"
|
|
-#include "OutputSection.h"
|
|
-#include "SymbolTable.h"
|
|
-#include "Symbols.h"
|
|
-#include "Target.h"
|
|
-
|
|
-#include "lld/Common/ErrorHandler.h"
|
|
-#include "lld/Common/Memory.h"
|
|
-#include "llvm/BinaryFormat/MachO.h"
|
|
-#include "llvm/Support/Endian.h"
|
|
-#include "llvm/Support/MemoryBuffer.h"
|
|
-#include "llvm/Support/Path.h"
|
|
-
|
|
-using namespace llvm;
|
|
-using namespace llvm::MachO;
|
|
-using namespace llvm::support::endian;
|
|
-using namespace llvm::sys;
|
|
-using namespace lld;
|
|
-using namespace lld::macho;
|
|
-
|
|
-std::vector<InputFile *> macho::inputFiles;
|
|
-
|
|
-// Open a given file path and return it as a memory-mapped file.
|
|
-Optional<MemoryBufferRef> macho::readFile(StringRef path) {
|
|
- // Open a file.
|
|
- auto mbOrErr = MemoryBuffer::getFile(path);
|
|
- if (auto ec = mbOrErr.getError()) {
|
|
- error("cannot open " + path + ": " + ec.message());
|
|
- return None;
|
|
- }
|
|
-
|
|
- std::unique_ptr<MemoryBuffer> &mb = *mbOrErr;
|
|
- MemoryBufferRef mbref = mb->getMemBufferRef();
|
|
- make<std::unique_ptr<MemoryBuffer>>(std::move(mb)); // take mb ownership
|
|
-
|
|
- // If this is a regular non-fat file, return it.
|
|
- const char *buf = mbref.getBufferStart();
|
|
- auto *hdr = reinterpret_cast<const MachO::fat_header *>(buf);
|
|
- if (read32be(&hdr->magic) != MachO::FAT_MAGIC)
|
|
- return mbref;
|
|
-
|
|
- // Object files and archive files may be fat files, which contains
|
|
- // multiple real files for different CPU ISAs. Here, we search for a
|
|
- // file that matches with the current link target and returns it as
|
|
- // a MemoryBufferRef.
|
|
- auto *arch = reinterpret_cast<const MachO::fat_arch *>(buf + sizeof(*hdr));
|
|
-
|
|
- for (uint32_t i = 0, n = read32be(&hdr->nfat_arch); i < n; ++i) {
|
|
- if (reinterpret_cast<const char *>(arch + i + 1) >
|
|
- buf + mbref.getBufferSize()) {
|
|
- error(path + ": fat_arch struct extends beyond end of file");
|
|
- return None;
|
|
- }
|
|
-
|
|
- if (read32be(&arch[i].cputype) != target->cpuType ||
|
|
- read32be(&arch[i].cpusubtype) != target->cpuSubtype)
|
|
- continue;
|
|
-
|
|
- uint32_t offset = read32be(&arch[i].offset);
|
|
- uint32_t size = read32be(&arch[i].size);
|
|
- if (offset + size > mbref.getBufferSize())
|
|
- error(path + ": slice extends beyond end of file");
|
|
- return MemoryBufferRef(StringRef(buf + offset, size), path.copy(bAlloc));
|
|
- }
|
|
-
|
|
- error("unable to find matching architecture in " + path);
|
|
- return None;
|
|
-}
|
|
-
|
|
-static const load_command *findCommand(const mach_header_64 *hdr,
|
|
- uint32_t type) {
|
|
- const uint8_t *p =
|
|
- reinterpret_cast<const uint8_t *>(hdr) + sizeof(mach_header_64);
|
|
-
|
|
- for (uint32_t i = 0, n = hdr->ncmds; i < n; ++i) {
|
|
- auto *cmd = reinterpret_cast<const load_command *>(p);
|
|
- if (cmd->cmd == type)
|
|
- return cmd;
|
|
- p += cmd->cmdsize;
|
|
- }
|
|
- return nullptr;
|
|
-}
|
|
-
|
|
-void InputFile::parseSections(ArrayRef<section_64> sections) {
|
|
- subsections.reserve(sections.size());
|
|
- auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart());
|
|
-
|
|
- for (const section_64 &sec : sections) {
|
|
- InputSection *isec = make<InputSection>();
|
|
- isec->file = this;
|
|
- isec->name = StringRef(sec.sectname, strnlen(sec.sectname, 16));
|
|
- isec->segname = StringRef(sec.segname, strnlen(sec.segname, 16));
|
|
- isec->data = {isZeroFill(sec.flags) ? nullptr : buf + sec.offset,
|
|
- static_cast<size_t>(sec.size)};
|
|
- if (sec.align >= 32)
|
|
- error("alignment " + std::to_string(sec.align) + " of section " +
|
|
- isec->name + " is too large");
|
|
- else
|
|
- isec->align = 1 << sec.align;
|
|
- isec->flags = sec.flags;
|
|
- subsections.push_back({{0, isec}});
|
|
- }
|
|
-}
|
|
-
|
|
-// Find the subsection corresponding to the greatest section offset that is <=
|
|
-// that of the given offset.
|
|
-//
|
|
-// offset: an offset relative to the start of the original InputSection (before
|
|
-// any subsection splitting has occurred). It will be updated to represent the
|
|
-// same location as an offset relative to the start of the containing
|
|
-// subsection.
|
|
-static InputSection *findContainingSubsection(SubsectionMap &map,
|
|
- uint32_t *offset) {
|
|
- auto it = std::prev(map.upper_bound(*offset));
|
|
- *offset -= it->first;
|
|
- return it->second;
|
|
-}
|
|
-
|
|
-void InputFile::parseRelocations(const section_64 &sec,
|
|
- SubsectionMap &subsecMap) {
|
|
- auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart());
|
|
- ArrayRef<any_relocation_info> relInfos(
|
|
- reinterpret_cast<const any_relocation_info *>(buf + sec.reloff),
|
|
- sec.nreloc);
|
|
-
|
|
- for (const any_relocation_info &anyRel : relInfos) {
|
|
- if (anyRel.r_word0 & R_SCATTERED)
|
|
- fatal("TODO: Scattered relocations not supported");
|
|
-
|
|
- auto rel = reinterpret_cast<const relocation_info &>(anyRel);
|
|
-
|
|
- Reloc r;
|
|
- r.type = rel.r_type;
|
|
- r.pcrel = rel.r_pcrel;
|
|
- r.length = rel.r_length;
|
|
- uint64_t rawAddend = target->getImplicitAddend(mb, sec, rel);
|
|
-
|
|
- if (rel.r_extern) {
|
|
- r.target = symbols[rel.r_symbolnum];
|
|
- r.addend = rawAddend;
|
|
- } else {
|
|
- if (rel.r_symbolnum == 0 || rel.r_symbolnum > subsections.size())
|
|
- fatal("invalid section index in relocation for offset " +
|
|
- std::to_string(r.offset) + " in section " + sec.sectname +
|
|
- " of " + getName());
|
|
-
|
|
- SubsectionMap &targetSubsecMap = subsections[rel.r_symbolnum - 1];
|
|
- const section_64 &targetSec = sectionHeaders[rel.r_symbolnum - 1];
|
|
- uint32_t targetOffset;
|
|
- if (rel.r_pcrel) {
|
|
- // The implicit addend for pcrel section relocations is the pcrel offset
|
|
- // in terms of the addresses in the input file. Here we adjust it so
|
|
- // that it describes the offset from the start of the target section.
|
|
- // TODO: The offset of 4 is probably not right for ARM64, nor for
|
|
- // relocations with r_length != 2.
|
|
- targetOffset =
|
|
- sec.addr + rel.r_address + 4 + rawAddend - targetSec.addr;
|
|
- } else {
|
|
- // The addend for a non-pcrel relocation is its absolute address.
|
|
- targetOffset = rawAddend - targetSec.addr;
|
|
- }
|
|
- r.target = findContainingSubsection(targetSubsecMap, &targetOffset);
|
|
- r.addend = targetOffset;
|
|
- }
|
|
-
|
|
- r.offset = rel.r_address;
|
|
- InputSection *subsec = findContainingSubsection(subsecMap, &r.offset);
|
|
- subsec->relocs.push_back(r);
|
|
- }
|
|
-}
|
|
-
|
|
-void InputFile::parseSymbols(ArrayRef<structs::nlist_64> nList,
|
|
- const char *strtab, bool subsectionsViaSymbols) {
|
|
- // resize(), not reserve(), because we are going to create N_ALT_ENTRY symbols
|
|
- // out-of-sequence.
|
|
- symbols.resize(nList.size());
|
|
- std::vector<size_t> altEntrySymIdxs;
|
|
-
|
|
- auto createDefined = [&](const structs::nlist_64 &sym, InputSection *isec,
|
|
- uint32_t value) -> Symbol * {
|
|
- StringRef name = strtab + sym.n_strx;
|
|
- if (sym.n_type & N_EXT)
|
|
- // Global defined symbol
|
|
- return symtab->addDefined(name, isec, value);
|
|
- else
|
|
- // Local defined symbol
|
|
- return make<Defined>(name, isec, value);
|
|
- };
|
|
-
|
|
- for (size_t i = 0, n = nList.size(); i < n; ++i) {
|
|
- const structs::nlist_64 &sym = nList[i];
|
|
-
|
|
- // Undefined symbol
|
|
- if (!sym.n_sect) {
|
|
- StringRef name = strtab + sym.n_strx;
|
|
- symbols[i] = symtab->addUndefined(name);
|
|
- continue;
|
|
- }
|
|
-
|
|
- const section_64 &sec = sectionHeaders[sym.n_sect - 1];
|
|
- SubsectionMap &subsecMap = subsections[sym.n_sect - 1];
|
|
- uint64_t offset = sym.n_value - sec.addr;
|
|
-
|
|
- // If the input file does not use subsections-via-symbols, all symbols can
|
|
- // use the same subsection. Otherwise, we must split the sections along
|
|
- // symbol boundaries.
|
|
- if (!subsectionsViaSymbols) {
|
|
- symbols[i] = createDefined(sym, subsecMap[0], offset);
|
|
- continue;
|
|
- }
|
|
-
|
|
- // nList entries aren't necessarily arranged in address order. Therefore,
|
|
- // we can't create alt-entry symbols at this point because a later symbol
|
|
- // may split its section, which may affect which subsection the alt-entry
|
|
- // symbol is assigned to. So we need to handle them in a second pass below.
|
|
- if (sym.n_desc & N_ALT_ENTRY) {
|
|
- altEntrySymIdxs.push_back(i);
|
|
- continue;
|
|
- }
|
|
-
|
|
- // Find the subsection corresponding to the greatest section offset that is
|
|
- // <= that of the current symbol. The subsection that we find either needs
|
|
- // to be used directly or split in two.
|
|
- uint32_t firstSize = offset;
|
|
- InputSection *firstIsec = findContainingSubsection(subsecMap, &firstSize);
|
|
-
|
|
- if (firstSize == 0) {
|
|
- // Alias of an existing symbol, or the first symbol in the section. These
|
|
- // are handled by reusing the existing section.
|
|
- symbols[i] = createDefined(sym, firstIsec, 0);
|
|
- continue;
|
|
- }
|
|
-
|
|
- // We saw a symbol definition at a new offset. Split the section into two
|
|
- // subsections. The new symbol uses the second subsection.
|
|
- auto *secondIsec = make<InputSection>(*firstIsec);
|
|
- secondIsec->data = firstIsec->data.slice(firstSize);
|
|
- firstIsec->data = firstIsec->data.slice(0, firstSize);
|
|
- // TODO: ld64 appears to preserve the original alignment as well as each
|
|
- // subsection's offset from the last aligned address. We should consider
|
|
- // emulating that behavior.
|
|
- secondIsec->align = MinAlign(firstIsec->align, offset);
|
|
-
|
|
- subsecMap[offset] = secondIsec;
|
|
- // By construction, the symbol will be at offset zero in the new section.
|
|
- symbols[i] = createDefined(sym, secondIsec, 0);
|
|
- }
|
|
-
|
|
- for (size_t idx : altEntrySymIdxs) {
|
|
- const structs::nlist_64 &sym = nList[idx];
|
|
- SubsectionMap &subsecMap = subsections[sym.n_sect - 1];
|
|
- uint32_t off = sym.n_value - sectionHeaders[sym.n_sect - 1].addr;
|
|
- InputSection *subsec = findContainingSubsection(subsecMap, &off);
|
|
- symbols[idx] = createDefined(sym, subsec, off);
|
|
- }
|
|
-}
|
|
-
|
|
-ObjFile::ObjFile(MemoryBufferRef mb) : InputFile(ObjKind, mb) {
|
|
- auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart());
|
|
- auto *hdr = reinterpret_cast<const mach_header_64 *>(mb.getBufferStart());
|
|
-
|
|
- if (const load_command *cmd = findCommand(hdr, LC_SEGMENT_64)) {
|
|
- auto *c = reinterpret_cast<const segment_command_64 *>(cmd);
|
|
- sectionHeaders = ArrayRef<section_64>{
|
|
- reinterpret_cast<const section_64 *>(c + 1), c->nsects};
|
|
- parseSections(sectionHeaders);
|
|
- }
|
|
-
|
|
- // TODO: Error on missing LC_SYMTAB?
|
|
- if (const load_command *cmd = findCommand(hdr, LC_SYMTAB)) {
|
|
- auto *c = reinterpret_cast<const symtab_command *>(cmd);
|
|
- ArrayRef<structs::nlist_64> nList(
|
|
- reinterpret_cast<const structs::nlist_64 *>(buf + c->symoff), c->nsyms);
|
|
- const char *strtab = reinterpret_cast<const char *>(buf) + c->stroff;
|
|
- bool subsectionsViaSymbols = hdr->flags & MH_SUBSECTIONS_VIA_SYMBOLS;
|
|
- parseSymbols(nList, strtab, subsectionsViaSymbols);
|
|
- }
|
|
-
|
|
- // The relocations may refer to the symbols, so we parse them after we have
|
|
- // parsed all the symbols.
|
|
- for (size_t i = 0, n = subsections.size(); i < n; ++i)
|
|
- parseRelocations(sectionHeaders[i], subsections[i]);
|
|
-}
|
|
-
|
|
-DylibFile::DylibFile(MemoryBufferRef mb, DylibFile *umbrella)
|
|
- : InputFile(DylibKind, mb) {
|
|
- if (umbrella == nullptr)
|
|
- umbrella = this;
|
|
-
|
|
- auto *buf = reinterpret_cast<const uint8_t *>(mb.getBufferStart());
|
|
- auto *hdr = reinterpret_cast<const mach_header_64 *>(mb.getBufferStart());
|
|
-
|
|
- // Initialize dylibName.
|
|
- if (const load_command *cmd = findCommand(hdr, LC_ID_DYLIB)) {
|
|
- auto *c = reinterpret_cast<const dylib_command *>(cmd);
|
|
- dylibName = reinterpret_cast<const char *>(cmd) + read32le(&c->dylib.name);
|
|
- } else {
|
|
- error("dylib " + getName() + " missing LC_ID_DYLIB load command");
|
|
- return;
|
|
- }
|
|
-
|
|
- // Initialize symbols.
|
|
- if (const load_command *cmd = findCommand(hdr, LC_DYLD_INFO_ONLY)) {
|
|
- auto *c = reinterpret_cast<const dyld_info_command *>(cmd);
|
|
- parseTrie(buf + c->export_off, c->export_size,
|
|
- [&](const Twine &name, uint64_t flags) {
|
|
- symbols.push_back(symtab->addDylib(saver.save(name), umbrella));
|
|
- });
|
|
- } else {
|
|
- error("LC_DYLD_INFO_ONLY not found in " + getName());
|
|
- return;
|
|
- }
|
|
-
|
|
- if (hdr->flags & MH_NO_REEXPORTED_DYLIBS)
|
|
- return;
|
|
-
|
|
- const uint8_t *p =
|
|
- reinterpret_cast<const uint8_t *>(hdr) + sizeof(mach_header_64);
|
|
- for (uint32_t i = 0, n = hdr->ncmds; i < n; ++i) {
|
|
- auto *cmd = reinterpret_cast<const load_command *>(p);
|
|
- p += cmd->cmdsize;
|
|
- if (cmd->cmd != LC_REEXPORT_DYLIB)
|
|
- continue;
|
|
-
|
|
- auto *c = reinterpret_cast<const dylib_command *>(cmd);
|
|
- StringRef reexportPath =
|
|
- reinterpret_cast<const char *>(c) + read32le(&c->dylib.name);
|
|
- // TODO: Expand @loader_path, @executable_path etc in reexportPath
|
|
- Optional<MemoryBufferRef> buffer = readFile(reexportPath);
|
|
- if (!buffer) {
|
|
- error("unable to read re-exported dylib at " + reexportPath);
|
|
- return;
|
|
- }
|
|
- reexported.push_back(make<DylibFile>(*buffer, umbrella));
|
|
- }
|
|
-}
|
|
-
|
|
-DylibFile::DylibFile(std::shared_ptr<llvm::MachO::InterfaceFile> interface,
|
|
- DylibFile *umbrella)
|
|
- : InputFile(DylibKind, MemoryBufferRef()) {
|
|
- if (umbrella == nullptr)
|
|
- umbrella = this;
|
|
-
|
|
- dylibName = saver.save(interface->getInstallName());
|
|
- // TODO(compnerd) filter out symbols based on the target platform
|
|
- for (const auto symbol : interface->symbols())
|
|
- if (symbol->getArchitectures().has(config->arch))
|
|
- symbols.push_back(
|
|
- symtab->addDylib(saver.save(symbol->getName()), umbrella));
|
|
- // TODO(compnerd) properly represent the hierarchy of the documents as it is
|
|
- // in theory possible to have re-exported dylibs from re-exported dylibs which
|
|
- // should be parent'ed to the child.
|
|
- for (auto document : interface->documents())
|
|
- reexported.push_back(make<DylibFile>(document, umbrella));
|
|
-}
|
|
-
|
|
-ArchiveFile::ArchiveFile(std::unique_ptr<llvm::object::Archive> &&f)
|
|
- : InputFile(ArchiveKind, f->getMemoryBufferRef()), file(std::move(f)) {
|
|
- for (const object::Archive::Symbol &sym : file->symbols())
|
|
- symtab->addLazy(sym.getName(), this, sym);
|
|
-}
|
|
-
|
|
-void ArchiveFile::fetch(const object::Archive::Symbol &sym) {
|
|
- object::Archive::Child c =
|
|
- CHECK(sym.getMember(), toString(this) +
|
|
- ": could not get the member for symbol " +
|
|
- sym.getName());
|
|
-
|
|
- if (!seen.insert(c.getChildOffset()).second)
|
|
- return;
|
|
-
|
|
- MemoryBufferRef mb =
|
|
- CHECK(c.getMemoryBufferRef(),
|
|
- toString(this) +
|
|
- ": could not get the buffer for the member defining symbol " +
|
|
- sym.getName());
|
|
- auto file = make<ObjFile>(mb);
|
|
- symbols.insert(symbols.end(), file->symbols.begin(), file->symbols.end());
|
|
- subsections.insert(subsections.end(), file->subsections.begin(),
|
|
- file->subsections.end());
|
|
-}
|
|
-
|
|
-// Returns "<internal>" or "baz.o".
|
|
-std::string lld::toString(const InputFile *file) {
|
|
- return file ? std::string(file->getName()) : "<internal>";
|
|
-}
|
|
diff --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h
|
|
deleted file mode 100644
|
|
index bc5ad86ccaa..00000000000
|
|
--- a/lld/MachO/InputFiles.h
|
|
+++ /dev/null
|
|
@@ -1,121 +0,0 @@
|
|
-//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_INPUT_FILES_H
|
|
-#define LLD_MACHO_INPUT_FILES_H
|
|
-
|
|
-#include "MachOStructs.h"
|
|
-
|
|
-#include "lld/Common/LLVM.h"
|
|
-#include "llvm/ADT/DenseSet.h"
|
|
-#include "llvm/BinaryFormat/MachO.h"
|
|
-#include "llvm/Object/Archive.h"
|
|
-#include "llvm/Support/MemoryBuffer.h"
|
|
-#include "llvm/TextAPI/MachO/InterfaceFile.h"
|
|
-#include "llvm/TextAPI/MachO/TextAPIReader.h"
|
|
-
|
|
-#include <map>
|
|
-#include <vector>
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-class InputSection;
|
|
-class Symbol;
|
|
-struct Reloc;
|
|
-
|
|
-// If .subsections_via_symbols is set, each InputSection will be split along
|
|
-// symbol boundaries. The keys of a SubsectionMap represent the offsets of
|
|
-// each subsection from the start of the original pre-split InputSection.
|
|
-using SubsectionMap = std::map<uint32_t, InputSection *>;
|
|
-
|
|
-class InputFile {
|
|
-public:
|
|
- enum Kind {
|
|
- ObjKind,
|
|
- DylibKind,
|
|
- ArchiveKind,
|
|
- };
|
|
-
|
|
- virtual ~InputFile() = default;
|
|
- Kind kind() const { return fileKind; }
|
|
- StringRef getName() const { return mb.getBufferIdentifier(); }
|
|
-
|
|
- MemoryBufferRef mb;
|
|
- std::vector<Symbol *> symbols;
|
|
- ArrayRef<llvm::MachO::section_64> sectionHeaders;
|
|
- std::vector<SubsectionMap> subsections;
|
|
-
|
|
-protected:
|
|
- InputFile(Kind kind, MemoryBufferRef mb) : mb(mb), fileKind(kind) {}
|
|
-
|
|
- void parseSections(ArrayRef<llvm::MachO::section_64>);
|
|
-
|
|
- void parseSymbols(ArrayRef<lld::structs::nlist_64> nList, const char *strtab,
|
|
- bool subsectionsViaSymbols);
|
|
-
|
|
- void parseRelocations(const llvm::MachO::section_64 &, SubsectionMap &);
|
|
-
|
|
-private:
|
|
- const Kind fileKind;
|
|
-};
|
|
-
|
|
-// .o file
|
|
-class ObjFile : public InputFile {
|
|
-public:
|
|
- explicit ObjFile(MemoryBufferRef mb);
|
|
- static bool classof(const InputFile *f) { return f->kind() == ObjKind; }
|
|
-};
|
|
-
|
|
-// .dylib file
|
|
-class DylibFile : public InputFile {
|
|
-public:
|
|
- explicit DylibFile(std::shared_ptr<llvm::MachO::InterfaceFile> interface,
|
|
- DylibFile *umbrella = nullptr);
|
|
-
|
|
- // Mach-O dylibs can re-export other dylibs as sub-libraries, meaning that the
|
|
- // symbols in those sub-libraries will be available under the umbrella
|
|
- // library's namespace. Those sub-libraries can also have their own
|
|
- // re-exports. When loading a re-exported dylib, `umbrella` should be set to
|
|
- // the root dylib to ensure symbols in the child library are correctly bound
|
|
- // to the root. On the other hand, if a dylib is being directly loaded
|
|
- // (through an -lfoo flag), then `umbrella` should be a nullptr.
|
|
- explicit DylibFile(MemoryBufferRef mb, DylibFile *umbrella = nullptr);
|
|
-
|
|
- static bool classof(const InputFile *f) { return f->kind() == DylibKind; }
|
|
-
|
|
- StringRef dylibName;
|
|
- uint64_t ordinal = 0; // Ordinal numbering starts from 1, so 0 is a sentinel
|
|
- bool reexport = false;
|
|
- std::vector<DylibFile *> reexported;
|
|
-};
|
|
-
|
|
-// .a file
|
|
-class ArchiveFile : public InputFile {
|
|
-public:
|
|
- explicit ArchiveFile(std::unique_ptr<llvm::object::Archive> &&file);
|
|
- static bool classof(const InputFile *f) { return f->kind() == ArchiveKind; }
|
|
- void fetch(const llvm::object::Archive::Symbol &sym);
|
|
-
|
|
-private:
|
|
- std::unique_ptr<llvm::object::Archive> file;
|
|
- // Keep track of children fetched from the archive by tracking
|
|
- // which address offsets have been fetched already.
|
|
- llvm::DenseSet<uint64_t> seen;
|
|
-};
|
|
-
|
|
-extern std::vector<InputFile *> inputFiles;
|
|
-
|
|
-llvm::Optional<MemoryBufferRef> readFile(StringRef path);
|
|
-
|
|
-} // namespace macho
|
|
-
|
|
-std::string toString(const macho::InputFile *file);
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp
|
|
deleted file mode 100644
|
|
index 72d48928305..00000000000
|
|
--- a/lld/MachO/InputSection.cpp
|
|
+++ /dev/null
|
|
@@ -1,48 +0,0 @@
|
|
-//===- InputSection.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 "InputSection.h"
|
|
-#include "OutputSegment.h"
|
|
-#include "Symbols.h"
|
|
-#include "Target.h"
|
|
-#include "lld/Common/Memory.h"
|
|
-#include "llvm/Support/Endian.h"
|
|
-
|
|
-using namespace llvm;
|
|
-using namespace llvm::MachO;
|
|
-using namespace llvm::support;
|
|
-using namespace lld;
|
|
-using namespace lld::macho;
|
|
-
|
|
-std::vector<InputSection *> macho::inputSections;
|
|
-
|
|
-uint64_t InputSection::getFileOffset() const {
|
|
- return parent->fileOff + outSecFileOff;
|
|
-}
|
|
-
|
|
-uint64_t InputSection::getVA() const { return parent->addr + outSecOff; }
|
|
-
|
|
-void InputSection::writeTo(uint8_t *buf) {
|
|
- if (getFileSize() == 0)
|
|
- return;
|
|
-
|
|
- memcpy(buf, data.data(), data.size());
|
|
-
|
|
- for (Reloc &r : relocs) {
|
|
- uint64_t va = 0;
|
|
- if (auto *s = r.target.dyn_cast<Symbol *>())
|
|
- va = target->getSymbolVA(*s, r.type);
|
|
- else if (auto *isec = r.target.dyn_cast<InputSection *>())
|
|
- va = isec->getVA();
|
|
-
|
|
- uint64_t val = va + r.addend;
|
|
- if (r.pcrel)
|
|
- val -= getVA() + r.offset;
|
|
- target->relocateOne(buf + r.offset, r, val);
|
|
- }
|
|
-}
|
|
diff --git a/lld/MachO/InputSection.h b/lld/MachO/InputSection.h
|
|
deleted file mode 100644
|
|
index 96ae0cbe6ea..00000000000
|
|
--- a/lld/MachO/InputSection.h
|
|
+++ /dev/null
|
|
@@ -1,74 +0,0 @@
|
|
-//===- InputSection.h -------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_INPUT_SECTION_H
|
|
-#define LLD_MACHO_INPUT_SECTION_H
|
|
-
|
|
-#include "lld/Common/LLVM.h"
|
|
-#include "llvm/ADT/ArrayRef.h"
|
|
-#include "llvm/ADT/PointerUnion.h"
|
|
-#include "llvm/BinaryFormat/MachO.h"
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-class InputFile;
|
|
-class InputSection;
|
|
-class OutputSection;
|
|
-class Symbol;
|
|
-
|
|
-struct Reloc {
|
|
- uint8_t type;
|
|
- bool pcrel;
|
|
- uint8_t length;
|
|
- // The offset from the start of the subsection that this relocation belongs
|
|
- // to.
|
|
- uint32_t offset;
|
|
- // Adding this offset to the address of the target symbol or subsection gives
|
|
- // the destination that this relocation refers to.
|
|
- uint64_t addend;
|
|
- llvm::PointerUnion<Symbol *, InputSection *> target;
|
|
-};
|
|
-
|
|
-inline bool isZeroFill(uint8_t flags) {
|
|
- return (flags & llvm::MachO::SECTION_TYPE) == llvm::MachO::S_ZEROFILL;
|
|
-}
|
|
-
|
|
-class InputSection {
|
|
-public:
|
|
- virtual ~InputSection() = default;
|
|
- virtual uint64_t getSize() const { return data.size(); }
|
|
- virtual uint64_t getFileSize() const {
|
|
- return isZeroFill(flags) ? 0 : getSize();
|
|
- }
|
|
- uint64_t getFileOffset() const;
|
|
- uint64_t getVA() const;
|
|
-
|
|
- virtual void writeTo(uint8_t *buf);
|
|
-
|
|
- InputFile *file = nullptr;
|
|
- StringRef name;
|
|
- StringRef segname;
|
|
-
|
|
- OutputSection *parent = nullptr;
|
|
- uint64_t outSecOff = 0;
|
|
- uint64_t outSecFileOff = 0;
|
|
-
|
|
- uint32_t align = 1;
|
|
- uint32_t flags = 0;
|
|
-
|
|
- ArrayRef<uint8_t> data;
|
|
- std::vector<Reloc> relocs;
|
|
-};
|
|
-
|
|
-extern std::vector<InputSection *> inputSections;
|
|
-
|
|
-} // namespace macho
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/MachOStructs.h b/lld/MachO/MachOStructs.h
|
|
deleted file mode 100644
|
|
index 69b50ec2317..00000000000
|
|
--- a/lld/MachO/MachOStructs.h
|
|
+++ /dev/null
|
|
@@ -1,36 +0,0 @@
|
|
-//===- MachOStructs.h -------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-//
|
|
-// This file defines structures used in the MachO object file format. Note that
|
|
-// unlike llvm/BinaryFormat/MachO.h, the structs here are defined in terms of
|
|
-// endian- and alignment-compatibility wrappers.
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_MACHO_STRUCTS_H
|
|
-#define LLD_MACHO_MACHO_STRUCTS_H
|
|
-
|
|
-#include "llvm/Support/Endian.h"
|
|
-
|
|
-namespace lld {
|
|
-
|
|
-namespace structs {
|
|
-
|
|
-struct nlist_64 {
|
|
- llvm::support::ulittle32_t n_strx;
|
|
- uint8_t n_type;
|
|
- uint8_t n_sect;
|
|
- llvm::support::ulittle16_t n_desc;
|
|
- llvm::support::ulittle64_t n_value;
|
|
-};
|
|
-
|
|
-} // namespace structs
|
|
-
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/MergedOutputSection.cpp b/lld/MachO/MergedOutputSection.cpp
|
|
deleted file mode 100644
|
|
index 2d0be253834..00000000000
|
|
--- a/lld/MachO/MergedOutputSection.cpp
|
|
+++ /dev/null
|
|
@@ -1,74 +0,0 @@
|
|
-//===- OutputSection.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 "MergedOutputSection.h"
|
|
-#include "lld/Common/ErrorHandler.h"
|
|
-#include "lld/Common/Memory.h"
|
|
-#include "llvm/BinaryFormat/MachO.h"
|
|
-
|
|
-using namespace llvm;
|
|
-using namespace llvm::MachO;
|
|
-using namespace lld;
|
|
-using namespace lld::macho;
|
|
-
|
|
-void MergedOutputSection::mergeInput(InputSection *input) {
|
|
- if (inputs.empty()) {
|
|
- align = input->align;
|
|
- flags = input->flags;
|
|
- } else {
|
|
- mergeFlags(input->flags);
|
|
- align = std::max(align, input->align);
|
|
- }
|
|
-
|
|
- inputs.push_back(input);
|
|
- input->parent = this;
|
|
-}
|
|
-
|
|
-void MergedOutputSection::finalize() {
|
|
- uint64_t isecAddr = addr;
|
|
- uint64_t isecFileOff = fileOff;
|
|
- for (InputSection *isec : inputs) {
|
|
- isecAddr = alignTo(isecAddr, isec->align);
|
|
- isecFileOff = alignTo(isecFileOff, isec->align);
|
|
- isec->outSecOff = isecAddr - addr;
|
|
- isec->outSecFileOff = isecFileOff - fileOff;
|
|
- isecAddr += isec->getSize();
|
|
- isecFileOff += isec->getFileSize();
|
|
- }
|
|
- size = isecAddr - addr;
|
|
- fileSize = isecFileOff - fileOff;
|
|
-}
|
|
-
|
|
-void MergedOutputSection::writeTo(uint8_t *buf) const {
|
|
- for (InputSection *isec : inputs) {
|
|
- isec->writeTo(buf + isec->outSecFileOff);
|
|
- }
|
|
-}
|
|
-
|
|
-// TODO: this is most likely wrong; reconsider how section flags
|
|
-// are actually merged. The logic presented here was written without
|
|
-// any form of informed research.
|
|
-void MergedOutputSection::mergeFlags(uint32_t inputFlags) {
|
|
- uint8_t sectionFlag = MachO::SECTION_TYPE & inputFlags;
|
|
- if (sectionFlag != (MachO::SECTION_TYPE & flags))
|
|
- error("Cannot add merge section; inconsistent type flags " +
|
|
- Twine(sectionFlag));
|
|
-
|
|
- uint32_t inconsistentFlags =
|
|
- MachO::S_ATTR_DEBUG | MachO::S_ATTR_STRIP_STATIC_SYMS |
|
|
- MachO::S_ATTR_NO_DEAD_STRIP | MachO::S_ATTR_LIVE_SUPPORT;
|
|
- if ((inputFlags ^ flags) & inconsistentFlags)
|
|
- error("Cannot add merge section; cannot merge inconsistent flags");
|
|
-
|
|
- // Negate pure instruction presence if any section isn't pure.
|
|
- uint32_t pureMask = ~MachO::S_ATTR_PURE_INSTRUCTIONS | (inputFlags & flags);
|
|
-
|
|
- // Merge the rest
|
|
- flags |= inputFlags;
|
|
- flags &= pureMask;
|
|
-}
|
|
diff --git a/lld/MachO/MergedOutputSection.h b/lld/MachO/MergedOutputSection.h
|
|
deleted file mode 100644
|
|
index 279a7e0f75c..00000000000
|
|
--- a/lld/MachO/MergedOutputSection.h
|
|
+++ /dev/null
|
|
@@ -1,56 +0,0 @@
|
|
-//===- OutputSection.h ------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_MERGED_OUTPUT_SECTION_H
|
|
-#define LLD_MACHO_MERGED_OUTPUT_SECTION_H
|
|
-
|
|
-#include "InputSection.h"
|
|
-#include "OutputSection.h"
|
|
-#include "lld/Common/LLVM.h"
|
|
-#include "llvm/ADT/MapVector.h"
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-// Linking multiple files will inevitably mean resolving sections in different
|
|
-// files that are labeled with the same segment and section name. This class
|
|
-// contains all such sections and writes the data from each section sequentially
|
|
-// in the final binary.
|
|
-class MergedOutputSection : public OutputSection {
|
|
-public:
|
|
- MergedOutputSection(StringRef name) : OutputSection(MergedKind, name) {}
|
|
-
|
|
- const InputSection *firstSection() const { return inputs.front(); }
|
|
- const InputSection *lastSection() const { return inputs.back(); }
|
|
-
|
|
- // These accessors will only be valid after finalizing the section
|
|
- uint64_t getSize() const override { return size; }
|
|
- uint64_t getFileSize() const override { return fileSize; }
|
|
-
|
|
- void mergeInput(InputSection *input);
|
|
- void finalize() override;
|
|
-
|
|
- void writeTo(uint8_t *buf) const override;
|
|
-
|
|
- std::vector<InputSection *> inputs;
|
|
-
|
|
- static bool classof(const OutputSection *sec) {
|
|
- return sec->kind() == MergedKind;
|
|
- }
|
|
-
|
|
-private:
|
|
- void mergeFlags(uint32_t inputFlags);
|
|
-
|
|
- size_t size = 0;
|
|
- uint64_t fileSize = 0;
|
|
-};
|
|
-
|
|
-} // namespace macho
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td
|
|
deleted file mode 100644
|
|
index 1e42542b9ac..00000000000
|
|
--- a/lld/MachO/Options.td
|
|
+++ /dev/null
|
|
@@ -1,1297 +0,0 @@
|
|
-include "llvm/Option/OptParser.td"
|
|
-
|
|
-def help : Flag<["-", "--"], "help">;
|
|
-def help_hidden : Flag<["--"], "help-hidden">,
|
|
- HelpText<"Display help for hidden options">;
|
|
-
|
|
-// This is a complete Options.td compiled from Apple's ld(1) manpage
|
|
-// dated 2018-03-07 and cross checked with ld64 source code in repo
|
|
-// https://github.com/apple-opensource/ld64 at git tag "512.4" dated
|
|
-// 2018-03-18.
|
|
-
|
|
-// Flags<[HelpHidden]> marks options that are not yet ported to lld,
|
|
-// and serve as a scoreboard for annotating our progress toward
|
|
-// implementing ld64 options in lld. As you add implementions to
|
|
-// Driver.cpp, please remove the hidden flag here.
|
|
-
|
|
-def grp_kind : OptionGroup<"kind">, HelpText<"OUTPUT KIND">;
|
|
-
|
|
-def execute : Flag<["-"], "execute">,
|
|
- HelpText<"Produce a main executable (default)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_kind>;
|
|
-def dylib : Flag<["-"], "dylib">,
|
|
- HelpText<"Produce a shared library">,
|
|
- Group<grp_kind>;
|
|
-def bundle : Flag<["-"], "bundle">,
|
|
- HelpText<"Produce a bundle">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_kind>;
|
|
-def r : Flag<["-"], "r">,
|
|
- HelpText<"Merge multiple object files into one, retaining relocations">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_kind>;
|
|
-def dylinker : Flag<["-"], "dylinker">,
|
|
- HelpText<"Produce a dylinker only used when building dyld">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_kind>;
|
|
-def dynamic : Flag<["-"], "dynamic">,
|
|
- HelpText<"Link dynamically (default)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_kind>;
|
|
-def static : Flag<["-"], "static">,
|
|
- HelpText<"Link statically">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_kind>;
|
|
-def preload : Flag<["-"], "preload">,
|
|
- HelpText<"Produce an unsegmented binary for embedded systems">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_kind>;
|
|
-def arch : Separate<["-"], "arch">,
|
|
- MetaVarName<"<arch_name>">,
|
|
- HelpText<"The architecture (e.g. ppc, ppc64, i386, x86_64)">,
|
|
- Group<grp_kind>;
|
|
-def o : Separate<["-"], "o">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"The name of the output file (default: `a.out')">,
|
|
- Group<grp_kind>;
|
|
-
|
|
-def grp_libs : OptionGroup<"libs">, HelpText<"LIBRARIES">;
|
|
-
|
|
-def l : Joined<["-"], "l">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Search for lib<name>.dylib or lib<name>.a on the library search path">,
|
|
- Group<grp_libs>;
|
|
-def weak_l : Joined<["-"], "weak-l">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Like -l<name>, but mark library and its references as weak imports">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def weak_library : Separate<["-"], "weak_library">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Like bare <path>, but mark library and its references as weak imports">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def reexport_l : Joined<["-"], "reexport-l">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Like -l<name>, but export all symbols of <name> from newly created library">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def reexport_library : Separate<["-"], "reexport_library">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Like bare <path>, but export all symbols of <path> from newly created library">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def upward_l : Joined<["-"], "upward-l">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Like -l<name>, but specify dylib as an upward dependency">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def upward_library : Separate<["-"], "upward_library">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Like bare <path>, but specify dylib as an upward dependency">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def L : JoinedOrSeparate<["-"], "L">,
|
|
- MetaVarName<"<dir>">,
|
|
- HelpText<"Add dir to the library search path">,
|
|
- Group<grp_libs>;
|
|
-def Z : Flag<["-"], "Z">,
|
|
- HelpText<"Remove standard directories from the library and framework search paths">,
|
|
- Group<grp_libs>;
|
|
-def syslibroot : Separate<["-"], "syslibroot">,
|
|
- MetaVarName<"<rootdir>">,
|
|
- HelpText<"Prepend <rootdir> to all library and framework search paths">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def search_paths_first : Flag<["-"], "search_paths_first">,
|
|
- HelpText<"Search for lib<name>.dylib and lib<name>.a at each step in traversing search path (default for Xcode 4 and later)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def search_dylibs_first : Flag<["-"], "search_dylibs_first">,
|
|
- HelpText<"Search for lib<name>.dylib on first pass, then for lib<name>.a on second pass through search path (default for Xcode 3 and earlier)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def framework : Separate<["-"], "framework">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Search for <name>.framework/<name> on the framework search path">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def weak_framework : Separate<["-"], "weak_framework">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Like -framework <name>, but mark framework and its references as weak imports">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def reexport_framework : Separate<["-"], "reexport_framework">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Like -framework <name>, but export all symbols of <name> from the newly created library">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def upward_framework : Separate<["-"], "upward_framework">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Like -framework <name>, but specify the framework as an upward dependency">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def F : JoinedOrSeparate<["-"], "F">,
|
|
- MetaVarName<"<dir>">,
|
|
- HelpText<"Add dir to the framework search path">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def all_load : Flag<["-"], "all_load">,
|
|
- HelpText<"Load all members of all static archive libraries">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def ObjC : Flag<["-"], "ObjC">,
|
|
- HelpText<"Load all members of static archives that are an Objective-C class or category.">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-def force_load : Separate<["-"], "force_load">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Load all members static archive library at <path>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_libs>;
|
|
-
|
|
-def grp_content : OptionGroup<"content">, HelpText<"ADDITIONAL CONTENT">;
|
|
-
|
|
-def sectcreate : MultiArg<["-"], "sectcreate", 3>,
|
|
- MetaVarName<"<segment> <section> <file>">,
|
|
- HelpText<"Create <section> in <segment> from the contents of <file>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_content>;
|
|
-def segcreate : MultiArg<["-"], "segcreate", 3>,
|
|
- MetaVarName<"<segment> <section> <file>">,
|
|
- Alias<sectcreate>,
|
|
- HelpText<"Alias for -sectcreate">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_content>;
|
|
-def filelist : Separate<["-"], "filelist">,
|
|
- MetaVarName<"<file>">,
|
|
- HelpText<"Read names of files to link from <file>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_content>;
|
|
-def dtrace : Separate<["-"], "dtrace">,
|
|
- MetaVarName<"<script>">,
|
|
- HelpText<"Enable DTrace static probes according to declarations in <script>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_content>;
|
|
-
|
|
-def grp_opts : OptionGroup<"opts">, HelpText<"OPTIMIZATIONS">;
|
|
-
|
|
-def dead_strip : Flag<["-"], "dead_strip">,
|
|
- HelpText<"Remove unreachable functions and data">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def order_file : Separate<["-"], "order_file">,
|
|
- MetaVarName<"<file>">,
|
|
- HelpText<"Layout functions and data according to specification in <file>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def sectorder : MultiArg<["-"], "sectorder", 3>,
|
|
- MetaVarName<"<segname> <sectname> <orderfile>">,
|
|
- HelpText<"Replaced by more general -order_file option">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def no_order_inits : Flag<["-"], "no_order_inits">,
|
|
- HelpText<"Disable default reordering of initializer and terminator functions">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def no_order_data : Flag<["-"], "no_order_data">,
|
|
- HelpText<"Disable default reordering of global data accessed at launch time">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def platform_version : MultiArg<["-"], "platform_version", 3>,
|
|
- MetaVarName<"<platform> <min_version> <sdk_version>">,
|
|
- HelpText<"Platform (e.g., macos, ios, tvos, watchos, bridgeos, mac-catalyst, ios-sim, tvos-sim, watchos-sim, driverkit) and version numbers">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def macos_version_min : Separate<["-"], "macos_version_min">,
|
|
- MetaVarName<"<version>">,
|
|
- HelpText<"Oldest macOS version for which linked output is useable">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def macosx_version_min : Separate<["-"], "macosx_version_min">,
|
|
- MetaVarName<"<version>">,
|
|
- Alias<macos_version_min>,
|
|
- HelpText<"Alias for -macos_version_min">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def ios_version_min : Separate<["-"], "ios_version_min">,
|
|
- MetaVarName<"<version>">,
|
|
- HelpText<"Oldest iOS version for which linked output is useable">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def iphoneos_version_min : Separate<["-"], "iphoneos_version_min">,
|
|
- MetaVarName<"<version>">,
|
|
- Alias<ios_version_min>,
|
|
- HelpText<"Alias for -ios_version_min">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def image_base : Separate<["-"], "image_base">,
|
|
- MetaVarName<"<address>">,
|
|
- HelpText<"Preferred hex load address for a dylib or bundle.">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def seg1addr : Separate<["-"], "seg1addr">,
|
|
- MetaVarName<"<address>">,
|
|
- Alias<image_base>,
|
|
- HelpText<"Alias for -image_base">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def no_implicit_dylibs : Flag<["-"], "no_implicit_dylibs">,
|
|
- HelpText<"Do not optimize public dylib transitive symbol references">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def exported_symbols_order : Separate<["-"], "exported_symbols_order">,
|
|
- MetaVarName<"<file>">,
|
|
- HelpText<"Specify frequently-used symbols in <file> to optimize symbol exports">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def no_zero_fill_sections : Flag<["-"], "no_zero_fill_sections">,
|
|
- HelpText<"Explicitly store zeroed data in the final image">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def merge_zero_fill_sections : Flag<["-"], "merge_zero_fill_sections">,
|
|
- HelpText<"Merge all zeroed data into the __zerofill section">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-def no_branch_islands : Flag<["-"], "no_branch_islands">,
|
|
- HelpText<"Disable infra for branches beyond the maximum branch distance.">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_opts>;
|
|
-
|
|
-def grp_dylib : OptionGroup<"dylib">, HelpText<"DYNAMIC LIBRARIES (DYLIB)">;
|
|
-
|
|
-def install_name : Separate<["-"], "install_name">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Set an internal install path in a dylib">,
|
|
- Group<grp_dylib>;
|
|
-def dylib_install_name : Separate<["-"], "dylib_install_name">,
|
|
- MetaVarName<"<name>">,
|
|
- Alias<install_name>,
|
|
- HelpText<"Alias for -install_name">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_dylib>;
|
|
-def dylinker_install_name : Separate<["-"], "dylinker_install_name">,
|
|
- MetaVarName<"<name>">,
|
|
- Alias<install_name>,
|
|
- HelpText<"Alias for -install_name">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_dylib>;
|
|
-def mark_dead_strippable_dylib : Flag<["-"], "mark_dead_strippable_dylib">,
|
|
- HelpText<"Clients can discard this dylib if it is unreferenced">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_dylib>;
|
|
-def compatibility_version : Separate<["-"], "compatibility_version">,
|
|
- MetaVarName<"<version>">,
|
|
- HelpText<"Compatibility <version> of this library">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_dylib>;
|
|
-def dylib_compatibility_version : Separate<["-"], "dylib_compatibility_version">,
|
|
- MetaVarName<"<version>">,
|
|
- Alias<compatibility_version>,
|
|
- HelpText<"Alias for -compatibility_version">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_dylib>;
|
|
-def current_version : Separate<["-"], "current_version">,
|
|
- MetaVarName<"<version>">,
|
|
- HelpText<"Current <version> of this library">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_dylib>;
|
|
-def dylib_current_version : Separate<["-"], "dylib_current_version">,
|
|
- MetaVarName<"<version>">,
|
|
- Alias<current_version>,
|
|
- HelpText<"Alias for -current_version">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_dylib>;
|
|
-
|
|
-def grp_main : OptionGroup<"main">, HelpText<"MAIN EXECUTABLE">;
|
|
-
|
|
-def pie : Flag<["-"], "pie">,
|
|
- HelpText<"Build a position independent executable (default for macOS 10.7 and later)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_main>;
|
|
-def no_pie : Flag<["-"], "no_pie">,
|
|
- HelpText<"Do not build a position independent executable (default for macOS 10.6 and earlier)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_main>;
|
|
-def pagezero_size : Separate<["-"], "pagezero_size">,
|
|
- MetaVarName<"<size>">,
|
|
- HelpText<"Size of unreadable segment at address zero is hex <size> (default is 4KB on 32-bit and 4GB on 64-bit)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_main>;
|
|
-def stack_size : Separate<["-"], "stack_size">,
|
|
- MetaVarName<"<size>">,
|
|
- HelpText<"Maximum hex stack size for the main thread in a program. (default is 8MB)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_main>;
|
|
-def allow_stack_execute : Flag<["-"], "allow_stack_execute">,
|
|
- HelpText<"Mark stack segment as executable">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_main>;
|
|
-def export_dynamic : Flag<["-"], "export_dynamic">,
|
|
- HelpText<"Preserve all global symbols during LTO">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_main>;
|
|
-
|
|
-def grp_bundle : OptionGroup<"bundle">, HelpText<"CREATING A BUNDLE">;
|
|
-
|
|
-def bundle_loader : Separate<["-"], "bundle_loader">,
|
|
- MetaVarName<"<executable>">,
|
|
- HelpText<"Resolve undefined symbols from <executable>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_bundle>;
|
|
-
|
|
-def grp_object : OptionGroup<"object">, HelpText<"CREATING AN OBJECT FILE">;
|
|
-
|
|
-def keep_private_externs : Flag<["-"], "keep_private_externs">,
|
|
- HelpText<"Do not convert private external symbols to static symbols">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_object>;
|
|
-def d : Flag<["-"], "d">,
|
|
- HelpText<"Force tentative into real definitions for common symbols">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_object>;
|
|
-
|
|
-def grp_resolve : OptionGroup<"resolve">, HelpText<"SYMBOL RESOLUTION">;
|
|
-
|
|
-def exported_symbols_list : Separate<["-"], "exported_symbols_list">,
|
|
- MetaVarName<"<file>">,
|
|
- HelpText<"Symbols specified in <file> remain global, while others become private externs">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-def exported_symbol : Separate<["-"], "exported_symbol">,
|
|
- MetaVarName<"<symbol>">,
|
|
- HelpText<"<symbol> remains global, while others become private externs">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-def unexported_symbols_list : Separate<["-"], "unexported_symbols_list">,
|
|
- MetaVarName<"<file>">,
|
|
- HelpText<"Global symbols specified in <file> become private externs">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-def unexported_symbol : Separate<["-"], "unexported_symbol">,
|
|
- MetaVarName<"<symbol>">,
|
|
- HelpText<"Global <symbol> becomes private extern">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-def reexported_symbols_list : Separate<["-"], "reexported_symbols_list">,
|
|
- MetaVarName<"<file>">,
|
|
- HelpText<"Symbols from dependent dylibs specified in <file> are reexported by this dylib">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-def alias : MultiArg<["-"], "alias", 2>,
|
|
- MetaVarName<"<symbol_name> <alternate_name>">,
|
|
- HelpText<"Create a symbol alias with default global visibility">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-def alias_list : Separate<["-"], "alias_list">,
|
|
- MetaVarName<"<file>">,
|
|
- HelpText<"Create symbol aliases specified in <file>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-def flat_namespace : Flag<["-"], "flat_namespace">,
|
|
- HelpText<"Resolve symbols from all dylibs, both direct & transitive. Do not record source libraries: dyld must re-search at runtime and use the first definition found">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-def u : Separate<["-"], "u">,
|
|
- MetaVarName<"<symbol>">,
|
|
- HelpText<"Require that <symbol> be defined for the link to succeed">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-def U : Separate<["-"], "U">,
|
|
- MetaVarName<"<symbol>">,
|
|
- HelpText<"Allow <symbol> to have no definition">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-def undefined : Separate<["-"], "undefined">,
|
|
- MetaVarName<"<treatment>">,
|
|
- HelpText<"Handle undefined symbols according to <treatment>: error, warning, suppress, or dynamic_lookup (default is error)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-def rpath : Separate<["-"], "rpath">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Add <path> to dyld search list for dylibs with load path prefix `@rpath/'">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-def commons : Separate<["-"], "commons">,
|
|
- MetaVarName<"<treatment>">,
|
|
- HelpText<"Resolve tentative definitions in dylibs according to <treatment>: ignore_dylibs, use_dylibs, error (default is ignore_dylibs)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_resolve>;
|
|
-
|
|
-def grp_introspect : OptionGroup<"introspect">, HelpText<"INTROSPECTING THE LINKER">;
|
|
-
|
|
-def why_load : Flag<["-"], "why_load">,
|
|
- HelpText<"Log the symbol that compels loading of each object file from a static library">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_introspect>;
|
|
-def whyload : Flag<["-"], "whyload">,
|
|
- Alias<why_load>,
|
|
- HelpText<"Alias for -why_load">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_introspect>;
|
|
-def why_live : Separate<["-"], "why_live">,
|
|
- MetaVarName<"<symbol>">,
|
|
- HelpText<"Log a chain of references to <symbol>, for use with -dead_strip">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_introspect>;
|
|
-def print_statistics : Flag<["-"], "print_statistics">,
|
|
- HelpText<"Log the linker's memory and CPU usage">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_introspect>;
|
|
-def t : Flag<["-"], "t">,
|
|
- HelpText<"Log every file the linker loads: object, archive, and dylib">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_introspect>;
|
|
-def whatsloaded : Flag<["-"], "whatsloaded">,
|
|
- HelpText<"Logs only the object files the linker loads">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_introspect>;
|
|
-def order_file_statistics : Flag<["-"], "order_file_statistics">,
|
|
- HelpText<"Logs information about -order_file">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_introspect>;
|
|
-def map : Separate<["-"], "map">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Writes all symbols and their addresses to <path>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_introspect>;
|
|
-
|
|
-def grp_symtab : OptionGroup<"symtab">, HelpText<"SYMBOL TABLE OPTIMIZATIONS">;
|
|
-
|
|
-def S : Flag<["-"], "S">,
|
|
- HelpText<"Strip debug information (STABS or DWARF) from the output">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_symtab>;
|
|
-def x : Flag<["-"], "x">,
|
|
- HelpText<"Exclude non-global symbols from the output symbol table">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_symtab>;
|
|
-def non_global_symbols_strip_list : Separate<["-"], "non_global_symbols_strip_list">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Specify in <path> the non-global symbols that should be removed from the output symbol table">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_symtab>;
|
|
-def non_global_symbols_no_strip_list : Separate<["-"], "non_global_symbols_no_strip_list">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Specify in <path> the non-global symbols that should remain in the output symbol table">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_symtab>;
|
|
-def oso_prefix : Separate<["-"], "oso_prefix">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Remove the prefix <path> from OSO symbols in the debug map">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_symtab>;
|
|
-
|
|
-def grp_bitcode : OptionGroup<"bitcode">, HelpText<"BITCODE BUILD FLOW">;
|
|
-
|
|
-def bitcode_bundle : Flag<["-"], "bitcode_bundle">,
|
|
- HelpText<"Generate an embedded bitcode bundle in the __LLVM,__bundle section of the output">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_bitcode>;
|
|
-def bitcode_hide_symbols : Flag<["-"], "bitcode_hide_symbols">,
|
|
- HelpText<"With -bitcode_bundle, hide all non-exported symbols from output bitcode bundle.">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_bitcode>;
|
|
-def bitcode_symbol_map : Separate<["-"], "bitcode_symbol_map">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Write the bitcode symbol reverse mapping to file <path>, or if a directory, to <path>/UUID.bcsymbolmap">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_bitcode>;
|
|
-
|
|
-def grp_rare : OptionGroup<"rare">, HelpText<"RARELY USED">;
|
|
-
|
|
-def v : Flag<["-"], "v">,
|
|
- HelpText<"Print the linker version">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def version_details : Flag<["-"], "version_details">,
|
|
- HelpText<"Print the linker version in JSON form">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def no_weak_imports : Flag<["-"], "no_weak_imports">,
|
|
- HelpText<"Fail if any symbols are weak imports, allowed to be NULL at runtime">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def no_deduplicate : Flag<["-"], "no_deduplicate">,
|
|
- HelpText<"Omit the deduplication pass">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def verbose_deduplicate : Flag<["-"], "verbose_deduplicate">,
|
|
- HelpText<"Print function names eliminated by deduplication and the total size of code savings">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def no_inits : Flag<["-"], "no_inits">,
|
|
- HelpText<"Fail if the output contains static initializers">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def no_warn_inits : Flag<["-"], "no_warn_inits">,
|
|
- HelpText<"Suppress warnings for static initializers in the output">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def debug_variant : Flag<["-"], "debug_variant">,
|
|
- HelpText<"Suppress warnings germane to binaries shipping to customers">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def unaligned_pointers : Separate<["-"], "unaligned_pointers">,
|
|
- MetaVarName<"<treatment>">,
|
|
- HelpText<"Handle unaligned pointers in __DATA segments according to <treatment>: warning, error, or suppress (default for arm64e is error, otherwise suppress)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def dirty_data_list : Separate<["-"], "dirty_data_list">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Specify data symbols in <path> destined for the __DATA_DIRTY segment">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def max_default_common_align : Separate<["-"], "max_default_common_align">,
|
|
- MetaVarName<"<boundary>">,
|
|
- HelpText<"Reduce maximum alignment for common symbols to a hex power-of-2 <boundary>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def move_to_rw_segment : MultiArg<["-"], "move_to_rw_segment", 2>,
|
|
- MetaVarName<"<segment> <path>">,
|
|
- HelpText<"Move data symbols listed in <path> to another <segment>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def move_to_ro_segment : MultiArg<["-"], "move_to_ro_segment", 2>,
|
|
- MetaVarName<"<segment> <path>">,
|
|
- HelpText<"Move code symbols listed in <path> to another <segment>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def rename_section : MultiArg<["-"], "rename_section", 4>,
|
|
- MetaVarName<"<from_segment> <from_section> <to_segment> <to_section>">,
|
|
- HelpText<"Rename <from_segment>/<from_section> as <to_segment>/<to_section>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def rename_segment : MultiArg<["-"], "rename_segment", 2>,
|
|
- MetaVarName<"<from_segment> <to_segment>">,
|
|
- HelpText<"Rename <from_segment> as <to_segment>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def trace_symbol_layout : Flag<["-"], "trace_symbol_layout">,
|
|
- HelpText<"Show where and why symbols move, as specified by -move_to_ro_segment, -move_to_rw_segment, -rename_section, and -rename_segment">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def section_order : MultiArg<["-"], "section_order", 2>,
|
|
- MetaVarName<"<segment> <sections>">,
|
|
- HelpText<"With -preload, specify layout sequence of colon-separated <sections> in <segment>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def segment_order : Separate<["-"], "segment_order">,
|
|
- MetaVarName<"<colon_separated_segment_list>">,
|
|
- HelpText<"With -preload, specify layout sequence of colon-separated <segments>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def allow_heap_execute : Flag<["-"], "allow_heap_execute">,
|
|
- HelpText<"On i386, allow any page to execute code">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def application_extension : Flag<["-"], "application_extension">,
|
|
- HelpText<"Designate the linker output as safe for use in an application extension">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def no_application_extension : Flag<["-"], "no_application_extension">,
|
|
- HelpText<"Designate the linker output as unsafe for use in an application extension">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def fatal_warnings : Flag<["-"], "fatal_warnings">,
|
|
- HelpText<"Escalate warnings as errors">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def no_eh_labels : Flag<["-"], "no_eh_labels">,
|
|
- HelpText<"In -r mode, suppress .eh labels in the __eh_frame section">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def warn_compact_unwind : Flag<["-"], "warn_compact_unwind">,
|
|
- HelpText<"Warn for each FDE that cannot compact into the __unwind_info section and must remain in the __eh_frame section">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def warn_weak_exports : Flag<["-"], "warn_weak_exports">,
|
|
- HelpText<"Warn if the linked image contains weak external symbols">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def no_weak_exports : Flag<["-"], "no_weak_exports">,
|
|
- HelpText<"Fail if the linked image contains weak external symbols">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def objc_gc_compaction : Flag<["-"], "objc_gc_compaction">,
|
|
- HelpText<"Mark the Objective-C image as compatible with compacting garbage collection">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def objc_gc : Flag<["-"], "objc_gc">,
|
|
- HelpText<"Verify that all code was compiled with -fobjc-gc or -fobjc-gc-only">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def objc_gc_only : Flag<["-"], "objc_gc_only">,
|
|
- HelpText<"Verify that all code was compiled with -fobjc-gc-only">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def dead_strip_dylibs : Flag<["-"], "dead_strip_dylibs">,
|
|
- HelpText<"Remove dylibs that are unreachable by the entry point or exported symbols">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def allow_sub_type_mismatches : Flag<["-"], "allow_sub_type_mismatches">,
|
|
- HelpText<"Permit mixing objects compiled for different ARM CPU subtypes">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def no_uuid : Flag<["-"], "no_uuid">,
|
|
- HelpText<"Do not generate the LC_UUID load command">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def root_safe : Flag<["-"], "root_safe">,
|
|
- HelpText<"Set the MH_ROOT_SAFE bit in the mach-o header">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def setuid_safe : Flag<["-"], "setuid_safe">,
|
|
- HelpText<"Set the MH_SETUID_SAFE bit in the mach-o header">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def interposable : Flag<["-"], "interposable">,
|
|
- HelpText<"Indirects access to all to exported symbols in a dylib">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def multi_module : Flag<["-"], "multi_module">,
|
|
- Alias<interposable>,
|
|
- HelpText<"Alias for -interposable">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def init : Separate<["-"], "init">,
|
|
- MetaVarName<"<symbol>">,
|
|
- HelpText<"Run <symbol> as the first initializer in a dylib">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def sub_library : Separate<["-"], "sub_library">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Re-export the dylib as <name>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def sub_umbrella : Separate<["-"], "sub_umbrella">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Re-export the framework as <name>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def allowable_client : Separate<["-"], "allowable_client">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Specify <name> of a dylib or framework that is allowed to link to this dylib">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def client_name : Separate<["-"], "client_name">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Specifies a <name> this client should match with the -allowable_client <name> in a dependent dylib">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def umbrella : Separate<["-"], "umbrella">,
|
|
- MetaVarName<"<<name>>">,
|
|
- HelpText<"Re-export this dylib through the umbrella framework <name>a">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def headerpad : Separate<["-"], "headerpad">,
|
|
- MetaVarName<"<size>">,
|
|
- HelpText<"Allocate hex <size> extra space for future expansion of the load commands via install_name_tool">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def headerpad_max_install_names : Flag<["-"], "headerpad_max_install_names">,
|
|
- HelpText<"Allocate extra space so all load-command paths can expand to MAXPATHLEN via install_name_tool">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def bind_at_load : Flag<["-"], "bind_at_load">,
|
|
- HelpText<"Tell dyld to bind all symbols at load time, rather than lazily">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def force_flat_namespace : Flag<["-"], "force_flat_namespace">,
|
|
- HelpText<"Tell dyld to use a flat namespace on this executable and all its dependent dylibs & bundles">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def segalign : Separate<["-"], "segalign">,
|
|
- MetaVarName<"<boundary>">,
|
|
- HelpText<"Align all segments to hex power-of-2 <boundary>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def sectalign : MultiArg<["-"], "sectalign", 3>,
|
|
- MetaVarName<"<segment> <section> <boundary>">,
|
|
- HelpText<"Align <section> within <segment> to hex power-of-2 <boundary>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def stack_addr : Separate<["-"], "stack_addr">,
|
|
- MetaVarName<"<address>">,
|
|
- HelpText<"Initialize stack pointer to hex <address> rounded to a page boundary">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def segprot : MultiArg<["-"], "segprot", 3>,
|
|
- MetaVarName<"<segment> <max> <init>">,
|
|
- HelpText<"Specifies the <max> and <init> virtual memory protection of <segment> as r/w/x/-seg_addr_table path Specify hex base addresses and dylib install names on successive lines in <path>. This option is obsolete">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def segs_read_write_addr : Separate<["-"], "segs_read_write_addr">,
|
|
- MetaVarName<"<address>">,
|
|
- HelpText<"This option is obsolete">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def segs_read_only_addr : Separate<["-"], "segs_read_only_addr">,
|
|
- MetaVarName<"<address>">,
|
|
- HelpText<"This option is obsolete">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def segaddr : MultiArg<["-"], "segaddr", 2>,
|
|
- MetaVarName<"<segment> <address>">,
|
|
- HelpText<"Specify the starting hex <address> at a 4KiB page boundary for <segment>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def seg_page_size : MultiArg<["-"], "seg_page_size", 2>,
|
|
- MetaVarName<"<segment> <size>">,
|
|
- HelpText<"Specifies the page <size> for <segment>. Segment size will be a multiple of its page size">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def dylib_file : Separate<["-"], "dylib_file">,
|
|
- MetaVarName<"<install_path:current_path>">,
|
|
- HelpText<"Specify <current_path> as different from where a dylib normally resides at <install_path>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def prebind : Flag<["-"], "prebind">,
|
|
- HelpText<"This option is obsolete">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def weak_reference_mismatches : Separate<["-"], "weak_reference_mismatches">,
|
|
- MetaVarName<"<treatment>">,
|
|
- HelpText<"Resolve symbol imports of conflicting weakness according to <treatment> as weak, non-weak, or error (default is non-weak)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def read_only_relocs : Separate<["-"], "read_only_relocs">,
|
|
- MetaVarName<"<treatment>">,
|
|
- HelpText<"Handle relocations that modify read-only pages according to <treatment> of warning, error, or suppress (i.e., allow)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def force_cpusubtype_ALL : Flag<["-"], "force_cpusubtype_ALL">,
|
|
- HelpText<"Mark binary as runnable on any PowerPC, ignoring any PowerPC cpu requirements encoded in the object files">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def no_arch_warnings : Flag<["-"], "no_arch_warnings">,
|
|
- HelpText<"Suppresses warnings about inputs whose architecture does not match the -arch option">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def arch_errors_fatal : Flag<["-"], "arch_errors_fatal">,
|
|
- HelpText<"Escalate to errors any warnings about inputs whose architecture does not match the -arch option">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def e : Separate<["-"], "e">,
|
|
- MetaVarName<"<symbol>">,
|
|
- HelpText<"Make <symbol> the entry point of an executable (default is \"start\" from crt1.o)">,
|
|
- Group<grp_rare>;
|
|
-def w : Flag<["-"], "w">,
|
|
- HelpText<"Suppress all warnings">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def final_output : Separate<["-"], "final_output">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"Specify the dylib install name if -install_name is not used--used by compiler driver for multiple -arch arguments">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def arch_multiple : Flag<["-"], "arch_multiple">,
|
|
- HelpText<"Augment error and warning messages with the architecture name">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def twolevel_namespace_hints : Flag<["-"], "twolevel_namespace_hints">,
|
|
- HelpText<"This option is obsolete">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def dot : Separate<["-"], "dot">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Write a graph of symbol dependencies to <path> as a .dot file viewable with GraphViz">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def keep_relocs : Flag<["-"], "keep_relocs">,
|
|
- HelpText<"Retain section-based relocation records in the output, which are ignored at runtime by dyld">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def warn_stabs : Flag<["-"], "warn_stabs">,
|
|
- HelpText<"Warn when bad stab symbols inside a BINCL/EINCL prevent optimization">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def warn_commons : Flag<["-"], "warn_commons">,
|
|
- HelpText<"Warn when a tentative definition in an object file matches an external symbol in a dylib, which often means \"extern\" is missing from a variable declaration in a header file">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def read_only_stubs : Flag<["-"], "read_only_stubs">,
|
|
- HelpText<"On i386, make the __IMPORT segment of a final linked image read-only">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def slow_stubs : Flag<["-"], "slow_stubs">,
|
|
- HelpText<"This option is obsolete">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def interposable_list : Separate<["-"], "interposable_list">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Access global symbols listed in <path> indirectly">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def no_function_starts : Flag<["-"], "no_function_starts">,
|
|
- HelpText<"Do not creates a compressed table of function start addresses">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def no_objc_category_merging : Flag<["-"], "no_objc_category_merging">,
|
|
- HelpText<"Do not merge Objective-C categories into their classes">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def object_path_lto : Separate<["-"], "object_path_lto">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Retain any temporary mach-o file in <path> that would otherwise be deleted during LTO">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def lto_library : Separate<["-"], "lto_library">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Override the default ../lib/libLTO.dylib as <path>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def cache_path_lto : Separate<["-"], "cache_path_lto">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"Use <path> as a directory for the incremental LTO cache">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def prune_interval_lto : Separate<["-"], "prune_interval_lto">,
|
|
- MetaVarName<"<seconds>">,
|
|
- HelpText<"Prune the incremental LTO cache after <seconds> (-1 disables pruning)">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def prune_after_lto : Separate<["-"], "prune_after_lto">,
|
|
- MetaVarName<"<seconds>">,
|
|
- HelpText<"Remove LTO cache entries after <seconds>">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def max_relative_cache_size_lto : Separate<["-"], "max_relative_cache_size_lto">,
|
|
- MetaVarName<"<percent>">,
|
|
- HelpText<"Limit the incremental LTO cache growth to <percent> of free disk, space">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def page_align_data_atoms : Flag<["-"], "page_align_data_atoms">,
|
|
- HelpText<"Distribute global variables on separate pages so page used/dirty status can guide creation of an order file to cluster commonly used/dirty globals">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-def not_for_dyld_shared_cache : Flag<["-"], "not_for_dyld_shared_cache">,
|
|
- HelpText<"Prevent system dylibs from being placed into the dylib shared cache">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_rare>;
|
|
-
|
|
-def grp_deprecated : OptionGroup<"deprecated">, HelpText<"DEPRECATED">;
|
|
-
|
|
-def lazy_framework : Separate<["-"], "lazy_framework">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"This option is deprecated and is now an alias for -framework.">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_deprecated>;
|
|
-def lazy_library : Separate<["-"], "lazy_library">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"This option is deprecated and is now an alias for regular linking">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_deprecated>;
|
|
-def lazy_l : Joined<["-"], "lazy-l">,
|
|
- MetaVarName<"<name>">,
|
|
- HelpText<"This option is deprecated and is now an alias for -l<path>.">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_deprecated>;
|
|
-def single_module : Flag<["-"], "single_module">,
|
|
- HelpText<"Unnecessary option: this is already the default">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_deprecated>;
|
|
-def no_dead_strip_inits_and_terms : Flag<["-"], "no_dead_strip_inits_and_terms">,
|
|
- HelpText<"Unnecessary option: initialization and termination are roots of the dead strip graph, so never dead stripped">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_deprecated>;
|
|
-def noall_load : Flag<["-"], "noall_load">,
|
|
- HelpText<"Unnecessary option: this is already the default">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_deprecated>;
|
|
-
|
|
-def grp_obsolete : OptionGroup<"obsolete">, HelpText<"OBSOLETE">;
|
|
-
|
|
-def y : Joined<["-"], "y">,
|
|
- MetaVarName<"<symbol>">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def sectobjectsymbols : MultiArg<["-"], "sectobjectsymbols", 2>,
|
|
- MetaVarName<"<segname> <sectname>">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def nofixprebinding : Flag<["-"], "nofixprebinding">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def noprebind_all_twolevel_modules : Flag<["-"], "noprebind_all_twolevel_modules">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def prebind_all_twolevel_modules : Flag<["-"], "prebind_all_twolevel_modules">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def prebind_allow_overlap : Flag<["-"], "prebind_allow_overlap">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def noprebind : Flag<["-"], "noprebind">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def sect_diff_relocs : Separate<["-"], "sect_diff_relocs">,
|
|
- MetaVarName<"<treatment>">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def A : Separate<["-"], "A">,
|
|
- MetaVarName<"<basefile>">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def b : Flag<["-"], "b">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def Sn : Flag<["-"], "Sn">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def Si : Flag<["-"], "Si">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def Sp : Flag<["-"], "Sp">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def X : Flag<["-"], "X">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def s : Flag<["-"], "s">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def m : Flag<["-"], "m">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def Y : Separate<["-"], "Y">,
|
|
- MetaVarName<"<number>">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def nomultidefs : Flag<["-"], "nomultidefs">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def multiply_defined_unused : Separate<["-"], "multiply_defined_unused">,
|
|
- MetaVarName<"<treatment>">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def multiply_defined : Separate<["-"], "multiply_defined">,
|
|
- MetaVarName<"<treatment>">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def private_bundle : Flag<["-"], "private_bundle">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def seg_addr_table_filename : Separate<["-"], "seg_addr_table_filename">,
|
|
- MetaVarName<"<path>">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def sectorder_detail : Flag<["-"], "sectorder_detail">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def no_compact_linkedit : Flag<["-"], "no_compact_linkedit">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def dependent_dr_info : Flag<["-"], "dependent_dr_info">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def no_dependent_dr_info : Flag<["-"], "no_dependent_dr_info">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def seglinkedit : Flag<["-"], "seglinkedit">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def noseglinkedit : Flag<["-"], "noseglinkedit">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def fvmlib : Flag<["-"], "fvmlib">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-def run_init_lazily : Flag<["-"], "run_init_lazily">,
|
|
- HelpText<"This option is obsolete in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_obsolete>;
|
|
-
|
|
-def grp_undocumented : OptionGroup<"undocumented">, HelpText<"UNDOCUMENTED">;
|
|
-
|
|
-def add_ast_path : Flag<["-"], "add_ast_path">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def add_linker_option : Flag<["-"], "add_linker_option">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def add_source_version : Flag<["-"], "add_source_version">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def no_source_version : Flag<["-"], "no_source_version">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def add_split_seg_info : Flag<["-"], "add_split_seg_info">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def allow_dead_duplicates : Flag<["-"], "allow_dead_duplicates">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def allow_simulator_linking_to_macosx_dylibs : Flag<["-"], "allow_simulator_linking_to_macosx_dylibs">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def bitcode_process_mode : Flag<["-"], "bitcode_process_mode">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def bitcode_verify : Flag<["-"], "bitcode_verify">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def classic_linker : Flag<["-"], "classic_linker">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def data_const : Flag<["-"], "data_const">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def no_data_const : Flag<["-"], "no_data_const">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def data_in_code_info : Flag<["-"], "data_in_code_info">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def no_data_in_code_info : Flag<["-"], "no_data_in_code_info">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def debug_snapshot : Flag<["-"], "debug_snapshot">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def demangle : Flag<["-"], "demangle">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def dependency_info : Flag<["-"], "dependency_info">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def dyld_env : Flag<["-"], "dyld_env">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def encryptable : Flag<["-"], "encryptable">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def executable_path : Flag<["-"], "executable_path">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def fixup_chains : Flag<["-"], "fixup_chains">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def fixup_chains_section : Flag<["-"], "fixup_chains_section">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def flto_codegen_only : Flag<["-"], "flto-codegen-only">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def force_load_swift_libs : Flag<["-"], "force_load_swift_libs">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def force_symbol_not_weak : Flag<["-"], "force_symbol_not_weak">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def force_symbols_coalesce_list : Flag<["-"], "force_symbols_coalesce_list">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def force_symbols_not_weak_list : Flag<["-"], "force_symbols_not_weak_list">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def force_symbols_weak_list : Flag<["-"], "force_symbols_weak_list">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def force_symbol_weak : Flag<["-"], "force_symbol_weak">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def function_starts : Flag<["-"], "function_starts">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def i : Flag<["-"], "i">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def ignore_auto_link : Flag<["-"], "ignore_auto_link">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def ignore_optimization_hints : Flag<["-"], "ignore_optimization_hints">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def init_offsets : Flag<["-"], "init_offsets">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def keep_dwarf_unwind : Flag<["-"], "keep_dwarf_unwind">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def no_keep_dwarf_unwind : Flag<["-"], "no_keep_dwarf_unwind">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def kext : Flag<["-"], "kext">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def kext_objects_dir : Flag<["-"], "kext_objects_dir">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def no_kext_objects : Flag<["-"], "no_kext_objects">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def kexts_use_stubs : Flag<["-"], "kexts_use_stubs">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def maccatalyst_version_min : Flag<["-"], "maccatalyst_version_min">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def iosmac_version_min : Flag<["-"], "iosmac_version_min">,
|
|
- Alias<maccatalyst_version_min>,
|
|
- HelpText<"Alias for -maccatalyst_version_min">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def uikitformac_version_min : Flag<["-"], "uikitformac_version_min">,
|
|
- Alias<maccatalyst_version_min>,
|
|
- HelpText<"Alias for -maccatalyst_version_min">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def mcpu : Flag<["-"], "mcpu">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def mllvm : Flag<["-"], "mllvm">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def no_compact_unwind : Flag<["-"], "no_compact_unwind">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def no_dtrace_dof : Flag<["-"], "no_dtrace_dof">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def no_encryption : Flag<["-"], "no_encryption">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def no_new_main : Flag<["-"], "no_new_main">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def objc_abi_version : Flag<["-"], "objc_abi_version">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def pause : Flag<["-"], "pause">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def random_uuid : Flag<["-"], "random_uuid">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def save_temps : Flag<["-"], "save-temps">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def sdk_version : Flag<["-"], "sdk_version">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def simulator_support : Flag<["-"], "simulator_support">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def snapshot_dir : Flag<["-"], "snapshot_dir">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def source_version : Flag<["-"], "source_version">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def text_exec : Flag<["-"], "text_exec">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def threaded_starts_section : Flag<["-"], "threaded_starts_section">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def twolevel_namespace : Flag<["-"], "twolevel_namespace">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def verbose_optimization_hints : Flag<["-"], "verbose_optimization_hints">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-def version_load_command : Flag<["-"], "version_load_command">,
|
|
- HelpText<"This option is undocumented in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_undocumented>;
|
|
-
|
|
-def grp_ignored : OptionGroup<"ignored">, HelpText<"IGNORED">;
|
|
-
|
|
-def M : Flag<["-"], "M">,
|
|
- HelpText<"This option is ignored in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_ignored>;
|
|
-def new_linker : Flag<["-"], "new_linker">,
|
|
- HelpText<"This option is ignored in ld64">,
|
|
- Flags<[HelpHidden]>,
|
|
- Group<grp_ignored>;
|
|
diff --git a/lld/MachO/OutputSection.cpp b/lld/MachO/OutputSection.cpp
|
|
deleted file mode 100644
|
|
index c006828267c..00000000000
|
|
--- a/lld/MachO/OutputSection.cpp
|
|
+++ /dev/null
|
|
@@ -1,18 +0,0 @@
|
|
-//===- OutputSection.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 "OutputSection.h"
|
|
-#include "OutputSegment.h"
|
|
-
|
|
-using namespace llvm;
|
|
-using namespace lld;
|
|
-using namespace lld::macho;
|
|
-
|
|
-uint64_t OutputSection::getSegmentOffset() const {
|
|
- return addr - parent->firstSection()->addr;
|
|
-}
|
|
diff --git a/lld/MachO/OutputSection.h b/lld/MachO/OutputSection.h
|
|
deleted file mode 100644
|
|
index 07b53a04639..00000000000
|
|
--- a/lld/MachO/OutputSection.h
|
|
+++ /dev/null
|
|
@@ -1,74 +0,0 @@
|
|
-//===- OutputSection.h ------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_OUTPUT_SECTION_H
|
|
-#define LLD_MACHO_OUTPUT_SECTION_H
|
|
-
|
|
-#include "lld/Common/LLVM.h"
|
|
-#include "llvm/ADT/DenseMap.h"
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-class InputSection;
|
|
-class OutputSegment;
|
|
-
|
|
-// Output sections represent the finalized sections present within the final
|
|
-// linked executable. They can represent special sections (like the symbol
|
|
-// table), or represent coalesced sections from the various inputs given to the
|
|
-// linker with the same segment / section name.
|
|
-class OutputSection {
|
|
-public:
|
|
- enum Kind {
|
|
- MergedKind,
|
|
- SyntheticKind,
|
|
- };
|
|
-
|
|
- OutputSection(Kind kind, StringRef name) : name(name), sectionKind(kind) {}
|
|
- virtual ~OutputSection() = default;
|
|
- Kind kind() const { return sectionKind; }
|
|
-
|
|
- // These accessors will only be valid after finalizing the section.
|
|
- uint64_t getSegmentOffset() const;
|
|
-
|
|
- // How much space the section occupies in the address space.
|
|
- virtual uint64_t getSize() const = 0;
|
|
- // How much space the section occupies in the file. Most sections are copied
|
|
- // as-is so their file size is the same as their address space size.
|
|
- virtual uint64_t getFileSize() const { return getSize(); }
|
|
-
|
|
- // Hidden sections omit header content, but body content may still be present.
|
|
- virtual bool isHidden() const { return false; }
|
|
- // Unneeded sections are omitted entirely (header and body).
|
|
- virtual bool isNeeded() const { return true; }
|
|
-
|
|
- // Specifically finalizes addresses and section size, not content.
|
|
- virtual void finalize() {
|
|
- // TODO investigate refactoring synthetic section finalization logic into
|
|
- // overrides of this function.
|
|
- }
|
|
-
|
|
- virtual void writeTo(uint8_t *buf) const = 0;
|
|
-
|
|
- StringRef name;
|
|
- OutputSegment *parent = nullptr;
|
|
-
|
|
- uint32_t index = 0;
|
|
- uint64_t addr = 0;
|
|
- uint64_t fileOff = 0;
|
|
- uint32_t align = 1;
|
|
- uint32_t flags = 0;
|
|
-
|
|
-private:
|
|
- Kind sectionKind;
|
|
-};
|
|
-
|
|
-} // namespace macho
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/OutputSegment.cpp b/lld/MachO/OutputSegment.cpp
|
|
deleted file mode 100644
|
|
index 5e57c49f5c0..00000000000
|
|
--- a/lld/MachO/OutputSegment.cpp
|
|
+++ /dev/null
|
|
@@ -1,67 +0,0 @@
|
|
-//===- OutputSegment.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 "OutputSegment.h"
|
|
-#include "InputSection.h"
|
|
-#include "MergedOutputSection.h"
|
|
-#include "SyntheticSections.h"
|
|
-
|
|
-#include "lld/Common/ErrorHandler.h"
|
|
-#include "lld/Common/Memory.h"
|
|
-#include "llvm/BinaryFormat/MachO.h"
|
|
-
|
|
-using namespace llvm;
|
|
-using namespace llvm::MachO;
|
|
-using namespace lld;
|
|
-using namespace lld::macho;
|
|
-
|
|
-static uint32_t initProt(StringRef name) {
|
|
- if (name == segment_names::text)
|
|
- return VM_PROT_READ | VM_PROT_EXECUTE;
|
|
- if (name == segment_names::pageZero)
|
|
- return 0;
|
|
- if (name == segment_names::linkEdit)
|
|
- return VM_PROT_READ;
|
|
- return VM_PROT_READ | VM_PROT_WRITE;
|
|
-}
|
|
-
|
|
-static uint32_t maxProt(StringRef name) {
|
|
- if (name == segment_names::pageZero)
|
|
- return 0;
|
|
- return VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
|
|
-}
|
|
-
|
|
-size_t OutputSegment::numNonHiddenSections() const {
|
|
- size_t count = 0;
|
|
- for (const OutputSection *osec : sections) {
|
|
- count += (!osec->isHidden() ? 1 : 0);
|
|
- }
|
|
- return count;
|
|
-}
|
|
-
|
|
-void OutputSegment::addOutputSection(OutputSection *osec) {
|
|
- osec->parent = this;
|
|
- sections.push_back(osec);
|
|
-}
|
|
-
|
|
-static llvm::DenseMap<StringRef, OutputSegment *> nameToOutputSegment;
|
|
-std::vector<OutputSegment *> macho::outputSegments;
|
|
-
|
|
-OutputSegment *macho::getOrCreateOutputSegment(StringRef name) {
|
|
- OutputSegment *&segRef = nameToOutputSegment[name];
|
|
- if (segRef != nullptr)
|
|
- return segRef;
|
|
-
|
|
- segRef = make<OutputSegment>();
|
|
- segRef->name = name;
|
|
- segRef->maxProt = maxProt(name);
|
|
- segRef->initProt = initProt(name);
|
|
-
|
|
- outputSegments.push_back(segRef);
|
|
- return segRef;
|
|
-}
|
|
diff --git a/lld/MachO/OutputSegment.h b/lld/MachO/OutputSegment.h
|
|
deleted file mode 100644
|
|
index d977c281272..00000000000
|
|
--- a/lld/MachO/OutputSegment.h
|
|
+++ /dev/null
|
|
@@ -1,62 +0,0 @@
|
|
-//===- OutputSegment.h ------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_OUTPUT_SEGMENT_H
|
|
-#define LLD_MACHO_OUTPUT_SEGMENT_H
|
|
-
|
|
-#include "OutputSection.h"
|
|
-#include "lld/Common/LLVM.h"
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-namespace segment_names {
|
|
-
|
|
-constexpr const char pageZero[] = "__PAGEZERO";
|
|
-constexpr const char text[] = "__TEXT";
|
|
-constexpr const char data[] = "__DATA";
|
|
-constexpr const char linkEdit[] = "__LINKEDIT";
|
|
-constexpr const char dataConst[] = "__DATA_CONST";
|
|
-
|
|
-} // namespace segment_names
|
|
-
|
|
-class OutputSection;
|
|
-class InputSection;
|
|
-
|
|
-class OutputSegment {
|
|
-public:
|
|
- const OutputSection *firstSection() const { return sections.front(); }
|
|
- const OutputSection *lastSection() const { return sections.back(); }
|
|
-
|
|
- void addOutputSection(OutputSection *os);
|
|
- void sortOutputSections(
|
|
- llvm::function_ref<bool(OutputSection *, OutputSection *)> comparator) {
|
|
- llvm::stable_sort(sections, comparator);
|
|
- }
|
|
-
|
|
- const std::vector<OutputSection *> &getSections() const { return sections; }
|
|
- size_t numNonHiddenSections() const;
|
|
-
|
|
- uint64_t fileOff = 0;
|
|
- StringRef name;
|
|
- uint32_t maxProt = 0;
|
|
- uint32_t initProt = 0;
|
|
- uint8_t index;
|
|
-
|
|
-private:
|
|
- std::vector<OutputSection *> sections;
|
|
-};
|
|
-
|
|
-extern std::vector<OutputSegment *> outputSegments;
|
|
-
|
|
-OutputSegment *getOrCreateOutputSegment(StringRef name);
|
|
-
|
|
-} // namespace macho
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp
|
|
deleted file mode 100644
|
|
index 80e870d7989..00000000000
|
|
--- a/lld/MachO/SymbolTable.cpp
|
|
+++ /dev/null
|
|
@@ -1,87 +0,0 @@
|
|
-//===- SymbolTable.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 "SymbolTable.h"
|
|
-#include "InputFiles.h"
|
|
-#include "Symbols.h"
|
|
-#include "lld/Common/ErrorHandler.h"
|
|
-#include "lld/Common/Memory.h"
|
|
-
|
|
-using namespace llvm;
|
|
-using namespace lld;
|
|
-using namespace lld::macho;
|
|
-
|
|
-Symbol *SymbolTable::find(StringRef name) {
|
|
- auto it = symMap.find(llvm::CachedHashStringRef(name));
|
|
- if (it == symMap.end())
|
|
- return nullptr;
|
|
- return symVector[it->second];
|
|
-}
|
|
-
|
|
-std::pair<Symbol *, bool> SymbolTable::insert(StringRef name) {
|
|
- auto p = symMap.insert({CachedHashStringRef(name), (int)symVector.size()});
|
|
-
|
|
- // Name already present in the symbol table.
|
|
- if (!p.second)
|
|
- return {symVector[p.first->second], false};
|
|
-
|
|
- // Name is a new symbol.
|
|
- Symbol *sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
|
|
- symVector.push_back(sym);
|
|
- return {sym, true};
|
|
-}
|
|
-
|
|
-Symbol *SymbolTable::addDefined(StringRef name, InputSection *isec,
|
|
- uint32_t value) {
|
|
- Symbol *s;
|
|
- bool wasInserted;
|
|
- std::tie(s, wasInserted) = insert(name);
|
|
-
|
|
- if (!wasInserted && isa<Defined>(s))
|
|
- error("duplicate symbol: " + name);
|
|
-
|
|
- replaceSymbol<Defined>(s, name, isec, value);
|
|
- return s;
|
|
-}
|
|
-
|
|
-Symbol *SymbolTable::addUndefined(StringRef name) {
|
|
- Symbol *s;
|
|
- bool wasInserted;
|
|
- std::tie(s, wasInserted) = insert(name);
|
|
-
|
|
- if (wasInserted)
|
|
- replaceSymbol<Undefined>(s, name);
|
|
- else if (LazySymbol *lazy = dyn_cast<LazySymbol>(s))
|
|
- lazy->fetchArchiveMember();
|
|
- return s;
|
|
-}
|
|
-
|
|
-Symbol *SymbolTable::addDylib(StringRef name, DylibFile *file) {
|
|
- Symbol *s;
|
|
- bool wasInserted;
|
|
- std::tie(s, wasInserted) = insert(name);
|
|
-
|
|
- if (wasInserted || isa<Undefined>(s))
|
|
- replaceSymbol<DylibSymbol>(s, file, name);
|
|
- return s;
|
|
-}
|
|
-
|
|
-Symbol *SymbolTable::addLazy(StringRef name, ArchiveFile *file,
|
|
- const llvm::object::Archive::Symbol &sym) {
|
|
- Symbol *s;
|
|
- bool wasInserted;
|
|
- std::tie(s, wasInserted) = insert(name);
|
|
-
|
|
- if (wasInserted)
|
|
- replaceSymbol<LazySymbol>(s, file, sym);
|
|
- else if (isa<Undefined>(s))
|
|
- file->fetch(sym);
|
|
- return s;
|
|
-}
|
|
-
|
|
-SymbolTable *macho::symtab;
|
|
diff --git a/lld/MachO/SymbolTable.h b/lld/MachO/SymbolTable.h
|
|
deleted file mode 100644
|
|
index 2379008db56..00000000000
|
|
--- a/lld/MachO/SymbolTable.h
|
|
+++ /dev/null
|
|
@@ -1,50 +0,0 @@
|
|
-//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_SYMBOL_TABLE_H
|
|
-#define LLD_MACHO_SYMBOL_TABLE_H
|
|
-
|
|
-#include "lld/Common/LLVM.h"
|
|
-#include "llvm/ADT/CachedHashString.h"
|
|
-#include "llvm/ADT/DenseMap.h"
|
|
-#include "llvm/Object/Archive.h"
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-class ArchiveFile;
|
|
-class DylibFile;
|
|
-class InputSection;
|
|
-class Symbol;
|
|
-
|
|
-class SymbolTable {
|
|
-public:
|
|
- Symbol *addDefined(StringRef name, InputSection *isec, uint32_t value);
|
|
-
|
|
- Symbol *addUndefined(StringRef name);
|
|
-
|
|
- Symbol *addDylib(StringRef name, DylibFile *file);
|
|
-
|
|
- Symbol *addLazy(StringRef name, ArchiveFile *file,
|
|
- const llvm::object::Archive::Symbol &sym);
|
|
-
|
|
- ArrayRef<Symbol *> getSymbols() const { return symVector; }
|
|
- Symbol *find(StringRef name);
|
|
-
|
|
-private:
|
|
- std::pair<Symbol *, bool> insert(StringRef name);
|
|
- llvm::DenseMap<llvm::CachedHashStringRef, int> symMap;
|
|
- std::vector<Symbol *> symVector;
|
|
-};
|
|
-
|
|
-extern SymbolTable *symtab;
|
|
-
|
|
-} // namespace macho
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/Symbols.cpp b/lld/MachO/Symbols.cpp
|
|
deleted file mode 100644
|
|
index fbafa8a92a4..00000000000
|
|
--- a/lld/MachO/Symbols.cpp
|
|
+++ /dev/null
|
|
@@ -1,23 +0,0 @@
|
|
-//===- Symbols.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 "Symbols.h"
|
|
-#include "InputFiles.h"
|
|
-
|
|
-using namespace llvm;
|
|
-using namespace lld;
|
|
-using namespace lld::macho;
|
|
-
|
|
-void LazySymbol::fetchArchiveMember() { file->fetch(sym); }
|
|
-
|
|
-// Returns a symbol for an error message.
|
|
-std::string lld::toString(const Symbol &sym) {
|
|
- if (Optional<std::string> s = demangleItanium(sym.getName()))
|
|
- return *s;
|
|
- return std::string(sym.getName());
|
|
-}
|
|
diff --git a/lld/MachO/Symbols.h b/lld/MachO/Symbols.h
|
|
deleted file mode 100644
|
|
index 63748ee4832..00000000000
|
|
--- a/lld/MachO/Symbols.h
|
|
+++ /dev/null
|
|
@@ -1,138 +0,0 @@
|
|
-//===- Symbols.h ------------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_SYMBOLS_H
|
|
-#define LLD_MACHO_SYMBOLS_H
|
|
-
|
|
-#include "InputSection.h"
|
|
-#include "Target.h"
|
|
-#include "lld/Common/ErrorHandler.h"
|
|
-#include "lld/Common/Strings.h"
|
|
-#include "llvm/Object/Archive.h"
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-class InputSection;
|
|
-class DylibFile;
|
|
-class ArchiveFile;
|
|
-
|
|
-struct StringRefZ {
|
|
- StringRefZ(const char *s) : data(s), size(-1) {}
|
|
- StringRefZ(StringRef s) : data(s.data()), size(s.size()) {}
|
|
-
|
|
- const char *data;
|
|
- const uint32_t size;
|
|
-};
|
|
-
|
|
-class Symbol {
|
|
-public:
|
|
- enum Kind {
|
|
- DefinedKind,
|
|
- UndefinedKind,
|
|
- DylibKind,
|
|
- LazyKind,
|
|
- };
|
|
-
|
|
- Kind kind() const { return static_cast<Kind>(symbolKind); }
|
|
-
|
|
- StringRef getName() const { return {name.data, name.size}; }
|
|
-
|
|
- uint64_t getVA() const;
|
|
-
|
|
- uint64_t getFileOffset() const;
|
|
-
|
|
- uint32_t gotIndex = UINT32_MAX;
|
|
-
|
|
-protected:
|
|
- Symbol(Kind k, StringRefZ name) : symbolKind(k), name(name) {}
|
|
-
|
|
- Kind symbolKind;
|
|
- StringRefZ name;
|
|
-};
|
|
-
|
|
-class Defined : public Symbol {
|
|
-public:
|
|
- Defined(StringRefZ name, InputSection *isec, uint32_t value)
|
|
- : Symbol(DefinedKind, name), isec(isec), value(value) {}
|
|
-
|
|
- InputSection *isec;
|
|
- uint32_t value;
|
|
-
|
|
- static bool classof(const Symbol *s) { return s->kind() == DefinedKind; }
|
|
-};
|
|
-
|
|
-class Undefined : public Symbol {
|
|
-public:
|
|
- Undefined(StringRefZ name) : Symbol(UndefinedKind, name) {}
|
|
-
|
|
- static bool classof(const Symbol *s) { return s->kind() == UndefinedKind; }
|
|
-};
|
|
-
|
|
-class DylibSymbol : public Symbol {
|
|
-public:
|
|
- DylibSymbol(DylibFile *file, StringRefZ name)
|
|
- : Symbol(DylibKind, name), file(file) {}
|
|
-
|
|
- static bool classof(const Symbol *s) { return s->kind() == DylibKind; }
|
|
-
|
|
- DylibFile *file;
|
|
- uint32_t stubsIndex = UINT32_MAX;
|
|
- uint32_t lazyBindOffset = UINT32_MAX;
|
|
-};
|
|
-
|
|
-class LazySymbol : public Symbol {
|
|
-public:
|
|
- LazySymbol(ArchiveFile *file, const llvm::object::Archive::Symbol &sym)
|
|
- : Symbol(LazyKind, sym.getName()), file(file), sym(sym) {}
|
|
-
|
|
- static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
|
|
-
|
|
- void fetchArchiveMember();
|
|
-
|
|
-private:
|
|
- ArchiveFile *file;
|
|
- const llvm::object::Archive::Symbol sym;
|
|
-};
|
|
-
|
|
-inline uint64_t Symbol::getVA() const {
|
|
- if (auto *d = dyn_cast<Defined>(this))
|
|
- return d->isec->getVA() + d->value;
|
|
- return 0;
|
|
-}
|
|
-
|
|
-inline uint64_t Symbol::getFileOffset() const {
|
|
- if (auto *d = dyn_cast<Defined>(this))
|
|
- return d->isec->getFileOffset() + d->value;
|
|
- llvm_unreachable("attempt to get an offset from an undefined symbol");
|
|
-}
|
|
-
|
|
-union SymbolUnion {
|
|
- alignas(Defined) char a[sizeof(Defined)];
|
|
- alignas(Undefined) char b[sizeof(Undefined)];
|
|
- alignas(DylibSymbol) char c[sizeof(DylibSymbol)];
|
|
- alignas(LazySymbol) char d[sizeof(LazySymbol)];
|
|
-};
|
|
-
|
|
-template <typename T, typename... ArgT>
|
|
-void replaceSymbol(Symbol *s, ArgT &&... arg) {
|
|
- static_assert(sizeof(T) <= sizeof(SymbolUnion), "SymbolUnion too small");
|
|
- static_assert(alignof(T) <= alignof(SymbolUnion),
|
|
- "SymbolUnion not aligned enough");
|
|
- assert(static_cast<Symbol *>(static_cast<T *>(nullptr)) == nullptr &&
|
|
- "Not a Symbol");
|
|
-
|
|
- new (s) T(std::forward<ArgT>(arg)...);
|
|
-}
|
|
-
|
|
-} // namespace macho
|
|
-
|
|
-std::string toString(const macho::Symbol &);
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
|
|
deleted file mode 100644
|
|
index cc0d5a93c40..00000000000
|
|
--- a/lld/MachO/SyntheticSections.cpp
|
|
+++ /dev/null
|
|
@@ -1,409 +0,0 @@
|
|
-//===- SyntheticSections.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 "SyntheticSections.h"
|
|
-#include "Config.h"
|
|
-#include "ExportTrie.h"
|
|
-#include "InputFiles.h"
|
|
-#include "MachOStructs.h"
|
|
-#include "MergedOutputSection.h"
|
|
-#include "OutputSegment.h"
|
|
-#include "SymbolTable.h"
|
|
-#include "Symbols.h"
|
|
-#include "Writer.h"
|
|
-
|
|
-#include "lld/Common/ErrorHandler.h"
|
|
-#include "lld/Common/Memory.h"
|
|
-#include "llvm/Support/EndianStream.h"
|
|
-#include "llvm/Support/LEB128.h"
|
|
-
|
|
-using namespace llvm;
|
|
-using namespace llvm::support;
|
|
-using namespace llvm::support::endian;
|
|
-using namespace lld;
|
|
-using namespace lld::macho;
|
|
-
|
|
-InStruct macho::in;
|
|
-std::vector<SyntheticSection *> macho::syntheticSections;
|
|
-
|
|
-SyntheticSection::SyntheticSection(const char *segname, const char *name)
|
|
- : OutputSection(SyntheticKind, name), segname(segname) {
|
|
- syntheticSections.push_back(this);
|
|
-}
|
|
-
|
|
-// dyld3's MachOLoaded::getSlide() assumes that the __TEXT segment starts
|
|
-// from the beginning of the file (i.e. the header).
|
|
-MachHeaderSection::MachHeaderSection()
|
|
- : SyntheticSection(segment_names::text, section_names::header) {}
|
|
-
|
|
-void MachHeaderSection::addLoadCommand(LoadCommand *lc) {
|
|
- loadCommands.push_back(lc);
|
|
- sizeOfCmds += lc->getSize();
|
|
-}
|
|
-
|
|
-uint64_t MachHeaderSection::getSize() const {
|
|
- return sizeof(MachO::mach_header_64) + sizeOfCmds;
|
|
-}
|
|
-
|
|
-void MachHeaderSection::writeTo(uint8_t *buf) const {
|
|
- auto *hdr = reinterpret_cast<MachO::mach_header_64 *>(buf);
|
|
- hdr->magic = MachO::MH_MAGIC_64;
|
|
- hdr->cputype = MachO::CPU_TYPE_X86_64;
|
|
- hdr->cpusubtype = MachO::CPU_SUBTYPE_X86_64_ALL | MachO::CPU_SUBTYPE_LIB64;
|
|
- hdr->filetype = config->outputType;
|
|
- hdr->ncmds = loadCommands.size();
|
|
- hdr->sizeofcmds = sizeOfCmds;
|
|
- hdr->flags = MachO::MH_NOUNDEFS | MachO::MH_DYLDLINK | MachO::MH_TWOLEVEL;
|
|
- if (config->outputType == MachO::MH_DYLIB && !config->hasReexports)
|
|
- hdr->flags |= MachO::MH_NO_REEXPORTED_DYLIBS;
|
|
-
|
|
- uint8_t *p = reinterpret_cast<uint8_t *>(hdr + 1);
|
|
- for (LoadCommand *lc : loadCommands) {
|
|
- lc->writeTo(p);
|
|
- p += lc->getSize();
|
|
- }
|
|
-}
|
|
-
|
|
-PageZeroSection::PageZeroSection()
|
|
- : SyntheticSection(segment_names::pageZero, section_names::pageZero) {}
|
|
-
|
|
-GotSection::GotSection()
|
|
- : SyntheticSection(segment_names::dataConst, section_names::got) {
|
|
- align = 8;
|
|
- flags = MachO::S_NON_LAZY_SYMBOL_POINTERS;
|
|
-
|
|
- // TODO: section_64::reserved1 should be an index into the indirect symbol
|
|
- // table, which we do not currently emit
|
|
-}
|
|
-
|
|
-void GotSection::addEntry(Symbol &sym) {
|
|
- if (entries.insert(&sym)) {
|
|
- sym.gotIndex = entries.size() - 1;
|
|
- }
|
|
-}
|
|
-
|
|
-void GotSection::writeTo(uint8_t *buf) const {
|
|
- for (size_t i = 0, n = entries.size(); i < n; ++i)
|
|
- if (auto *defined = dyn_cast<Defined>(entries[i]))
|
|
- write64le(&buf[i * WordSize], defined->getVA());
|
|
-}
|
|
-
|
|
-BindingSection::BindingSection()
|
|
- : SyntheticSection(segment_names::linkEdit, section_names::binding) {}
|
|
-
|
|
-bool BindingSection::isNeeded() const {
|
|
- return bindings.size() != 0 || in.got->isNeeded();
|
|
-}
|
|
-
|
|
-namespace {
|
|
-struct Binding {
|
|
- OutputSegment *segment = nullptr;
|
|
- uint64_t offset = 0;
|
|
- int64_t addend = 0;
|
|
- uint8_t ordinal = 0;
|
|
-};
|
|
-} // namespace
|
|
-
|
|
-// Encode a sequence of opcodes that tell dyld to write the address of dysym +
|
|
-// addend at osec->addr + outSecOff.
|
|
-//
|
|
-// The bind opcode "interpreter" remembers the values of each binding field, so
|
|
-// we only need to encode the differences between bindings. Hence the use of
|
|
-// lastBinding.
|
|
-static void encodeBinding(const DylibSymbol &dysym, const OutputSection *osec,
|
|
- uint64_t outSecOff, int64_t addend,
|
|
- Binding &lastBinding, raw_svector_ostream &os) {
|
|
- using namespace llvm::MachO;
|
|
- OutputSegment *seg = osec->parent;
|
|
- uint64_t offset = osec->getSegmentOffset() + outSecOff;
|
|
- if (lastBinding.segment != seg) {
|
|
- os << static_cast<uint8_t>(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB |
|
|
- seg->index);
|
|
- encodeULEB128(offset, os);
|
|
- lastBinding.segment = seg;
|
|
- lastBinding.offset = offset;
|
|
- } else if (lastBinding.offset != offset) {
|
|
- assert(lastBinding.offset <= offset);
|
|
- os << static_cast<uint8_t>(BIND_OPCODE_ADD_ADDR_ULEB);
|
|
- encodeULEB128(offset - lastBinding.offset, os);
|
|
- lastBinding.offset = offset;
|
|
- }
|
|
-
|
|
- if (lastBinding.ordinal != dysym.file->ordinal) {
|
|
- if (dysym.file->ordinal <= BIND_IMMEDIATE_MASK) {
|
|
- os << static_cast<uint8_t>(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM |
|
|
- dysym.file->ordinal);
|
|
- } else {
|
|
- error("TODO: Support larger dylib symbol ordinals");
|
|
- return;
|
|
- }
|
|
- lastBinding.ordinal = dysym.file->ordinal;
|
|
- }
|
|
-
|
|
- if (lastBinding.addend != addend) {
|
|
- os << static_cast<uint8_t>(BIND_OPCODE_SET_ADDEND_SLEB);
|
|
- encodeSLEB128(addend, os);
|
|
- lastBinding.addend = addend;
|
|
- }
|
|
-
|
|
- os << static_cast<uint8_t>(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM)
|
|
- << dysym.getName() << '\0'
|
|
- << static_cast<uint8_t>(BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER)
|
|
- << static_cast<uint8_t>(BIND_OPCODE_DO_BIND);
|
|
- // DO_BIND causes dyld to both perform the binding and increment the offset
|
|
- lastBinding.offset += WordSize;
|
|
-}
|
|
-
|
|
-// Emit bind opcodes, which are a stream of byte-sized opcodes that dyld
|
|
-// interprets to update a record with the following fields:
|
|
-// * segment index (of the segment to write the symbol addresses to, typically
|
|
-// the __DATA_CONST segment which contains the GOT)
|
|
-// * offset within the segment, indicating the next location to write a binding
|
|
-// * symbol type
|
|
-// * symbol library ordinal (the index of its library's LC_LOAD_DYLIB command)
|
|
-// * symbol name
|
|
-// * addend
|
|
-// When dyld sees BIND_OPCODE_DO_BIND, it uses the current record state to bind
|
|
-// a symbol in the GOT, and increments the segment offset to point to the next
|
|
-// entry. It does *not* clear the record state after doing the bind, so
|
|
-// subsequent opcodes only need to encode the differences between bindings.
|
|
-void BindingSection::finalizeContents() {
|
|
- raw_svector_ostream os{contents};
|
|
- Binding lastBinding;
|
|
- bool didEncode = false;
|
|
- size_t gotIdx = 0;
|
|
- for (const Symbol *sym : in.got->getEntries()) {
|
|
- if (const auto *dysym = dyn_cast<DylibSymbol>(sym)) {
|
|
- didEncode = true;
|
|
- encodeBinding(*dysym, in.got, gotIdx * WordSize, 0, lastBinding, os);
|
|
- }
|
|
- ++gotIdx;
|
|
- }
|
|
-
|
|
- // Sorting the relocations by segment and address allows us to encode them
|
|
- // more compactly.
|
|
- llvm::sort(bindings, [](const BindingEntry &a, const BindingEntry &b) {
|
|
- OutputSegment *segA = a.isec->parent->parent;
|
|
- OutputSegment *segB = b.isec->parent->parent;
|
|
- if (segA != segB)
|
|
- return segA->fileOff < segB->fileOff;
|
|
- OutputSection *osecA = a.isec->parent;
|
|
- OutputSection *osecB = b.isec->parent;
|
|
- if (osecA != osecB)
|
|
- return osecA->addr < osecB->addr;
|
|
- if (a.isec != b.isec)
|
|
- return a.isec->outSecOff < b.isec->outSecOff;
|
|
- return a.offset < b.offset;
|
|
- });
|
|
- for (const BindingEntry &b : bindings) {
|
|
- didEncode = true;
|
|
- encodeBinding(*b.dysym, b.isec->parent, b.isec->outSecOff + b.offset,
|
|
- b.addend, lastBinding, os);
|
|
- }
|
|
- if (didEncode)
|
|
- os << static_cast<uint8_t>(MachO::BIND_OPCODE_DONE);
|
|
-}
|
|
-
|
|
-void BindingSection::writeTo(uint8_t *buf) const {
|
|
- memcpy(buf, contents.data(), contents.size());
|
|
-}
|
|
-
|
|
-StubsSection::StubsSection()
|
|
- : SyntheticSection(segment_names::text, "__stubs") {}
|
|
-
|
|
-uint64_t StubsSection::getSize() const {
|
|
- return entries.size() * target->stubSize;
|
|
-}
|
|
-
|
|
-void StubsSection::writeTo(uint8_t *buf) const {
|
|
- size_t off = 0;
|
|
- for (const DylibSymbol *sym : in.stubs->getEntries()) {
|
|
- target->writeStub(buf + off, *sym);
|
|
- off += target->stubSize;
|
|
- }
|
|
-}
|
|
-
|
|
-void StubsSection::addEntry(DylibSymbol &sym) {
|
|
- if (entries.insert(&sym))
|
|
- sym.stubsIndex = entries.size() - 1;
|
|
-}
|
|
-
|
|
-StubHelperSection::StubHelperSection()
|
|
- : SyntheticSection(segment_names::text, "__stub_helper") {}
|
|
-
|
|
-uint64_t StubHelperSection::getSize() const {
|
|
- return target->stubHelperHeaderSize +
|
|
- in.stubs->getEntries().size() * target->stubHelperEntrySize;
|
|
-}
|
|
-
|
|
-bool StubHelperSection::isNeeded() const {
|
|
- return !in.stubs->getEntries().empty();
|
|
-}
|
|
-
|
|
-void StubHelperSection::writeTo(uint8_t *buf) const {
|
|
- target->writeStubHelperHeader(buf);
|
|
- size_t off = target->stubHelperHeaderSize;
|
|
- for (const DylibSymbol *sym : in.stubs->getEntries()) {
|
|
- target->writeStubHelperEntry(buf + off, *sym, addr + off);
|
|
- off += target->stubHelperEntrySize;
|
|
- }
|
|
-}
|
|
-
|
|
-void StubHelperSection::setup() {
|
|
- stubBinder = dyn_cast_or_null<DylibSymbol>(symtab->find("dyld_stub_binder"));
|
|
- if (stubBinder == nullptr) {
|
|
- error("symbol dyld_stub_binder not found (normally in libSystem.dylib). "
|
|
- "Needed to perform lazy binding.");
|
|
- return;
|
|
- }
|
|
- in.got->addEntry(*stubBinder);
|
|
-
|
|
- inputSections.push_back(in.imageLoaderCache);
|
|
- symtab->addDefined("__dyld_private", in.imageLoaderCache, 0);
|
|
-}
|
|
-
|
|
-ImageLoaderCacheSection::ImageLoaderCacheSection() {
|
|
- segname = segment_names::data;
|
|
- name = "__data";
|
|
- uint8_t *arr = bAlloc.Allocate<uint8_t>(WordSize);
|
|
- memset(arr, 0, WordSize);
|
|
- data = {arr, WordSize};
|
|
-}
|
|
-
|
|
-LazyPointerSection::LazyPointerSection()
|
|
- : SyntheticSection(segment_names::data, "__la_symbol_ptr") {
|
|
- align = 8;
|
|
- flags = MachO::S_LAZY_SYMBOL_POINTERS;
|
|
-}
|
|
-
|
|
-uint64_t LazyPointerSection::getSize() const {
|
|
- return in.stubs->getEntries().size() * WordSize;
|
|
-}
|
|
-
|
|
-bool LazyPointerSection::isNeeded() const {
|
|
- return !in.stubs->getEntries().empty();
|
|
-}
|
|
-
|
|
-void LazyPointerSection::writeTo(uint8_t *buf) const {
|
|
- size_t off = 0;
|
|
- for (const DylibSymbol *sym : in.stubs->getEntries()) {
|
|
- uint64_t stubHelperOffset = target->stubHelperHeaderSize +
|
|
- sym->stubsIndex * target->stubHelperEntrySize;
|
|
- write64le(buf + off, in.stubHelper->addr + stubHelperOffset);
|
|
- off += WordSize;
|
|
- }
|
|
-}
|
|
-
|
|
-LazyBindingSection::LazyBindingSection()
|
|
- : SyntheticSection(segment_names::linkEdit, section_names::lazyBinding) {}
|
|
-
|
|
-bool LazyBindingSection::isNeeded() const { return in.stubs->isNeeded(); }
|
|
-
|
|
-void LazyBindingSection::finalizeContents() {
|
|
- // TODO: Just precompute output size here instead of writing to a temporary
|
|
- // buffer
|
|
- for (DylibSymbol *sym : in.stubs->getEntries())
|
|
- sym->lazyBindOffset = encode(*sym);
|
|
-}
|
|
-
|
|
-void LazyBindingSection::writeTo(uint8_t *buf) const {
|
|
- memcpy(buf, contents.data(), contents.size());
|
|
-}
|
|
-
|
|
-// Unlike the non-lazy binding section, the bind opcodes in this section aren't
|
|
-// interpreted all at once. Rather, dyld will start interpreting opcodes at a
|
|
-// given offset, typically only binding a single symbol before it finds a
|
|
-// BIND_OPCODE_DONE terminator. As such, unlike in the non-lazy-binding case,
|
|
-// we cannot encode just the differences between symbols; we have to emit the
|
|
-// complete bind information for each symbol.
|
|
-uint32_t LazyBindingSection::encode(const DylibSymbol &sym) {
|
|
- uint32_t opstreamOffset = contents.size();
|
|
- OutputSegment *dataSeg = in.lazyPointers->parent;
|
|
- os << static_cast<uint8_t>(MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB |
|
|
- dataSeg->index);
|
|
- uint64_t offset = in.lazyPointers->addr - dataSeg->firstSection()->addr +
|
|
- sym.stubsIndex * WordSize;
|
|
- encodeULEB128(offset, os);
|
|
- if (sym.file->ordinal <= MachO::BIND_IMMEDIATE_MASK)
|
|
- os << static_cast<uint8_t>(MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM |
|
|
- sym.file->ordinal);
|
|
- else
|
|
- fatal("TODO: Support larger dylib symbol ordinals");
|
|
-
|
|
- os << static_cast<uint8_t>(MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM)
|
|
- << sym.getName() << '\0'
|
|
- << static_cast<uint8_t>(MachO::BIND_OPCODE_DO_BIND)
|
|
- << static_cast<uint8_t>(MachO::BIND_OPCODE_DONE);
|
|
- return opstreamOffset;
|
|
-}
|
|
-
|
|
-ExportSection::ExportSection()
|
|
- : SyntheticSection(segment_names::linkEdit, section_names::export_) {}
|
|
-
|
|
-void ExportSection::finalizeContents() {
|
|
- // TODO: We should check symbol visibility.
|
|
- for (const Symbol *sym : symtab->getSymbols())
|
|
- if (auto *defined = dyn_cast<Defined>(sym))
|
|
- trieBuilder.addSymbol(*defined);
|
|
- size = trieBuilder.build();
|
|
-}
|
|
-
|
|
-void ExportSection::writeTo(uint8_t *buf) const { trieBuilder.writeTo(buf); }
|
|
-
|
|
-SymtabSection::SymtabSection(StringTableSection &stringTableSection)
|
|
- : SyntheticSection(segment_names::linkEdit, section_names::symbolTable),
|
|
- stringTableSection(stringTableSection) {
|
|
- // TODO: When we introduce the SyntheticSections superclass, we should make
|
|
- // all synthetic sections aligned to WordSize by default.
|
|
- align = WordSize;
|
|
-}
|
|
-
|
|
-uint64_t SymtabSection::getSize() const {
|
|
- return symbols.size() * sizeof(structs::nlist_64);
|
|
-}
|
|
-
|
|
-void SymtabSection::finalizeContents() {
|
|
- // TODO support other symbol types
|
|
- for (Symbol *sym : symtab->getSymbols())
|
|
- if (isa<Defined>(sym))
|
|
- symbols.push_back({sym, stringTableSection.addString(sym->getName())});
|
|
-}
|
|
-
|
|
-void SymtabSection::writeTo(uint8_t *buf) const {
|
|
- auto *nList = reinterpret_cast<structs::nlist_64 *>(buf);
|
|
- for (const SymtabEntry &entry : symbols) {
|
|
- nList->n_strx = entry.strx;
|
|
- // TODO support other symbol types
|
|
- // TODO populate n_desc
|
|
- if (auto *defined = dyn_cast<Defined>(entry.sym)) {
|
|
- nList->n_type = MachO::N_EXT | MachO::N_SECT;
|
|
- nList->n_sect = defined->isec->parent->index;
|
|
- // For the N_SECT symbol type, n_value is the address of the symbol
|
|
- nList->n_value = defined->value + defined->isec->getVA();
|
|
- }
|
|
- ++nList;
|
|
- }
|
|
-}
|
|
-
|
|
-StringTableSection::StringTableSection()
|
|
- : SyntheticSection(segment_names::linkEdit, section_names::stringTable) {}
|
|
-
|
|
-uint32_t StringTableSection::addString(StringRef str) {
|
|
- uint32_t strx = size;
|
|
- strings.push_back(str);
|
|
- size += str.size() + 1; // account for null terminator
|
|
- return strx;
|
|
-}
|
|
-
|
|
-void StringTableSection::writeTo(uint8_t *buf) const {
|
|
- uint32_t off = 0;
|
|
- for (StringRef str : strings) {
|
|
- memcpy(buf + off, str.data(), str.size());
|
|
- off += str.size() + 1; // account for null terminator
|
|
- }
|
|
-}
|
|
diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h
|
|
deleted file mode 100644
|
|
index a8fbf6c8a26..00000000000
|
|
--- a/lld/MachO/SyntheticSections.h
|
|
+++ /dev/null
|
|
@@ -1,290 +0,0 @@
|
|
-//===- SyntheticSections.h -------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_SYNTHETIC_SECTIONS_H
|
|
-#define LLD_MACHO_SYNTHETIC_SECTIONS_H
|
|
-
|
|
-#include "Config.h"
|
|
-#include "ExportTrie.h"
|
|
-#include "InputSection.h"
|
|
-#include "OutputSection.h"
|
|
-#include "Target.h"
|
|
-
|
|
-#include "llvm/ADT/SetVector.h"
|
|
-#include "llvm/Support/raw_ostream.h"
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-namespace section_names {
|
|
-
|
|
-constexpr const char pageZero[] = "__pagezero";
|
|
-constexpr const char header[] = "__mach_header";
|
|
-constexpr const char binding[] = "__binding";
|
|
-constexpr const char lazyBinding[] = "__lazy_binding";
|
|
-constexpr const char export_[] = "__export";
|
|
-constexpr const char symbolTable[] = "__symbol_table";
|
|
-constexpr const char stringTable[] = "__string_table";
|
|
-constexpr const char got[] = "__got";
|
|
-
|
|
-} // namespace section_names
|
|
-
|
|
-class DylibSymbol;
|
|
-class LoadCommand;
|
|
-
|
|
-class SyntheticSection : public OutputSection {
|
|
-public:
|
|
- SyntheticSection(const char *segname, const char *name);
|
|
- virtual ~SyntheticSection() = default;
|
|
-
|
|
- static bool classof(const OutputSection *sec) {
|
|
- return sec->kind() == SyntheticKind;
|
|
- }
|
|
-
|
|
- const StringRef segname;
|
|
-};
|
|
-
|
|
-// The header of the Mach-O file, which must have a file offset of zero.
|
|
-class MachHeaderSection : public SyntheticSection {
|
|
-public:
|
|
- MachHeaderSection();
|
|
- void addLoadCommand(LoadCommand *);
|
|
- bool isHidden() const override { return true; }
|
|
- uint64_t getSize() const override;
|
|
- void writeTo(uint8_t *buf) const override;
|
|
-
|
|
-private:
|
|
- std::vector<LoadCommand *> loadCommands;
|
|
- uint32_t sizeOfCmds = 0;
|
|
-};
|
|
-
|
|
-// A hidden section that exists solely for the purpose of creating the
|
|
-// __PAGEZERO segment, which is used to catch null pointer dereferences.
|
|
-class PageZeroSection : public SyntheticSection {
|
|
-public:
|
|
- PageZeroSection();
|
|
- bool isHidden() const override { return true; }
|
|
- uint64_t getSize() const override { return PageZeroSize; }
|
|
- uint64_t getFileSize() const override { return 0; }
|
|
- void writeTo(uint8_t *buf) const override {}
|
|
-};
|
|
-
|
|
-// This section will be populated by dyld with addresses to non-lazily-loaded
|
|
-// dylib symbols.
|
|
-class GotSection : public SyntheticSection {
|
|
-public:
|
|
- GotSection();
|
|
-
|
|
- const llvm::SetVector<const Symbol *> &getEntries() const { return entries; }
|
|
-
|
|
- bool isNeeded() const override { return !entries.empty(); }
|
|
-
|
|
- uint64_t getSize() const override { return entries.size() * WordSize; }
|
|
-
|
|
- void writeTo(uint8_t *buf) const override;
|
|
-
|
|
- void addEntry(Symbol &sym);
|
|
-
|
|
-private:
|
|
- llvm::SetVector<const Symbol *> entries;
|
|
-};
|
|
-
|
|
-struct BindingEntry {
|
|
- const DylibSymbol *dysym;
|
|
- const InputSection *isec;
|
|
- uint64_t offset;
|
|
- int64_t addend;
|
|
- BindingEntry(const DylibSymbol *dysym, const InputSection *isec,
|
|
- uint64_t offset, int64_t addend)
|
|
- : dysym(dysym), isec(isec), offset(offset), addend(addend) {}
|
|
-};
|
|
-
|
|
-// Stores bind opcodes for telling dyld which symbols to load non-lazily.
|
|
-class BindingSection : public SyntheticSection {
|
|
-public:
|
|
- BindingSection();
|
|
- void finalizeContents();
|
|
- uint64_t getSize() const override { return contents.size(); }
|
|
- // Like other sections in __LINKEDIT, the binding section is special: its
|
|
- // offsets are recorded in the LC_DYLD_INFO_ONLY load command, instead of in
|
|
- // section headers.
|
|
- bool isHidden() const override { return true; }
|
|
- bool isNeeded() const override;
|
|
- void writeTo(uint8_t *buf) const override;
|
|
-
|
|
- void addEntry(const DylibSymbol *dysym, const InputSection *isec,
|
|
- uint64_t offset, int64_t addend) {
|
|
- bindings.emplace_back(dysym, isec, offset, addend);
|
|
- }
|
|
-
|
|
-private:
|
|
- std::vector<BindingEntry> bindings;
|
|
- SmallVector<char, 128> contents;
|
|
-};
|
|
-
|
|
-// The following sections implement lazy symbol binding -- very similar to the
|
|
-// PLT mechanism in ELF.
|
|
-//
|
|
-// ELF's .plt section is broken up into two sections in Mach-O: StubsSection and
|
|
-// StubHelperSection. Calls to functions in dylibs will end up calling into
|
|
-// StubsSection, which contains indirect jumps to addresses stored in the
|
|
-// LazyPointerSection (the counterpart to ELF's .plt.got).
|
|
-//
|
|
-// Initially, the LazyPointerSection contains addresses that point into one of
|
|
-// the entry points in the middle of the StubHelperSection. The code in
|
|
-// StubHelperSection will push on the stack an offset into the
|
|
-// LazyBindingSection. The push is followed by a jump to the beginning of the
|
|
-// StubHelperSection (similar to PLT0), which then calls into dyld_stub_binder.
|
|
-// dyld_stub_binder is a non-lazily-bound symbol, so this call looks it up in
|
|
-// the GOT.
|
|
-//
|
|
-// The stub binder will look up the bind opcodes in the LazyBindingSection at
|
|
-// the given offset. The bind opcodes will tell the binder to update the address
|
|
-// in the LazyPointerSection to point to the symbol, so that subsequent calls
|
|
-// don't have to redo the symbol resolution. The binder will then jump to the
|
|
-// resolved symbol.
|
|
-
|
|
-class StubsSection : public SyntheticSection {
|
|
-public:
|
|
- StubsSection();
|
|
- uint64_t getSize() const override;
|
|
- bool isNeeded() const override { return !entries.empty(); }
|
|
- void writeTo(uint8_t *buf) const override;
|
|
-
|
|
- const llvm::SetVector<DylibSymbol *> &getEntries() const { return entries; }
|
|
-
|
|
- void addEntry(DylibSymbol &sym);
|
|
-
|
|
-private:
|
|
- llvm::SetVector<DylibSymbol *> entries;
|
|
-};
|
|
-
|
|
-class StubHelperSection : public SyntheticSection {
|
|
-public:
|
|
- StubHelperSection();
|
|
- uint64_t getSize() const override;
|
|
- bool isNeeded() const override;
|
|
- void writeTo(uint8_t *buf) const override;
|
|
-
|
|
- void setup();
|
|
-
|
|
- DylibSymbol *stubBinder = nullptr;
|
|
-};
|
|
-
|
|
-// This section contains space for just a single word, and will be used by dyld
|
|
-// to cache an address to the image loader it uses. Note that unlike the other
|
|
-// synthetic sections, which are OutputSections, the ImageLoaderCacheSection is
|
|
-// an InputSection that gets merged into the __data OutputSection.
|
|
-class ImageLoaderCacheSection : public InputSection {
|
|
-public:
|
|
- ImageLoaderCacheSection();
|
|
- uint64_t getSize() const override { return WordSize; }
|
|
-};
|
|
-
|
|
-class LazyPointerSection : public SyntheticSection {
|
|
-public:
|
|
- LazyPointerSection();
|
|
- uint64_t getSize() const override;
|
|
- bool isNeeded() const override;
|
|
- void writeTo(uint8_t *buf) const override;
|
|
-};
|
|
-
|
|
-class LazyBindingSection : public SyntheticSection {
|
|
-public:
|
|
- LazyBindingSection();
|
|
- void finalizeContents();
|
|
- uint64_t getSize() const override { return contents.size(); }
|
|
- uint32_t encode(const DylibSymbol &);
|
|
- // Like other sections in __LINKEDIT, the lazy binding section is special: its
|
|
- // offsets are recorded in the LC_DYLD_INFO_ONLY load command, instead of in
|
|
- // section headers.
|
|
- bool isHidden() const override { return true; }
|
|
- bool isNeeded() const override;
|
|
- void writeTo(uint8_t *buf) const override;
|
|
-
|
|
-private:
|
|
- SmallVector<char, 128> contents;
|
|
- llvm::raw_svector_ostream os{contents};
|
|
-};
|
|
-
|
|
-// Stores a trie that describes the set of exported symbols.
|
|
-class ExportSection : public SyntheticSection {
|
|
-public:
|
|
- ExportSection();
|
|
- void finalizeContents();
|
|
- uint64_t getSize() const override { return size; }
|
|
- // Like other sections in __LINKEDIT, the export section is special: its
|
|
- // offsets are recorded in the LC_DYLD_INFO_ONLY load command, instead of in
|
|
- // section headers.
|
|
- bool isHidden() const override { return true; }
|
|
- void writeTo(uint8_t *buf) const override;
|
|
-
|
|
-private:
|
|
- TrieBuilder trieBuilder;
|
|
- size_t size = 0;
|
|
-};
|
|
-
|
|
-// Stores the strings referenced by the symbol table.
|
|
-class StringTableSection : public SyntheticSection {
|
|
-public:
|
|
- StringTableSection();
|
|
- // Returns the start offset of the added string.
|
|
- uint32_t addString(StringRef);
|
|
- uint64_t getSize() const override { return size; }
|
|
- // Like other sections in __LINKEDIT, the string table section is special: its
|
|
- // offsets are recorded in the LC_SYMTAB load command, instead of in section
|
|
- // headers.
|
|
- bool isHidden() const override { return true; }
|
|
- void writeTo(uint8_t *buf) const override;
|
|
-
|
|
-private:
|
|
- // An n_strx value of 0 always indicates the empty string, so we must locate
|
|
- // our non-empty string values at positive offsets in the string table.
|
|
- // Therefore we insert a dummy value at position zero.
|
|
- std::vector<StringRef> strings{"\0"};
|
|
- size_t size = 1;
|
|
-};
|
|
-
|
|
-struct SymtabEntry {
|
|
- Symbol *sym;
|
|
- size_t strx;
|
|
-};
|
|
-
|
|
-class SymtabSection : public SyntheticSection {
|
|
-public:
|
|
- SymtabSection(StringTableSection &);
|
|
- void finalizeContents();
|
|
- size_t getNumSymbols() const { return symbols.size(); }
|
|
- uint64_t getSize() const override;
|
|
- // Like other sections in __LINKEDIT, the symtab section is special: its
|
|
- // offsets are recorded in the LC_SYMTAB load command, instead of in section
|
|
- // headers.
|
|
- bool isHidden() const override { return true; }
|
|
- void writeTo(uint8_t *buf) const override;
|
|
-
|
|
-private:
|
|
- StringTableSection &stringTableSection;
|
|
- std::vector<SymtabEntry> symbols;
|
|
-};
|
|
-
|
|
-struct InStruct {
|
|
- BindingSection *binding = nullptr;
|
|
- GotSection *got = nullptr;
|
|
- LazyPointerSection *lazyPointers = nullptr;
|
|
- StubsSection *stubs = nullptr;
|
|
- StubHelperSection *stubHelper = nullptr;
|
|
- ImageLoaderCacheSection *imageLoaderCache = nullptr;
|
|
-};
|
|
-
|
|
-extern InStruct in;
|
|
-extern std::vector<SyntheticSection *> syntheticSections;
|
|
-
|
|
-} // namespace macho
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/Target.cpp b/lld/MachO/Target.cpp
|
|
deleted file mode 100644
|
|
index 0f70776a507..00000000000
|
|
--- a/lld/MachO/Target.cpp
|
|
+++ /dev/null
|
|
@@ -1,14 +0,0 @@
|
|
-//===- Target.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 "Target.h"
|
|
-
|
|
-using namespace lld;
|
|
-using namespace lld::macho;
|
|
-
|
|
-TargetInfo *macho::target = nullptr;
|
|
diff --git a/lld/MachO/Target.h b/lld/MachO/Target.h
|
|
deleted file mode 100644
|
|
index 8ea1bde1230..00000000000
|
|
--- a/lld/MachO/Target.h
|
|
+++ /dev/null
|
|
@@ -1,75 +0,0 @@
|
|
-//===- Target.h -------------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_TARGET_H
|
|
-#define LLD_MACHO_TARGET_H
|
|
-
|
|
-#include "llvm/BinaryFormat/MachO.h"
|
|
-#include "llvm/Support/MemoryBuffer.h"
|
|
-
|
|
-#include <cstddef>
|
|
-#include <cstdint>
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-class Symbol;
|
|
-class DylibSymbol;
|
|
-class InputSection;
|
|
-struct Reloc;
|
|
-
|
|
-enum : uint64_t {
|
|
- // We are currently only supporting 64-bit targets since macOS and iOS are
|
|
- // deprecating 32-bit apps.
|
|
- WordSize = 8,
|
|
- PageSize = 4096,
|
|
- PageZeroSize = 1ull << 32, // XXX should be 4096 for 32-bit targets
|
|
- MaxAlignmentPowerOf2 = 32,
|
|
-};
|
|
-
|
|
-class TargetInfo {
|
|
-public:
|
|
- virtual ~TargetInfo() = default;
|
|
-
|
|
- // Validate the relocation structure and get its addend.
|
|
- virtual uint64_t
|
|
- getImplicitAddend(llvm::MemoryBufferRef, const llvm::MachO::section_64 &,
|
|
- const llvm::MachO::relocation_info &) const = 0;
|
|
- virtual void relocateOne(uint8_t *loc, const Reloc &, uint64_t val) const = 0;
|
|
-
|
|
- // Write code for lazy binding. See the comments on StubsSection for more
|
|
- // details.
|
|
- virtual void writeStub(uint8_t *buf, const DylibSymbol &) const = 0;
|
|
- virtual void writeStubHelperHeader(uint8_t *buf) const = 0;
|
|
- virtual void writeStubHelperEntry(uint8_t *buf, const DylibSymbol &,
|
|
- uint64_t entryAddr) const = 0;
|
|
-
|
|
- // Symbols may be referenced via either the GOT or the stubs section,
|
|
- // depending on the relocation type. prepareSymbolRelocation() will set up the
|
|
- // GOT/stubs entries, and getSymbolVA() will return the addresses of those
|
|
- // entries.
|
|
- virtual void prepareSymbolRelocation(Symbol &, const InputSection *,
|
|
- const Reloc &) = 0;
|
|
- virtual uint64_t getSymbolVA(const Symbol &, uint8_t type) const = 0;
|
|
-
|
|
- uint32_t cpuType;
|
|
- uint32_t cpuSubtype;
|
|
-
|
|
- size_t stubSize;
|
|
- size_t stubHelperHeaderSize;
|
|
- size_t stubHelperEntrySize;
|
|
-};
|
|
-
|
|
-TargetInfo *createX86_64TargetInfo();
|
|
-
|
|
-extern TargetInfo *target;
|
|
-
|
|
-} // namespace macho
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
|
|
deleted file mode 100644
|
|
index 03000a7f437..00000000000
|
|
--- a/lld/MachO/Writer.cpp
|
|
+++ /dev/null
|
|
@@ -1,542 +0,0 @@
|
|
-//===- Writer.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 "Writer.h"
|
|
-#include "Config.h"
|
|
-#include "InputFiles.h"
|
|
-#include "InputSection.h"
|
|
-#include "MergedOutputSection.h"
|
|
-#include "OutputSection.h"
|
|
-#include "OutputSegment.h"
|
|
-#include "SymbolTable.h"
|
|
-#include "Symbols.h"
|
|
-#include "SyntheticSections.h"
|
|
-#include "Target.h"
|
|
-
|
|
-#include "lld/Common/ErrorHandler.h"
|
|
-#include "lld/Common/Memory.h"
|
|
-#include "llvm/BinaryFormat/MachO.h"
|
|
-#include "llvm/Support/LEB128.h"
|
|
-#include "llvm/Support/MathExtras.h"
|
|
-#include "llvm/Support/Path.h"
|
|
-
|
|
-using namespace llvm;
|
|
-using namespace llvm::MachO;
|
|
-using namespace lld;
|
|
-using namespace lld::macho;
|
|
-
|
|
-namespace {
|
|
-class LCLinkEdit;
|
|
-class LCDyldInfo;
|
|
-class LCSymtab;
|
|
-
|
|
-class Writer {
|
|
-public:
|
|
- Writer() : buffer(errorHandler().outputBuffer) {}
|
|
-
|
|
- void scanRelocations();
|
|
- void createOutputSections();
|
|
- void createLoadCommands();
|
|
- void assignAddresses(OutputSegment *);
|
|
- void createSymtabContents();
|
|
-
|
|
- void openFile();
|
|
- void writeSections();
|
|
-
|
|
- void run();
|
|
-
|
|
- std::unique_ptr<FileOutputBuffer> &buffer;
|
|
- uint64_t addr = 0;
|
|
- uint64_t fileOff = 0;
|
|
- MachHeaderSection *headerSection = nullptr;
|
|
- LazyBindingSection *lazyBindingSection = nullptr;
|
|
- ExportSection *exportSection = nullptr;
|
|
- StringTableSection *stringTableSection = nullptr;
|
|
- SymtabSection *symtabSection = nullptr;
|
|
-};
|
|
-
|
|
-// LC_DYLD_INFO_ONLY stores the offsets of symbol import/export information.
|
|
-class LCDyldInfo : public LoadCommand {
|
|
-public:
|
|
- LCDyldInfo(BindingSection *bindingSection,
|
|
- LazyBindingSection *lazyBindingSection,
|
|
- ExportSection *exportSection)
|
|
- : bindingSection(bindingSection), lazyBindingSection(lazyBindingSection),
|
|
- exportSection(exportSection) {}
|
|
-
|
|
- uint32_t getSize() const override { return sizeof(dyld_info_command); }
|
|
-
|
|
- void writeTo(uint8_t *buf) const override {
|
|
- auto *c = reinterpret_cast<dyld_info_command *>(buf);
|
|
- c->cmd = LC_DYLD_INFO_ONLY;
|
|
- c->cmdsize = getSize();
|
|
- if (bindingSection->isNeeded()) {
|
|
- c->bind_off = bindingSection->fileOff;
|
|
- c->bind_size = bindingSection->getFileSize();
|
|
- }
|
|
- if (lazyBindingSection->isNeeded()) {
|
|
- c->lazy_bind_off = lazyBindingSection->fileOff;
|
|
- c->lazy_bind_size = lazyBindingSection->getFileSize();
|
|
- }
|
|
- if (exportSection->isNeeded()) {
|
|
- c->export_off = exportSection->fileOff;
|
|
- c->export_size = exportSection->getFileSize();
|
|
- }
|
|
- }
|
|
-
|
|
- BindingSection *bindingSection;
|
|
- LazyBindingSection *lazyBindingSection;
|
|
- ExportSection *exportSection;
|
|
-};
|
|
-
|
|
-class LCDysymtab : public LoadCommand {
|
|
-public:
|
|
- uint32_t getSize() const override { return sizeof(dysymtab_command); }
|
|
-
|
|
- void writeTo(uint8_t *buf) const override {
|
|
- auto *c = reinterpret_cast<dysymtab_command *>(buf);
|
|
- c->cmd = LC_DYSYMTAB;
|
|
- c->cmdsize = getSize();
|
|
- }
|
|
-};
|
|
-
|
|
-class LCSegment : public LoadCommand {
|
|
-public:
|
|
- LCSegment(StringRef name, OutputSegment *seg) : name(name), seg(seg) {}
|
|
-
|
|
- uint32_t getSize() const override {
|
|
- return sizeof(segment_command_64) +
|
|
- seg->numNonHiddenSections() * sizeof(section_64);
|
|
- }
|
|
-
|
|
- void writeTo(uint8_t *buf) const override {
|
|
- auto *c = reinterpret_cast<segment_command_64 *>(buf);
|
|
- buf += sizeof(segment_command_64);
|
|
-
|
|
- c->cmd = LC_SEGMENT_64;
|
|
- c->cmdsize = getSize();
|
|
- memcpy(c->segname, name.data(), name.size());
|
|
- c->fileoff = seg->fileOff;
|
|
- c->maxprot = seg->maxProt;
|
|
- c->initprot = seg->initProt;
|
|
-
|
|
- if (seg->getSections().empty())
|
|
- return;
|
|
-
|
|
- c->vmaddr = seg->firstSection()->addr;
|
|
- c->vmsize =
|
|
- seg->lastSection()->addr + seg->lastSection()->getSize() - c->vmaddr;
|
|
- c->nsects = seg->numNonHiddenSections();
|
|
-
|
|
- for (OutputSection *osec : seg->getSections()) {
|
|
- c->filesize += osec->getFileSize();
|
|
-
|
|
- if (osec->isHidden())
|
|
- continue;
|
|
-
|
|
- auto *sectHdr = reinterpret_cast<section_64 *>(buf);
|
|
- buf += sizeof(section_64);
|
|
-
|
|
- memcpy(sectHdr->sectname, osec->name.data(), osec->name.size());
|
|
- memcpy(sectHdr->segname, name.data(), name.size());
|
|
-
|
|
- sectHdr->addr = osec->addr;
|
|
- sectHdr->offset = osec->fileOff;
|
|
- sectHdr->align = Log2_32(osec->align);
|
|
- sectHdr->flags = osec->flags;
|
|
- sectHdr->size = osec->getSize();
|
|
- }
|
|
- }
|
|
-
|
|
-private:
|
|
- StringRef name;
|
|
- OutputSegment *seg;
|
|
-};
|
|
-
|
|
-class LCMain : public LoadCommand {
|
|
- uint32_t getSize() const override { return sizeof(entry_point_command); }
|
|
-
|
|
- void writeTo(uint8_t *buf) const override {
|
|
- auto *c = reinterpret_cast<entry_point_command *>(buf);
|
|
- c->cmd = LC_MAIN;
|
|
- c->cmdsize = getSize();
|
|
- c->entryoff = config->entry->getFileOffset();
|
|
- c->stacksize = 0;
|
|
- }
|
|
-};
|
|
-
|
|
-class LCSymtab : public LoadCommand {
|
|
-public:
|
|
- LCSymtab(SymtabSection *symtabSection, StringTableSection *stringTableSection)
|
|
- : symtabSection(symtabSection), stringTableSection(stringTableSection) {}
|
|
-
|
|
- uint32_t getSize() const override { return sizeof(symtab_command); }
|
|
-
|
|
- void writeTo(uint8_t *buf) const override {
|
|
- auto *c = reinterpret_cast<symtab_command *>(buf);
|
|
- c->cmd = LC_SYMTAB;
|
|
- c->cmdsize = getSize();
|
|
- c->symoff = symtabSection->fileOff;
|
|
- c->nsyms = symtabSection->getNumSymbols();
|
|
- c->stroff = stringTableSection->fileOff;
|
|
- c->strsize = stringTableSection->getFileSize();
|
|
- }
|
|
-
|
|
- SymtabSection *symtabSection = nullptr;
|
|
- StringTableSection *stringTableSection = nullptr;
|
|
-};
|
|
-
|
|
-// There are several dylib load commands that share the same structure:
|
|
-// * LC_LOAD_DYLIB
|
|
-// * LC_ID_DYLIB
|
|
-// * LC_REEXPORT_DYLIB
|
|
-class LCDylib : public LoadCommand {
|
|
-public:
|
|
- LCDylib(LoadCommandType type, StringRef path) : type(type), path(path) {}
|
|
-
|
|
- uint32_t getSize() const override {
|
|
- return alignTo(sizeof(dylib_command) + path.size() + 1, 8);
|
|
- }
|
|
-
|
|
- void writeTo(uint8_t *buf) const override {
|
|
- auto *c = reinterpret_cast<dylib_command *>(buf);
|
|
- buf += sizeof(dylib_command);
|
|
-
|
|
- c->cmd = type;
|
|
- c->cmdsize = getSize();
|
|
- c->dylib.name = sizeof(dylib_command);
|
|
-
|
|
- memcpy(buf, path.data(), path.size());
|
|
- buf[path.size()] = '\0';
|
|
- }
|
|
-
|
|
-private:
|
|
- LoadCommandType type;
|
|
- StringRef path;
|
|
-};
|
|
-
|
|
-class LCLoadDylinker : public LoadCommand {
|
|
-public:
|
|
- uint32_t getSize() const override {
|
|
- return alignTo(sizeof(dylinker_command) + path.size() + 1, 8);
|
|
- }
|
|
-
|
|
- void writeTo(uint8_t *buf) const override {
|
|
- auto *c = reinterpret_cast<dylinker_command *>(buf);
|
|
- buf += sizeof(dylinker_command);
|
|
-
|
|
- c->cmd = LC_LOAD_DYLINKER;
|
|
- c->cmdsize = getSize();
|
|
- c->name = sizeof(dylinker_command);
|
|
-
|
|
- memcpy(buf, path.data(), path.size());
|
|
- buf[path.size()] = '\0';
|
|
- }
|
|
-
|
|
-private:
|
|
- // Recent versions of Darwin won't run any binary that has dyld at a
|
|
- // different location.
|
|
- const StringRef path = "/usr/lib/dyld";
|
|
-};
|
|
-} // namespace
|
|
-
|
|
-void Writer::scanRelocations() {
|
|
- for (InputSection *isec : inputSections) {
|
|
- for (Reloc &r : isec->relocs) {
|
|
- if (auto *s = r.target.dyn_cast<lld::macho::Symbol *>()) {
|
|
- if (isa<Undefined>(s))
|
|
- error("undefined symbol " + s->getName() + ", referenced from " +
|
|
- sys::path::filename(isec->file->getName()));
|
|
- else
|
|
- target->prepareSymbolRelocation(*s, isec, r);
|
|
- }
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-void Writer::createLoadCommands() {
|
|
- headerSection->addLoadCommand(
|
|
- make<LCDyldInfo>(in.binding, lazyBindingSection, exportSection));
|
|
- headerSection->addLoadCommand(
|
|
- make<LCSymtab>(symtabSection, stringTableSection));
|
|
- headerSection->addLoadCommand(make<LCDysymtab>());
|
|
-
|
|
- switch (config->outputType) {
|
|
- case MH_EXECUTE:
|
|
- headerSection->addLoadCommand(make<LCMain>());
|
|
- headerSection->addLoadCommand(make<LCLoadDylinker>());
|
|
- break;
|
|
- case MH_DYLIB:
|
|
- headerSection->addLoadCommand(
|
|
- make<LCDylib>(LC_ID_DYLIB, config->installName));
|
|
- break;
|
|
- default:
|
|
- llvm_unreachable("unhandled output file type");
|
|
- }
|
|
-
|
|
- uint8_t segIndex = 0;
|
|
- for (OutputSegment *seg : outputSegments) {
|
|
- headerSection->addLoadCommand(make<LCSegment>(seg->name, seg));
|
|
- seg->index = segIndex++;
|
|
- }
|
|
-
|
|
- uint64_t dylibOrdinal = 1;
|
|
- for (InputFile *file : inputFiles) {
|
|
- if (auto *dylibFile = dyn_cast<DylibFile>(file)) {
|
|
- headerSection->addLoadCommand(
|
|
- make<LCDylib>(LC_LOAD_DYLIB, dylibFile->dylibName));
|
|
- dylibFile->ordinal = dylibOrdinal++;
|
|
-
|
|
- if (dylibFile->reexport)
|
|
- headerSection->addLoadCommand(
|
|
- make<LCDylib>(LC_REEXPORT_DYLIB, dylibFile->dylibName));
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-static size_t getSymbolPriority(const SymbolPriorityEntry &entry,
|
|
- const InputFile &file) {
|
|
- return std::max(entry.objectFiles.lookup(sys::path::filename(file.getName())),
|
|
- entry.anyObjectFile);
|
|
-}
|
|
-
|
|
-// Each section gets assigned the priority of the highest-priority symbol it
|
|
-// contains.
|
|
-static DenseMap<const InputSection *, size_t> buildInputSectionPriorities() {
|
|
- DenseMap<const InputSection *, size_t> sectionPriorities;
|
|
-
|
|
- if (config->priorities.empty())
|
|
- return sectionPriorities;
|
|
-
|
|
- auto addSym = [&](Defined &sym) {
|
|
- auto it = config->priorities.find(sym.getName());
|
|
- if (it == config->priorities.end())
|
|
- return;
|
|
-
|
|
- SymbolPriorityEntry &entry = it->second;
|
|
- size_t &priority = sectionPriorities[sym.isec];
|
|
- priority = std::max(priority, getSymbolPriority(entry, *sym.isec->file));
|
|
- };
|
|
-
|
|
- // TODO: Make sure this handles weak symbols correctly.
|
|
- for (InputFile *file : inputFiles)
|
|
- if (isa<ObjFile>(file) || isa<ArchiveFile>(file))
|
|
- for (lld::macho::Symbol *sym : file->symbols)
|
|
- if (auto *d = dyn_cast<Defined>(sym))
|
|
- addSym(*d);
|
|
-
|
|
- return sectionPriorities;
|
|
-}
|
|
-
|
|
-static int segmentOrder(OutputSegment *seg) {
|
|
- return StringSwitch<int>(seg->name)
|
|
- .Case(segment_names::pageZero, -2)
|
|
- .Case(segment_names::text, -1)
|
|
- // Make sure __LINKEDIT is the last segment (i.e. all its hidden
|
|
- // sections must be ordered after other sections).
|
|
- .Case(segment_names::linkEdit, std::numeric_limits<int>::max())
|
|
- .Default(0);
|
|
-}
|
|
-
|
|
-static int sectionOrder(OutputSection *osec) {
|
|
- StringRef segname = osec->parent->name;
|
|
- // Sections are uniquely identified by their segment + section name.
|
|
- if (segname == segment_names::text) {
|
|
- if (osec->name == section_names::header)
|
|
- return -1;
|
|
- } else if (segname == segment_names::linkEdit) {
|
|
- return StringSwitch<int>(osec->name)
|
|
- .Case(section_names::binding, -4)
|
|
- .Case(section_names::export_, -3)
|
|
- .Case(section_names::symbolTable, -2)
|
|
- .Case(section_names::stringTable, -1)
|
|
- .Default(0);
|
|
- }
|
|
- // ZeroFill sections must always be the at the end of their segments,
|
|
- // otherwise subsequent sections may get overwritten with zeroes at runtime.
|
|
- if (isZeroFill(osec->flags))
|
|
- return std::numeric_limits<int>::max();
|
|
- return 0;
|
|
-}
|
|
-
|
|
-template <typename T, typename F>
|
|
-static std::function<bool(T, T)> compareByOrder(F ord) {
|
|
- return [=](T a, T b) { return ord(a) < ord(b); };
|
|
-}
|
|
-
|
|
-// Sorting only can happen once all outputs have been collected. Here we sort
|
|
-// segments, output sections within each segment, and input sections within each
|
|
-// output segment.
|
|
-static void sortSegmentsAndSections() {
|
|
- llvm::stable_sort(outputSegments,
|
|
- compareByOrder<OutputSegment *>(segmentOrder));
|
|
-
|
|
- DenseMap<const InputSection *, size_t> isecPriorities =
|
|
- buildInputSectionPriorities();
|
|
-
|
|
- uint32_t sectionIndex = 0;
|
|
- for (OutputSegment *seg : outputSegments) {
|
|
- seg->sortOutputSections(compareByOrder<OutputSection *>(sectionOrder));
|
|
- for (auto *osec : seg->getSections()) {
|
|
- // Now that the output sections are sorted, assign the final
|
|
- // output section indices.
|
|
- if (!osec->isHidden())
|
|
- osec->index = ++sectionIndex;
|
|
-
|
|
- if (!isecPriorities.empty()) {
|
|
- if (auto *merged = dyn_cast<MergedOutputSection>(osec)) {
|
|
- llvm::stable_sort(merged->inputs,
|
|
- [&](InputSection *a, InputSection *b) {
|
|
- return isecPriorities[a] > isecPriorities[b];
|
|
- });
|
|
- }
|
|
- }
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-void Writer::createOutputSections() {
|
|
- // First, create hidden sections
|
|
- headerSection = make<MachHeaderSection>();
|
|
- lazyBindingSection = make<LazyBindingSection>();
|
|
- stringTableSection = make<StringTableSection>();
|
|
- symtabSection = make<SymtabSection>(*stringTableSection);
|
|
- exportSection = make<ExportSection>();
|
|
-
|
|
- switch (config->outputType) {
|
|
- case MH_EXECUTE:
|
|
- make<PageZeroSection>();
|
|
- break;
|
|
- case MH_DYLIB:
|
|
- break;
|
|
- default:
|
|
- llvm_unreachable("unhandled output file type");
|
|
- }
|
|
-
|
|
- // Then merge input sections into output sections.
|
|
- MapVector<std::pair<StringRef, StringRef>, MergedOutputSection *>
|
|
- mergedOutputSections;
|
|
- for (InputSection *isec : inputSections) {
|
|
- MergedOutputSection *&osec =
|
|
- mergedOutputSections[{isec->segname, isec->name}];
|
|
- if (osec == nullptr)
|
|
- osec = make<MergedOutputSection>(isec->name);
|
|
- osec->mergeInput(isec);
|
|
- }
|
|
-
|
|
- for (const auto &it : mergedOutputSections) {
|
|
- StringRef segname = it.first.first;
|
|
- MergedOutputSection *osec = it.second;
|
|
- getOrCreateOutputSegment(segname)->addOutputSection(osec);
|
|
- }
|
|
-
|
|
- for (SyntheticSection *ssec : syntheticSections) {
|
|
- auto it = mergedOutputSections.find({ssec->segname, ssec->name});
|
|
- if (it == mergedOutputSections.end()) {
|
|
- if (ssec->isNeeded())
|
|
- getOrCreateOutputSegment(ssec->segname)->addOutputSection(ssec);
|
|
- } else {
|
|
- error("section from " + it->second->firstSection()->file->getName() +
|
|
- " conflicts with synthetic section " + ssec->segname + "," +
|
|
- ssec->name);
|
|
- }
|
|
- }
|
|
-}
|
|
-
|
|
-void Writer::assignAddresses(OutputSegment *seg) {
|
|
- addr = alignTo(addr, PageSize);
|
|
- fileOff = alignTo(fileOff, PageSize);
|
|
- seg->fileOff = fileOff;
|
|
-
|
|
- for (auto *osec : seg->getSections()) {
|
|
- addr = alignTo(addr, osec->align);
|
|
- fileOff = alignTo(fileOff, osec->align);
|
|
- osec->addr = addr;
|
|
- osec->fileOff = isZeroFill(osec->flags) ? 0 : fileOff;
|
|
- osec->finalize();
|
|
-
|
|
- addr += osec->getSize();
|
|
- fileOff += osec->getFileSize();
|
|
- }
|
|
-}
|
|
-
|
|
-void Writer::openFile() {
|
|
- Expected<std::unique_ptr<FileOutputBuffer>> bufferOrErr =
|
|
- FileOutputBuffer::create(config->outputFile, fileOff,
|
|
- FileOutputBuffer::F_executable);
|
|
-
|
|
- if (!bufferOrErr)
|
|
- error("failed to open " + config->outputFile + ": " +
|
|
- llvm::toString(bufferOrErr.takeError()));
|
|
- else
|
|
- buffer = std::move(*bufferOrErr);
|
|
-}
|
|
-
|
|
-void Writer::writeSections() {
|
|
- uint8_t *buf = buffer->getBufferStart();
|
|
- for (OutputSegment *seg : outputSegments)
|
|
- for (OutputSection *osec : seg->getSections())
|
|
- osec->writeTo(buf + osec->fileOff);
|
|
-}
|
|
-
|
|
-void Writer::run() {
|
|
- // dyld requires __LINKEDIT segment to always exist (even if empty).
|
|
- OutputSegment *linkEditSegment =
|
|
- getOrCreateOutputSegment(segment_names::linkEdit);
|
|
-
|
|
- scanRelocations();
|
|
- if (in.stubHelper->isNeeded())
|
|
- in.stubHelper->setup();
|
|
-
|
|
- // Sort and assign sections to their respective segments. No more sections nor
|
|
- // segments may be created after these methods run.
|
|
- createOutputSections();
|
|
- sortSegmentsAndSections();
|
|
-
|
|
- createLoadCommands();
|
|
-
|
|
- // Ensure that segments (and the sections they contain) are allocated
|
|
- // addresses in ascending order, which dyld requires.
|
|
- //
|
|
- // Note that at this point, __LINKEDIT sections are empty, but we need to
|
|
- // determine addresses of other segments/sections before generating its
|
|
- // contents.
|
|
- for (OutputSegment *seg : outputSegments)
|
|
- if (seg != linkEditSegment)
|
|
- assignAddresses(seg);
|
|
-
|
|
- // Fill __LINKEDIT contents.
|
|
- in.binding->finalizeContents();
|
|
- lazyBindingSection->finalizeContents();
|
|
- exportSection->finalizeContents();
|
|
- symtabSection->finalizeContents();
|
|
-
|
|
- // Now that __LINKEDIT is filled out, do a proper calculation of its
|
|
- // addresses and offsets.
|
|
- assignAddresses(linkEditSegment);
|
|
-
|
|
- openFile();
|
|
- if (errorCount())
|
|
- return;
|
|
-
|
|
- writeSections();
|
|
-
|
|
- if (auto e = buffer->commit())
|
|
- error("failed to write to the output file: " + toString(std::move(e)));
|
|
-}
|
|
-
|
|
-void macho::writeResult() { Writer().run(); }
|
|
-
|
|
-void macho::createSyntheticSections() {
|
|
- in.binding = make<BindingSection>();
|
|
- in.got = make<GotSection>();
|
|
- in.lazyPointers = make<LazyPointerSection>();
|
|
- in.stubs = make<StubsSection>();
|
|
- in.stubHelper = make<StubHelperSection>();
|
|
- in.imageLoaderCache = make<ImageLoaderCacheSection>();
|
|
-}
|
|
diff --git a/lld/MachO/Writer.h b/lld/MachO/Writer.h
|
|
deleted file mode 100644
|
|
index 7f846233107..00000000000
|
|
--- a/lld/MachO/Writer.h
|
|
+++ /dev/null
|
|
@@ -1,31 +0,0 @@
|
|
-//===- Writer.h -------------------------------------------------*- C++ -*-===//
|
|
-//
|
|
-// 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
|
|
-//
|
|
-//===----------------------------------------------------------------------===//
|
|
-
|
|
-#ifndef LLD_MACHO_WRITER_H
|
|
-#define LLD_MACHO_WRITER_H
|
|
-
|
|
-#include <cstdint>
|
|
-
|
|
-namespace lld {
|
|
-namespace macho {
|
|
-
|
|
-class LoadCommand {
|
|
-public:
|
|
- virtual ~LoadCommand() = default;
|
|
- virtual uint32_t getSize() const = 0;
|
|
- virtual void writeTo(uint8_t *buf) const = 0;
|
|
-};
|
|
-
|
|
-void writeResult();
|
|
-
|
|
-void createSyntheticSections();
|
|
-
|
|
-} // namespace macho
|
|
-} // namespace lld
|
|
-
|
|
-#endif
|
|
diff --git a/lld/include/lld/Common/Driver.h b/lld/include/lld/Common/Driver.h
|
|
index 6db3d234eb5..0a358d8aff6 100644
|
|
--- a/lld/include/lld/Common/Driver.h
|
|
+++ b/lld/include/lld/Common/Driver.h
|
|
@@ -33,11 +33,6 @@ bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
|
|
llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS);
|
|
}
|
|
|
|
-namespace macho {
|
|
-bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
|
|
- llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS);
|
|
-}
|
|
-
|
|
namespace wasm {
|
|
bool link(llvm::ArrayRef<const char *> args, bool canExitEarly,
|
|
llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS);
|
|
diff --git a/lld/test/MachO/Inputs/MacOSX.sdk/usr/lib/libSystem.tbd b/lld/test/MachO/Inputs/MacOSX.sdk/usr/lib/libSystem.tbd
|
|
deleted file mode 100644
|
|
index fddd192630d..00000000000
|
|
--- a/lld/test/MachO/Inputs/MacOSX.sdk/usr/lib/libSystem.tbd
|
|
+++ /dev/null
|
|
@@ -1,42 +0,0 @@
|
|
---- !tapi-tbd-v3
|
|
-archs: [ x86_64 ]
|
|
-uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000000' ]
|
|
-platform: macosx
|
|
-install-name: '/usr/lib/libSystem.B.dylib'
|
|
-current-version: 0001.001.1
|
|
-exports:
|
|
- - archs: [ 'x86_64' ]
|
|
- re-exports: [ '/usr/lib/system/libdyld.dylib',
|
|
- '/usr/lib/system/libsystem_c.dylib',
|
|
- '/usr/lib/system/libsystem_m.dylib' ]
|
|
---- !tapi-tbd-v3
|
|
-archs: [ x86_64 ]
|
|
-uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000001' ]
|
|
-platform: macosx
|
|
-install-name: '/usr/lib/system/libdyld.dylib'
|
|
-current-version: 0001.001.1
|
|
-parent-umbrella: System
|
|
-exports:
|
|
- - archs: [ 'x86_64' ]
|
|
- symbols: [ dyld_stub_binder ]
|
|
---- !tapi-tbd-v3
|
|
-archs: [ x86_64 ]
|
|
-uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000002' ]
|
|
-platform: macosx
|
|
-install-name: '/usr/lib/system/libsystem_c.dylib'
|
|
-current-version: 0001.001.1
|
|
-parent-umbrella: System
|
|
-exports:
|
|
- - archs: [ 'x86_64' ]
|
|
- symbols: [ ]
|
|
---- !tapi-tbd-v3
|
|
-archs: [ x86_64 ]
|
|
-uuids: [ 'x86_64: 00000000-0000-0000-0000-000000000003' ]
|
|
-platform: macosx
|
|
-install-name: '/usr/lib/system/libsystem_m.dylib'
|
|
-current-version: 0001.001.1
|
|
-parent-umbrella: System
|
|
-exports:
|
|
- - archs: [ 'x86_64' ]
|
|
- symbols: [ ___nan ]
|
|
-...
|
|
diff --git a/lld/test/MachO/Inputs/iPhoneSimulator.sdk/usr/lib/libSystem.tbd b/lld/test/MachO/Inputs/iPhoneSimulator.sdk/usr/lib/libSystem.tbd
|
|
deleted file mode 100644
|
|
index 3e62c2ee711..00000000000
|
|
--- a/lld/test/MachO/Inputs/iPhoneSimulator.sdk/usr/lib/libSystem.tbd
|
|
+++ /dev/null
|
|
@@ -1,23 +0,0 @@
|
|
---- !tapi-tbd-v3
|
|
-archs: [ i386, x86_64 ]
|
|
-uuids: [ 'i386: 00000000-0000-0000-0000-000000000000', 'x86_64: 00000000-0000-0000-0000-000000000001' ]
|
|
-platform: ios
|
|
-install-name: '/usr/lib/libSystem.B.dylib'
|
|
-current-version: 1281
|
|
-exports:
|
|
- - archs: [ i386, x86_64 ]
|
|
- re-exports: [ '/usr/lib/system/libcache.dylib' ]
|
|
- symbols: [ __crashreporter_info__ ]
|
|
---- !tapi-tbd-v3
|
|
-archs: [ i386, x86_64 ]
|
|
-uuids: [ 'i386: 00000000-0000-0000-0000-000000000002', 'x86_64: 00000000-0000-0000-0000-000000000003' ]
|
|
-platform: ios
|
|
-install-name: '/usr/lib/libcache.dylib'
|
|
-current-version: 83
|
|
-parent-umbrella: System
|
|
-exports:
|
|
- - archs: [ i386 ]
|
|
- symbols: [ __cache_handle_memory_pressure_event ]
|
|
- - archs: [ i386, x86_64 ]
|
|
- symbols: [ _cache_create, _cache_destroy, _cache_get ]
|
|
-...
|
|
diff --git a/lld/test/MachO/Inputs/libfunction.s b/lld/test/MachO/Inputs/libfunction.s
|
|
deleted file mode 100644
|
|
index fe0b3879a41..00000000000
|
|
--- a/lld/test/MachO/Inputs/libfunction.s
|
|
+++ /dev/null
|
|
@@ -1,6 +0,0 @@
|
|
-.section __TEXT,__text
|
|
-.globl _some_function
|
|
-
|
|
-_some_function:
|
|
- mov $1, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/Inputs/libgoodbye.s b/lld/test/MachO/Inputs/libgoodbye.s
|
|
deleted file mode 100644
|
|
index 40c829cfc6e..00000000000
|
|
--- a/lld/test/MachO/Inputs/libgoodbye.s
|
|
+++ /dev/null
|
|
@@ -1,14 +0,0 @@
|
|
-.section __TEXT,__cstring
|
|
-.globl _goodbye_world, _print_goodbye
|
|
-
|
|
-_goodbye_world:
|
|
-.asciz "Goodbye world!\n"
|
|
-
|
|
-.text
|
|
-_print_goodbye:
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- leaq _goodbye_world(%rip), %rsi
|
|
- mov $15, %rdx # length of str
|
|
- syscall
|
|
- ret
|
|
diff --git a/lld/test/MachO/Inputs/libhello.s b/lld/test/MachO/Inputs/libhello.s
|
|
deleted file mode 100644
|
|
index 0b9930bafcb..00000000000
|
|
--- a/lld/test/MachO/Inputs/libhello.s
|
|
+++ /dev/null
|
|
@@ -1,17 +0,0 @@
|
|
-.section __TEXT,__cstring
|
|
-.globl _hello_world, _hello_its_me, _print_hello
|
|
-
|
|
-_hello_world:
|
|
-.asciz "Hello world!\n"
|
|
-
|
|
-_hello_its_me:
|
|
-.asciz "Hello, it's me\n"
|
|
-
|
|
-.text
|
|
-_print_hello:
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- leaq _hello_world(%rip), %rsi
|
|
- mov $13, %rdx # length of str
|
|
- syscall
|
|
- ret
|
|
diff --git a/lld/test/MachO/arch.s b/lld/test/MachO/arch.s
|
|
deleted file mode 100644
|
|
index a0a1962f640..00000000000
|
|
--- a/lld/test/MachO/arch.s
|
|
+++ /dev/null
|
|
@@ -1,11 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -o /dev/null %t.o
|
|
-# RUN: not lld -flavor darwinnew -arch i386 -o /dev/null %t.o 2>&1 | FileCheck %s
|
|
-# CHECK: error: missing or unsupported -arch i386
|
|
-
|
|
-.text
|
|
-.global _main
|
|
-_main:
|
|
- mov $0, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/archive.s b/lld/test/MachO/archive.s
|
|
deleted file mode 100644
|
|
index 370980768fa..00000000000
|
|
--- a/lld/test/MachO/archive.s
|
|
+++ /dev/null
|
|
@@ -1,35 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: mkdir -p %t
|
|
-# RUN: echo ".global _boo; _boo: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/2.o
|
|
-# RUN: echo ".global _bar; _bar: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/3.o
|
|
-# RUN: echo ".global _undefined; .global _unused; _unused: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/4.o
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/main.o
|
|
-
|
|
-# RUN: rm -f %t/test.a
|
|
-# RUN: llvm-ar rcs %t/test.a %t/2.o %t/3.o %t/4.o
|
|
-# RUN: lld -flavor darwinnew %t/main.o %t/test.a -o %t/test.out
|
|
-
|
|
-## TODO: Run llvm-nm -p to validate symbol order
|
|
-# RUN: llvm-nm %t/test.out | FileCheck %s
|
|
-# CHECK: T _bar
|
|
-# CHECK: T _boo
|
|
-# CHECK: T _main
|
|
-
|
|
-## Linking with the archive first in the command line shouldn't change anything
|
|
-# RUN: lld -flavor darwinnew %t/test.a %t/main.o -o %t/test.out
|
|
-# RUN: llvm-nm %t/test.out | FileCheck %s --check-prefix ARCHIVE-FIRST
|
|
-# ARCHIVE-FIRST: T _bar
|
|
-# ARCHIVE-FIRST: T _boo
|
|
-# ARCHIVE-FIRST: T _main
|
|
-
|
|
-
|
|
-# RUN: llvm-nm %t/test.out | FileCheck %s --check-prefix VISIBLE
|
|
-# VISIBLE-NOT: T _undefined
|
|
-# VISIBLE-NOT: T _unused
|
|
-
|
|
-.global _main
|
|
-_main:
|
|
- callq _boo
|
|
- callq _bar
|
|
- mov $0, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/bss.s b/lld/test/MachO/bss.s
|
|
deleted file mode 100644
|
|
index b56f02d2bcb..00000000000
|
|
--- a/lld/test/MachO/bss.s
|
|
+++ /dev/null
|
|
@@ -1,59 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -o %t %t.o
|
|
-# RUN: llvm-readobj --section-headers --macho-segment %t | FileCheck %s
|
|
-
|
|
-## Check that __bss takes up zero file size, is at file offset zero, and
|
|
-## appears at the end of its segment.
|
|
-
|
|
-# CHECK: Index: 1
|
|
-# CHECK-NEXT: Name: __data
|
|
-# CHECK-NEXT: Segment: __DATA
|
|
-# CHECK-NEXT: Address:
|
|
-# CHECK-NEXT: Size: 0x8
|
|
-# CHECK-NEXT: Offset: 4096
|
|
-# CHECK-NEXT: Alignment: 0
|
|
-# CHECK-NEXT: RelocationOffset: 0x0
|
|
-# CHECK-NEXT: RelocationCount: 0
|
|
-# CHECK-NEXT: Type: Regular (0x0)
|
|
-# CHECK-NEXT: Attributes [ (0x0)
|
|
-# CHECK-NEXT: ]
|
|
-# CHECK-NEXT: Reserved1: 0x0
|
|
-# CHECK-NEXT: Reserved2: 0x0
|
|
-# CHECK-NEXT: Reserved3: 0x0
|
|
-
|
|
-# CHECK: Index: 2
|
|
-# CHECK-NEXT: Name: __bss
|
|
-# CHECK-NEXT: Segment: __DATA
|
|
-# CHECK-NEXT: Address:
|
|
-# CHECK-NEXT: Size: 0x4
|
|
-# CHECK-NEXT: Offset: 0
|
|
-# CHECK-NEXT: Alignment: 0
|
|
-# CHECK-NEXT: RelocationOffset: 0x0
|
|
-# CHECK-NEXT: RelocationCount: 0
|
|
-# CHECK-NEXT: Type: ZeroFill (0x1)
|
|
-# CHECK-NEXT: Attributes [ (0x0)
|
|
-# CHECK-NEXT: ]
|
|
-# CHECK-NEXT: Reserved1: 0x0
|
|
-# CHECK-NEXT: Reserved2: 0x0
|
|
-# CHECK-NEXT: Reserved3: 0x0
|
|
-
|
|
-# CHECK: Name: __DATA
|
|
-# CHECK-NEXT: Size:
|
|
-# CHECK-NEXT: vmaddr:
|
|
-# CHECK-NEXT: vmsize: 0xC
|
|
-# CHECK-NEXT: fileoff:
|
|
-# CHECK-NEXT: filesize: 8
|
|
-
|
|
-.globl _main
|
|
-
|
|
-.text
|
|
-_main:
|
|
- movq $0, %rax
|
|
- retq
|
|
-
|
|
-.bss
|
|
-.zero 4
|
|
-
|
|
-.data
|
|
-.quad 0x1234
|
|
diff --git a/lld/test/MachO/dylib.s b/lld/test/MachO/dylib.s
|
|
deleted file mode 100644
|
|
index 507a7de8742..00000000000
|
|
--- a/lld/test/MachO/dylib.s
|
|
+++ /dev/null
|
|
@@ -1,35 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-
|
|
-# RUN: lld -flavor darwinnew -dylib -install_name @executable_path/libfoo.dylib \
|
|
-# RUN: %t.o -o %t.dylib
|
|
-# RUN: llvm-objdump --macho --dylib-id %t.dylib | FileCheck %s
|
|
-# CHECK: @executable_path/libfoo.dylib
|
|
-
|
|
-## If we are building a dylib, we shouldn't error out even if we are passed
|
|
-## a flag for a missing entry symbol (since dylibs don't have entry symbols).
|
|
-## Also check that we come up with the right install name if one isn't
|
|
-## specified.
|
|
-# RUN: lld -flavor darwinnew -dylib %t.o -o %t.defaultInstallName.dylib -e missing_entry
|
|
-# RUN: obj2yaml %t.defaultInstallName.dylib | FileCheck %s -DOUTPUT=%t.defaultInstallName.dylib --check-prefix=DEFAULT-INSTALL-NAME
|
|
-# DEFAULT-INSTALL-NAME: [[OUTPUT]]
|
|
-
|
|
-## Check for the absence of load commands / segments that should not be in a
|
|
-## dylib.
|
|
-# RUN: llvm-objdump --macho --all-headers %t.dylib | FileCheck %s --check-prefix=NCHECK
|
|
-# NCHECK-NOT: cmd LC_LOAD_DYLINKER
|
|
-# NCHECK-NOT: cmd LC_MAIN
|
|
-# NCHECK-NOT: segname __PAGEZERO
|
|
-
|
|
-# RUN: llvm-objdump --syms --exports-trie %t.dylib | \
|
|
-# RUN: FileCheck %s --check-prefix=EXPORTS
|
|
-# EXPORTS-LABEL: SYMBOL TABLE:
|
|
-# EXPORTS: [[#%x, HELLO_WORLD_ADDR:]] {{.*}} _hello_world
|
|
-# EXPORTS-LABEL: Exports trie:
|
|
-# EXPORTS: 0x{{0*}}[[#%X, HELLO_WORLD_ADDR]] _hello_world
|
|
-
|
|
-.section __TEXT,__cstring
|
|
-.globl _hello_world
|
|
-
|
|
-_hello_world:
|
|
-.asciz "Hello world!\n"
|
|
diff --git a/lld/test/MachO/dylink-lazy.s b/lld/test/MachO/dylink-lazy.s
|
|
deleted file mode 100644
|
|
index 16051b45bd9..00000000000
|
|
--- a/lld/test/MachO/dylink-lazy.s
|
|
+++ /dev/null
|
|
@@ -1,62 +0,0 @@
|
|
-# REQUIRES: x86, shell
|
|
-# RUN: mkdir -p %t
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %p/Inputs/libhello.s \
|
|
-# RUN: -o %t/libhello.o
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %p/Inputs/libgoodbye.s \
|
|
-# RUN: -o %t/libgoodbye.o
|
|
-# RUN: lld -flavor darwinnew -dylib -L%S/Inputs/MacOSX.sdk/usr/lib \
|
|
-# RUN: -install_name @executable_path/libhello.dylib %t/libhello.o \
|
|
-# RUN: -o %t/libhello.dylib
|
|
-# RUN: lld -flavor darwinnew -dylib -L%S/Inputs/MacOSX.sdk/usr/lib \
|
|
-# RUN: -install_name @executable_path/libgoodbye.dylib %t/libgoodbye.o \
|
|
-# RUN: -o %t/libgoodbye.dylib
|
|
-
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/dylink-lazy.o
|
|
-# RUN: lld -flavor darwinnew -o %t/dylink-lazy \
|
|
-# RUN: -L%S/Inputs/MacOSX.sdk/usr/lib -L%t -lhello -lgoodbye %t/dylink-lazy.o -lSystem
|
|
-
|
|
-## When looking at the __stubs section alone, we are unable to easily tell which
|
|
-## symbol each entry points to. So we call objdump twice in order to get the
|
|
-## disassembly of __text and the bind tables first, which allow us to check for
|
|
-## matching entries in __stubs.
|
|
-# RUN: (llvm-objdump -d --no-show-raw-insn --syms --bind --lazy-bind %t/dylink-lazy; \
|
|
-# RUN: llvm-objdump -D --no-show-raw-insn %t/dylink-lazy) | FileCheck %s
|
|
-
|
|
-# CHECK-LABEL: SYMBOL TABLE:
|
|
-# CHECK: {{0*}}[[#%x, IMGLOADER:]] {{.*}} __DATA,__data __dyld_private
|
|
-
|
|
-# CHECK-LABEL: Disassembly of section __TEXT,__text:
|
|
-# CHECK: callq 0x[[#%x, HELLO_STUB:]]
|
|
-# CHECK-NEXT: callq 0x[[#%x, GOODBYE_STUB:]]
|
|
-
|
|
-# CHECK-LABEL: Bind table:
|
|
-# CHECK: __DATA_CONST __got 0x[[#%x, BINDER:]] pointer 0 libSystem dyld_stub_binder
|
|
-
|
|
-# CHECK-LABEL: Lazy bind table:
|
|
-# CHECK-DAG: __DATA __la_symbol_ptr 0x{{0*}}[[#%x, HELLO_LAZY_PTR:]] libhello _print_hello
|
|
-# CHECK-DAG: __DATA __la_symbol_ptr 0x{{0*}}[[#%x, GOODBYE_LAZY_PTR:]] libgoodbye _print_goodbye
|
|
-
|
|
-# CHECK-LABEL: Disassembly of section __TEXT,__stubs:
|
|
-# CHECK-DAG: [[#%x, HELLO_STUB]]: jmpq *[[#%u, HELLO_LAZY_PTR - HELLO_STUB - 6]](%rip)
|
|
-# CHECK-DAG: [[#%x, GOODBYE_STUB]]: jmpq *[[#%u, GOODBYE_LAZY_PTR - GOODBYE_STUB - 6]](%rip)
|
|
-
|
|
-# CHECK-LABEL: Disassembly of section __TEXT,__stub_helper:
|
|
-# CHECK: {{0*}}[[#%x, STUB_HELPER_ENTRY:]] <__stub_helper>:
|
|
-# CHECK-NEXT: leaq [[#%u, IMGLOADER - STUB_HELPER_ENTRY - 7]](%rip), %r11
|
|
-# CHECK-NEXT: pushq %r11
|
|
-# CHECK-NEXT: jmpq *[[#%u, BINDER_OFF:]](%rip)
|
|
-# CHECK-NEXT: [[#%x, BINDER - BINDER_OFF]]: nop
|
|
-# CHECK-NEXT: pushq $0
|
|
-# CHECK-NEXT: jmp 0x[[#STUB_HELPER_ENTRY]]
|
|
-# CHECK-NEXT: pushq $21
|
|
-# CHECK-NEXT: jmp 0x[[#STUB_HELPER_ENTRY]]
|
|
-
|
|
-.text
|
|
-.globl _main
|
|
-
|
|
-_main:
|
|
- sub $8, %rsp # 16-byte-align the stack; dyld checks for this
|
|
- callq _print_hello
|
|
- callq _print_goodbye
|
|
- add $8, %rsp
|
|
- ret
|
|
diff --git a/lld/test/MachO/dylink.s b/lld/test/MachO/dylink.s
|
|
deleted file mode 100644
|
|
index 0549aab9829..00000000000
|
|
--- a/lld/test/MachO/dylink.s
|
|
+++ /dev/null
|
|
@@ -1,69 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: mkdir -p %t
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %p/Inputs/libhello.s \
|
|
-# RUN: -o %t/libhello.o
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %p/Inputs/libgoodbye.s \
|
|
-# RUN: -o %t/libgoodbye.o
|
|
-# RUN: lld -flavor darwinnew -dylib -install_name \
|
|
-# RUN: @executable_path/libhello.dylib %t/libhello.o -o %t/libhello.dylib
|
|
-# RUN: lld -flavor darwinnew -dylib -install_name \
|
|
-# RUN: @executable_path/libgoodbye.dylib %t/libgoodbye.o -o %t/libgoodbye.dylib
|
|
-
|
|
-## Make sure we are using the export trie and not the symbol table when linking
|
|
-## against these dylibs.
|
|
-# RUN: llvm-strip %t/libhello.dylib
|
|
-# RUN: llvm-strip %t/libgoodbye.dylib
|
|
-# RUN: llvm-nm %t/libhello.dylib 2>&1 | FileCheck %s --check-prefix=NOSYM
|
|
-# RUN: llvm-nm %t/libgoodbye.dylib 2>&1 | FileCheck %s --check-prefix=NOSYM
|
|
-# NOSYM: no symbols
|
|
-
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/dylink.o
|
|
-# RUN: lld -flavor darwinnew -o %t/dylink -Z -L%t -lhello -lgoodbye %t/dylink.o
|
|
-# RUN: llvm-objdump --bind -d --no-show-raw-insn %t/dylink | FileCheck %s
|
|
-
|
|
-# CHECK: movq [[#%u, HELLO_OFF:]](%rip), %rsi
|
|
-# CHECK-NEXT: [[#%x, HELLO_RIP:]]:
|
|
-
|
|
-# CHECK: movq [[#%u, HELLO_ITS_ME_OFF:]](%rip), %rsi
|
|
-# CHECK-NEXT: [[#%x, HELLO_ITS_ME_RIP:]]:
|
|
-
|
|
-# CHECK: pushq [[#%u, GOODBYE_OFF:]](%rip)
|
|
-# CHECK-NEXT: [[#%x, GOODBYE_RIP:]]: popq %rsi
|
|
-
|
|
-# CHECK-LABEL: Bind table:
|
|
-# CHECK-DAG: __DATA_CONST __got 0x{{0*}}[[#%x, HELLO_RIP + HELLO_OFF]] pointer 0 libhello _hello_world
|
|
-# CHECK-DAG: __DATA_CONST __got 0x{{0*}}[[#%x, HELLO_ITS_ME_RIP + HELLO_ITS_ME_OFF]] pointer 0 libhello _hello_its_me
|
|
-# CHECK-DAG: __DATA_CONST __got 0x{{0*}}[[#%x, GOODBYE_RIP + GOODBYE_OFF]] pointer 0 libgoodbye _goodbye_world
|
|
-# CHECK-DAG: __DATA __data 0x[[#%x, DATA_ADDR:]] pointer 0 libhello _hello_world
|
|
-# CHECK-DAG: __DATA __data 0x{{0*}}[[#%x, DATA_ADDR + 8]] pointer 8 libhello _hello_its_me
|
|
-# CHECK-DAG: __DATA __data 0x{{0*}}[[#%x, DATA_ADDR + 16]] pointer -15 libgoodbye _goodbye_world
|
|
-
|
|
-.section __TEXT,__text
|
|
-.globl _main
|
|
-
|
|
-_main:
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- movq _hello_world@GOTPCREL(%rip), %rsi
|
|
- mov $13, %rdx # length of str
|
|
- syscall
|
|
-
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- movq _hello_its_me@GOTPCREL(%rip), %rsi
|
|
- mov $15, %rdx # length of str
|
|
- syscall
|
|
-
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- pushq _goodbye_world@GOTPCREL(%rip)
|
|
- popq %rsi
|
|
- mov $15, %rdx # length of str
|
|
- syscall
|
|
- mov $0, %rax
|
|
- ret
|
|
-
|
|
-.data
|
|
-.quad _hello_world
|
|
-.quad _hello_its_me + 0x8
|
|
-.quad _goodbye_world - 0xf
|
|
diff --git a/lld/test/MachO/entry-symbol.s b/lld/test/MachO/entry-symbol.s
|
|
deleted file mode 100644
|
|
index 159c7c5af04..00000000000
|
|
--- a/lld/test/MachO/entry-symbol.s
|
|
+++ /dev/null
|
|
@@ -1,28 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -o %t %t.o -e _not_main
|
|
-# RUN: llvm-objdump --macho --all-headers --syms %t | FileCheck %s
|
|
-# CHECK-LABEL: SYMBOL TABLE
|
|
-# CHECK-NEXT: {{0*}}[[#%x, ENTRY_ADDR:]] {{.*}} __TEXT,__text _not_main
|
|
-# CHECK: cmd LC_MAIN
|
|
-# CHECK-NEXT: cmdsize 24
|
|
-# CHECK-NEXT: entryoff [[#ENTRYOFF:]]
|
|
-# CHECK: sectname __text
|
|
-# CHECK-NEXT: segname __TEXT
|
|
-## Note: the following checks assume that the entry symbol is right at the
|
|
-## beginning of __text.
|
|
-# CHECK-NEXT: addr 0x{{0*}}[[#ENTRY_ADDR]]
|
|
-# CHECK-NEXT: size
|
|
-# CHECK-NEXT: offset [[#ENTRYOFF]]
|
|
-
|
|
-
|
|
-# RUN: not lld -flavor darwinnew -o /dev/null %t.o -e _missing 2>&1 | FileCheck %s --check-prefix=UNDEFINED
|
|
-# UNDEFINED: error: undefined symbol: _missing
|
|
-# RUN: not lld -flavor darwinnew -o /dev/null %t.o 2>&1 | FileCheck %s --check-prefix=DEFAULT-ENTRY
|
|
-# DEFAULT-ENTRY: error: undefined symbol: _main
|
|
-
|
|
-.text
|
|
-.global _not_main
|
|
-_not_main:
|
|
- movq $0, %rax
|
|
- retq
|
|
diff --git a/lld/test/MachO/export-trie.s b/lld/test/MachO/export-trie.s
|
|
deleted file mode 100644
|
|
index fc1f6d110db..00000000000
|
|
--- a/lld/test/MachO/export-trie.s
|
|
+++ /dev/null
|
|
@@ -1,44 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -dylib %t.o -o %t.dylib
|
|
-
|
|
-# RUN: llvm-objdump --syms --exports-trie %t.dylib | \
|
|
-# RUN: FileCheck %s --check-prefix=EXPORTS
|
|
-# EXPORTS-LABEL: SYMBOL TABLE:
|
|
-# EXPORTS-DAG: [[#%x, HELLO_ADDR:]] {{.*}} _hello
|
|
-# EXPORTS-DAG: [[#%x, HELLO_WORLD_ADDR:]] {{.*}} _hello_world
|
|
-# EXPORTS-DAG: [[#%x, HELLO_ITS_ME_ADDR:]] {{.*}} _hello_its_me
|
|
-# EXPORTS-DAG: [[#%x, HELLO_ITS_YOU_ADDR:]] {{.*}} _hello_its_you
|
|
-# EXPORTS-LABEL: Exports trie:
|
|
-# EXPORTS-DAG: 0x{{0*}}[[#%X, HELLO_ADDR]] _hello
|
|
-# EXPORTS-DAG: 0x{{0*}}[[#%X, HELLO_WORLD_ADDR]] _hello_world
|
|
-# EXPORTS-DAG: 0x{{0*}}[[#%x, HELLO_ITS_ME_ADDR:]] _hello_its_me
|
|
-# EXPORTS-DAG: 0x{{0*}}[[#%x, HELLO_ITS_YOU_ADDR:]] _hello_its_you
|
|
-
|
|
-## Check that we are sharing prefixes in the trie.
|
|
-# RUN: obj2yaml %t.dylib | FileCheck %s
|
|
-# CHECK-LABEL: ExportTrie:
|
|
-# CHECK: Name: ''
|
|
-# CHECK: Name: _hello
|
|
-# CHECK: Name: _
|
|
-# CHECK: Name: world
|
|
-# CHECK: Name: its_
|
|
-# CHECK: Name: me
|
|
-# CHECK: Name: you
|
|
-
|
|
-.section __TEXT,__cstring
|
|
-.globl _hello, _hello_world, _hello_its_me, _hello_its_you
|
|
-
|
|
-## Test for when an entire symbol name is a prefix of another.
|
|
-_hello:
|
|
-.asciz "Hello!\n"
|
|
-
|
|
-_hello_world:
|
|
-.asciz "Hello world!\n"
|
|
-
|
|
-.data
|
|
-_hello_its_me:
|
|
-.asciz "Hello, it's me\n"
|
|
-
|
|
-_hello_its_you:
|
|
-.asciz "Hello, it's you\n"
|
|
diff --git a/lld/test/MachO/fat-arch.s b/lld/test/MachO/fat-arch.s
|
|
deleted file mode 100644
|
|
index cb5a74b0917..00000000000
|
|
--- a/lld/test/MachO/fat-arch.s
|
|
+++ /dev/null
|
|
@@ -1,16 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=i386-apple-darwin %s -o %t.i386.o
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.x86_64.o
|
|
-# RUN: llvm-lipo %t.i386.o %t.x86_64.o -create -o %t.fat.o
|
|
-# RUN: lld -flavor darwinnew -o /dev/null %t.fat.o
|
|
-
|
|
-# RUN: llvm-lipo %t.i386.o -create -o %t.noarch.o
|
|
-# RUN: not lld -flavor darwinnew -o /dev/null %t.noarch.o 2>&1 | \
|
|
-# RUN: FileCheck %s -DFILE=%t.noarch.o
|
|
-# CHECK: error: unable to find matching architecture in [[FILE]]
|
|
-
|
|
-.text
|
|
-.global _main
|
|
-_main:
|
|
- mov $0, %eax
|
|
- ret
|
|
diff --git a/lld/test/MachO/invalid/alignment-too-large.yaml b/lld/test/MachO/invalid/alignment-too-large.yaml
|
|
deleted file mode 100644
|
|
index 79950524bcf..00000000000
|
|
--- a/lld/test/MachO/invalid/alignment-too-large.yaml
|
|
+++ /dev/null
|
|
@@ -1,58 +0,0 @@
|
|
-# RUN: yaml2obj %s -o %t.o
|
|
-# RUN: not lld -flavor darwinnew -o %t %t.o 2>&1 | FileCheck %s
|
|
-#
|
|
-# CHECK: error: alignment 32 of section __text is too large
|
|
---- !mach-o
|
|
-FileHeader:
|
|
- magic: 0xFEEDFACF
|
|
- cputype: 0x01000007
|
|
- cpusubtype: 0x00000003
|
|
- filetype: 0x00000001
|
|
- ncmds: 4
|
|
- sizeofcmds: 280
|
|
- flags: 0x00000000
|
|
- reserved: 0x00000000
|
|
-LoadCommands:
|
|
- - cmd: LC_SEGMENT_64
|
|
- cmdsize: 152
|
|
- segname: ''
|
|
- vmaddr: 0
|
|
- vmsize: 8
|
|
- fileoff: 312
|
|
- filesize: 8
|
|
- maxprot: 7
|
|
- initprot: 7
|
|
- nsects: 1
|
|
- flags: 0
|
|
- Sections:
|
|
- - sectname: __text
|
|
- segname: __TEXT
|
|
- addr: 0x0000000000000000
|
|
- size: 8
|
|
- offset: 0x00000138
|
|
- align: 32
|
|
- reloff: 0x00000000
|
|
- nreloc: 0
|
|
- flags: 0x80000400
|
|
- reserved1: 0x00000000
|
|
- reserved2: 0x00000000
|
|
- reserved3: 0x00000000
|
|
- content: 48C7C000000000C3
|
|
- - cmd: LC_SYMTAB
|
|
- cmdsize: 24
|
|
- symoff: 320
|
|
- nsyms: 1
|
|
- stroff: 336
|
|
- strsize: 8
|
|
-LinkEditData:
|
|
- NameList:
|
|
- - n_strx: 1
|
|
- n_type: 0x0F
|
|
- n_sect: 1
|
|
- n_desc: 0
|
|
- n_value: 0
|
|
- StringTable:
|
|
- - ''
|
|
- - _main
|
|
- - ''
|
|
-...
|
|
diff --git a/lld/test/MachO/invalid/archive-no-index.s b/lld/test/MachO/invalid/archive-no-index.s
|
|
deleted file mode 100644
|
|
index 0f2f023e83c..00000000000
|
|
--- a/lld/test/MachO/invalid/archive-no-index.s
|
|
+++ /dev/null
|
|
@@ -1,17 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: mkdir -p %t
|
|
-# RUN: echo ".global _boo; _boo: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/2.o
|
|
-# RUN: echo ".global _bar; _bar: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/3.o
|
|
-# RUN: echo ".global _undefined; .global _unused; _unused: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/4.o
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/main.o
|
|
-
|
|
-# RUN: rm -f %t/test.a
|
|
-# RUN: llvm-ar rcS %t/test.a %t/2.o %t/3.o %t/4.o
|
|
-
|
|
-# RUN: not lld -flavor darwinnew %t/test.o %t/test.a -o /dev/null 2>&1 | FileCheck %s
|
|
-# CHECK: error: {{.*}}.a: archive has no index; run ranlib to add one
|
|
-
|
|
-.global _main
|
|
-_main:
|
|
- mov $0, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/invalid/bad-archive.s b/lld/test/MachO/invalid/bad-archive.s
|
|
deleted file mode 100644
|
|
index 9429dc3ec31..00000000000
|
|
--- a/lld/test/MachO/invalid/bad-archive.s
|
|
+++ /dev/null
|
|
@@ -1,11 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: echo "!<arch>" > %t.a
|
|
-# RUN: echo "foo" >> %t.a
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-
|
|
-# RUN: not lld -flavor darwinnew %t.o %t.a -o /dev/null 2>&1 | FileCheck -DFILE=%t.a %s
|
|
-# CHECK: error: [[FILE]]: failed to parse archive: truncated or malformed archive (remaining size of archive too small for next archive member header at offset 8)
|
|
-
|
|
-.global _main
|
|
-_main:
|
|
- ret
|
|
diff --git a/lld/test/MachO/invalid/duplicate-symbol.s b/lld/test/MachO/invalid/duplicate-symbol.s
|
|
deleted file mode 100644
|
|
index d08f34fc0de..00000000000
|
|
--- a/lld/test/MachO/invalid/duplicate-symbol.s
|
|
+++ /dev/null
|
|
@@ -1,12 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t-dup.o
|
|
-# RUN: not lld -flavor darwinnew -o /dev/null %t-dup.o %t.o 2>&1 | FileCheck %s
|
|
-
|
|
-# CHECK: error: duplicate symbol: _main
|
|
-
|
|
-.text
|
|
-.global _main
|
|
-_main:
|
|
- mov $0, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/invalid/invalid-executable.s b/lld/test/MachO/invalid/invalid-executable.s
|
|
deleted file mode 100644
|
|
index d8d7accf49c..00000000000
|
|
--- a/lld/test/MachO/invalid/invalid-executable.s
|
|
+++ /dev/null
|
|
@@ -1,11 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -o %t %t.o
|
|
-# RUN: not lld -flavor darwinnew -o /dev/null %t 2>&1 | FileCheck %s -DFILE=%t
|
|
-# CHECK: error: [[FILE]]: unhandled file type
|
|
-
|
|
-.text
|
|
-.global _main
|
|
-_main:
|
|
- mov $0, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/invalid/invalid-fat-narch.s b/lld/test/MachO/invalid/invalid-fat-narch.s
|
|
deleted file mode 100644
|
|
index 2b74893bff4..00000000000
|
|
--- a/lld/test/MachO/invalid/invalid-fat-narch.s
|
|
+++ /dev/null
|
|
@@ -1,12 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: yaml2obj %s -o %t.o
|
|
-# RUN: not lld -flavor darwinnew -o /dev/null %t.o 2>&1 | \
|
|
-# RUN: FileCheck %s -DFILE=%t.o
|
|
-# CHECK: error: [[FILE]]: fat_arch struct extends beyond end of file
|
|
-
|
|
-!fat-mach-o
|
|
-FatHeader:
|
|
- magic: 0xCAFEBABE
|
|
- nfat_arch: 2
|
|
-FatArchs:
|
|
-Slices:
|
|
diff --git a/lld/test/MachO/invalid/invalid-fat-offset.s b/lld/test/MachO/invalid/invalid-fat-offset.s
|
|
deleted file mode 100644
|
|
index fed97907352..00000000000
|
|
--- a/lld/test/MachO/invalid/invalid-fat-offset.s
|
|
+++ /dev/null
|
|
@@ -1,22 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: yaml2obj %s -o %t.o
|
|
-# RUN: not lld -flavor darwinnew -o /dev/null %t.o 2>&1 | \
|
|
-# RUN: FileCheck %s -DFILE=%t.o
|
|
-# CHECK: error: [[FILE]]: slice extends beyond end of file
|
|
-
|
|
-!fat-mach-o
|
|
-FatHeader:
|
|
- magic: 0xCAFEBABE
|
|
- nfat_arch: 2
|
|
-FatArchs:
|
|
- - cputype: 0x01000007
|
|
- cpusubtype: 0x00000003
|
|
- offset: 0x0000000000001000
|
|
- size: 0
|
|
- align: 12
|
|
- - cputype: 0x00000007
|
|
- cpusubtype: 0x00000003
|
|
- offset: 0x000000000000B000
|
|
- size: 0
|
|
- align: 12
|
|
-Slices:
|
|
diff --git a/lld/test/MachO/invalid/invalid-relocation-length.yaml b/lld/test/MachO/invalid/invalid-relocation-length.yaml
|
|
deleted file mode 100644
|
|
index e256c4fb7a8..00000000000
|
|
--- a/lld/test/MachO/invalid/invalid-relocation-length.yaml
|
|
+++ /dev/null
|
|
@@ -1,99 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: yaml2obj %s -o %t.o
|
|
-# RUN: not lld -flavor darwinnew -o %t %t.o 2>&1 | FileCheck %s -DFILE=%t.o
|
|
-#
|
|
-# CHECK: error: invalid relocation at offset 1 of __TEXT,__text in [[FILE]]: relocations of type 0 must have r_length of 2 or 3
|
|
-
|
|
-!mach-o
|
|
-FileHeader:
|
|
- magic: 0xFEEDFACF
|
|
- cputype: 0x01000007
|
|
- cpusubtype: 0x00000003
|
|
- filetype: 0x00000001
|
|
- ncmds: 4
|
|
- sizeofcmds: 280
|
|
- flags: 0x00000000
|
|
- reserved: 0x00000000
|
|
-LoadCommands:
|
|
- - cmd: LC_SEGMENT_64
|
|
- cmdsize: 152
|
|
- segname: ''
|
|
- vmaddr: 0
|
|
- vmsize: 9
|
|
- fileoff: 312
|
|
- filesize: 9
|
|
- maxprot: 7
|
|
- initprot: 7
|
|
- nsects: 1
|
|
- flags: 0
|
|
- Sections:
|
|
- - sectname: __text
|
|
- segname: __TEXT
|
|
- addr: 0x0000000000000000
|
|
- size: 9
|
|
- offset: 0x00000138
|
|
- align: 0
|
|
- reloff: 0x00000144
|
|
- nreloc: 1
|
|
- flags: 0x80000000
|
|
- reserved1: 0x00000000
|
|
- reserved2: 0x00000000
|
|
- reserved3: 0x00000000
|
|
- content: '000000000000000000'
|
|
- relocations:
|
|
- - address: 0x00000001
|
|
- symbolnum: 1
|
|
- pcrel: false
|
|
- length: 1
|
|
- extern: true
|
|
- type: 0
|
|
- scattered: false
|
|
- value: 0
|
|
- - cmd: LC_BUILD_VERSION
|
|
- cmdsize: 24
|
|
- platform: 1
|
|
- minos: 659200
|
|
- sdk: 0
|
|
- ntools: 0
|
|
- - cmd: LC_SYMTAB
|
|
- cmdsize: 24
|
|
- symoff: 332
|
|
- nsyms: 2
|
|
- stroff: 364
|
|
- strsize: 12
|
|
- - cmd: LC_DYSYMTAB
|
|
- cmdsize: 80
|
|
- ilocalsym: 0
|
|
- nlocalsym: 0
|
|
- iextdefsym: 0
|
|
- nextdefsym: 2
|
|
- iundefsym: 2
|
|
- nundefsym: 0
|
|
- tocoff: 0
|
|
- ntoc: 0
|
|
- modtaboff: 0
|
|
- nmodtab: 0
|
|
- extrefsymoff: 0
|
|
- nextrefsyms: 0
|
|
- indirectsymoff: 0
|
|
- nindirectsyms: 0
|
|
- extreloff: 0
|
|
- nextrel: 0
|
|
- locreloff: 0
|
|
- nlocrel: 0
|
|
-LinkEditData:
|
|
- NameList:
|
|
- - n_strx: 1
|
|
- n_type: 0x0F
|
|
- n_sect: 1
|
|
- n_desc: 0
|
|
- n_value: 1
|
|
- - n_strx: 6
|
|
- n_type: 0x0F
|
|
- n_sect: 1
|
|
- n_desc: 0
|
|
- n_value: 9
|
|
- StringTable:
|
|
- - ''
|
|
- - _foo
|
|
- - _main
|
|
diff --git a/lld/test/MachO/invalid/invalid-relocation-pcrel.yaml b/lld/test/MachO/invalid/invalid-relocation-pcrel.yaml
|
|
deleted file mode 100644
|
|
index ed7c24ead74..00000000000
|
|
--- a/lld/test/MachO/invalid/invalid-relocation-pcrel.yaml
|
|
+++ /dev/null
|
|
@@ -1,99 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: yaml2obj %s -o %t.o
|
|
-# RUN: not lld -flavor darwinnew -o %t %t.o 2>&1 | FileCheck %s -DFILE=%t.o
|
|
-#
|
|
-# CHECK: error: invalid relocation at offset 1 of __TEXT,__text in [[FILE]]: relocations of type 0 must not be pcrel
|
|
-
|
|
-!mach-o
|
|
-FileHeader:
|
|
- magic: 0xFEEDFACF
|
|
- cputype: 0x01000007
|
|
- cpusubtype: 0x00000003
|
|
- filetype: 0x00000001
|
|
- ncmds: 4
|
|
- sizeofcmds: 280
|
|
- flags: 0x00000000
|
|
- reserved: 0x00000000
|
|
-LoadCommands:
|
|
- - cmd: LC_SEGMENT_64
|
|
- cmdsize: 152
|
|
- segname: ''
|
|
- vmaddr: 0
|
|
- vmsize: 9
|
|
- fileoff: 312
|
|
- filesize: 9
|
|
- maxprot: 7
|
|
- initprot: 7
|
|
- nsects: 1
|
|
- flags: 0
|
|
- Sections:
|
|
- - sectname: __text
|
|
- segname: __TEXT
|
|
- addr: 0x0000000000000000
|
|
- size: 9
|
|
- offset: 0x00000138
|
|
- align: 0
|
|
- reloff: 0x00000144
|
|
- nreloc: 1
|
|
- flags: 0x80000000
|
|
- reserved1: 0x00000000
|
|
- reserved2: 0x00000000
|
|
- reserved3: 0x00000000
|
|
- content: '000000000000000000'
|
|
- relocations:
|
|
- - address: 0x00000001
|
|
- symbolnum: 1
|
|
- pcrel: true
|
|
- length: 3
|
|
- extern: true
|
|
- type: 0
|
|
- scattered: false
|
|
- value: 0
|
|
- - cmd: LC_BUILD_VERSION
|
|
- cmdsize: 24
|
|
- platform: 1
|
|
- minos: 659200
|
|
- sdk: 0
|
|
- ntools: 0
|
|
- - cmd: LC_SYMTAB
|
|
- cmdsize: 24
|
|
- symoff: 332
|
|
- nsyms: 2
|
|
- stroff: 364
|
|
- strsize: 12
|
|
- - cmd: LC_DYSYMTAB
|
|
- cmdsize: 80
|
|
- ilocalsym: 0
|
|
- nlocalsym: 0
|
|
- iextdefsym: 0
|
|
- nextdefsym: 2
|
|
- iundefsym: 2
|
|
- nundefsym: 0
|
|
- tocoff: 0
|
|
- ntoc: 0
|
|
- modtaboff: 0
|
|
- nmodtab: 0
|
|
- extrefsymoff: 0
|
|
- nextrefsyms: 0
|
|
- indirectsymoff: 0
|
|
- nindirectsyms: 0
|
|
- extreloff: 0
|
|
- nextrel: 0
|
|
- locreloff: 0
|
|
- nlocrel: 0
|
|
-LinkEditData:
|
|
- NameList:
|
|
- - n_strx: 1
|
|
- n_type: 0x0F
|
|
- n_sect: 1
|
|
- n_desc: 0
|
|
- n_value: 1
|
|
- - n_strx: 6
|
|
- n_type: 0x0F
|
|
- n_sect: 1
|
|
- n_desc: 0
|
|
- n_value: 9
|
|
- StringTable:
|
|
- - ''
|
|
- - _foo
|
|
- - _main
|
|
diff --git a/lld/test/MachO/invalid/missing-dylib.s b/lld/test/MachO/invalid/missing-dylib.s
|
|
deleted file mode 100644
|
|
index ad7e51130c4..00000000000
|
|
--- a/lld/test/MachO/invalid/missing-dylib.s
|
|
+++ /dev/null
|
|
@@ -1,5 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: not lld -flavor darwinnew -Z -o %t -lmissing %t.o 2>&1 | FileCheck %s
|
|
-
|
|
-# CHECK: error: library not found for -lmissing
|
|
diff --git a/lld/test/MachO/invalid/no-id-dylink.yaml b/lld/test/MachO/invalid/no-id-dylink.yaml
|
|
deleted file mode 100644
|
|
index d5b0b33dcfe..00000000000
|
|
--- a/lld/test/MachO/invalid/no-id-dylink.yaml
|
|
+++ /dev/null
|
|
@@ -1,166 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: mkdir -p %t
|
|
-# RUN: yaml2obj %s -o %t/libnoid.dylib
|
|
-# RUN: echo ".globl _main; .text; _main: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/no-id-dylink.o
|
|
-# RUN: not lld -flavor darwinnew -o %t/no-id-dylink -Z -L%t -lnoid %t/no-id-dylink.o 2>&1 | FileCheck %s
|
|
-# CHECK: error: dylib {{.*}}libnoid.dylib missing LC_ID_DYLIB load command
|
|
-
|
|
-## This YAML file was originally generated from linking the following source
|
|
-## input with ld64 and passing the resulting binary through obj2yaml:
|
|
-##
|
|
-## .section __TEXT,__cstring
|
|
-## .globl _hello_world
|
|
-##
|
|
-## _hello_world:
|
|
-## .asciz "Hello world!\n"
|
|
-##
|
|
-## Then we deleted the LC_ID_DYLIB command from the file.
|
|
-
|
|
-!mach-o
|
|
-FileHeader:
|
|
- magic: 0xFEEDFACF
|
|
- cputype: 0x01000007
|
|
- cpusubtype: 0x00000003
|
|
- filetype: 0x00000006
|
|
- ncmds: 10
|
|
- sizeofcmds: 616
|
|
- flags: 0x00100085
|
|
- reserved: 0x00000000
|
|
-LoadCommands:
|
|
- - cmd: LC_SEGMENT_64
|
|
- cmdsize: 232
|
|
- segname: __TEXT
|
|
- vmaddr: 0
|
|
- vmsize: 4096
|
|
- fileoff: 0
|
|
- filesize: 4096
|
|
- maxprot: 5
|
|
- initprot: 5
|
|
- nsects: 2
|
|
- flags: 0
|
|
- Sections:
|
|
- - sectname: __text
|
|
- segname: __TEXT
|
|
- addr: 0x0000000000000FF2
|
|
- size: 0
|
|
- offset: 0x00000FF2
|
|
- align: 0
|
|
- reloff: 0x00000000
|
|
- nreloc: 0
|
|
- flags: 0x80000400
|
|
- reserved1: 0x00000000
|
|
- reserved2: 0x00000000
|
|
- reserved3: 0x00000000
|
|
- content: ''
|
|
- - sectname: __cstring
|
|
- segname: __TEXT
|
|
- addr: 0x0000000000000FF2
|
|
- size: 14
|
|
- offset: 0x00000FF2
|
|
- align: 0
|
|
- reloff: 0x00000000
|
|
- nreloc: 0
|
|
- flags: 0x00000002
|
|
- reserved1: 0x00000000
|
|
- reserved2: 0x00000000
|
|
- reserved3: 0x00000000
|
|
- content: 48656C6C6F20776F726C64210A00
|
|
- - cmd: LC_SEGMENT_64
|
|
- cmdsize: 72
|
|
- segname: __LINKEDIT
|
|
- vmaddr: 4096
|
|
- vmsize: 4096
|
|
- fileoff: 4096
|
|
- filesize: 64
|
|
- maxprot: 1
|
|
- initprot: 1
|
|
- nsects: 0
|
|
- flags: 0
|
|
- - cmd: LC_DYLD_INFO_ONLY
|
|
- cmdsize: 48
|
|
- rebase_off: 0
|
|
- rebase_size: 0
|
|
- bind_off: 0
|
|
- bind_size: 0
|
|
- weak_bind_off: 0
|
|
- weak_bind_size: 0
|
|
- lazy_bind_off: 0
|
|
- lazy_bind_size: 0
|
|
- export_off: 4096
|
|
- export_size: 24
|
|
- - cmd: LC_SYMTAB
|
|
- cmdsize: 24
|
|
- symoff: 4128
|
|
- nsyms: 1
|
|
- stroff: 4144
|
|
- strsize: 16
|
|
- - cmd: LC_DYSYMTAB
|
|
- cmdsize: 80
|
|
- ilocalsym: 0
|
|
- nlocalsym: 0
|
|
- iextdefsym: 0
|
|
- nextdefsym: 1
|
|
- iundefsym: 1
|
|
- nundefsym: 0
|
|
- tocoff: 0
|
|
- ntoc: 0
|
|
- modtaboff: 0
|
|
- nmodtab: 0
|
|
- extrefsymoff: 0
|
|
- nextrefsyms: 0
|
|
- indirectsymoff: 0
|
|
- nindirectsyms: 0
|
|
- extreloff: 0
|
|
- nextrel: 0
|
|
- locreloff: 0
|
|
- nlocrel: 0
|
|
- - cmd: LC_UUID
|
|
- cmdsize: 24
|
|
- uuid: 4826226E-9210-3984-A388-D5BD6D6DB368
|
|
- - cmd: LC_BUILD_VERSION
|
|
- cmdsize: 32
|
|
- platform: 1
|
|
- minos: 659200
|
|
- sdk: 659200
|
|
- ntools: 1
|
|
- Tools:
|
|
- - tool: 3
|
|
- version: 34734080
|
|
- - cmd: LC_SOURCE_VERSION
|
|
- cmdsize: 16
|
|
- version: 0
|
|
- - cmd: LC_FUNCTION_STARTS
|
|
- cmdsize: 16
|
|
- dataoff: 4120
|
|
- datasize: 8
|
|
- - cmd: LC_DATA_IN_CODE
|
|
- cmdsize: 16
|
|
- dataoff: 4128
|
|
- datasize: 0
|
|
-LinkEditData:
|
|
- ExportTrie:
|
|
- TerminalSize: 0
|
|
- NodeOffset: 0
|
|
- Name: ''
|
|
- Flags: 0x0000000000000000
|
|
- Address: 0x0000000000000000
|
|
- Other: 0x0000000000000000
|
|
- ImportName: ''
|
|
- Children:
|
|
- - TerminalSize: 3
|
|
- NodeOffset: 16
|
|
- Name: _hello_world
|
|
- Flags: 0x0000000000000000
|
|
- Address: 0x0000000000000FF2
|
|
- Other: 0x0000000000000000
|
|
- ImportName: ''
|
|
- NameList:
|
|
- - n_strx: 2
|
|
- n_type: 0x0F
|
|
- n_sect: 2
|
|
- n_desc: 0
|
|
- n_value: 4082
|
|
- StringTable:
|
|
- - ' '
|
|
- - _hello_world
|
|
- - ''
|
|
diff --git a/lld/test/MachO/invalid/no-such-file.s b/lld/test/MachO/invalid/no-such-file.s
|
|
deleted file mode 100644
|
|
index 0122c6105fb..00000000000
|
|
--- a/lld/test/MachO/invalid/no-such-file.s
|
|
+++ /dev/null
|
|
@@ -1,4 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: not lld -flavor darwinnew -o /dev/null %t-no-such-file.o 2>&1 | FileCheck %s
|
|
-
|
|
-# CHECK: error: cannot open {{.*}}no-such-file.o
|
|
diff --git a/lld/test/MachO/invalid/order-file-bad-arch.test b/lld/test/MachO/invalid/order-file-bad-arch.test
|
|
deleted file mode 100644
|
|
index 84fe6963d24..00000000000
|
|
--- a/lld/test/MachO/invalid/order-file-bad-arch.test
|
|
+++ /dev/null
|
|
@@ -1,9 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: echo ".globl _main; .text; _main: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t.o
|
|
-# RUN: not lld -flavor darwinnew -o %t %t.o -order_file %s 2>&1 | FileCheck %s
|
|
-# CHECK: error: invalid arch "sparc" in order file: expected one of arm, arm64, i386, x86_64, ppc, ppc64
|
|
-# CHECK-EMPTY:
|
|
-
|
|
-_barsymbol
|
|
-sparc:hello.o:_foosymbol
|
|
-i386:hello.o:_foosymbol
|
|
diff --git a/lld/test/MachO/invalid/order-file-bad-objfile.test b/lld/test/MachO/invalid/order-file-bad-objfile.test
|
|
deleted file mode 100644
|
|
index 19e9404da42..00000000000
|
|
--- a/lld/test/MachO/invalid/order-file-bad-objfile.test
|
|
+++ /dev/null
|
|
@@ -1,10 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: echo ".globl _main; .text; _main: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t.o
|
|
-# RUN: not lld -flavor darwinnew -o %t %t.o -order_file %s 2>&1 | FileCheck %s
|
|
-# CHECK: invalid object file name "helloo" in order file: should end with .o
|
|
-# CHECK: invalid object file name "z80" in order file: should end with .o
|
|
-# CHECK-EMPTY:
|
|
-
|
|
-_barsymbol
|
|
-x86_64:helloo:_foosymbol
|
|
-z80:_foosymbol
|
|
diff --git a/lld/test/MachO/invalid/reserved-section-name.s b/lld/test/MachO/invalid/reserved-section-name.s
|
|
deleted file mode 100644
|
|
index 8d767bcf292..00000000000
|
|
--- a/lld/test/MachO/invalid/reserved-section-name.s
|
|
+++ /dev/null
|
|
@@ -1,14 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: not lld -flavor darwinnew -o %t %t.o 2>&1 | FileCheck %s -DFILE=%t.o
|
|
-# CHECK: error: section from [[FILE]] conflicts with synthetic section __DATA_CONST,__got
|
|
-
|
|
-.globl _main
|
|
-
|
|
-.section __DATA_CONST,__got
|
|
-.space 1
|
|
-
|
|
-.text
|
|
-_main:
|
|
- mov $0, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/invalid/stub-link.s b/lld/test/MachO/invalid/stub-link.s
|
|
deleted file mode 100644
|
|
index f1c15903702..00000000000
|
|
--- a/lld/test/MachO/invalid/stub-link.s
|
|
+++ /dev/null
|
|
@@ -1,15 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-
|
|
-# RUN: mkdir -p %t
|
|
-#
|
|
-# RUN: llvm-mc -filetype obj -triple x86_64-apple-ios %s -o %t/test.o
|
|
-# RUN: not lld -flavor darwinnew -o %t/test -Z -L%S/../Inputs/iPhoneSimulator.sdk/usr/lib -lSystem %t/test.o 2>&1 | FileCheck %s
|
|
-
|
|
-# CHECK: error: undefined symbol __cache_handle_memory_pressure_event
|
|
-
|
|
-.section __TEXT,__text
|
|
-.global _main
|
|
-
|
|
-_main:
|
|
- movq __cache_handle_memory_pressure_event@GOTPCREL(%rip), %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/invalid/undefined-symbol.s b/lld/test/MachO/invalid/undefined-symbol.s
|
|
deleted file mode 100644
|
|
index 88eabfd1ce0..00000000000
|
|
--- a/lld/test/MachO/invalid/undefined-symbol.s
|
|
+++ /dev/null
|
|
@@ -1,11 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: not lld -flavor darwinnew -Z -o %t %t.o 2>&1 | FileCheck %s -DBASENAME=%basename_t
|
|
-# CHECK: error: undefined symbol _foo, referenced from [[BASENAME]]
|
|
-
|
|
-.globl _main
|
|
-.text
|
|
-_main:
|
|
- callq _foo
|
|
- movq $0, %rax
|
|
- retq
|
|
diff --git a/lld/test/MachO/link-search-order.s b/lld/test/MachO/link-search-order.s
|
|
deleted file mode 100644
|
|
index 9819e171c7d..00000000000
|
|
--- a/lld/test/MachO/link-search-order.s
|
|
+++ /dev/null
|
|
@@ -1,43 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-
|
|
-# RUN: mkdir -p %t
|
|
-#
|
|
-# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %p/Inputs/libhello.s -o %t/hello.o
|
|
-# RUN: lld -flavor darwinnew -dylib -install_name @executable_path/libhello.dylib %t/hello.o -o %t/libhello.dylib
|
|
-#
|
|
-# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %p/Inputs/libgoodbye.s -o %t/goodbye.o
|
|
-# RUN: lld -flavor darwinnew -dylib -install_name @executable_path/libgoodbye.dylib %t/goodbye.o -o %t/libgoodbye.dylib
|
|
-# RUN: llvm-ar --format=darwin crs %t/libgoodbye.a %t/goodbye.o
|
|
-#
|
|
-# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %s -o %t/test.o
|
|
-# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -o %t/test -Z -L%t -lhello -lgoodbye -lSystem %t/test.o
|
|
-#
|
|
-# RUN: llvm-objdump --macho --dylibs-used %t/test | FileCheck %s
|
|
-
|
|
-# CHECK: @executable_path/libhello.dylib
|
|
-# CHECK: @executable_path/libgoodbye.dylib
|
|
-# CHECK: /usr/lib/libSystem.B.dylib
|
|
-
|
|
-.section __TEXT,__text
|
|
-.global _main
|
|
-
|
|
-_main:
|
|
- movl $0x2000004, %eax # write()
|
|
- mov $1, %rdi # stdout
|
|
- movq _hello_world@GOTPCREL(%rip), %rsi
|
|
- mov $13, %rdx # length
|
|
- syscall
|
|
-
|
|
- movl $0x2000004, %eax # write()
|
|
- mov $1, %rdi # stdout
|
|
- movq _hello_its_me@GOTPCREL(%rip), %rsi
|
|
- mov $15, %rdx # length
|
|
- syscall
|
|
-
|
|
- movl $0x2000004, %eax # write()
|
|
- mov $1, %rdi # stdout
|
|
- movq _goodbye_world@GOTPCREL(%rip), %rsi
|
|
- mov $15, %rdx # length
|
|
- syscall
|
|
- mov $0, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/load-commands.s b/lld/test/MachO/load-commands.s
|
|
deleted file mode 100644
|
|
index c9f5d9b5c21..00000000000
|
|
--- a/lld/test/MachO/load-commands.s
|
|
+++ /dev/null
|
|
@@ -1,22 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -o %t %t.o
|
|
-
|
|
-## Check for the presence of load commands that are essential for a working
|
|
-## executable.
|
|
-# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s
|
|
-# CHECK-DAG: cmd LC_DYLD_INFO_ONLY
|
|
-# CHECK-DAG: cmd LC_SYMTAB
|
|
-# CHECK-DAG: cmd LC_DYSYMTAB
|
|
-# CHECK-DAG: cmd LC_MAIN
|
|
-# CHECK-DAG: cmd LC_LOAD_DYLINKER
|
|
-
|
|
-## Check for the absence of load commands that should not be in an executable.
|
|
-# RUN: llvm-objdump --macho --all-headers %t | FileCheck %s --check-prefix=NCHECK
|
|
-# NCHECK-NOT: cmd: LC_ID_DYLIB
|
|
-
|
|
-.text
|
|
-.global _main
|
|
-_main:
|
|
- mov $0, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/local-got.s b/lld/test/MachO/local-got.s
|
|
deleted file mode 100644
|
|
index 6099a6bf18c..00000000000
|
|
--- a/lld/test/MachO/local-got.s
|
|
+++ /dev/null
|
|
@@ -1,58 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: mkdir -p %t
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %p/Inputs/libhello.s \
|
|
-# RUN: -o %t/libhello.o
|
|
-# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem -dylib -install_name \
|
|
-# RUN: @executable_path/libhello.dylib %t/libhello.o -o %t/libhello.dylib
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/test.o
|
|
-# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem -o %t/test %t/test.o -L%t -lhello
|
|
-# RUN: llvm-objdump --full-contents --bind %t/test | FileCheck %s --match-full-lines
|
|
-
|
|
-## Check that the GOT references the cstrings. --full-contents displays the
|
|
-## 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: 1000003cc {{.*}}
|
|
-
|
|
-## 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:]] da030000 01000000 cc030000 01000000 {{.*}}
|
|
-# CHECK-NEXT: [[#ADDR + 16]] 00000000 00000000 {{.*}}
|
|
-
|
|
-## Check that a non-locally-defined symbol is still bound at the correct offset:
|
|
-# CHECK: Bind table:
|
|
-# CHECK-NEXT: segment section address type addend dylib symbol
|
|
-# CHECK-NEXT: __DATA_CONST __got 0x[[#ADDR+16]] pointer 0 libhello _hello_its_me
|
|
-
|
|
-.globl _main
|
|
-
|
|
-.text
|
|
-_main:
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- movq _hello_its_me@GOTPCREL(%rip), %rsi
|
|
- mov $15, %rdx # length of str
|
|
- syscall
|
|
-
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- movq _hello_world@GOTPCREL(%rip), %rsi
|
|
- mov $13, %rdx # length of str
|
|
- syscall
|
|
-
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- movq _goodbye_world@GOTPCREL(%rip), %rsi
|
|
- mov $15, %rdx # length of str
|
|
- syscall
|
|
-
|
|
- mov $0, %rax
|
|
- ret
|
|
-
|
|
-.section __TEXT,__cstring
|
|
-_hello_world:
|
|
- .asciz "Hello world!\n"
|
|
-
|
|
-_goodbye_world:
|
|
- .asciz "Goodbye world!\n"
|
|
diff --git a/lld/test/MachO/no-exports-dylib.s b/lld/test/MachO/no-exports-dylib.s
|
|
deleted file mode 100644
|
|
index 896c31ef3c2..00000000000
|
|
--- a/lld/test/MachO/no-exports-dylib.s
|
|
+++ /dev/null
|
|
@@ -1,6 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -dylib %t.o -o %t.dylib
|
|
-
|
|
-# RUN: obj2yaml %t.dylib | FileCheck %s
|
|
-# CHECK: export_size: 0
|
|
diff --git a/lld/test/MachO/order-file.s b/lld/test/MachO/order-file.s
|
|
deleted file mode 100644
|
|
index 4ced92a4eca..00000000000
|
|
--- a/lld/test/MachO/order-file.s
|
|
+++ /dev/null
|
|
@@ -1,131 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: mkdir -p %t
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/test.o
|
|
-# RUN: echo ".globl _foo; .text; _foo: _bar: ret" | \
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/foo.o
|
|
-# RUN: rm -f %t/foo.a
|
|
-# RUN: llvm-ar rcs %t/foo.a %t/foo.o
|
|
-
|
|
-# FOO-FIRST: <_foo>:
|
|
-# FOO-FIRST: <_main>:
|
|
-
|
|
-# FOO-SECOND: <_main>:
|
|
-# FOO-SECOND: <_foo>:
|
|
-
|
|
-# RUN: echo "_foo # just a comment" > %t/ord-1
|
|
-# RUN: echo "_main # another comment" >> %t/ord-1
|
|
-# RUN: lld -flavor darwinnew -o %t/test-1 %t/test.o %t/foo.o -order_file %t/ord-1
|
|
-# RUN: llvm-objdump -d %t/test-1 | FileCheck %s --check-prefix=FOO-FIRST
|
|
-## Output should be the same regardless of the command-line order of object files
|
|
-# RUN: lld -flavor darwinnew -o %t/test-1 %t/foo.o %t/test.o -order_file %t/ord-1
|
|
-# RUN: llvm-objdump -d %t/test-1 | FileCheck %s --check-prefix=FOO-FIRST
|
|
-
|
|
-# RUN: echo "_main # just a comment" > %t/ord-2
|
|
-# RUN: echo "_foo # another comment" >> %t/ord-2
|
|
-# RUN: lld -flavor darwinnew -o %t/test-2 %t/test.o %t/foo.o -order_file %t/ord-2
|
|
-# RUN: llvm-objdump -d %t/test-2 | FileCheck %s --check-prefix=FOO-SECOND
|
|
-# RUN: lld -flavor darwinnew -o %t/test-2 %t/foo.o %t/test.o -order_file %t/ord-2
|
|
-# RUN: llvm-objdump -d %t/test-2 | FileCheck %s --check-prefix=FOO-SECOND
|
|
-
|
|
-# RUN: echo "foo.o:_foo" > %t/ord-file-match
|
|
-# RUN: echo "_main" >> %t/ord-file-match
|
|
-# RUN: lld -flavor darwinnew -o %t/test-file-match %t/test.o %t/foo.o -order_file %t/ord-file-match
|
|
-# RUN: llvm-objdump -d %t/test-file-match | FileCheck %s --check-prefix=FOO-FIRST
|
|
-## Output should be the same regardless of the command-line order of object files
|
|
-# RUN: lld -flavor darwinnew -o %t/test-file-match %t/foo.o %t/test.o -order_file %t/ord-file-match
|
|
-# RUN: llvm-objdump -d %t/test-file-match | FileCheck %s --check-prefix=FOO-FIRST
|
|
-
|
|
-# RUN: echo "bar.o:_foo" > %t/ord-file-nomatch
|
|
-# RUN: echo "_main" >> %t/ord-file-nomatch
|
|
-# RUN: echo "_foo" >> %t/ord-file-nomatch
|
|
-# RUN: lld -flavor darwinnew -o %t/test-file-nomatch %t/test.o %t/foo.o -order_file %t/ord-file-nomatch
|
|
-# RUN: llvm-objdump -d %t/test-file-nomatch | FileCheck %s --check-prefix=FOO-SECOND
|
|
-# RUN: lld -flavor darwinnew -o %t/test-file-nomatch %t/foo.o %t/test.o -order_file %t/ord-file-nomatch
|
|
-# RUN: llvm-objdump -d %t/test-file-nomatch | FileCheck %s --check-prefix=FOO-SECOND
|
|
-
|
|
-# RUN: echo "x86_64:_foo" > %t/ord-arch-match
|
|
-# RUN: echo "_main" >> %t/ord-arch-match
|
|
-# RUN: lld -flavor darwinnew -o %t/test-arch-match %t/test.o %t/foo.o -order_file %t/ord-arch-match
|
|
-# RUN: llvm-objdump -d %t/test-arch-match | FileCheck %s --check-prefix=FOO-FIRST
|
|
-# RUN: lld -flavor darwinnew -o %t/test-arch-match %t/foo.o %t/test.o -order_file %t/ord-arch-match
|
|
-# RUN: llvm-objdump -d %t/test-arch-match | FileCheck %s --check-prefix=FOO-FIRST
|
|
-
|
|
-# RUN: echo "ppc:_foo" > %t/ord-arch-nomatch
|
|
-# RUN: echo "_main" >> %t/ord-arch-nomatch
|
|
-# RUN: echo "_foo" >> %t/ord-arch-nomatch
|
|
-# RUN: lld -flavor darwinnew -o %t/test-arch-nomatch %t/test.o %t/foo.o -order_file %t/ord-arch-nomatch
|
|
-# RUN: llvm-objdump -d %t/test-arch-nomatch | FileCheck %s --check-prefix=FOO-SECOND
|
|
-# RUN: lld -flavor darwinnew -o %t/test-arch-nomatch %t/foo.o %t/test.o -order_file %t/ord-arch-nomatch
|
|
-# RUN: llvm-objdump -d %t/test-arch-nomatch | FileCheck %s --check-prefix=FOO-SECOND
|
|
-
|
|
-# RUN: echo "x86_64:bar.o:_foo" > %t/ord-arch-file-match
|
|
-# RUN: echo "_main" >> %t/ord-arch-match
|
|
-# RUN: lld -flavor darwinnew -o %t/test-arch-match %t/test.o %t/foo.o -order_file %t/ord-arch-match
|
|
-# RUN: llvm-objdump -d %t/test-arch-match | FileCheck %s --check-prefix=FOO-FIRST
|
|
-# RUN: lld -flavor darwinnew -o %t/test-arch-match %t/foo.o %t/test.o -order_file %t/ord-arch-match
|
|
-# RUN: llvm-objdump -d %t/test-arch-match | FileCheck %s --check-prefix=FOO-FIRST
|
|
-
|
|
-## Test archives
|
|
-
|
|
-# RUN: lld -flavor darwinnew -o %t/test-archive-1 %t/test.o %t/foo.a -order_file %t/ord-1
|
|
-# RUN: llvm-objdump -d %t/test-archive-1 | FileCheck %s --check-prefix=FOO-FIRST
|
|
-# RUN: lld -flavor darwinnew -o %t/test-archive-1 %t/foo.a %t/test.o -order_file %t/ord-1
|
|
-# RUN: llvm-objdump -d %t/test-archive-1 | FileCheck %s --check-prefix=FOO-FIRST
|
|
-
|
|
-# RUN: lld -flavor darwinnew -o %t/test-archive-file-no-match %t/test.o %t/foo.a -order_file %t/ord-file-nomatch
|
|
-# RUN: llvm-objdump -d %t/test-archive-file-no-match | FileCheck %s --check-prefix=FOO-SECOND
|
|
-# RUN: lld -flavor darwinnew -o %t/test-archive %t/foo.a %t/test.o -order_file %t/ord-file-nomatch
|
|
-# RUN: llvm-objdump -d %t/test-archive-file-no-match | FileCheck %s --check-prefix=FOO-SECOND
|
|
-
|
|
-## The following tests check that if an address is matched by multiple order
|
|
-## file entries, it should always use the lowest-ordered match.
|
|
-
|
|
-# RUN: echo "_foo" > %t/ord-multiple-1
|
|
-# RUN: echo "_main" >> %t/ord-multiple-1
|
|
-# RUN: echo "foo.o:_foo" >> %t/ord-multiple-1
|
|
-# RUN: lld -flavor darwinnew -o %t/test-1 %t/test.o %t/foo.o -order_file %t/ord-multiple-1
|
|
-# RUN: llvm-objdump -d %t/test-1 | FileCheck %s --check-prefix=FOO-FIRST
|
|
-# RUN: lld -flavor darwinnew -o %t/test-1 %t/foo.o %t/test.o -order_file %t/ord-multiple-1
|
|
-# RUN: llvm-objdump -d %t/test-1 | FileCheck %s --check-prefix=FOO-FIRST
|
|
-
|
|
-# RUN: echo "foo.o:_foo" > %t/ord-multiple-2
|
|
-# RUN: echo "_main" >> %t/ord-multiple-2
|
|
-# RUN: echo "_foo" >> %t/ord-multiple-2
|
|
-# RUN: lld -flavor darwinnew -o %t/test-2 %t/test.o %t/foo.o -order_file %t/ord-multiple-2
|
|
-# RUN: llvm-objdump -d %t/test-2 | FileCheck %s --check-prefix=FOO-FIRST
|
|
-# RUN: lld -flavor darwinnew -o %t/test-2 %t/foo.o %t/test.o -order_file %t/ord-multiple-2
|
|
-# RUN: llvm-objdump -d %t/test-2 | FileCheck %s --check-prefix=FOO-FIRST
|
|
-
|
|
-# RUN: echo "_foo" > %t/ord-multiple-3
|
|
-# RUN: echo "_main" >> %t/ord-multiple-3
|
|
-# RUN: echo "_foo" >> %t/ord-multiple-3
|
|
-# RUN: lld -flavor darwinnew -o %t/test-3 %t/test.o %t/foo.o -order_file %t/ord-multiple-3
|
|
-# RUN: llvm-objdump -d %t/test-3 | FileCheck %s --check-prefix=FOO-FIRST
|
|
-# RUN: lld -flavor darwinnew -o %t/test-3 %t/foo.o %t/test.o -order_file %t/ord-multiple-3
|
|
-# RUN: llvm-objdump -d %t/test-3 | FileCheck %s --check-prefix=FOO-FIRST
|
|
-
|
|
-# RUN: echo "foo.o:_foo" > %t/ord-multiple-4
|
|
-# RUN: echo "_main" >> %t/ord-multiple-4
|
|
-# RUN: echo "foo.o:_foo" >> %t/ord-multiple-4
|
|
-# RUN: lld -flavor darwinnew -o %t/test-4 %t/test.o %t/foo.o -order_file %t/ord-multiple-4
|
|
-# RUN: llvm-objdump -d %t/test-4 | FileCheck %s --check-prefix=FOO-FIRST
|
|
-# RUN: lld -flavor darwinnew -o %t/test-4 %t/foo.o %t/test.o -order_file %t/ord-multiple-4
|
|
-# RUN: llvm-objdump -d %t/test-4 | FileCheck %s --check-prefix=FOO-FIRST
|
|
-
|
|
-## _foo and _bar both point to the same location. When both symbols appear in
|
|
-## an order file, the location in question should be ordered according to the
|
|
-## lowest-ordered symbol that references it.
|
|
-# RUN: echo "_bar" > %t/ord-alias
|
|
-# RUN: echo "_main" >> %t/ord-alias
|
|
-# RUN: echo "_foo" >> %t/ord-alias
|
|
-# RUN: lld -flavor darwinnew -o %t/test-alias %t/test.o %t/foo.o -order_file %t/ord-alias
|
|
-# RUN: llvm-objdump -d %t/test-alias | FileCheck %s --check-prefix=FOO-FIRST
|
|
-# RUN: lld -flavor darwinnew -o %t/test-alias %t/foo.o %t/test.o -order_file %t/ord-alias
|
|
-# RUN: llvm-objdump -d %t/test-alias | FileCheck %s --check-prefix=FOO-FIRST
|
|
-
|
|
-.text
|
|
-.globl _main
|
|
-
|
|
-_main:
|
|
- callq _foo
|
|
- ret
|
|
diff --git a/lld/test/MachO/platform-version.test b/lld/test/MachO/platform-version.test
|
|
deleted file mode 100644
|
|
index baa4ced08fb..00000000000
|
|
--- a/lld/test/MachO/platform-version.test
|
|
+++ /dev/null
|
|
@@ -1,17 +0,0 @@
|
|
-# RUN: not lld -flavor darwinnew -platform_version 2>&1 \
|
|
-# RUN: | FileCheck --check-prefix=MISSING %s
|
|
-# RUN: not lld -flavor darwinnew -platform_version macos 2>&1 \
|
|
-# RUN: | FileCheck --check-prefix=MISSING %s
|
|
-# RUN: not lld -flavor darwinnew -platform_version macos 10.15 2>&1 \
|
|
-# RUN: | FileCheck --check-prefix=MISSING %s
|
|
-# RUN: not lld -flavor darwinnew -platform_version macos -lfoo 10.15 2>&1 \
|
|
-# RUN: | FileCheck --check-prefix=GOOD %s
|
|
-# RUN: not lld -flavor darwinnew -platform_version macos 10.15 10.15.4 2>&1 \
|
|
-# RUN: | FileCheck --check-prefix=GOOD %s
|
|
-# RUN: not lld -flavor darwinnew -platform_version macos 10.15 10.15.4 foobar 2>&1 \
|
|
-# RUN: | FileCheck --check-prefix=FAIL_FILE %s
|
|
-
|
|
-MISSING: -platform_version: missing argument
|
|
-FAIL: usage: -platform_version platform min_version sdk_version
|
|
-GOOD: undefined symbol: _main
|
|
-FAIL_FILE: cannot open foobar
|
|
diff --git a/lld/test/MachO/relocations.s b/lld/test/MachO/relocations.s
|
|
deleted file mode 100644
|
|
index edaa3089356..00000000000
|
|
--- a/lld/test/MachO/relocations.s
|
|
+++ /dev/null
|
|
@@ -1,66 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem -o %t %t.o
|
|
-# RUN: llvm-objdump --section-headers --syms -d %t | FileCheck %s
|
|
-
|
|
-# CHECK-LABEL: Sections:
|
|
-# CHECK: __cstring {{[0-9a-z]+}} [[#%x, CSTRING_ADDR:]]
|
|
-
|
|
-# CHECK-LABEL: SYMBOL TABLE:
|
|
-# CHECK: [[#%x, F_ADDR:]] {{.*}} _f
|
|
-
|
|
-# CHECK-LABEL: <_main>:
|
|
-## Test X86_64_RELOC_BRANCH
|
|
-# CHECK: callq 0x[[#%x, F_ADDR]] <_f>
|
|
-## Test extern (symbol) X86_64_RELOC_SIGNED
|
|
-# CHECK: leaq [[#%u, STR_OFF:]](%rip), %rsi
|
|
-# CHECK-NEXT: [[#%x, CSTRING_ADDR - STR_OFF]]
|
|
-## Test non-extern (section) X86_64_RELOC_SIGNED
|
|
-# 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
|
|
-# NONPCREL: Contents of section __const:
|
|
-# NONPCREL-NEXT: 100001000 b0030000 01000000 b0030000 01000000
|
|
-
|
|
-.section __TEXT,__text
|
|
-.globl _main, _f
|
|
-_main:
|
|
- callq _f # X86_64_RELOC_BRANCH
|
|
- mov $0, %rax
|
|
- ret
|
|
-
|
|
-_f:
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- leaq _str(%rip), %rsi # Generates a X86_64_RELOC_SIGNED pcrel symbol relocation
|
|
- mov $21, %rdx # length of str
|
|
- syscall
|
|
-
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- leaq L_.str(%rip), %rsi # Generates a X86_64_RELOC_SIGNED pcrel section relocation
|
|
- mov $15, %rdx # length of str
|
|
- syscall
|
|
-
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- movq L_.ptr_1_to_str(%rip), %rsi
|
|
- mov $15, %rdx # length of str
|
|
- syscall
|
|
- ret
|
|
-
|
|
-.section __TEXT,__cstring
|
|
-## References to this generate a symbol relocation
|
|
-_str:
|
|
- .asciz "Local defined symbol\n"
|
|
-## References to this generate a section relocation
|
|
-L_.str:
|
|
- .asciz "Private symbol\n"
|
|
-
|
|
-.section __DATA,__const
|
|
-## These generate X86_64_RELOC_UNSIGNED non-pcrel section relocations
|
|
-L_.ptr_1_to_str:
|
|
- .quad L_.str
|
|
-L_.ptr_2_to_str:
|
|
- .quad L_.str
|
|
diff --git a/lld/test/MachO/resolution.s b/lld/test/MachO/resolution.s
|
|
deleted file mode 100644
|
|
index a13bb529cf7..00000000000
|
|
--- a/lld/test/MachO/resolution.s
|
|
+++ /dev/null
|
|
@@ -1,44 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: mkdir -p %t
|
|
-# RUN: echo '.globl _foo, _bar, _baz; _foo: _bar: _baz:' | \
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/libresolution.o
|
|
-# RUN: lld -flavor darwinnew -dylib -install_name \
|
|
-# RUN: @executable_path/libresolution.dylib %t/libresolution.o -o %t/libresolution.dylib
|
|
-# RUN: lld -flavor darwinnew -dylib -install_name \
|
|
-# RUN: @executable_path/libresolution2.dylib %t/libresolution.o -o %t/libresolution2.dylib
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/resolution.o
|
|
-
|
|
-## Check that we select the symbol defined in the first dylib passed on the
|
|
-## command line.
|
|
-# RUN: lld -flavor darwinnew -o %t/dylib-first -Z -L%t -lresolution -lresolution2 %t/resolution.o
|
|
-# RUN: llvm-objdump --macho --bind %t/dylib-first | FileCheck %s --check-prefix=DYLIB-FIRST
|
|
-# DYLIB-FIRST: libresolution _foo
|
|
-
|
|
-# RUN: lld -flavor darwinnew -o %t/dylib2-first -Z -L%t -lresolution2 -lresolution %t/resolution.o
|
|
-# RUN: llvm-objdump --macho --bind %t/dylib2-first | FileCheck %s --check-prefix=DYLIB2-FIRST
|
|
-# DYLIB2-FIRST: libresolution2 _foo
|
|
-
|
|
-## Also check that defined symbols take precedence over dylib symbols.
|
|
-# DYLIB-FIRST-NOT: libresolution _bar
|
|
-# DYLIB-FIRST-NOT: libresolution _baz
|
|
-
|
|
-## Check that we pick the dylib symbol over the undefined symbol in the object
|
|
-## file, even if the object file appears first on the command line.
|
|
-# RUN: lld -flavor darwinnew -o %t/obj-first -Z -L%t %t/resolution.o -lresolution
|
|
-# RUN: llvm-objdump --macho --bind %t/obj-first | FileCheck %s --check-prefix=OBJ-FIRST
|
|
-# OBJ-FIRST: libresolution _foo
|
|
-## But defined symbols should still take precedence.
|
|
-# OBJ-FIRST-NOT: libresolution _bar
|
|
-# OBJ-FIRST-NOT: libresolution _baz
|
|
-
|
|
-.globl _main, _bar
|
|
-# Global defined symbol
|
|
-_bar:
|
|
-# Local defined symbol
|
|
-_baz:
|
|
-
|
|
-_main:
|
|
- movq _foo@GOTPCREL(%rip), %rsi
|
|
- movq _bar@GOTPCREL(%rip), %rsi
|
|
- movq _baz@GOTPCREL(%rip), %rsi
|
|
- ret
|
|
diff --git a/lld/test/MachO/search-paths-darwin.test b/lld/test/MachO/search-paths-darwin.test
|
|
deleted file mode 100644
|
|
index 85b7e30671b..00000000000
|
|
--- a/lld/test/MachO/search-paths-darwin.test
|
|
+++ /dev/null
|
|
@@ -1,20 +0,0 @@
|
|
-REQUIRES: x86
|
|
-REQUIRES: darwin
|
|
-
|
|
-RUN: mkdir -p %t1 %t2
|
|
-
|
|
-RUN: lld -flavor darwinnew -arch x86_64 -v -L%t1 -F%t2 2>&1 | FileCheck -DLDIR=%t1 -DFDIR=%t2 %s
|
|
-CHECK: Library search paths:
|
|
-CHECK-NEXT: [[LDIR]]
|
|
-CHECK-NEXT: /usr/lib
|
|
-CHECK-NEXT: /usr/local/lib
|
|
-CHECK-NEXT: Framework search paths:
|
|
-CHECK-NEXT: [[FDIR]]
|
|
-CHECK-NEXT: /Library/Frameworks
|
|
-CHECK-NEXT: /System/Library/Frameworks
|
|
-
|
|
-RUN: lld -flavor darwinnew -arch x86_64 -v -L%t1 -F%t2 -Z 2>&1 | FileCheck -DLDIR=%t1 -DFDIR=%t2 --check-prefix=CHECK_Z %s
|
|
-CHECK_Z: Library search paths:
|
|
-CHECK_Z-NEXT: [[LDIR]]
|
|
-CHECK_Z-NEXT: Framework search paths:
|
|
-CHECK_Z-NEXT: [[FDIR]]
|
|
diff --git a/lld/test/MachO/search-paths.test b/lld/test/MachO/search-paths.test
|
|
deleted file mode 100644
|
|
index 124a2a080b6..00000000000
|
|
--- a/lld/test/MachO/search-paths.test
|
|
+++ /dev/null
|
|
@@ -1,15 +0,0 @@
|
|
-UNSUPPORTED: darwin
|
|
-
|
|
-RUN: mkdir -p %t1 %t2
|
|
-
|
|
-RUN: lld -flavor darwinnew -v -L%t1 -F%t2 2>&1 | FileCheck -DLDIR=%t1 -DFDIR=%t2 %s
|
|
-CHECK: Library search paths:
|
|
-CHECK-NEXT: [[LDIR]]
|
|
-CHECK-NEXT: Framework search paths:
|
|
-CHECK-NEXT: [[FDIR]]
|
|
-
|
|
-RUN: lld -flavor darwinnew -v -L%t1 -F%t2 -Z 2>&1 | FileCheck -DLDIR=%t1 -DFDIR=%t2 --check-prefix=CHECK_Z %s
|
|
-CHECK_Z: Library search paths:
|
|
-CHECK_Z-NEXT: [[LDIR]]
|
|
-CHECK_Z-NEXT: Framework search paths:
|
|
-CHECK_Z-NEXT: [[FDIR]]
|
|
diff --git a/lld/test/MachO/section-headers.s b/lld/test/MachO/section-headers.s
|
|
deleted file mode 100644
|
|
index 9fafc5a912b..00000000000
|
|
--- a/lld/test/MachO/section-headers.s
|
|
+++ /dev/null
|
|
@@ -1,46 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -o %t %t.o
|
|
-# RUN: llvm-readobj --section-headers %t | FileCheck %s
|
|
-
|
|
-# CHECK: Name: __text
|
|
-# CHECK-NEXT: Segment: __TEXT
|
|
-# CHECK-NOT: }
|
|
-# CHECK: Alignment: 1
|
|
-# CHECK-NOT: }
|
|
-# CHECK: Type: Regular (0x0)
|
|
-# CHECK-NEXT: Attributes [ (0x800004)
|
|
-# CHECK-NEXT: PureInstructions (0x800000)
|
|
-# CHECK-NEXT: SomeInstructions (0x4)
|
|
-# CHECK-NEXT: ]
|
|
-
|
|
-# CHECK: Name: __cstring
|
|
-# CHECK-NEXT: Segment: __TEXT
|
|
-# CHECK-NOT: }
|
|
-# CHECK: Alignment: 2
|
|
-# CHECK-NOT: }
|
|
-# CHECK: Type: CStringLiterals (0x2)
|
|
-# CHECK-NEXT: Attributes [ (0x0)
|
|
-# CHECK-NEXT: ]
|
|
-
|
|
-# CHECK: Name: maxlen_16ch_name
|
|
-# CHECK-NEXT: Segment: __TEXT
|
|
-# CHECK-NOT: }
|
|
-# CHECK: Alignment: 3
|
|
-# CHECK-NOT: }
|
|
-# CHECK: Type: Regular (0x0)
|
|
-
|
|
-.text
|
|
-.align 1
|
|
-.global _main
|
|
-_main:
|
|
- mov $0, %rax
|
|
- ret
|
|
-
|
|
-.section __TEXT,__cstring
|
|
-.align 2
|
|
-str:
|
|
- .asciz "Hello world!\n"
|
|
-
|
|
-.section __TEXT,maxlen_16ch_name
|
|
-.align 3
|
|
diff --git a/lld/test/MachO/section-merge.s b/lld/test/MachO/section-merge.s
|
|
deleted file mode 100644
|
|
index 69c55a047b4..00000000000
|
|
--- a/lld/test/MachO/section-merge.s
|
|
+++ /dev/null
|
|
@@ -1,26 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: mkdir -p %t
|
|
-## Verify that we preserve alignment when merging sections.
|
|
-# RUN: echo ".globl _foo; .data; .p2align 0; _foo: .byte 0xca" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/foo.o
|
|
-# RUN: echo ".globl _bar; .data; .p2align 2; _bar: .byte 0xfe" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/bar.o
|
|
-# RUN: echo ".globl _baz; .data; .p2align 3; _baz: .byte 0xba" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/baz.o
|
|
-# RUN: echo ".globl _qux; .data; .p2align 0; _qux: .quad 0xdeadbeef" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/qux.o
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/main.o
|
|
-# RUN: lld -flavor darwinnew -o %t/output %t/foo.o %t/bar.o %t/baz.o %t/qux.o %t/main.o
|
|
-
|
|
-# RUN: llvm-objdump --syms --section=__data --full-contents %t/output | FileCheck %s
|
|
-# CHECK: SYMBOL TABLE:
|
|
-# CHECK-DAG: [[#%x, ADDR:]] g O __DATA,__data _foo
|
|
-# CHECK-DAG: {{0*}}[[#ADDR+0x4]] g O __DATA,__data _bar
|
|
-# CHECK-DAG: {{0*}}[[#ADDR+0x8]] g O __DATA,__data _baz
|
|
-# CHECK-DAG: {{0*}}[[#ADDR+0x9]] g O __DATA,__data _qux
|
|
-
|
|
-# CHECK: Contents of section __data:
|
|
-# CHECK-NEXT: {{0*}}[[#ADDR]] ca000000 fe000000 baefbead de000000
|
|
-
|
|
-.section __TEXT,__text
|
|
-.global _main
|
|
-
|
|
-_main:
|
|
- mov $0, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/segments.s b/lld/test/MachO/segments.s
|
|
deleted file mode 100644
|
|
index acb0f1e9010..00000000000
|
|
--- a/lld/test/MachO/segments.s
|
|
+++ /dev/null
|
|
@@ -1,53 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -o %t %t.o
|
|
-# RUN: llvm-readobj --macho-segment %t | FileCheck %s
|
|
-
|
|
-## These two segments must always be present at the start of an executable.
|
|
-# CHECK-NOT: Segment {
|
|
-# CHECK: Segment {
|
|
-# CHECK: Cmd: LC_SEGMENT_64
|
|
-# CHECK: Name: __PAGEZERO
|
|
-# CHECK: Size: 72
|
|
-# CHECK: vmaddr: 0x0
|
|
-# CHECK: vmsize: 0x100000000
|
|
-# CHECK: fileoff: 0
|
|
-# CHECK: filesize: 0
|
|
-## The kernel won't execute a binary with the wrong protections for __PAGEZERO.
|
|
-# CHECK: maxprot: ---
|
|
-# CHECK: initprot: ---
|
|
-# CHECK: nsects: 0
|
|
-# CHECK: flags: 0x0
|
|
-# CHECK: }
|
|
-# CHECK: Segment {
|
|
-# CHECK: Cmd: LC_SEGMENT_64
|
|
-# CHECK: Name: __TEXT
|
|
-# CHECK: Size: 152
|
|
-# CHECK: vmaddr: 0x100000000
|
|
-# CHECK: vmsize:
|
|
-## dyld3 assumes that the __TEXT segment starts from the file header
|
|
-# CHECK: fileoff: 0
|
|
-# CHECK: filesize:
|
|
-# CHECK: maxprot: rwx
|
|
-# CHECK: initprot: r-x
|
|
-# CHECK: nsects: 1
|
|
-# CHECK: flags: 0x0
|
|
-# CHECK: }
|
|
-
|
|
-## Check that we handle max-length names correctly.
|
|
-# CHECK: Cmd: LC_SEGMENT_64
|
|
-# CHECK-NEXT: Name: maxlen_16ch_name
|
|
-
|
|
-## This segment must always be present at the end of an executable.
|
|
-# CHECK: Name: __LINKEDIT
|
|
-# CHECK: maxprot: rwx
|
|
-# CHECK: initprot: r--
|
|
-# CHECK-NOT: Cmd: LC_SEGMENT_64
|
|
-
|
|
-.text
|
|
-.global _main
|
|
-_main:
|
|
- mov $0, %rax
|
|
- ret
|
|
-
|
|
-.section maxlen_16ch_name,foo
|
|
diff --git a/lld/test/MachO/silent-ignore.test b/lld/test/MachO/silent-ignore.test
|
|
deleted file mode 100644
|
|
index ae68dd8fe81..00000000000
|
|
--- a/lld/test/MachO/silent-ignore.test
|
|
+++ /dev/null
|
|
@@ -1,9 +0,0 @@
|
|
-RUN: lld -flavor darwinnew -v \
|
|
-RUN: -demangle \
|
|
-RUN: -dynamic \
|
|
-RUN: -no_deduplicate \
|
|
-RUN: -lto_library /lib/foo \
|
|
-RUN: -macosx_version_min 0 \
|
|
-RUN: -syslibroot /path/to/MacOSX.platform/Developer/SDKs/MacOSX.sdk
|
|
-RUN: not lld -flavor darwinnew -v --not-an-ignored-argument 2>&1 | FileCheck %s
|
|
-CHECK: error: unknown argument: --not-an-ignored-argument
|
|
diff --git a/lld/test/MachO/static-link.s b/lld/test/MachO/static-link.s
|
|
deleted file mode 100644
|
|
index f8260807df6..00000000000
|
|
--- a/lld/test/MachO/static-link.s
|
|
+++ /dev/null
|
|
@@ -1,30 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-
|
|
-# RUN: mkdir -p %t
|
|
-#
|
|
-# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %p/Inputs/libgoodbye.s -o %t/goodbye.o
|
|
-# RUN: llvm-ar --format=darwin crs %t/libgoodbye.a %t/goodbye.o
|
|
-#
|
|
-# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %s -o %t/test.o
|
|
-# RUN: lld -flavor darwinnew -o %t/test -Z -L%t -lgoodbye %t/test.o
|
|
-#
|
|
-# RUN: llvm-objdump --syms -d -r %t/test | FileCheck %s
|
|
-
|
|
-# CHECK: SYMBOL TABLE:
|
|
-# CHECK: {{0+}}[[ADDR:[0-9a-f]+]] g O __TEXT,__cstring _goodbye_world
|
|
-
|
|
-# CHECK: Disassembly of section __TEXT,__text
|
|
-# CHECK-LABEL: <_main>:
|
|
-# CHECK: leaq {{.*}}(%rip), %rsi # [[ADDR]] <_goodbye_world>
|
|
-
|
|
-.section __TEXT,__text
|
|
-.global _main
|
|
-
|
|
-_main:
|
|
- movl $0x2000004, %eax # write()
|
|
- mov $1, %rdi # stdout
|
|
- leaq _goodbye_world(%rip), %rsi
|
|
- mov $15, %rdx # length
|
|
- syscall
|
|
- mov $0, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/stub-link.s b/lld/test/MachO/stub-link.s
|
|
deleted file mode 100644
|
|
index 1bf65c46a78..00000000000
|
|
--- a/lld/test/MachO/stub-link.s
|
|
+++ /dev/null
|
|
@@ -1,21 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-
|
|
-# RUN: mkdir -p %t
|
|
-#
|
|
-# RUN: llvm-mc -filetype obj -triple x86_64-apple-darwin %s -o %t/test.o
|
|
-# RUN: lld -flavor darwinnew -o %t/test -Z -L%S/Inputs/MacOSX.sdk/usr/lib -lSystem %t/test.o
|
|
-#
|
|
-# RUN: llvm-objdump --bind --no-show-raw-insn -d -r %t/test | FileCheck %s
|
|
-
|
|
-# CHECK: Disassembly of section __TEXT,__text:
|
|
-# CHECK: movq {{.*}} # [[ADDR:[0-9a-f]+]]
|
|
-
|
|
-# CHECK: Bind table:
|
|
-# CHECK: __DATA_CONST __got 0x[[ADDR]] pointer 0 libSystem ___nan
|
|
-
|
|
-.section __TEXT,__text
|
|
-.global _main
|
|
-
|
|
-_main:
|
|
- movq ___nan@GOTPCREL(%rip), %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/sub-library.s b/lld/test/MachO/sub-library.s
|
|
deleted file mode 100644
|
|
index e858eaf0bff..00000000000
|
|
--- a/lld/test/MachO/sub-library.s
|
|
+++ /dev/null
|
|
@@ -1,74 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: mkdir -p %t
|
|
-
|
|
-## Create a libsuper that has libgoodbye as a sub-library, which in turn has
|
|
-## libhello as another sub-library.
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %p/Inputs/libhello.s \
|
|
-# RUN: -o %t/libhello.o
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %p/Inputs/libgoodbye.s \
|
|
-# RUN: -o %t/libgoodbye.o
|
|
-# RUN: echo "" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/libsuper.o
|
|
-# RUN: lld -flavor darwinnew -dylib %t/libhello.o -o %t/libhello.dylib
|
|
-# RUN: lld -flavor darwinnew -dylib -L%t -sub_library libhello -lhello \
|
|
-# RUN: %t/libgoodbye.o -o %t/libgoodbye.dylib
|
|
-# RUN: lld -flavor darwinnew -dylib -L%t -sub_library libgoodbye -lgoodbye -install_name \
|
|
-# RUN: @executable_path/libsuper.dylib %t/libsuper.o -o %t/libsuper.dylib
|
|
-
|
|
-
|
|
-## Check that they have the appropriate LC_REEXPORT_DYLIB commands, and that
|
|
-## NO_REEXPORTED_DYLIBS is (un)set as appropriate.
|
|
-
|
|
-# RUN: llvm-objdump --macho --all-headers %t/libhello.dylib | FileCheck %s \
|
|
-# RUN: --check-prefix=HELLO-HEADERS
|
|
-# HELLO-HEADERS: NO_REEXPORTED_DYLIBS
|
|
-
|
|
-# RUN: llvm-objdump --macho --all-headers %t/libgoodbye.dylib | FileCheck %s -DDIR=%t \
|
|
-# RUN: --check-prefix=GOODBYE-HEADERS
|
|
-# GOODBYE-HEADERS-NOT: NO_REEXPORTED_DYLIBS
|
|
-# GOODBYE-HEADERS: cmd LC_REEXPORT_DYLIB
|
|
-# GOODBYE-HEADERS-NOT: Load command
|
|
-# GOODBYE-HEADERS: name [[DIR]]/libhello.dylib
|
|
-
|
|
-# RUN: llvm-objdump --macho --all-headers %t/libsuper.dylib | FileCheck %s -DDIR=%t \
|
|
-# RUN: --check-prefix=SUPER-HEADERS
|
|
-# SUPER-HEADERS-NOT: NO_REEXPORTED_DYLIBS
|
|
-# SUPER-HEADERS: cmd LC_REEXPORT_DYLIB
|
|
-# SUPER-HEADERS-NOT: Load command
|
|
-# SUPER-HEADERS: name [[DIR]]/libgoodbye.dylib
|
|
-
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/sub-library.o
|
|
-# RUN: lld -flavor darwinnew -o %t/sub-library -L%t -lsuper %t/sub-library.o
|
|
-
|
|
-# RUN: llvm-objdump --macho --bind %t/sub-library | FileCheck %s
|
|
-# CHECK-LABEL: Bind table:
|
|
-# CHECK-DAG: __DATA_CONST __got {{.*}} libsuper _hello_world
|
|
-# CHECK-DAG: __DATA_CONST __got {{.*}} libsuper _goodbye_world
|
|
-
|
|
-
|
|
-## Check that we fail gracefully if the sub-library is missing
|
|
-# RUN: not lld -flavor darwinnew -dylib -Z -o %t/sub-library -sub_library libmissing %t/sub-library.o 2>&1 \
|
|
-# RUN: | FileCheck %s --check-prefix=MISSING-SUB-LIBRARY
|
|
-# MISSING-SUB-LIBRARY: error: -sub_library libmissing does not match a supplied dylib
|
|
-# RUN: rm -f %t/libgoodbye.dylib
|
|
-# RUN: not lld -flavor darwinnew -o %t/sub-library -Z -L%t -lsuper %t/sub-library.o 2>&1 \
|
|
-# RUN: | FileCheck %s --check-prefix=MISSING-REEXPORT -DDIR=%t
|
|
-# MISSING-REEXPORT: error: unable to read re-exported dylib at [[DIR]]/libgoodbye.dylib
|
|
-
|
|
-.text
|
|
-.globl _main
|
|
-
|
|
-_main:
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- movq _hello_world@GOTPCREL(%rip), %rsi
|
|
- mov $13, %rdx # length of str
|
|
- syscall
|
|
- mov $0, %rax
|
|
-
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- movq _goodbye_world@GOTPCREL(%rip), %rsi
|
|
- mov $15, %rdx # length of str
|
|
- syscall
|
|
- mov $0, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/subsections-section-relocs.s b/lld/test/MachO/subsections-section-relocs.s
|
|
deleted file mode 100644
|
|
index e8a8d7a3ec4..00000000000
|
|
--- a/lld/test/MachO/subsections-section-relocs.s
|
|
+++ /dev/null
|
|
@@ -1,47 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: mkdir -p %t
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/test.o
|
|
-
|
|
-# RUN: echo "_bar_str" > %t/order-file
|
|
-# RUN: echo "_foo_str" >> %t/order-file
|
|
-
|
|
-# RUN: lld -flavor darwinnew -o %t/test %t/test.o -order_file %t/order-file
|
|
-# RUN: llvm-objdump --section-headers -d --no-show-raw-insn %t/test | FileCheck %s
|
|
-# CHECK-LABEL: Sections:
|
|
-# CHECK: __cstring {{[^ ]*}} {{0*}}[[#%x, CSTRING_ADDR:]]
|
|
-# CHECK-LABEL: Disassembly of section __TEXT,__text:
|
|
-## L._str should end up at CSTRING_ADDR + 4, and leaq is 7 bytes long so we
|
|
-## have RIP = ADDR + 7
|
|
-# CHECK: [[#%x, ADDR:]]: leaq
|
|
-# CHECK-SAME: [[#%u, CSTRING_ADDR + 4 - ADDR - 7]](%rip), %rsi {{.*}} <_bar_str+0x4>
|
|
-
|
|
-# RUN: llvm-readobj --string-dump=__cstring %t/test | FileCheck %s --check-prefix=STRINGS
|
|
-# STRINGS: bar
|
|
-# STRINGS: Private symbol
|
|
-# STRINGS: foo
|
|
-
|
|
-.text
|
|
-.globl _main, _foo_str, _bar_str
|
|
-
|
|
-_main:
|
|
- leaq L_.str(%rip), %rsi
|
|
- mov $0, %rax
|
|
- ret
|
|
-
|
|
-.section __TEXT,__cstring
|
|
-_foo_str:
|
|
- .asciz "foo"
|
|
-
|
|
-_bar_str:
|
|
- .asciz "bar"
|
|
-
|
|
-## References to this generate a section relocation
|
|
-## N.B.: ld64 doesn't actually reorder symbols in __cstring based on the order
|
|
-## file. Only our implementation does. However, I'm not sure how else to
|
|
-## test section relocations that target an address inside a relocated
|
|
-## symbol: using a non-__cstring section would cause llvm-mc to emit a
|
|
-## symbol relocation instead using the nearest symbol.
|
|
-L_.str:
|
|
- .asciz "Private symbol"
|
|
-
|
|
-.subsections_via_symbols
|
|
diff --git a/lld/test/MachO/subsections-symbol-relocs.s b/lld/test/MachO/subsections-symbol-relocs.s
|
|
deleted file mode 100644
|
|
index 475c909377d..00000000000
|
|
--- a/lld/test/MachO/subsections-symbol-relocs.s
|
|
+++ /dev/null
|
|
@@ -1,55 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: mkdir -p %t
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/test.o
|
|
-
|
|
-# RUN: echo "_bar" > %t/order-file-1
|
|
-# RUN: echo "_foo" >> %t/order-file-1
|
|
-# RUN: echo "_main" >> %t/order-file-1
|
|
-## _qux is marked as .alt_entry, so it should not create a new subsection and
|
|
-## its contents should move with _bar to the start of the output despite the
|
|
-## order file listing it at the end.
|
|
-# RUN: echo "_qux" >> %t/order-file-1
|
|
-
|
|
-## _bar and _baz point to the same address, so both order files should achieve
|
|
-## the same result.
|
|
-# RUN: echo "_baz" > %t/order-file-2
|
|
-# RUN: echo "_foo" >> %t/order-file-2
|
|
-# RUN: echo "_main" >> %t/order-file-2
|
|
-# RUN: echo "_qux" >> %t/order-file-2
|
|
-
|
|
-# RUN: lld -flavor darwinnew -o %t/test-1 %t/test.o -order_file %t/order-file-1
|
|
-# RUN: llvm-objdump -d --no-show-raw-insn %t/test-1 | FileCheck %s
|
|
-# RUN: lld -flavor darwinnew -o %t/test-2 %t/test.o -order_file %t/order-file-2
|
|
-# RUN: llvm-objdump -d --no-show-raw-insn %t/test-2 | FileCheck %s
|
|
-# CHECK-LABEL: Disassembly of section __TEXT,__text:
|
|
-# CHECK: <_bar>:
|
|
-# CHECK-NEXT: callq {{.*}} <_foo>
|
|
-# CHECK-EMPTY:
|
|
-# CHECK-NEXT: <_qux>:
|
|
-# CHECK-NEXT: retq
|
|
-# CHECK: <_foo>:
|
|
-# CHECK-NEXT: retq
|
|
-# CHECK: <_main>:
|
|
-# CHECK-NEXT: callq {{.*}} <_bar>
|
|
-# CHECK-NEXT: movq $0, %rax
|
|
-# CHECK-NEXT: retq
|
|
-
|
|
-.text
|
|
-.globl _main, _foo, _bar, _qux
|
|
-.alt_entry _qux
|
|
-
|
|
-_foo:
|
|
- retq
|
|
-
|
|
-_main:
|
|
- callq _bar
|
|
- movq $0, %rax
|
|
- retq
|
|
-
|
|
-_bar:
|
|
-_baz:
|
|
- callq _foo
|
|
-_qux:
|
|
- retq
|
|
-
|
|
-.subsections_via_symbols
|
|
diff --git a/lld/test/MachO/symbol-order.s b/lld/test/MachO/symbol-order.s
|
|
deleted file mode 100644
|
|
index 328ff9e2475..00000000000
|
|
--- a/lld/test/MachO/symbol-order.s
|
|
+++ /dev/null
|
|
@@ -1,46 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: mkdir -p %t
|
|
-# RUN: echo ".global f, g; .section __TEXT,test_g; g: callq f" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/g.o
|
|
-# RUN: echo ".global f; .section __TEXT,test_f1; f: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/f1.o
|
|
-# RUN: echo ".global f; .section __TEXT,test_f2; f: ret" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/f2.o
|
|
-# RUN: echo ".global f, g; .section __TEXT,test_fg; f: ret; g: callq f" | llvm-mc -filetype=obj -triple=x86_64-apple-darwin -o %t/fg.o
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t/test.o
|
|
-# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib -dylib -o %t/libf1.dylib %t/f1.o -lSystem
|
|
-
|
|
-# RUN: rm -f %t/libf2_g.a
|
|
-# RUN: llvm-ar rcs %t/libf2_g.a %t/f2.o %t/g.o
|
|
-
|
|
-# RUN: rm -f %t/libfg.a
|
|
-# RUN: llvm-ar rcs %t/libfg.a %t/fg.o
|
|
-
|
|
-# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib %t/libf1.dylib %t/libf2_g.a %t/test.o -o %t/test.out -lSystem
|
|
-# RUN: llvm-objdump --syms --macho --lazy-bind %t/test.out | FileCheck %s --check-prefix DYLIB-FIRST
|
|
-# DYLIB-FIRST: SYMBOL TABLE:
|
|
-# DYLIB-FIRST-DAG: __TEXT,test_g g
|
|
-# DYLIB-FIRST: Lazy bind table:
|
|
-# DYLIB-FIRST-NEXT: segment section address dylib symbol
|
|
-# DYLIB-FIRST-NEXT: __DATA __la_symbol_ptr {{[0-9a-z]+}} libf1 f
|
|
-
|
|
-# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib %t/libf2_g.a %t/libf1.dylib %t/test.o -o %t/test.out -lSystem
|
|
-# RUN: llvm-objdump --syms --macho --lazy-bind %t/test.out | FileCheck %s --check-prefix ARCHIVE-FIRST
|
|
-# ARCHIVE-FIRST: SYMBOL TABLE:
|
|
-# ARCHIVE-FIRST-DAG: __TEXT,test_f2 f
|
|
-# ARCHIVE-FIRST-DAG: __TEXT,test_g g
|
|
-# ARCHIVE-FIRST: Lazy bind table:
|
|
-# ARCHIVE-FIRST-NEXT: segment section address dylib symbol
|
|
-# ARCHIVE-FIRST-EMPTY:
|
|
-
|
|
-# RUN: lld -flavor darwinnew -L%S/Inputs/MacOSX.sdk/usr/lib %t/libf1.dylib %t/libfg.a %t/test.o -o %t/test.out -lSystem
|
|
-# RUN: llvm-objdump --syms --macho --lazy-bind %t/test.out | FileCheck %s --check-prefix ARCHIVE-PRIORITY
|
|
-# ARCHIVE-PRIORITY: SYMBOL TABLE:
|
|
-# ARCHIVE-PRIORITY-DAG: __TEXT,test_fg f
|
|
-# ARCHIVE-PRIORITY-DAG: __TEXT,test_fg g
|
|
-# ARCHIVE-PRIORITY: Lazy bind table:
|
|
-# ARCHIVE-PRIORITY-NEXT: segment section address dylib symbol
|
|
-# ARCHIVE-PRIORITY-EMPTY:
|
|
-
|
|
-.global g
|
|
-.global _main
|
|
-_main:
|
|
- callq g
|
|
- ret
|
|
diff --git a/lld/test/MachO/symtab.s b/lld/test/MachO/symtab.s
|
|
deleted file mode 100644
|
|
index 44a016912bd..00000000000
|
|
--- a/lld/test/MachO/symtab.s
|
|
+++ /dev/null
|
|
@@ -1,54 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -o %t %t.o
|
|
-# RUN: llvm-readobj -symbols %t | FileCheck %s
|
|
-
|
|
-# CHECK: Symbols [
|
|
-# CHECK-NEXT: Symbol {
|
|
-# CHECK-NEXT: Name: _main
|
|
-# CHECK-NEXT: Extern
|
|
-# CHECK-NEXT: Type: Section (0xE)
|
|
-# CHECK-NEXT: Section: __text (0x1)
|
|
-# CHECK-NEXT: RefType:
|
|
-# CHECK-NEXT: Flags [ (0x0)
|
|
-# CHECK-NEXT: ]
|
|
-# CHECK-NEXT: Value:
|
|
-# CHECK-NEXT: }
|
|
-# CHECK-NEXT: Symbol {
|
|
-# CHECK-NEXT: Name: bar
|
|
-# CHECK-NEXT: Extern
|
|
-# CHECK-NEXT: Type: Section (0xE)
|
|
-# CHECK-NEXT: Section: __text (0x1)
|
|
-# CHECK-NEXT: RefType:
|
|
-# CHECK-NEXT: Flags [ (0x0)
|
|
-# CHECK-NEXT: ]
|
|
-# CHECK-NEXT: Value:
|
|
-# CHECK-NEXT: }
|
|
-# CHECK-NEXT: Symbol {
|
|
-# CHECK-NEXT: Name: foo
|
|
-# CHECK-NEXT: Extern
|
|
-# CHECK-NEXT: Type: Section (0xE)
|
|
-# CHECK-NEXT: Section: __data
|
|
-# CHECK-NEXT: RefType:
|
|
-# CHECK-NEXT: Flags [ (0x0)
|
|
-# CHECK-NEXT: ]
|
|
-# CHECK-NEXT: Value:
|
|
-# CHECK-NEXT: }
|
|
-# CHECK-NEXT: ]
|
|
-
|
|
-.data
|
|
-.global foo
|
|
-foo:
|
|
- .asciz "Hello world!\n"
|
|
-
|
|
-.text
|
|
-.global bar
|
|
-.global _main
|
|
-
|
|
-_main:
|
|
- mov $0, %rax
|
|
- ret
|
|
-
|
|
-bar:
|
|
- mov $2, %rax
|
|
- ret
|
|
diff --git a/lld/test/MachO/x86-64-reloc-signed.s b/lld/test/MachO/x86-64-reloc-signed.s
|
|
deleted file mode 100644
|
|
index 568f65c7c1e..00000000000
|
|
--- a/lld/test/MachO/x86-64-reloc-signed.s
|
|
+++ /dev/null
|
|
@@ -1,64 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -o %t %t.o
|
|
-# RUN: llvm-objdump -D %t | FileCheck %s
|
|
-
|
|
-# CHECK: <_main>:
|
|
-# CHECK-NEXT: movl {{.*}} # 100001000 <_s>
|
|
-# CHECK-NEXT: callq {{.*}}
|
|
-# CHECK-NEXT: movl {{.*}} # 100001002 <_s+0x2>
|
|
-# CHECK-NEXT: callq {{.*}}
|
|
-# CHECK-NEXT: movb {{.*}} # 100001000 <_s>
|
|
-# CHECK-NEXT: callq {{.*}}
|
|
-# CHECK: <__not_text>:
|
|
-# CHECK-NEXT: movl {{.*}} # 100001005
|
|
-# CHECK-NEXT: callq {{.*}}
|
|
-# CHECK-NEXT: movl {{.*}} # 100001007
|
|
-# CHECK-NEXT: callq {{.*}}
|
|
-# CHECK-NEXT: movb {{.*}} # 100001005
|
|
-# CHECK-NEXT: callq {{.*}}
|
|
-
|
|
-.section __TEXT,__text
|
|
-.globl _main
|
|
-_main:
|
|
- ## Symbol relocations
|
|
- movl $0x434241, _s(%rip) # X86_64_RELOC_SIGNED_4
|
|
- callq _f
|
|
- movl $0x44, _s+2(%rip) # X86_64_RELOC_SIGNED_2
|
|
- callq _f
|
|
- movb $0x45, _s(%rip) # X86_64_RELOC_SIGNED_1
|
|
- callq _f
|
|
- xorq %rax, %rax
|
|
- ret
|
|
-
|
|
-_f:
|
|
- movl $0x2000004, %eax # write() syscall
|
|
- mov $1, %rdi # stdout
|
|
- leaq _s(%rip), %rsi
|
|
- mov $3, %rdx # length
|
|
- syscall
|
|
- ret
|
|
-
|
|
-.section __TEXT,__not_text
|
|
- ## Section relocations. We intentionally put them in a separate section since
|
|
- ## the __text section typically starts at an address of zero in object files,
|
|
- ## and so does not fully exercise the relocation logic.
|
|
- movl $0x434241, L._s(%rip) # X86_64_RELOC_SIGNED_4
|
|
- callq _f
|
|
- movl $0x44, L._s+2(%rip) # X86_64_RELOC_SIGNED_2
|
|
- callq _f
|
|
- movb $0x45, L._s(%rip) # X86_64_RELOC_SIGNED_1
|
|
- callq _f
|
|
- ret
|
|
-
|
|
-.section __DATA,__data
|
|
-.globl _s
|
|
-_s:
|
|
- .space 5
|
|
-
|
|
-## Create a new section to force the assembler to use a section relocation for
|
|
-## the private symbol L._s. Otherwise, it will instead use a nearby non-private
|
|
-## symbol to create a symbol relocation plus an addend.
|
|
-.section __DATA,__foo
|
|
-L._s:
|
|
- .space 5
|
|
diff --git a/lld/test/MachO/x86-64-reloc-unsigned.s b/lld/test/MachO/x86-64-reloc-unsigned.s
|
|
deleted file mode 100644
|
|
index 52a3d536139..00000000000
|
|
--- a/lld/test/MachO/x86-64-reloc-unsigned.s
|
|
+++ /dev/null
|
|
@@ -1,31 +0,0 @@
|
|
-# REQUIRES: x86
|
|
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
|
|
-# RUN: lld -flavor darwinnew -o %t %t.o
|
|
-# RUN: llvm-objdump --full-contents %t | FileCheck %s
|
|
-# CHECK: Contents of section foo:
|
|
-# CHECK: 100001000 08100000 01000000
|
|
-# CHECK: Contents of section bar:
|
|
-# CHECK: 100001008 011000f0 11211111 02000000
|
|
-
|
|
-.globl _main, _foo, _bar
|
|
-
|
|
-.section __DATA,foo
|
|
-_foo:
|
|
-.quad _bar
|
|
-
|
|
-.section __DATA,bar
|
|
-_bar:
|
|
-## We create a .int symbol reference here -- with non-zero data immediately
|
|
-## after -- to check that lld reads precisely 32 bits (and not more) of the
|
|
-## implicit addend when handling unsigned relocations of r_length = 2.
|
|
-## Note that __PAGEZERO occupies the lower 32 bits, so all symbols are above
|
|
-## that. To get a final relocated address that fits within 32 bits, we need to
|
|
-## subtract an offset here.
|
|
-.int _foo - 0x0fffffff
|
|
-## The unsigned relocation should support 64-bit addends too (r_length = 3).
|
|
-.quad _foo + 0x111111111
|
|
-
|
|
-.text
|
|
-_main:
|
|
- mov $0, %rax
|
|
- ret
|
|
diff --git a/lld/tools/lld/CMakeLists.txt b/lld/tools/lld/CMakeLists.txt
|
|
index e6f72fcd348..ca589942712 100644
|
|
--- a/lld/tools/lld/CMakeLists.txt
|
|
+++ b/lld/tools/lld/CMakeLists.txt
|
|
@@ -15,7 +15,6 @@ target_link_libraries(lld
|
|
lldCOFF
|
|
lldDriver
|
|
lldELF
|
|
- lldMachO2
|
|
lldMinGW
|
|
lldWasm
|
|
)
|
|
diff --git a/lld/tools/lld/lld.cpp b/lld/tools/lld/lld.cpp
|
|
index 8a8f8d04bbd..1063e80b8a8 100644
|
|
--- a/lld/tools/lld/lld.cpp
|
|
+++ b/lld/tools/lld/lld.cpp
|
|
@@ -45,11 +45,10 @@ using namespace llvm::sys;
|
|
|
|
enum Flavor {
|
|
Invalid,
|
|
- Gnu, // -flavor gnu
|
|
- WinLink, // -flavor link
|
|
- Darwin, // -flavor darwin
|
|
- DarwinNew, // -flavor darwinnew
|
|
- Wasm, // -flavor wasm
|
|
+ Gnu, // -flavor gnu
|
|
+ WinLink, // -flavor link
|
|
+ Darwin, // -flavor darwin
|
|
+ Wasm, // -flavor wasm
|
|
};
|
|
|
|
LLVM_ATTRIBUTE_NORETURN static void die(const Twine &s) {
|
|
@@ -63,7 +62,6 @@ static Flavor getFlavor(StringRef s) {
|
|
.CasesLower("wasm", "ld-wasm", Wasm)
|
|
.CaseLower("link", WinLink)
|
|
.CasesLower("ld64", "ld64.lld", "darwin", Darwin)
|
|
- .CaseLower("darwinnew", DarwinNew)
|
|
.Default(Invalid);
|
|
}
|
|
|
|
@@ -151,8 +149,6 @@ int main(int argc, const char **argv) {
|
|
return !coff::link(args, canExitEarly(), llvm::outs(), llvm::errs());
|
|
case Darwin:
|
|
return !mach_o::link(args, canExitEarly(), llvm::outs(), llvm::errs());
|
|
- case DarwinNew:
|
|
- return !macho::link(args, canExitEarly(), llvm::outs(), llvm::errs());
|
|
case Wasm:
|
|
return !wasm::link(args, canExitEarly(), llvm::outs(), llvm::errs());
|
|
default:
|
|
--
|
|
2.18.1
|
|
|