https://github.com/VisualEhrmanntraut updated https://github.com/llvm/llvm-project/pull/204805
>From 0b1bb93f4e9a240a6e4f3430bfd656099ea186ae Mon Sep 17 00:00:00 2001 From: Visual <[email protected]> Date: Fri, 19 Jun 2026 15:25:37 +0300 Subject: [PATCH] Somewhat finished Apple Kext support --- clang/lib/Driver/ToolChains/Darwin.cpp | 23 ++-- .../InstallAPI/DiagnosticBuilderWrappers.cpp | 3 + lld/MachO/Driver.cpp | 17 ++- lld/MachO/InputSection.cpp | 8 ++ lld/MachO/InputSection.h | 3 +- lld/MachO/Options.td | 7 +- lld/MachO/OutputSegment.cpp | 20 ++-- lld/MachO/SyntheticSections.cpp | 101 +++++++++++++++--- lld/MachO/SyntheticSections.h | 44 ++++++++ lld/MachO/Writer.cpp | 56 ++++++++-- llvm/include/llvm/TextAPI/FileTypes.h | 3 + llvm/lib/TextAPI/BinaryReader/DylibReader.cpp | 3 + 12 files changed, 242 insertions(+), 46 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 0fb94d8712e69..5607bffb0ccc0 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -345,10 +345,6 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, // FIXME: Why do this only on this path? Args.AddLastArg(CmdArgs, options::OPT_force__cpusubtype__ALL); - Args.AddLastArg(CmdArgs, options::OPT_bundle); - Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader); - Args.AddAllArgs(CmdArgs, options::OPT_client__name); - Arg *A; if ((A = Args.getLastArg(options::OPT_compatibility__version)) || (A = Args.getLastArg(options::OPT_current__version)) || @@ -356,14 +352,25 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args) << "-dynamiclib"; - Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace); + if ((A = Args.getLastArg(options::OPT_fapple_kext))) { + CmdArgs.push_back("-kext"); + CmdArgs.push_back("-undefined"); + CmdArgs.push_back("dynamic_lookup"); + } else { + Args.AddLastArg(CmdArgs, options::OPT_bundle); + Args.AddAllArgs(CmdArgs, options::OPT_bundle__loader); + Args.AddLastArg(CmdArgs, options::OPT_force__flat__namespace); + Args.AddLastArg(CmdArgs, options::OPT_private__bundle); + } + + Args.AddAllArgs(CmdArgs, options::OPT_client__name); Args.AddLastArg(CmdArgs, options::OPT_keep__private__externs); - Args.AddLastArg(CmdArgs, options::OPT_private__bundle); } else { CmdArgs.push_back("-dylib"); Arg *A; - if ((A = Args.getLastArg(options::OPT_bundle)) || + if ((A = Args.getLastArg(options::OPT_fapple_kext)) || + (A = Args.getLastArg(options::OPT_bundle)) || (A = Args.getLastArg(options::OPT_bundle__loader)) || (A = Args.getLastArg(options::OPT_client__name)) || (A = Args.getLastArg(options::OPT_force__flat__namespace)) || @@ -4087,6 +4094,8 @@ void Darwin::addStartObjectFileArgs(const ArgList &Args, // Derived from startfile spec. if (Args.hasArg(options::OPT_dynamiclib)) addDynamicLibLinkArgs(*this, Args, CmdArgs); + else if (Args.hasArg(options::OPT_fapple_kext)) + CmdArgs.push_back("-kext"); // TODO ? else if (Args.hasArg(options::OPT_bundle)) addBundleLinkArgs(*this, Args, CmdArgs); else if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) diff --git a/clang/lib/InstallAPI/DiagnosticBuilderWrappers.cpp b/clang/lib/InstallAPI/DiagnosticBuilderWrappers.cpp index 37b428216c91e..4e093392f5c34 100644 --- a/clang/lib/InstallAPI/DiagnosticBuilderWrappers.cpp +++ b/clang/lib/InstallAPI/DiagnosticBuilderWrappers.cpp @@ -57,6 +57,9 @@ const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, case FileType::MachO_Bundle: DB.AddString("mach-o bundle"); return DB; + case FileType::MachO_KextBundle: + DB.AddString("mach-o kext bundle"); + return DB; case FileType::MachO_DynamicLibrary: DB.AddString("mach-o dynamic library"); return DB; diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp index 0dfced91c511d..01a053a1f8619 100644 --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -73,11 +73,14 @@ std::unique_ptr<DependencyTracker> macho::depTracker; static HeaderFileType getOutputType(const InputArgList &args) { // TODO: -r, -dylinker, -preload... - Arg *outputArg = args.getLastArg(OPT_bundle, OPT_dylib, OPT_execute); + Arg *outputArg = + args.getLastArg(OPT_kext, OPT_bundle, OPT_dylib, OPT_execute); if (outputArg == nullptr) return MH_EXECUTE; switch (outputArg->getOption().getID()) { + case OPT_kext: + return MH_KEXT_BUNDLE; case OPT_bundle: return MH_BUNDLE; case OPT_dylib: @@ -1257,6 +1260,7 @@ static bool dataConstDefault(const InputArgList &args) { switch (config->outputType) { case MH_EXECUTE: + case MH_KEXT_BUNDLE: return !(args.hasArg(OPT_no_pie) && supportsNoPie()); case MH_BUNDLE: // FIXME: return false when -final_name ... @@ -1294,6 +1298,14 @@ static bool shouldEmitChainedFixups(const InputArgList &args) { return false; } + if (args.hasArg(OPT_kext) && + is_contained({AK_x86_64, AK_x86_64h}, config->arch())) { + if (requested) + error("-fixup_chains with -kext is only supported on arm64 targets"); + + return false; + } + if (args.hasArg(OPT_preload)) { if (requested) error("-fixup_chains is incompatible with -preload"); @@ -1884,7 +1896,8 @@ bool link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS, pie = true; } - config->isPic = config->outputType == MH_DYLIB || + config->isPic = config->outputType == MH_KEXT_BUNDLE || + config->outputType == MH_DYLIB || config->outputType == MH_BUNDLE || (config->outputType == MH_EXECUTE && pie); diff --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp index 6ea4b0ddd58e4..0bc199029c1af 100644 --- a/lld/MachO/InputSection.cpp +++ b/lld/MachO/InputSection.cpp @@ -252,6 +252,14 @@ void ConcatInputSection::writeTo(uint8_t *buf) { if (target->hasAttr(r.type, RelocAttrBits::LOAD) && !referentSym->isInGot()) target->relaxGotLoad(loc, r.type); + if (config->outputType == MH_KEXT_BUNDLE && !needsFixup && + needsBinding(referentSym)) { + if (target->hasAttr(r.type, RelocAttrBits::BRANCH)) { + continue; + } + if (!referentSym->isInGot()) + continue; + } // For dtrace symbols, do not handle them as normal undefined symbols if (referentSym->getName().starts_with("___dtrace_")) { // Change dtrace call site to pre-defined instructions diff --git a/lld/MachO/InputSection.h b/lld/MachO/InputSection.h index 49ea57a24129c..f7966540894e6 100644 --- a/lld/MachO/InputSection.h +++ b/lld/MachO/InputSection.h @@ -380,7 +380,8 @@ constexpr const char unwindInfo[] = "__unwind_info"; constexpr const char weakBinding[] = "__weak_binding"; constexpr const char zeroFill[] = "__zerofill"; constexpr const char addrSig[] = "__llvm_addrsig"; - +constexpr const char extRelocs[] = "__ext_relocs"; +constexpr const char localRelocs[] = "__local_relocs"; } // namespace section_names void addInputSection(InputSection *inputSection); diff --git a/lld/MachO/Options.td b/lld/MachO/Options.td index 32b6ce0a64a07..c8f6199d87892 100644 --- a/lld/MachO/Options.td +++ b/lld/MachO/Options.td @@ -244,6 +244,9 @@ def dylib : Flag<["-"], "dylib">, def bundle : Flag<["-"], "bundle">, HelpText<"Produce a bundle">, Group<grp_kind>; +def kext : Flag<["-"], "kext">, + HelpText<"Produce a kext bundle">, + Group<grp_kind>; def r : Flag<["-"], "r">, HelpText<"Merge multiple object files into one, retaining relocations">, Flags<[HelpHidden]>, @@ -1432,10 +1435,6 @@ 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]>, diff --git a/lld/MachO/OutputSegment.cpp b/lld/MachO/OutputSegment.cpp index 5824b5c7772b3..d705a0e3994d2 100644 --- a/lld/MachO/OutputSegment.cpp +++ b/lld/MachO/OutputSegment.cpp @@ -155,15 +155,17 @@ static int sectionOrder(OutputSection *osec) { } } else if (segname == segment_names::linkEdit) { return StringSwitch<int>(osec->name) - .Case(section_names::chainFixups, -11) - .Case(section_names::rebase, -10) - .Case(section_names::binding, -9) - .Case(section_names::weakBinding, -8) - .Case(section_names::lazyBinding, -7) - .Case(section_names::export_, -6) - .Case(section_names::functionStarts, -5) - .Case(section_names::dataInCode, -4) - .Case(section_names::symbolTable, -3) + .Case(section_names::chainFixups, -13) + .Case(section_names::rebase, -12) + .Case(section_names::binding, -11) + .Case(section_names::weakBinding, -10) + .Case(section_names::lazyBinding, -9) + .Case(section_names::export_, -8) + .Case(section_names::localRelocs, -7) + .Case(section_names::functionStarts, -6) + .Case(section_names::dataInCode, -5) + .Case(section_names::symbolTable, -4) + .Case(section_names::extRelocs, -3) .Case(section_names::indirectSymbolTable, -2) .Case(section_names::stringTable, -1) .Case(section_names::codeSignature, std::numeric_limits<int>::max()) diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp index 808f32fb2b094..8f53f7aede900 100644 --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -108,12 +108,14 @@ static uint32_t cpuSubtype() { static bool hasWeakBinding() { return config->emitChainedFixups ? in.chainedFixups->hasWeakBinding() - : in.weakBinding->hasEntry(); + : config->outputType != MH_KEXT_BUNDLE && + in.weakBinding->hasEntry(); } static bool hasNonWeakDefinition() { return config->emitChainedFixups ? in.chainedFixups->hasNonWeakDefinition() - : in.weakBinding->hasNonWeakDefinition(); + : config->outputType != MH_KEXT_BUNDLE && + in.weakBinding->hasNonWeakDefinition(); } void MachHeaderSection::writeTo(uint8_t *buf) const { @@ -141,10 +143,10 @@ void MachHeaderSection::writeTo(uint8_t *buf) const { if (config->outputType == MH_DYLIB && config->applicationExtension) hdr->flags |= MH_APP_EXTENSION_SAFE; - if (in.exports->hasWeakSymbol || hasNonWeakDefinition()) + if (in.exports && (in.exports->hasWeakSymbol || hasNonWeakDefinition())) hdr->flags |= MH_WEAK_DEFINES; - if (in.exports->hasWeakSymbol || hasWeakBinding()) + if (in.exports && (in.exports->hasWeakSymbol || hasWeakBinding())) hdr->flags |= MH_BINDS_TO_WEAK; for (const OutputSegment *seg : outputSegments) { @@ -319,6 +321,18 @@ void macho::addNonLazyBindingEntries(const Symbol *sym, return; } + if (config->outputType == MH_KEXT_BUNDLE) { + if (needsBinding(sym)) + in.extRelocs->addEntry(sym, isec, offset, target->unsignedRelocType, + /*pcrel=*/false, target->p2WordSize); + else if (isa<Defined>(sym)) + in.localRelocs->addEntry(sym, isec, offset, target->unsignedRelocType, + /*pcrel=*/false, target->p2WordSize); + else + llvm_unreachable("cannot bind to an undefined symbol"); + return; + } + if (const auto *dysym = dyn_cast<DylibSymbol>(sym)) { in.binding->addEntry(dysym, isec, offset, addend); if (dysym->isWeakDef()) @@ -750,7 +764,7 @@ void StubsSection::addEntry(Symbol *sym) { if (inserted) { sym->stubsIndex = entries.size() - 1; - if (config->emitChainedFixups) + if (config->emitChainedFixups || config->outputType == MH_KEXT_BUNDLE) in.got->addEntry(sym); else addBindingsForStub(sym); @@ -808,6 +822,57 @@ void StubHelperSection::setUp() { dyldPrivate->used = true; } +RelocSection::RelocSection(const char *name) + : LinkEditSection(segment_names::linkEdit, name) {} + +void RelocSection::addEntry(const Symbol *sym, const InputSection *isec, + uint32_t offset, uint8_t type, bool pcrel, + uint8_t length) { + assert(!this->isFinal && "RelocSection entry added after finalizeContents"); + this->entries.emplace_back(sym, isec, offset, type, pcrel, length); +} + +void RelocSection::finalizeContents() { + assert(!this->isFinal && "RelocSection finalized twice"); + this->isFinal = true; + + const bool isExternal = this->isExternal(); + + raw_svector_ostream os{contents}; + for (const Entry &e : entries) { + char buf[sizeof(uint32_t)]; + write32le(buf, e.isec->getVA(e.offset)); + os.write(buf, sizeof(buf)); + + uint32_t symOrSectNum; + if (isExternal) + symOrSectNum = e.sym->symtabIndex; + else { + const auto *def = dyn_cast_or_null<Defined>(e.sym); + const InputSection *targetIsec = def ? def->isec() : e.isec; + symOrSectNum = targetIsec->parent->index; + } + + write32le(buf, (symOrSectNum & 0x00ffffffu) | + (static_cast<uint32_t>(e.pcrel) << 24) | + (static_cast<uint32_t>(e.length) << 25) | + (static_cast<uint32_t>(isExternal) << 27) | + (static_cast<uint32_t>(e.type) << 28)); + os.write(buf, sizeof(buf)); + } +} + +void RelocSection::writeTo(uint8_t *buf) const { + assert(this->isFinal && "RelocSection contents written before finalization"); + memcpy(buf, contents.data(), contents.size()); +} + +ExternalRelocSection::ExternalRelocSection() + : RelocSection(section_names::extRelocs) {} + +LocalRelocSection::LocalRelocSection() + : RelocSection(section_names::localRelocs) {} + llvm::DenseMap<llvm::CachedHashStringRef, ConcatInputSection *> ObjCSelRefsHelper::methnameToSelref; void ObjCSelRefsHelper::initialize() { @@ -1494,25 +1559,26 @@ IndirectSymtabSection::IndirectSymtabSection() section_names::indirectSymbolTable) {} uint32_t IndirectSymtabSection::getNumSymbols() const { - uint32_t size = in.got->getEntries().size() + in.stubs->getEntries().size(); - if (!config->emitChainedFixups) - size += in.stubs->getEntries().size(); + uint32_t size = in.got->getEntries().size(); + if (in.stubs) + size += in.stubs->getEntries().size() * (config->emitChainedFixups ? 1 : 2); return size; } bool IndirectSymtabSection::isNeeded() const { - return in.got->isNeeded() || in.stubs->isNeeded(); + return in.got->isNeeded() || (in.stubs && in.stubs->isNeeded()); } void IndirectSymtabSection::finalizeContents() { uint32_t off = 0; in.got->reserved1 = off; off += in.got->getEntries().size(); - in.stubs->reserved1 = off; - if (in.lazyPointers) { + if (in.stubs) { + in.stubs->reserved1 = off; off += in.stubs->getEntries().size(); - in.lazyPointers->reserved1 = off; } + if (in.lazyPointers) + in.lazyPointers->reserved1 = off; } static uint32_t indirectValue(const Symbol *sym) { @@ -1527,9 +1593,11 @@ void IndirectSymtabSection::writeTo(uint8_t *buf) const { write32le(buf + off * sizeof(uint32_t), indirectValue(sym)); ++off; } - for (const Symbol *sym : in.stubs->getEntries()) { - write32le(buf + off * sizeof(uint32_t), indirectValue(sym)); - ++off; + if (in.stubs) { + for (const Symbol *sym : in.stubs->getEntries()) { + write32le(buf + off * sizeof(uint32_t), indirectValue(sym)); + ++off; + } } if (in.lazyPointers) { @@ -2327,6 +2395,9 @@ void macho::createSyntheticSymbols() { // The following symbols are N_SECT symbols, even though the header is not // part of any section and that they are private to the bundle/dylib/object // they are part of. + case MH_KEXT_BUNDLE: + addHeaderSymbol("__mh_kext_bundle_header"); + break; case MH_BUNDLE: addHeaderSymbol("__mh_bundle_header"); break; diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h index 2cc71414d56e7..f909b0f8e9805 100644 --- a/lld/MachO/SyntheticSections.h +++ b/lld/MachO/SyntheticSections.h @@ -288,6 +288,48 @@ class StubsSection final : public SyntheticSection { llvm::SetVector<Symbol *> entries; }; +class RelocSection : public LinkEditSection { +public: + RelocSection(const char *name); + void addEntry(const Symbol *sym, const InputSection *isec, uint32_t offset, + uint8_t type, bool pcrel, uint8_t length); + bool isNeeded() const override { return !entries.empty(); } + void finalizeContents() override; + uint64_t getRawSize() const override { return contents.size(); } + void writeTo(uint8_t *buf) const override; + + virtual bool isExternal() const = 0; + + struct Entry { + const Symbol *sym; + const InputSection *isec; + uint32_t offset; + uint8_t type; + bool pcrel; + uint8_t length; + + Entry(const Symbol *sym, const InputSection *isec, uint32_t offset, + uint8_t type, bool pcrel, uint8_t length) + : sym(sym), isec(isec), offset(offset), type(type), pcrel(pcrel), + length(length) {} + }; + bool isFinal = false; + std::vector<Entry> entries; + SmallVector<char, 128> contents; +}; + +class ExternalRelocSection final : public RelocSection { +public: + ExternalRelocSection(); + bool isExternal() const override { return true; } +}; + +class LocalRelocSection final : public RelocSection { +public: + LocalRelocSection(); + bool isExternal() const override { return false; } +}; + class StubHelperSection final : public SyntheticSection { public: StubHelperSection(); @@ -844,6 +886,8 @@ struct InStruct { InitOffsetsSection *initOffsets = nullptr; ObjCMethListSection *objcMethList = nullptr; ChainedFixupsSection *chainedFixups = nullptr; + ExternalRelocSection *extRelocs = nullptr; + LocalRelocSection *localRelocs = nullptr; CStringSection *getOrCreateCStringSection(StringRef name, bool forceDedupStrings = false) { diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp index b97203d656ebd..532a385a8a9f5 100644 --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -212,6 +212,16 @@ class LCDysymtab final : public LoadCommand { c->indirectsymoff = indirectSymtabSection->fileOff; c->nindirectsyms = indirectSymtabSection->getNumSymbols(); + + // For kext bundles + if (in.extRelocs && in.extRelocs->isNeeded()) { + c->extreloff = in.extRelocs->fileOff; + c->nextrel = in.extRelocs->entries.size(); + } + if (in.localRelocs && in.localRelocs->isNeeded()) { + c->locreloff = in.localRelocs->fileOff; + c->nlocrel = in.localRelocs->entries.size(); + } } SymtabSection *symtabSection; @@ -684,12 +694,23 @@ static void prepareSymbolRelocation(Symbol *sym, const InputSection *isec, const RelocAttrs &relocAttrs = target->getRelocAttrs(r.type); if (relocAttrs.hasAttr(RelocAttrBits::BRANCH)) { - if (needsBinding(sym)) - in.stubs->addEntry(sym); + if (needsBinding(sym)) { + if (config->outputType == MH_KEXT_BUNDLE) { + in.extRelocs->addEntry(sym, isec, r.offset, r.type, r.pcrel, r.length); + } else { + in.stubs->addEntry(sym); + } + } } else if (relocAttrs.hasAttr(RelocAttrBits::GOT)) { if (relocAttrs.hasAttr(RelocAttrBits::POINTER) || needsBinding(sym)) addNonLazyPointerEntry(sym); } else if (relocAttrs.hasAttr(RelocAttrBits::TLV)) { + if (config->outputType == MH_KEXT_BUNDLE) { + fatal(isec->getLocation(r.offset) + + ": TLV reference to external symbol " + sym->getName() + + " is not supported in kext bundles"); + return; + } if (needsBinding(sym)) addNonLazyPointerEntry(sym); } else if (relocAttrs.hasAttr(RelocAttrBits::UNSIGNED)) { @@ -741,6 +762,9 @@ void Writer::scanRelocations() { if (!r.pcrel) { if (config->emitChainedFixups) in.chainedFixups->addRebase(isec, r.offset); + else if (config->outputType == MH_KEXT_BUNDLE) + in.localRelocs->addEntry(sym, isec, r.offset, r.type, false, + r.length); else in.rebase->addEntry(isec, r.offset); } @@ -830,8 +854,9 @@ template <class LP> void Writer::createLoadCommands() { if (config->emitChainedFixups) { in.header->addLoadCommand(make<LCChainedFixups>(in.chainedFixups)); - in.header->addLoadCommand(make<LCExportsTrie>(in.exports)); - } else { + if (config->outputType != MH_KEXT_BUNDLE) + in.header->addLoadCommand(make<LCExportsTrie>(in.exports)); + } else if (config->outputType != MH_KEXT_BUNDLE) { in.header->addLoadCommand(make<LCDyldInfo>( in.rebase, in.binding, in.weakBinding, in.lazyBinding, in.exports)); } @@ -857,6 +882,7 @@ template <class LP> void Writer::createLoadCommands() { in.header->addLoadCommand(make<LCSubClient>(client)); break; case MH_BUNDLE: + case MH_KEXT_BUNDLE: break; default: llvm_unreachable("unhandled output file type"); @@ -1089,6 +1115,7 @@ template <class LP> void Writer::createOutputSections() { break; case MH_DYLIB: case MH_BUNDLE: + case MH_KEXT_BUNDLE: break; default: llvm_unreachable("unhandled output file type"); @@ -1208,6 +1235,11 @@ void Writer::finalizeLinkEditSegment() { osec->finalizeContents(); }); + if (in.extRelocs) + in.extRelocs->finalizeContents(); + if (in.localRelocs) + in.localRelocs->finalizeContents(); + // Now that __LINKEDIT is filled out, do a proper calculation of its // addresses and offsets. linkEditSegment->addr = addr; @@ -1434,9 +1466,9 @@ void macho::createSyntheticSections() { in.getOrCreateCStringSection(section_names::objcMethname, /*forceDedupStrings=*/true)); in.wordLiteralSection = make<WordLiteralSection>(); - if (config->emitChainedFixups) { + if (config->emitChainedFixups) in.chainedFixups = make<ChainedFixupsSection>(); - } else { + else if (config->outputType != MH_KEXT_BUNDLE) { in.rebase = make<RebaseSection>(); in.binding = make<BindingSection>(); in.weakBinding = make<WeakBindingSection>(); @@ -1444,14 +1476,22 @@ void macho::createSyntheticSections() { in.lazyPointers = make<LazyPointerSection>(); in.stubHelper = make<StubHelperSection>(); } - in.exports = make<ExportSection>(); + if (config->outputType == MH_KEXT_BUNDLE) { + if (!config->emitChainedFixups) + in.localRelocs = make<LocalRelocSection>(); + } else { + in.exports = make<ExportSection>(); + } in.got = make<GotSection>(); - in.stubs = make<StubsSection>(); + if (config->outputType != MH_KEXT_BUNDLE) + in.stubs = make<StubsSection>(); in.objcStubs = make<ObjCStubsSection>(); in.unwindInfo = makeUnwindInfoSection(); in.objCImageInfo = make<ObjCImageInfoSection>(); in.initOffsets = make<InitOffsetsSection>(); in.objcMethList = make<ObjCMethListSection>(); + if (config->outputType == MH_KEXT_BUNDLE) + in.extRelocs = make<ExternalRelocSection>(); // 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. diff --git a/llvm/include/llvm/TextAPI/FileTypes.h b/llvm/include/llvm/TextAPI/FileTypes.h index 5876e9d5a5304..b8d35130a39d7 100644 --- a/llvm/include/llvm/TextAPI/FileTypes.h +++ b/llvm/include/llvm/TextAPI/FileTypes.h @@ -40,6 +40,9 @@ enum FileType : unsigned { /// Text-based stub file (.tbd) version 5.0 TBD_V5 = 1U << 7, + /// \brief MachO Kernel Extension Bundle file. + MachO_KextBundle = 1U << 8, + All = ~0U, LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/All), diff --git a/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp b/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp index f55bc9c1a28c2..b072f6349e317 100644 --- a/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp +++ b/llvm/lib/TextAPI/BinaryReader/DylibReader.cpp @@ -157,6 +157,9 @@ static Error readMachOHeader(MachOObjectFile *Obj, RecordsSlice &Slice) { case MachO::MH_BUNDLE: BA.File = FileType::MachO_Bundle; break; + case MachO::MH_KEXT_BUNDLE: + BA.File = FileType::MachO_KextBundle; + break; } if (H.flags & MachO::MH_TWOLEVEL) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
