diff --git a/llvm/include/llvm/MC/MCMachObjectWriter.h b/llvm/include/llvm/MC/MCMachObjectWriter.h index 24004c6616220..f47af7bd631aa 100644 --- a/llvm/include/llvm/MC/MCMachObjectWriter.h +++ b/llvm/include/llvm/MC/MCMachObjectWriter.h @@ -86,12 +86,6 @@ class MCMachObjectTargetWriter : public MCObjectTargetWriter { class MachObjectWriter : public MCObjectWriter { public: - struct DataRegionData { - MachO::DataRegionType Kind; - MCSymbol *Start; - MCSymbol *End; - }; - // A Major version of 0 indicates that no version information was supplied // and so the corresponding load command should not be emitted. using VersionInfoType = struct { @@ -118,11 +112,6 @@ class MachObjectWriter : public MCObjectWriter { bool operator<(const MachSymbolData &RHS) const; }; - struct IndirectSymbolData { - MCSymbol *Symbol; - MCSection *Section; - }; - /// The target specific Mach-O writer instance. std::unique_ptr TargetObjectWriter; @@ -143,11 +132,8 @@ class MachObjectWriter : public MCObjectWriter { private: DenseMap> Relocations; - std::vector IndirectSymbols; DenseMap IndirectSymBase; - std::vector DataRegions; - SectionAddrMap SectionAddress; // List of sections in layout order. Virtual sections are after non-virtual @@ -165,18 +151,12 @@ class MachObjectWriter : public MCObjectWriter { /// @} - // Used to communicate Linker Optimization Hint information. - MCLOHContainer LOHContainer; - VersionInfoType VersionInfo{}; VersionInfoType TargetVariantVersionInfo{}; std::optional PtrAuthABIVersion; bool PtrAuthKernelABIVersion; - // The list of linker options for LC_LINKER_OPTION. - std::vector> LinkerOptions; - MachSymbolData *findSymbolData(const MCSymbol &Sym); void writeWithPadding(StringRef Str, uint64_t Size); @@ -214,15 +194,10 @@ class MachObjectWriter : public MCObjectWriter { bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); - std::vector &getIndirectSymbols() { - return IndirectSymbols; - } - std::vector &getDataRegions() { return DataRegions; } const llvm::SmallVectorImpl &getSectionOrder() const { return SectionOrder; } SectionAddrMap &getSectionAddressMap() { return SectionAddress; } - MCLOHContainer &getLOHContainer() { return LOHContainer; } uint64_t getSectionAddress(const MCSection *Sec) const { return SectionAddress.lookup(Sec); @@ -281,9 +256,6 @@ class MachObjectWriter : public MCObjectWriter { void setPtrAuthKernelABIVersion(bool V) override { PtrAuthKernelABIVersion = V; } - std::vector> &getLinkerOptions() { - return LinkerOptions; - } /// @} diff --git a/llvm/include/llvm/MC/MCObjectWriter.h b/llvm/include/llvm/MC/MCObjectWriter.h index 2cb01578f1a5e..89623cbbec451 100644 --- a/llvm/include/llvm/MC/MCObjectWriter.h +++ b/llvm/include/llvm/MC/MCObjectWriter.h @@ -10,6 +10,7 @@ #define LLVM_MC_MCOBJECTWRITER_H #include "llvm/MC/MCDirectives.h" +#include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCSymbol.h" #include "llvm/TargetParser/Triple.h" #include @@ -32,7 +33,29 @@ class MCValue; /// MCAssembler instance, which contains all the symbol and section data which /// should be emitted as part of writeObject(). class MCObjectWriter { +public: + struct DataRegionData { + unsigned Kind; + MCSymbol *Start; + MCSymbol *End; + }; + protected: + struct IndirectSymbolData { + MCSymbol *Symbol; + MCSection *Section; + }; + + std::vector IndirectSymbols; + + std::vector DataRegions; + + // The list of linker options for LC_LINKER_OPTION. + std::vector> LinkerOptions; + + // Used to communicate Linker Optimization Hint information. + MCLOHContainer LOHContainer; + /// List of declared file names SmallVector, 0> FileNames; // XCOFF specific: Optional compiler version. @@ -61,6 +84,18 @@ class MCObjectWriter { /// \name High-Level API /// @{ + std::vector> &getLinkerOptions() { + return LinkerOptions; + } + + std::vector &getIndirectSymbols() { + return IndirectSymbols; + } + + MCLOHContainer &getLOHContainer() { return LOHContainer; } + + std::vector &getDataRegions() { return DataRegions; } + /// Perform any late binding of symbols (for example, to assign symbol /// indices for use when generating relocations). /// diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp index 479b1df250893..6cc545b5b7c81 100644 --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -78,9 +78,12 @@ class MCMachOStreamer : public MCObjectStreamer { MCObjectStreamer::reset(); } - MachObjectWriter &getWriter() { - return static_cast(getAssembler().getWriter()); - } + // This function is commented out downstream because it is unsafe to use a + // MachObjectWriter in the McMachOStreamer which may hold a MachOCASWriter + // instead. + // MachObjectWriter &getWriter() { + // return static_cast(getAssembler().getWriter()); + // } MCObjectWriter &getMCObjectWriter() { return static_cast(getAssembler().getWriter()); @@ -124,12 +127,12 @@ class MCMachOStreamer : public MCObjectStreamer { } void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override { - getWriter().getLOHContainer().addDirective(Kind, Args); + getMCObjectWriter().getLOHContainer().addDirective(Kind, Args); } void emitCGProfileEntry(const MCSymbolRefExpr *From, const MCSymbolRefExpr *To, uint64_t Count) override { if (!From->getSymbol().isTemporary() && !To->getSymbol().isTemporary()) - getWriter().getCGProfile().push_back({From, To, Count}); + getMCObjectWriter().getCGProfile().push_back({From, To, Count}); } void finishImpl() override; @@ -203,11 +206,11 @@ void MCMachOStreamer::emitDataRegion(MachO::DataRegionType Kind) { MCSymbol *Start = getContext().createTempSymbol(); emitLabel(Start); // Record the region for the object writer to use. - getWriter().getDataRegions().push_back({Kind, Start, nullptr}); + getMCObjectWriter().getDataRegions().push_back({Kind, Start, nullptr}); } void MCMachOStreamer::emitDataRegionEnd() { - auto &Regions = getWriter().getDataRegions(); + auto &Regions = getMCObjectWriter().getDataRegions(); assert(!Regions.empty() && "Mismatched .end_data_region!"); auto &Data = Regions.back(); assert(!Data.End && "Mismatched .end_data_region!"); @@ -232,7 +235,7 @@ void MCMachOStreamer::emitAssemblerFlag(MCAssemblerFlag Flag) { } void MCMachOStreamer::emitLinkerOptions(ArrayRef Options) { - getWriter().getLinkerOptions().push_back(Options); + getMCObjectWriter().getLinkerOptions().push_back(Options); } void MCMachOStreamer::emitDataRegion(MCDataRegionType Kind) { @@ -277,8 +280,8 @@ void MCMachOStreamer::emitDarwinTargetVariantBuildVersion( void MCMachOStreamer::EmitPtrAuthABIVersion(unsigned PtrAuthABIVersion, bool PtrAuthKernelABIVersion) { - getWriter().setPtrAuthABIVersion(PtrAuthABIVersion); - getWriter().setPtrAuthKernelABIVersion(PtrAuthKernelABIVersion); + getMCObjectWriter().setPtrAuthABIVersion(PtrAuthABIVersion); + getMCObjectWriter().setPtrAuthKernelABIVersion(PtrAuthKernelABIVersion); } void MCMachOStreamer::emitThumbFunc(MCSymbol *Symbol) { @@ -297,7 +300,7 @@ bool MCMachOStreamer::emitSymbolAttribute(MCSymbol *Sym, if (Attribute == MCSA_IndirectSymbol) { // Note that we intentionally cannot use the symbol data here; this is // important for matching the string table that 'as' generates. - getWriter().getIndirectSymbols().push_back( + getMCObjectWriter().getIndirectSymbols().push_back( {Symbol, getCurrentSectionOnly()}); return true; } @@ -518,7 +521,7 @@ void MCMachOStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE) { void MCMachOStreamer::finalizeCGProfile() { MCAssembler &Asm = getAssembler(); - MCObjectWriter &W = getWriter(); + MCObjectWriter &W = getMCObjectWriter(); if (W.getCGProfile().empty()) return; for (auto &E : W.getCGProfile()) { diff --git a/llvm/lib/MC/MCObjectWriter.cpp b/llvm/lib/MC/MCObjectWriter.cpp index 818e703514d61..b0e922b669176 100644 --- a/llvm/lib/MC/MCObjectWriter.cpp +++ b/llvm/lib/MC/MCObjectWriter.cpp @@ -25,6 +25,10 @@ void MCObjectWriter::reset() { EmitAddrsigSection = false; SubsectionsViaSymbols = false; CGProfile.clear(); + LinkerOptions.clear(); + LOHContainer.reset(); + DataRegions.clear(); + IndirectSymbols.clear(); } bool MCObjectWriter::isSymbolRefDifferenceFullyResolved( diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp index a158e431c37b1..8f2bc100e39a2 100644 --- a/llvm/lib/MC/MachObjectWriter.cpp +++ b/llvm/lib/MC/MachObjectWriter.cpp @@ -49,21 +49,18 @@ void MachObjectWriter::reset() { Relocations.clear(); IndirectSymBase.clear(); IndirectSymbols.clear(); - DataRegions.clear(); SectionAddress.clear(); SectionOrder.clear(); StringTable.clear(); LocalSymbolData.clear(); ExternalSymbolData.clear(); UndefinedSymbolData.clear(); - LOHContainer.reset(); VersionInfo.Major = 0; VersionInfo.SDKVersion = VersionTuple(); TargetVariantVersionInfo.Major = 0; TargetVariantVersionInfo.SDKVersion = VersionTuple(); PtrAuthABIVersion = std::nullopt; PtrAuthKernelABIVersion = false; - LinkerOptions.clear(); MCObjectWriter::reset(); } @@ -1097,10 +1094,11 @@ void MachObjectWriter::writeDataInCodeRegion(MCAssembler &Asm) { else report_fatal_error("Data region not terminated"); - LLVM_DEBUG(dbgs() << "data in code region-- kind: " << Data.Kind - << " start: " << Start << "(" << Data.Start->getName() - << ")" << " end: " << End << "(" << Data.End->getName() - << ")" << " size: " << End - Start << "\n"); + LLVM_DEBUG(dbgs() << "data in code region-- kind: " + << (MachO::DataRegionType)Data.Kind << " start: " + << Start << "(" << Data.Start->getName() << ")" + << " end: " << End << "(" << Data.End->getName() << ")" + << " size: " << End - Start << "\n"); W.write(Start); W.write(End - Start); W.write(Data.Kind); diff --git a/llvm/test/MC/MachO/linker-options.ll b/llvm/test/MC/MachO/linker-options.ll index 0f678cd3ad16c..0ddc8c0bce260 100644 --- a/llvm/test/MC/MachO/linker-options.ll +++ b/llvm/test/MC/MachO/linker-options.ll @@ -6,6 +6,8 @@ ; RUN: llc -O0 -mtriple=x86_64-apple-darwin -filetype=obj -o - %s | llvm-readobj --macho-linker-options - > %t ; RUN: FileCheck --check-prefix=CHECK-OBJ < %t %s +; RUN: mkdir -p %t.dir/cas +; RUN: llc -O0 -mtriple=x86_64-apple-darwin -filetype=obj --cas %t.dir/cas -cas-backend -o - %s | llvm-readobj --macho-linker-options - > %t ; CHECK-OBJ: Linker Options { ; CHECK-OBJ: Size: 16