diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -967,6 +967,10 @@ } } + if (config->outputType == MH_BUNDLE) { + symtab->addMHHeader(in.header); + } + // Write to an output file. writeResult(); diff --git a/lld/MachO/SymbolTable.h b/lld/MachO/SymbolTable.h --- a/lld/MachO/SymbolTable.h +++ b/lld/MachO/SymbolTable.h @@ -9,6 +9,8 @@ #ifndef LLD_MACHO_SYMBOL_TABLE_H #define LLD_MACHO_SYMBOL_TABLE_H +#include "Symbols.h" +#include "lld/Common/ErrorHandler.h" #include "lld/Common/LLVM.h" #include "llvm/ADT/CachedHashString.h" #include "llvm/ADT/DenseMap.h" @@ -50,11 +52,29 @@ Symbol *addDSOHandle(const MachHeaderSection *); + Symbol *addMHHeader(const MachHeaderSection *); + ArrayRef getSymbols() const { return symVector; } Symbol *find(StringRef name); private: std::pair insert(StringRef name); + + template + Symbol *insertSymbol(const MachHeaderSection *header, StringRef name) { + Symbol *s; + bool wasInserted; + std::tie(s, wasInserted) = insert(name); + if (!wasInserted) { + // FIXME: Make every symbol (including absolute symbols) contain a + // reference to their originating file, then add that file name to this + // error message. dynamic_lookup symbols don't have an originating file. + if (isa(s)) + error("found defined symbol with illegal name " + name); + } + replaceSymbol(s, header); + return s; + } llvm::DenseMap symMap; std::vector symVector; }; diff --git a/lld/MachO/SymbolTable.cpp b/lld/MachO/SymbolTable.cpp --- a/lld/MachO/SymbolTable.cpp +++ b/lld/MachO/SymbolTable.cpp @@ -9,8 +9,6 @@ #include "SymbolTable.h" #include "Config.h" #include "InputFiles.h" -#include "Symbols.h" -#include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" using namespace llvm; @@ -159,18 +157,11 @@ } Symbol *SymbolTable::addDSOHandle(const MachHeaderSection *header) { - Symbol *s; - bool wasInserted; - std::tie(s, wasInserted) = insert(DSOHandle::name); - if (!wasInserted) { - // FIXME: Make every symbol (including absolute symbols) contain a - // reference to their originating file, then add that file name to this - // error message. dynamic_lookup symbols don't have an originating file. - if (isa(s)) - error("found defined symbol with illegal name " + DSOHandle::name); - } - replaceSymbol(s, header); - return s; + return insertSymbol(header, DSOHandle::name); +} + +Symbol *SymbolTable::addMHHeader(const MachHeaderSection *header) { + return insertSymbol(header, MHBundleHeader::name); } void lld::macho::treatUndefinedSymbol(const Undefined &sym) { diff --git a/lld/MachO/Symbols.h b/lld/MachO/Symbols.h --- a/lld/MachO/Symbols.h +++ b/lld/MachO/Symbols.h @@ -40,6 +40,7 @@ DylibKind, LazyKind, DSOHandleKind, + MHBundleHeaderKind, }; virtual ~Symbol() {} @@ -259,6 +260,27 @@ static bool classof(const Symbol *s) { return s->kind() == DSOHandleKind; } }; +class MHBundleHeader : public Symbol { +public: + MHBundleHeader(const MachHeaderSection *header) + : Symbol(MHBundleHeaderKind, name, nullptr), header(header) {} + const MachHeaderSection *header; + + uint64_t getVA() const override; + + uint64_t getFileOffset() const override; + + bool isWeakDef() const override { return false; } + + bool isTlv() const override { return false; } + + static constexpr StringRef name = "__mh_bundle_header"; + + static bool classof(const Symbol *s) { + return s->kind() == MHBundleHeaderKind; + } +}; + union SymbolUnion { alignas(Defined) char a[sizeof(Defined)]; alignas(Undefined) char b[sizeof(Undefined)]; @@ -266,6 +288,7 @@ alignas(DylibSymbol) char d[sizeof(DylibSymbol)]; alignas(LazySymbol) char e[sizeof(LazySymbol)]; alignas(DSOHandle) char f[sizeof(DSOHandle)]; + alignas(MHBundleHeader) char g[sizeof(MHBundleHeader)]; }; template diff --git a/lld/MachO/Symbols.cpp b/lld/MachO/Symbols.cpp --- a/lld/MachO/Symbols.cpp +++ b/lld/MachO/Symbols.cpp @@ -51,3 +51,9 @@ uint64_t DSOHandle::getFileOffset() const { return header->fileOff; } constexpr StringRef DSOHandle::name; + +uint64_t MHBundleHeader::getVA() const { return header->addr; } + +uint64_t MHBundleHeader::getFileOffset() const { return header->fileOff; } + +constexpr StringRef MHBundleHeader::name;