diff --git a/.gitignore b/.gitignore index 752dee4..ad335a7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -SOURCES/hans-gpg-key.asc -SOURCES/lld-11.0.0.src.tar.xz +SOURCES/lld-12.0.1.src.tar.xz +SOURCES/tstellar-gpg-key.asc diff --git a/.lld.metadata b/.lld.metadata index 2ae63c0..184b2a9 100644 --- a/.lld.metadata +++ b/.lld.metadata @@ -1,2 +1,2 @@ -32fa4b0193960f05064f2ab31b5a89c7cf48a0b9 SOURCES/hans-gpg-key.asc -60672d63fa16a0c3b6e267331fa605d76b79e87b SOURCES/lld-11.0.0.src.tar.xz +3b7e4908f6cf3a51590e37b4194180582cc1c32c SOURCES/lld-12.0.1.src.tar.xz +b8d2648a01d36ed0186fd2c5af325fd28797f9a0 SOURCES/tstellar-gpg-key.asc diff --git a/SOURCES/0001-CMake-Check-for-gtest-headers-even-if-lit.py-is-not-.patch b/SOURCES/0001-CMake-Check-for-gtest-headers-even-if-lit.py-is-not-.patch deleted file mode 100644 index c4af14d..0000000 --- a/SOURCES/0001-CMake-Check-for-gtest-headers-even-if-lit.py-is-not-.patch +++ /dev/null @@ -1,47 +0,0 @@ -From e5bdf4580677da063abe8d3880fbab9eaa7a7efe Mon Sep 17 00:00:00 2001 -From: Tom Stellard <tstellar@redhat.com> -Date: Thu, 30 Aug 2018 08:53:56 -0700 -Subject: [PATCH] CMake: Check for gtest headers even if lit.py is not present - -This makes it possible to build the unittests even withotu a full -checkout of the llvm source tree. ---- - CMakeLists.txt | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index e2fbdbf..c9b2927 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -75,6 +75,15 @@ Please install Python or specify the PYTHON_EXECUTABLE CMake variable.") - set(LLVM_UTILS_PROVIDED ON) - endif() - -+ # Check for gtest -+ set(UNITTEST_DIR ${LLVM_MAIN_SRC_DIR}/utils/unittest) -+ if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h -+ AND NOT EXISTS ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} -+ AND EXISTS ${UNITTEST_DIR}/CMakeLists.txt) -+ add_subdirectory(${UNITTEST_DIR} utils/unittest) -+ endif() -+ -+ # Check for lit - if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) - # Note: path not really used, except for checking if lit was found - set(LLVM_LIT ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) -@@ -84,12 +93,6 @@ Please install Python or specify the PYTHON_EXECUTABLE CMake variable.") - set(LLVM_UTILS_PROVIDED ON) - set(LLD_TEST_DEPS FileCheck not) - endif() -- set(UNITTEST_DIR ${LLVM_MAIN_SRC_DIR}/utils/unittest) -- if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h -- AND NOT EXISTS ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} -- AND EXISTS ${UNITTEST_DIR}/CMakeLists.txt) -- add_subdirectory(${UNITTEST_DIR} utils/unittest) -- endif() - else() - # Seek installed Lit. - find_program(LLVM_LIT --- -1.8.3.1 - diff --git a/SOURCES/0001-PATCH-lld-CMake-Check-for-gtest-headers-even-if-lit..patch b/SOURCES/0001-PATCH-lld-CMake-Check-for-gtest-headers-even-if-lit..patch new file mode 100644 index 0000000..ea10149 --- /dev/null +++ b/SOURCES/0001-PATCH-lld-CMake-Check-for-gtest-headers-even-if-lit..patch @@ -0,0 +1,48 @@ +From 760568cd24acd6ae9083b0dfea2c7c0ea6f0adc2 Mon Sep 17 00:00:00 2001 +From: Tom Stellard <tstellar@redhat.com> +Date: Thu, 30 Aug 2018 08:53:56 -0700 +Subject: [PATCH 1/2] [PATCH][lld] CMake: Check for gtest headers even if + lit.py is not present + +This makes it possible to build the unittests even withotu a full +checkout of the llvm source tree. +--- + lld/CMakeLists.txt | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/lld/CMakeLists.txt b/lld/CMakeLists.txt +index d4e561b..a7406d1c 100644 +--- a/lld/CMakeLists.txt ++++ b/lld/CMakeLists.txt +@@ -65,6 +65,15 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(LLVM_UTILS_PROVIDED ON) + endif() + ++ # Check for gtest ++ set(UNITTEST_DIR ${LLVM_MAIN_SRC_DIR}/utils/unittest) ++ if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h ++ AND NOT EXISTS ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} ++ AND EXISTS ${UNITTEST_DIR}/CMakeLists.txt) ++ add_subdirectory(${UNITTEST_DIR} utils/unittest) ++ endif() ++ ++ # Check for lit + if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) + # Note: path not really used, except for checking if lit was found + set(LLVM_LIT ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) +@@ -74,12 +83,6 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(LLVM_UTILS_PROVIDED ON) + set(LLD_TEST_DEPS FileCheck not) + endif() +- set(UNITTEST_DIR ${LLVM_MAIN_SRC_DIR}/utils/unittest) +- if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h +- AND NOT EXISTS ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX} +- AND EXISTS ${UNITTEST_DIR}/CMakeLists.txt) +- add_subdirectory(${UNITTEST_DIR} utils/unittest) +- endif() + else() + # Seek installed Lit. + find_program(LLVM_LIT +-- +1.8.3.1 + diff --git a/SOURCES/0001-Revert-lld-Initial-commit-for-new-Mach-O-backend.patch b/SOURCES/0001-Revert-lld-Initial-commit-for-new-Mach-O-backend.patch deleted file mode 100644 index 597ebb9..0000000 --- a/SOURCES/0001-Revert-lld-Initial-commit-for-new-Mach-O-backend.patch +++ /dev/null @@ -1,7986 +0,0 @@ -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 - diff --git a/SOURCES/0002-PATCH-lld-Import-compact_unwind_encoding.h-from-libu.patch b/SOURCES/0002-PATCH-lld-Import-compact_unwind_encoding.h-from-libu.patch new file mode 100644 index 0000000..7d8beda --- /dev/null +++ b/SOURCES/0002-PATCH-lld-Import-compact_unwind_encoding.h-from-libu.patch @@ -0,0 +1,498 @@ +From 43dfe54ce017c8d37eaec480a2f13a492bbc4203 Mon Sep 17 00:00:00 2001 +From: serge-sans-paille <sguelton@redhat.com> +Date: Thu, 25 Feb 2021 14:24:14 +0100 +Subject: [PATCH 2/2] [PATCH][lld] Import compact_unwind_encoding.h from + libunwind + +This avoids an implicit cross package dependency +--- + lld/include/mach-o/compact_unwind_encoding.h | 477 +++++++++++++++++++++++++++ + 1 file changed, 477 insertions(+) + create mode 100644 lld/include/mach-o/compact_unwind_encoding.h + +diff --git a/lld/include/mach-o/compact_unwind_encoding.h b/lld/include/mach-o/compact_unwind_encoding.h +new file mode 100644 +index 0000000..5301b10 +--- /dev/null ++++ b/lld/include/mach-o/compact_unwind_encoding.h +@@ -0,0 +1,477 @@ ++//===------------------ mach-o/compact_unwind_encoding.h ------------------===// ++// ++// 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 ++// ++// ++// Darwin's alternative to DWARF based unwind encodings. ++// ++//===----------------------------------------------------------------------===// ++ ++ ++#ifndef __COMPACT_UNWIND_ENCODING__ ++#define __COMPACT_UNWIND_ENCODING__ ++ ++#include <stdint.h> ++ ++// ++// Compilers can emit standard DWARF FDEs in the __TEXT,__eh_frame section ++// of object files. Or compilers can emit compact unwind information in ++// the __LD,__compact_unwind section. ++// ++// When the linker creates a final linked image, it will create a ++// __TEXT,__unwind_info section. This section is a small and fast way for the ++// runtime to access unwind info for any given function. If the compiler ++// emitted compact unwind info for the function, that compact unwind info will ++// be encoded in the __TEXT,__unwind_info section. If the compiler emitted ++// DWARF unwind info, the __TEXT,__unwind_info section will contain the offset ++// of the FDE in the __TEXT,__eh_frame section in the final linked image. ++// ++// Note: Previously, the linker would transform some DWARF unwind infos into ++// compact unwind info. But that is fragile and no longer done. ++ ++ ++// ++// The compact unwind endoding is a 32-bit value which encoded in an ++// architecture specific way, which registers to restore from where, and how ++// to unwind out of the function. ++// ++typedef uint32_t compact_unwind_encoding_t; ++ ++ ++// architecture independent bits ++enum { ++ UNWIND_IS_NOT_FUNCTION_START = 0x80000000, ++ UNWIND_HAS_LSDA = 0x40000000, ++ UNWIND_PERSONALITY_MASK = 0x30000000, ++}; ++ ++ ++ ++ ++// ++// x86 ++// ++// 1-bit: start ++// 1-bit: has lsda ++// 2-bit: personality index ++// ++// 4-bits: 0=old, 1=ebp based, 2=stack-imm, 3=stack-ind, 4=DWARF ++// ebp based: ++// 15-bits (5*3-bits per reg) register permutation ++// 8-bits for stack offset ++// frameless: ++// 8-bits stack size ++// 3-bits stack adjust ++// 3-bits register count ++// 10-bits register permutation ++// ++enum { ++ UNWIND_X86_MODE_MASK = 0x0F000000, ++ UNWIND_X86_MODE_EBP_FRAME = 0x01000000, ++ UNWIND_X86_MODE_STACK_IMMD = 0x02000000, ++ UNWIND_X86_MODE_STACK_IND = 0x03000000, ++ UNWIND_X86_MODE_DWARF = 0x04000000, ++ ++ UNWIND_X86_EBP_FRAME_REGISTERS = 0x00007FFF, ++ UNWIND_X86_EBP_FRAME_OFFSET = 0x00FF0000, ++ ++ UNWIND_X86_FRAMELESS_STACK_SIZE = 0x00FF0000, ++ UNWIND_X86_FRAMELESS_STACK_ADJUST = 0x0000E000, ++ UNWIND_X86_FRAMELESS_STACK_REG_COUNT = 0x00001C00, ++ UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF, ++ ++ UNWIND_X86_DWARF_SECTION_OFFSET = 0x00FFFFFF, ++}; ++ ++enum { ++ UNWIND_X86_REG_NONE = 0, ++ UNWIND_X86_REG_EBX = 1, ++ UNWIND_X86_REG_ECX = 2, ++ UNWIND_X86_REG_EDX = 3, ++ UNWIND_X86_REG_EDI = 4, ++ UNWIND_X86_REG_ESI = 5, ++ UNWIND_X86_REG_EBP = 6, ++}; ++ ++// ++// For x86 there are four modes for the compact unwind encoding: ++// UNWIND_X86_MODE_EBP_FRAME: ++// EBP based frame where EBP is push on stack immediately after return address, ++// then ESP is moved to EBP. Thus, to unwind ESP is restored with the current ++// EPB value, then EBP is restored by popping off the stack, and the return ++// is done by popping the stack once more into the pc. ++// All non-volatile registers that need to be restored must have been saved ++// in a small range in the stack that starts EBP-4 to EBP-1020. The offset/4 ++// is encoded in the UNWIND_X86_EBP_FRAME_OFFSET bits. The registers saved ++// are encoded in the UNWIND_X86_EBP_FRAME_REGISTERS bits as five 3-bit entries. ++// Each entry contains which register to restore. ++// UNWIND_X86_MODE_STACK_IMMD: ++// A "frameless" (EBP not used as frame pointer) function with a small ++// constant stack size. To return, a constant (encoded in the compact ++// unwind encoding) is added to the ESP. Then the return is done by ++// popping the stack into the pc. ++// All non-volatile registers that need to be restored must have been saved ++// on the stack immediately after the return address. The stack_size/4 is ++// encoded in the UNWIND_X86_FRAMELESS_STACK_SIZE (max stack size is 1024). ++// The number of registers saved is encoded in UNWIND_X86_FRAMELESS_STACK_REG_COUNT. ++// UNWIND_X86_FRAMELESS_STACK_REG_PERMUTATION constains which registers were ++// saved and their order. ++// UNWIND_X86_MODE_STACK_IND: ++// A "frameless" (EBP not used as frame pointer) function large constant ++// stack size. This case is like the previous, except the stack size is too ++// large to encode in the compact unwind encoding. Instead it requires that ++// the function contains "subl $nnnnnnnn,ESP" in its prolog. The compact ++// encoding contains the offset to the nnnnnnnn value in the function in ++// UNWIND_X86_FRAMELESS_STACK_SIZE. ++// UNWIND_X86_MODE_DWARF: ++// No compact unwind encoding is available. Instead the low 24-bits of the ++// compact encoding is the offset of the DWARF FDE in the __eh_frame section. ++// This mode is never used in object files. It is only generated by the ++// linker in final linked images which have only DWARF unwind info for a ++// function. ++// ++// The permutation encoding is a Lehmer code sequence encoded into a ++// single variable-base number so we can encode the ordering of up to ++// six registers in a 10-bit space. ++// ++// The following is the algorithm used to create the permutation encoding used ++// with frameless stacks. It is passed the number of registers to be saved and ++// an array of the register numbers saved. ++// ++//uint32_t permute_encode(uint32_t registerCount, const uint32_t registers[6]) ++//{ ++// uint32_t renumregs[6]; ++// for (int i=6-registerCount; i < 6; ++i) { ++// int countless = 0; ++// for (int j=6-registerCount; j < i; ++j) { ++// if ( registers[j] < registers[i] ) ++// ++countless; ++// } ++// renumregs[i] = registers[i] - countless -1; ++// } ++// uint32_t permutationEncoding = 0; ++// switch ( registerCount ) { ++// case 6: ++// permutationEncoding |= (120*renumregs[0] + 24*renumregs[1] ++// + 6*renumregs[2] + 2*renumregs[3] ++// + renumregs[4]); ++// break; ++// case 5: ++// permutationEncoding |= (120*renumregs[1] + 24*renumregs[2] ++// + 6*renumregs[3] + 2*renumregs[4] ++// + renumregs[5]); ++// break; ++// case 4: ++// permutationEncoding |= (60*renumregs[2] + 12*renumregs[3] ++// + 3*renumregs[4] + renumregs[5]); ++// break; ++// case 3: ++// permutationEncoding |= (20*renumregs[3] + 4*renumregs[4] ++// + renumregs[5]); ++// break; ++// case 2: ++// permutationEncoding |= (5*renumregs[4] + renumregs[5]); ++// break; ++// case 1: ++// permutationEncoding |= (renumregs[5]); ++// break; ++// } ++// return permutationEncoding; ++//} ++// ++ ++ ++ ++ ++// ++// x86_64 ++// ++// 1-bit: start ++// 1-bit: has lsda ++// 2-bit: personality index ++// ++// 4-bits: 0=old, 1=rbp based, 2=stack-imm, 3=stack-ind, 4=DWARF ++// rbp based: ++// 15-bits (5*3-bits per reg) register permutation ++// 8-bits for stack offset ++// frameless: ++// 8-bits stack size ++// 3-bits stack adjust ++// 3-bits register count ++// 10-bits register permutation ++// ++enum { ++ UNWIND_X86_64_MODE_MASK = 0x0F000000, ++ UNWIND_X86_64_MODE_RBP_FRAME = 0x01000000, ++ UNWIND_X86_64_MODE_STACK_IMMD = 0x02000000, ++ UNWIND_X86_64_MODE_STACK_IND = 0x03000000, ++ UNWIND_X86_64_MODE_DWARF = 0x04000000, ++ ++ UNWIND_X86_64_RBP_FRAME_REGISTERS = 0x00007FFF, ++ UNWIND_X86_64_RBP_FRAME_OFFSET = 0x00FF0000, ++ ++ UNWIND_X86_64_FRAMELESS_STACK_SIZE = 0x00FF0000, ++ UNWIND_X86_64_FRAMELESS_STACK_ADJUST = 0x0000E000, ++ UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT = 0x00001C00, ++ UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF, ++ ++ UNWIND_X86_64_DWARF_SECTION_OFFSET = 0x00FFFFFF, ++}; ++ ++enum { ++ UNWIND_X86_64_REG_NONE = 0, ++ UNWIND_X86_64_REG_RBX = 1, ++ UNWIND_X86_64_REG_R12 = 2, ++ UNWIND_X86_64_REG_R13 = 3, ++ UNWIND_X86_64_REG_R14 = 4, ++ UNWIND_X86_64_REG_R15 = 5, ++ UNWIND_X86_64_REG_RBP = 6, ++}; ++// ++// For x86_64 there are four modes for the compact unwind encoding: ++// UNWIND_X86_64_MODE_RBP_FRAME: ++// RBP based frame where RBP is push on stack immediately after return address, ++// then RSP is moved to RBP. Thus, to unwind RSP is restored with the current ++// EPB value, then RBP is restored by popping off the stack, and the return ++// is done by popping the stack once more into the pc. ++// All non-volatile registers that need to be restored must have been saved ++// in a small range in the stack that starts RBP-8 to RBP-2040. The offset/8 ++// is encoded in the UNWIND_X86_64_RBP_FRAME_OFFSET bits. The registers saved ++// are encoded in the UNWIND_X86_64_RBP_FRAME_REGISTERS bits as five 3-bit entries. ++// Each entry contains which register to restore. ++// UNWIND_X86_64_MODE_STACK_IMMD: ++// A "frameless" (RBP not used as frame pointer) function with a small ++// constant stack size. To return, a constant (encoded in the compact ++// unwind encoding) is added to the RSP. Then the return is done by ++// popping the stack into the pc. ++// All non-volatile registers that need to be restored must have been saved ++// on the stack immediately after the return address. The stack_size/8 is ++// encoded in the UNWIND_X86_64_FRAMELESS_STACK_SIZE (max stack size is 2048). ++// The number of registers saved is encoded in UNWIND_X86_64_FRAMELESS_STACK_REG_COUNT. ++// UNWIND_X86_64_FRAMELESS_STACK_REG_PERMUTATION constains which registers were ++// saved and their order. ++// UNWIND_X86_64_MODE_STACK_IND: ++// A "frameless" (RBP not used as frame pointer) function large constant ++// stack size. This case is like the previous, except the stack size is too ++// large to encode in the compact unwind encoding. Instead it requires that ++// the function contains "subq $nnnnnnnn,RSP" in its prolog. The compact ++// encoding contains the offset to the nnnnnnnn value in the function in ++// UNWIND_X86_64_FRAMELESS_STACK_SIZE. ++// UNWIND_X86_64_MODE_DWARF: ++// No compact unwind encoding is available. Instead the low 24-bits of the ++// compact encoding is the offset of the DWARF FDE in the __eh_frame section. ++// This mode is never used in object files. It is only generated by the ++// linker in final linked images which have only DWARF unwind info for a ++// function. ++// ++ ++ ++// ARM64 ++// ++// 1-bit: start ++// 1-bit: has lsda ++// 2-bit: personality index ++// ++// 4-bits: 4=frame-based, 3=DWARF, 2=frameless ++// frameless: ++// 12-bits of stack size ++// frame-based: ++// 4-bits D reg pairs saved ++// 5-bits X reg pairs saved ++// DWARF: ++// 24-bits offset of DWARF FDE in __eh_frame section ++// ++enum { ++ UNWIND_ARM64_MODE_MASK = 0x0F000000, ++ UNWIND_ARM64_MODE_FRAMELESS = 0x02000000, ++ UNWIND_ARM64_MODE_DWARF = 0x03000000, ++ UNWIND_ARM64_MODE_FRAME = 0x04000000, ++ ++ UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001, ++ UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002, ++ UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004, ++ UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008, ++ UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010, ++ UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100, ++ UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200, ++ UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400, ++ UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800, ++ ++ UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK = 0x00FFF000, ++ UNWIND_ARM64_DWARF_SECTION_OFFSET = 0x00FFFFFF, ++}; ++// For arm64 there are three modes for the compact unwind encoding: ++// UNWIND_ARM64_MODE_FRAME: ++// This is a standard arm64 prolog where FP/LR are immediately pushed on the ++// stack, then SP is copied to FP. If there are any non-volatile registers ++// saved, then are copied into the stack frame in pairs in a contiguous ++// range right below the saved FP/LR pair. Any subset of the five X pairs ++// and four D pairs can be saved, but the memory layout must be in register ++// number order. ++// UNWIND_ARM64_MODE_FRAMELESS: ++// A "frameless" leaf function, where FP/LR are not saved. The return address ++// remains in LR throughout the function. If any non-volatile registers ++// are saved, they must be pushed onto the stack before any stack space is ++// allocated for local variables. The stack sized (including any saved ++// non-volatile registers) divided by 16 is encoded in the bits ++// UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK. ++// UNWIND_ARM64_MODE_DWARF: ++// No compact unwind encoding is available. Instead the low 24-bits of the ++// compact encoding is the offset of the DWARF FDE in the __eh_frame section. ++// This mode is never used in object files. It is only generated by the ++// linker in final linked images which have only DWARF unwind info for a ++// function. ++// ++ ++ ++ ++ ++ ++//////////////////////////////////////////////////////////////////////////////// ++// ++// Relocatable Object Files: __LD,__compact_unwind ++// ++//////////////////////////////////////////////////////////////////////////////// ++ ++// ++// A compiler can generated compact unwind information for a function by adding ++// a "row" to the __LD,__compact_unwind section. This section has the ++// S_ATTR_DEBUG bit set, so the section will be ignored by older linkers. ++// It is removed by the new linker, so never ends up in final executables. ++// This section is a table, initially with one row per function (that needs ++// unwind info). The table columns and some conceptual entries are: ++// ++// range-start pointer to start of function/range ++// range-length ++// compact-unwind-encoding 32-bit encoding ++// personality-function or zero if no personality function ++// lsda or zero if no LSDA data ++// ++// The length and encoding fields are 32-bits. The other are all pointer sized. ++// ++// In x86_64 assembly, these entry would look like: ++// ++// .section __LD,__compact_unwind,regular,debug ++// ++// #compact unwind for _foo ++// .quad _foo ++// .set L1,LfooEnd-_foo ++// .long L1 ++// .long 0x01010001 ++// .quad 0 ++// .quad 0 ++// ++// #compact unwind for _bar ++// .quad _bar ++// .set L2,LbarEnd-_bar ++// .long L2 ++// .long 0x01020011 ++// .quad __gxx_personality ++// .quad except_tab1 ++// ++// ++// Notes: There is no need for any labels in the the __compact_unwind section. ++// The use of the .set directive is to force the evaluation of the ++// range-length at assembly time, instead of generating relocations. ++// ++// To support future compiler optimizations where which non-volatile registers ++// are saved changes within a function (e.g. delay saving non-volatiles until ++// necessary), there can by multiple lines in the __compact_unwind table for one ++// function, each with a different (non-overlapping) range and each with ++// different compact unwind encodings that correspond to the non-volatiles ++// saved at that range of the function. ++// ++// If a particular function is so wacky that there is no compact unwind way ++// to encode it, then the compiler can emit traditional DWARF unwind info. ++// The runtime will use which ever is available. ++// ++// Runtime support for compact unwind encodings are only available on 10.6 ++// and later. So, the compiler should not generate it when targeting pre-10.6. ++ ++ ++ ++ ++//////////////////////////////////////////////////////////////////////////////// ++// ++// Final Linked Images: __TEXT,__unwind_info ++// ++//////////////////////////////////////////////////////////////////////////////// ++ ++// ++// The __TEXT,__unwind_info section is laid out for an efficient two level lookup. ++// The header of the section contains a coarse index that maps function address ++// to the page (4096 byte block) containing the unwind info for that function. ++// ++ ++#define UNWIND_SECTION_VERSION 1 ++struct unwind_info_section_header ++{ ++ uint32_t version; // UNWIND_SECTION_VERSION ++ uint32_t commonEncodingsArraySectionOffset; ++ uint32_t commonEncodingsArrayCount; ++ uint32_t personalityArraySectionOffset; ++ uint32_t personalityArrayCount; ++ uint32_t indexSectionOffset; ++ uint32_t indexCount; ++ // compact_unwind_encoding_t[] ++ // uint32_t personalities[] ++ // unwind_info_section_header_index_entry[] ++ // unwind_info_section_header_lsda_index_entry[] ++}; ++ ++struct unwind_info_section_header_index_entry ++{ ++ uint32_t functionOffset; ++ uint32_t secondLevelPagesSectionOffset; // section offset to start of regular or compress page ++ uint32_t lsdaIndexArraySectionOffset; // section offset to start of lsda_index array for this range ++}; ++ ++struct unwind_info_section_header_lsda_index_entry ++{ ++ uint32_t functionOffset; ++ uint32_t lsdaOffset; ++}; ++ ++// ++// There are two kinds of second level index pages: regular and compressed. ++// A compressed page can hold up to 1021 entries, but it cannot be used ++// if too many different encoding types are used. The regular page holds ++// 511 entries. ++// ++ ++struct unwind_info_regular_second_level_entry ++{ ++ uint32_t functionOffset; ++ compact_unwind_encoding_t encoding; ++}; ++ ++#define UNWIND_SECOND_LEVEL_REGULAR 2 ++struct unwind_info_regular_second_level_page_header ++{ ++ uint32_t kind; // UNWIND_SECOND_LEVEL_REGULAR ++ uint16_t entryPageOffset; ++ uint16_t entryCount; ++ // entry array ++}; ++ ++#define UNWIND_SECOND_LEVEL_COMPRESSED 3 ++struct unwind_info_compressed_second_level_page_header ++{ ++ uint32_t kind; // UNWIND_SECOND_LEVEL_COMPRESSED ++ uint16_t entryPageOffset; ++ uint16_t entryCount; ++ uint16_t encodingsPageOffset; ++ uint16_t encodingsCount; ++ // 32-bit entry array ++ // encodings array ++}; ++ ++#define UNWIND_INFO_COMPRESSED_ENTRY_FUNC_OFFSET(entry) (entry & 0x00FFFFFF) ++#define UNWIND_INFO_COMPRESSED_ENTRY_ENCODING_INDEX(entry) ((entry >> 24) & 0xFF) ++ ++ ++ ++#endif ++ +-- +1.8.3.1 + diff --git a/SOURCES/lld-11.0.0.src.tar.xz.sig b/SOURCES/lld-11.0.0.src.tar.xz.sig deleted file mode 100644 index 0884359..0000000 Binary files a/SOURCES/lld-11.0.0.src.tar.xz.sig and /dev/null differ diff --git a/SOURCES/lld-12.0.1.src.tar.xz.sig b/SOURCES/lld-12.0.1.src.tar.xz.sig new file mode 100644 index 0000000..204df67 Binary files /dev/null and b/SOURCES/lld-12.0.1.src.tar.xz.sig differ diff --git a/SPECS/lld.spec b/SPECS/lld.spec index 01aa3d0..497ac4b 100644 --- a/SPECS/lld.spec +++ b/SPECS/lld.spec @@ -1,9 +1,8 @@ -#%%global rc_ver 6 -%global baserelease 3 +#%%global rc_ver 5 %global lld_srcdir lld-%{version}%{?rc_ver:rc%{rc_ver}}.src -%global maj_ver 11 +%global maj_ver 12 %global min_ver 0 -%global patch_ver 0 +%global patch_ver 1 # Don't include unittests in automatic generation of provides or requires. %global __provides_exclude_from ^%{_libdir}/lld/.*$ @@ -12,23 +11,25 @@ %bcond_with ld_alternative Name: lld -Version: %{maj_ver}.%{min_ver}.%{patch_ver} -Release: %{baserelease}%{?rc_ver:.rc%{rc_ver}}%{?dist} +Version: %{maj_ver}.%{min_ver}.%{patch_ver}%{?rc_ver:~rc%{rc_ver}} +Release: 1%{?dist} Summary: The LLVM Linker License: NCSA URL: http://llvm.org Source0: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{version}%{?rc_ver:-rc%{rc_ver}}/%{lld_srcdir}.tar.xz Source1: https://github.com/llvm/llvm-project/releases/download/llvmorg-%{version}%{?rc_ver:-rc%{rc_ver}}/%{lld_srcdir}.tar.xz.sig -Source2: https://prereleases.llvm.org/%{version}/hans-gpg-key.asc +Source2: tstellar-gpg-key.asc Source3: run-lit-tests Source4: lit.lld-test.cfg.py -Patch0: 0001-CMake-Check-for-gtest-headers-even-if-lit.py-is-not-.patch -Patch1: 0001-Revert-lld-Initial-commit-for-new-Mach-O-backend.patch - ExcludeArch: s390x +Patch0: 0001-PATCH-lld-CMake-Check-for-gtest-headers-even-if-lit..patch + +# Bundle libunwind header need during build for MachO support +Patch1: 0002-PATCH-lld-Import-compact_unwind_encoding.h-from-libu.patch + BuildRequires: gcc BuildRequires: gcc-c++ BuildRequires: cmake @@ -83,19 +84,17 @@ LLVM regression tests. %prep -%setup -q -n %{lld_srcdir} +%autosetup -n %{lld_srcdir} -p2 -%patch0 -p1 -b .gtest-fix -# Remove the MachO backend since it doesn't seem to work on big-endian hosts. -%ifarch s390x -%patch1 -p2 -b .remove-MachO -%endif %build -mkdir %{_target_platform} -cd %{_target_platform} +# Disable lto since it causes the COFF/libpath.test lit test to crash. +%global _lto_cflags %{nil} + +mkdir -p %{_vpath_builddir} +cd %{_vpath_builddir} %cmake .. \ -GNinja \ @@ -114,10 +113,10 @@ cd %{_target_platform} -DLLVM_LIBDIR_SUFFIX= %endif -%ninja_build +%cmake_build # Build the unittests so we can install them. -%ninja_build lld-test-depends +%cmake_build --target lld-test-depends %install @@ -146,7 +145,7 @@ mv %{lit_unit_cfg} %{buildroot}%{_datadir}/lld/src/%{_arch}.Unit.site.cfg.py tar --sort=name --mtime='UTC 2020-01-01' -c test/ | gzip -n > %{buildroot}%{_datadir}/lld/src/test.tar.gz install -d %{buildroot}%{_libexecdir}/tests/lld -cp %{SOURCE3} %{buildroot}%{_libexecdir}/tests/lld +install -m 0755 %{SOURCE3} %{buildroot}%{_libexecdir}/tests/lld # Install unit test binaries install -d %{buildroot}%{_libdir}/lld/ @@ -158,7 +157,10 @@ cp %{_target_platform}/%{_lib}/libgtest*so* %{buildroot}%{_libdir}/lld/ # Install libraries and binaries cd %{_target_platform} -%ninja_install + +%cmake_install +# This is generated by Patch1 during build and (probably) must be removed afterward +rm %{buildroot}%{_includedir}/mach-o/compact_unwind_encoding.h %if %{with ld_alternative} # Required when using update-alternatives: @@ -176,9 +178,11 @@ fi %check +cd %{_vpath_builddir} + # armv7lhl tests disabled because of arm issue, see https://koji.fedoraproject.org/koji/taskinfo?taskID=33660162 %ifnarch %{arm} -%ninja_build -C %{_target_platform} %{?_smp_mflags} check-lld +%cmake_build --target check-lld %endif %ldconfig_scriptlets libs @@ -191,6 +195,7 @@ fi %{_bindir}/lld* %{_bindir}/ld.lld %{_bindir}/ld64.lld +%{_bindir}/ld64.lld.darwinnew %{_bindir}/wasm-ld %files devel @@ -210,6 +215,12 @@ fi %{_datadir}/lld/lit.lld-test.cfg.py %changelog +* Fri Jul 16 2021 sguelton@redhat.com - 12.0.1-1 +- 12.0.1 release + +* Thu May 6 2021 sguelton@redhat.com - 12.0.0-1 +- 12.0.0 release + * Mon Nov 09 2020 sguelton@redhat.com - 11.0.0-3 - Exclude s390x, see rhbz#1894927