Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:14

0001 //===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_MC_MCOBJECTSTREAMER_H
0010 #define LLVM_MC_MCOBJECTSTREAMER_H
0011 
0012 #include "llvm/ADT/SetVector.h"
0013 #include "llvm/ADT/SmallVector.h"
0014 #include "llvm/MC/MCFixup.h"
0015 #include "llvm/MC/MCFragment.h"
0016 #include "llvm/MC/MCSection.h"
0017 #include "llvm/MC/MCStreamer.h"
0018 
0019 namespace llvm {
0020 class MCContext;
0021 class MCInst;
0022 class MCObjectWriter;
0023 class MCSymbol;
0024 struct MCDwarfFrameInfo;
0025 class MCAssembler;
0026 class MCCodeEmitter;
0027 class MCSubtargetInfo;
0028 class MCExpr;
0029 class MCAsmBackend;
0030 class raw_ostream;
0031 class raw_pwrite_stream;
0032 
0033 /// Streaming object file generation interface.
0034 ///
0035 /// This class provides an implementation of the MCStreamer interface which is
0036 /// suitable for use with the assembler backend. Specific object file formats
0037 /// are expected to subclass this interface to implement directives specific
0038 /// to that file format or custom semantics expected by the object writer
0039 /// implementation.
0040 class MCObjectStreamer : public MCStreamer {
0041   std::unique_ptr<MCAssembler> Assembler;
0042   bool EmitEHFrame;
0043   bool EmitDebugFrame;
0044   struct PendingMCFixup {
0045     const MCSymbol *Sym;
0046     MCFixup Fixup;
0047     MCDataFragment *DF;
0048     PendingMCFixup(const MCSymbol *McSym, MCDataFragment *F, MCFixup McFixup)
0049         : Sym(McSym), Fixup(McFixup), DF(F) {}
0050   };
0051   SmallVector<PendingMCFixup, 2> PendingFixups;
0052 
0053   struct PendingAssignment {
0054     MCSymbol *Symbol;
0055     const MCExpr *Value;
0056   };
0057 
0058   /// A list of conditional assignments we may need to emit if the target
0059   /// symbol is later emitted.
0060   DenseMap<const MCSymbol *, SmallVector<PendingAssignment, 1>>
0061       pendingAssignments;
0062 
0063   virtual void emitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
0064   void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
0065   void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
0066   MCSymbol *emitCFILabel() override;
0067   void emitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI);
0068   void resolvePendingFixups();
0069 
0070 protected:
0071   MCObjectStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
0072                    std::unique_ptr<MCObjectWriter> OW,
0073                    std::unique_ptr<MCCodeEmitter> Emitter);
0074   ~MCObjectStreamer();
0075 
0076 public:
0077   /// state management
0078   void reset() override;
0079 
0080   /// Object streamers require the integrated assembler.
0081   bool isIntegratedAssemblerRequired() const override { return true; }
0082 
0083   void emitFrames(MCAsmBackend *MAB);
0084   void emitCFISections(bool EH, bool Debug) override;
0085 
0086   void insert(MCFragment *F) {
0087     auto *Sec = CurFrag->getParent();
0088     F->setParent(Sec);
0089     F->setLayoutOrder(CurFrag->getLayoutOrder() + 1);
0090     CurFrag->Next = F;
0091     CurFrag = F;
0092     Sec->curFragList()->Tail = F;
0093   }
0094 
0095   /// Get a data fragment to write into, creating a new one if the current
0096   /// fragment is not a data fragment.
0097   /// Optionally a \p STI can be passed in so that a new fragment is created
0098   /// if the Subtarget differs from the current fragment.
0099   MCDataFragment *getOrCreateDataFragment(const MCSubtargetInfo* STI = nullptr);
0100 
0101 protected:
0102   bool changeSectionImpl(MCSection *Section, uint32_t Subsection);
0103 
0104 public:
0105   void visitUsedSymbol(const MCSymbol &Sym) override;
0106 
0107   MCAssembler &getAssembler() { return *Assembler; }
0108   MCAssembler *getAssemblerPtr() override;
0109   /// \name MCStreamer Interface
0110   /// @{
0111 
0112   void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
0113   virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F,
0114                               uint64_t Offset);
0115   void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
0116   void emitConditionalAssignment(MCSymbol *Symbol,
0117                                  const MCExpr *Value) override;
0118   void emitValueImpl(const MCExpr *Value, unsigned Size,
0119                      SMLoc Loc = SMLoc()) override;
0120   void emitULEB128Value(const MCExpr *Value) override;
0121   void emitSLEB128Value(const MCExpr *Value) override;
0122   void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
0123   void changeSection(MCSection *Section, uint32_t Subsection = 0) override;
0124   void switchSectionNoPrint(MCSection *Section) override;
0125   void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
0126 
0127   /// Emit an instruction to a special fragment, because this instruction
0128   /// can change its size during relaxation.
0129   virtual void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
0130 
0131   void emitBundleAlignMode(Align Alignment) override;
0132   void emitBundleLock(bool AlignToEnd) override;
0133   void emitBundleUnlock() override;
0134   void emitBytes(StringRef Data) override;
0135   void emitValueToAlignment(Align Alignment, int64_t Value = 0,
0136                             unsigned ValueSize = 1,
0137                             unsigned MaxBytesToEmit = 0) override;
0138   void emitCodeAlignment(Align ByteAlignment, const MCSubtargetInfo *STI,
0139                          unsigned MaxBytesToEmit = 0) override;
0140   void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
0141                          SMLoc Loc) override;
0142   void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
0143                              unsigned Flags, unsigned Isa,
0144                              unsigned Discriminator,
0145                              StringRef FileName) override;
0146   void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
0147                                 const MCSymbol *Label,
0148                                 unsigned PointerSize) override;
0149   void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel,
0150                              MCSymbol *EndLabel = nullptr) override;
0151   void emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
0152                                  const MCSymbol *Label, SMLoc Loc);
0153   void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
0154                           unsigned Column, bool PrologueEnd, bool IsStmt,
0155                           StringRef FileName, SMLoc Loc) override;
0156   void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin,
0157                                 const MCSymbol *End) override;
0158   void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
0159                                       unsigned SourceFileId,
0160                                       unsigned SourceLineNum,
0161                                       const MCSymbol *FnStartSym,
0162                                       const MCSymbol *FnEndSym) override;
0163   void emitCVDefRangeDirective(
0164       ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
0165       StringRef FixedSizePortion) override;
0166   void emitCVStringTableDirective() override;
0167   void emitCVFileChecksumsDirective() override;
0168   void emitCVFileChecksumOffsetDirective(unsigned FileNo) override;
0169   void emitDTPRel32Value(const MCExpr *Value) override;
0170   void emitDTPRel64Value(const MCExpr *Value) override;
0171   void emitTPRel32Value(const MCExpr *Value) override;
0172   void emitTPRel64Value(const MCExpr *Value) override;
0173   void emitGPRel32Value(const MCExpr *Value) override;
0174   void emitGPRel64Value(const MCExpr *Value) override;
0175   std::optional<std::pair<bool, std::string>>
0176   emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr,
0177                      SMLoc Loc, const MCSubtargetInfo &STI) override;
0178   using MCStreamer::emitFill;
0179   void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
0180                 SMLoc Loc = SMLoc()) override;
0181   void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
0182                 SMLoc Loc = SMLoc()) override;
0183   void emitNops(int64_t NumBytes, int64_t ControlledNopLength, SMLoc Loc,
0184                 const MCSubtargetInfo &STI) override;
0185   void emitFileDirective(StringRef Filename) override;
0186   void emitFileDirective(StringRef Filename, StringRef CompilerVersion,
0187                          StringRef TimeStamp, StringRef Description) override;
0188 
0189   void emitAddrsig() override;
0190   void emitAddrsigSym(const MCSymbol *Sym) override;
0191 
0192   void finishImpl() override;
0193 
0194   /// Emit the absolute difference between two symbols if possible.
0195   ///
0196   /// Emit the absolute difference between \c Hi and \c Lo, as long as we can
0197   /// compute it.  Currently, that requires that both symbols are in the same
0198   /// data fragment and that the target has not specified that diff expressions
0199   /// require relocations to be emitted. Otherwise, do nothing and return
0200   /// \c false.
0201   ///
0202   /// \pre Offset of \c Hi is greater than the offset \c Lo.
0203   void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
0204                               unsigned Size) override;
0205 
0206   void emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
0207                                        const MCSymbol *Lo) override;
0208 
0209   bool mayHaveInstructions(MCSection &Sec) const override;
0210 
0211   /// Emits pending conditional assignments that depend on \p Symbol
0212   /// being emitted.
0213   void emitPendingAssignments(MCSymbol *Symbol);
0214 };
0215 
0216 } // end namespace llvm
0217 
0218 #endif