Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- MCObjectStreamer.h - MCStreamer Object File Interface ----*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8.  
  9. #ifndef LLVM_MC_MCOBJECTSTREAMER_H
  10. #define LLVM_MC_MCOBJECTSTREAMER_H
  11.  
  12. #include "llvm/ADT/SetVector.h"
  13. #include "llvm/ADT/SmallVector.h"
  14. #include "llvm/MC/MCFixup.h"
  15. #include "llvm/MC/MCFragment.h"
  16. #include "llvm/MC/MCSection.h"
  17. #include "llvm/MC/MCStreamer.h"
  18.  
  19. namespace llvm {
  20. class MCContext;
  21. class MCInst;
  22. class MCObjectWriter;
  23. class MCSymbol;
  24. struct MCDwarfFrameInfo;
  25. class MCAssembler;
  26. class MCCodeEmitter;
  27. class MCSubtargetInfo;
  28. class MCExpr;
  29. class MCFragment;
  30. class MCDataFragment;
  31. class MCAsmBackend;
  32. class raw_ostream;
  33. class raw_pwrite_stream;
  34.  
  35. /// Streaming object file generation interface.
  36. ///
  37. /// This class provides an implementation of the MCStreamer interface which is
  38. /// suitable for use with the assembler backend. Specific object file formats
  39. /// are expected to subclass this interface to implement directives specific
  40. /// to that file format or custom semantics expected by the object writer
  41. /// implementation.
  42. class MCObjectStreamer : public MCStreamer {
  43.   std::unique_ptr<MCAssembler> Assembler;
  44.   MCSection::iterator CurInsertionPoint;
  45.   bool EmitEHFrame;
  46.   bool EmitDebugFrame;
  47.   SmallVector<MCSymbol *, 2> PendingLabels;
  48.   SmallSetVector<MCSection *, 4> PendingLabelSections;
  49.   unsigned CurSubsectionIdx;
  50.   struct PendingMCFixup {
  51.     const MCSymbol *Sym;
  52.     MCFixup Fixup;
  53.     MCDataFragment *DF;
  54.     PendingMCFixup(const MCSymbol *McSym, MCDataFragment *F, MCFixup McFixup)
  55.         : Sym(McSym), Fixup(McFixup), DF(F) {}
  56.   };
  57.   SmallVector<PendingMCFixup, 2> PendingFixups;
  58.  
  59.   struct PendingAssignment {
  60.     MCSymbol *Symbol;
  61.     const MCExpr *Value;
  62.   };
  63.  
  64.   /// A list of conditional assignments we may need to emit if the target
  65.   /// symbol is later emitted.
  66.   DenseMap<const MCSymbol *, SmallVector<PendingAssignment, 1>>
  67.       pendingAssignments;
  68.  
  69.   virtual void emitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
  70.   void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
  71.   void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
  72.   MCSymbol *emitCFILabel() override;
  73.   void emitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI);
  74.   void resolvePendingFixups();
  75.  
  76. protected:
  77.   MCObjectStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
  78.                    std::unique_ptr<MCObjectWriter> OW,
  79.                    std::unique_ptr<MCCodeEmitter> Emitter);
  80.   ~MCObjectStreamer();
  81.  
  82. public:
  83.   /// state management
  84.   void reset() override;
  85.  
  86.   /// Object streamers require the integrated assembler.
  87.   bool isIntegratedAssemblerRequired() const override { return true; }
  88.  
  89.   void emitFrames(MCAsmBackend *MAB);
  90.   void emitCFISections(bool EH, bool Debug) override;
  91.  
  92.   MCFragment *getCurrentFragment() const;
  93.  
  94.   void insert(MCFragment *F) {
  95.     flushPendingLabels(F);
  96.     MCSection *CurSection = getCurrentSectionOnly();
  97.     CurSection->getFragmentList().insert(CurInsertionPoint, F);
  98.     F->setParent(CurSection);
  99.   }
  100.  
  101.   /// Get a data fragment to write into, creating a new one if the current
  102.   /// fragment is not a data fragment.
  103.   /// Optionally a \p STI can be passed in so that a new fragment is created
  104.   /// if the Subtarget differs from the current fragment.
  105.   MCDataFragment *getOrCreateDataFragment(const MCSubtargetInfo* STI = nullptr);
  106.  
  107. protected:
  108.   bool changeSectionImpl(MCSection *Section, const MCExpr *Subsection);
  109.  
  110.   /// Assign a label to the current Section and Subsection even though a
  111.   /// fragment is not yet present. Use flushPendingLabels(F) to associate
  112.   /// a fragment with this label.
  113.   void addPendingLabel(MCSymbol* label);
  114.  
  115.   /// If any labels have been emitted but not assigned fragments in the current
  116.   /// Section and Subsection, ensure that they get assigned, either to fragment
  117.   /// F if possible or to a new data fragment. Optionally, one can provide an
  118.   /// offset \p FOffset as a symbol offset within the fragment.
  119.   void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0);
  120.  
  121. public:
  122.   void visitUsedSymbol(const MCSymbol &Sym) override;
  123.  
  124.   /// Create a data fragment for any pending labels across all Sections
  125.   /// and Subsections.
  126.   void flushPendingLabels();
  127.  
  128.   MCAssembler &getAssembler() { return *Assembler; }
  129.   MCAssembler *getAssemblerPtr() override;
  130.   /// \name MCStreamer Interface
  131.   /// @{
  132.  
  133.   void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
  134.   virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F,
  135.                               uint64_t Offset);
  136.   void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
  137.   void emitConditionalAssignment(MCSymbol *Symbol,
  138.                                  const MCExpr *Value) override;
  139.   void emitValueImpl(const MCExpr *Value, unsigned Size,
  140.                      SMLoc Loc = SMLoc()) override;
  141.   void emitULEB128Value(const MCExpr *Value) override;
  142.   void emitSLEB128Value(const MCExpr *Value) override;
  143.   void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
  144.   void changeSection(MCSection *Section, const MCExpr *Subsection) override;
  145.   void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
  146.  
  147.   /// Emit an instruction to a special fragment, because this instruction
  148.   /// can change its size during relaxation.
  149.   virtual void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
  150.  
  151.   void emitBundleAlignMode(Align Alignment) override;
  152.   void emitBundleLock(bool AlignToEnd) override;
  153.   void emitBundleUnlock() override;
  154.   void emitBytes(StringRef Data) override;
  155.   void emitValueToAlignment(Align Alignment, int64_t Value = 0,
  156.                             unsigned ValueSize = 1,
  157.                             unsigned MaxBytesToEmit = 0) override;
  158.   void emitCodeAlignment(Align ByteAlignment, const MCSubtargetInfo *STI,
  159.                          unsigned MaxBytesToEmit = 0) override;
  160.   void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
  161.                          SMLoc Loc) override;
  162.   void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
  163.                              unsigned Flags, unsigned Isa,
  164.                              unsigned Discriminator,
  165.                              StringRef FileName) override;
  166.   void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
  167.                                 const MCSymbol *Label,
  168.                                 unsigned PointerSize) override;
  169.   void emitDwarfLineEndEntry(MCSection *Section, MCSymbol *LastLabel) override;
  170.   void emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
  171.                                  const MCSymbol *Label);
  172.   void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
  173.                           unsigned Column, bool PrologueEnd, bool IsStmt,
  174.                           StringRef FileName, SMLoc Loc) override;
  175.   void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin,
  176.                                 const MCSymbol *End) override;
  177.   void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
  178.                                       unsigned SourceFileId,
  179.                                       unsigned SourceLineNum,
  180.                                       const MCSymbol *FnStartSym,
  181.                                       const MCSymbol *FnEndSym) override;
  182.   void emitCVDefRangeDirective(
  183.       ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
  184.       StringRef FixedSizePortion) override;
  185.   void emitCVStringTableDirective() override;
  186.   void emitCVFileChecksumsDirective() override;
  187.   void emitCVFileChecksumOffsetDirective(unsigned FileNo) override;
  188.   void emitDTPRel32Value(const MCExpr *Value) override;
  189.   void emitDTPRel64Value(const MCExpr *Value) override;
  190.   void emitTPRel32Value(const MCExpr *Value) override;
  191.   void emitTPRel64Value(const MCExpr *Value) override;
  192.   void emitGPRel32Value(const MCExpr *Value) override;
  193.   void emitGPRel64Value(const MCExpr *Value) override;
  194.   std::optional<std::pair<bool, std::string>>
  195.   emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr,
  196.                      SMLoc Loc, const MCSubtargetInfo &STI) override;
  197.   using MCStreamer::emitFill;
  198.   void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
  199.                 SMLoc Loc = SMLoc()) override;
  200.   void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
  201.                 SMLoc Loc = SMLoc()) override;
  202.   void emitNops(int64_t NumBytes, int64_t ControlledNopLength, SMLoc Loc,
  203.                 const MCSubtargetInfo &STI) override;
  204.   void emitFileDirective(StringRef Filename) override;
  205.   void emitFileDirective(StringRef Filename, StringRef CompilerVerion,
  206.                          StringRef TimeStamp, StringRef Description) override;
  207.  
  208.   void emitAddrsig() override;
  209.   void emitAddrsigSym(const MCSymbol *Sym) override;
  210.  
  211.   void finishImpl() override;
  212.  
  213.   /// Emit the absolute difference between two symbols if possible.
  214.   ///
  215.   /// Emit the absolute difference between \c Hi and \c Lo, as long as we can
  216.   /// compute it.  Currently, that requires that both symbols are in the same
  217.   /// data fragment and that the target has not specified that diff expressions
  218.   /// require relocations to be emitted. Otherwise, do nothing and return
  219.   /// \c false.
  220.   ///
  221.   /// \pre Offset of \c Hi is greater than the offset \c Lo.
  222.   void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
  223.                               unsigned Size) override;
  224.  
  225.   void emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
  226.                                        const MCSymbol *Lo) override;
  227.  
  228.   bool mayHaveInstructions(MCSection &Sec) const override;
  229.  
  230.   /// Emits pending conditional assignments that depend on \p Symbol
  231.   /// being emitted.
  232.   void emitPendingAssignments(MCSymbol *Symbol);
  233. };
  234.  
  235. } // end namespace llvm
  236.  
  237. #endif
  238.