1 //===- MCAssembler.h - Object File Generation -------------------*- 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_MCASSEMBLER_H 10 #define LLVM_MC_MCASSEMBLER_H 11 12 #include "llvm/ADT/ArrayRef.h" 13 #include "llvm/ADT/SmallPtrSet.h" 14 #include "llvm/ADT/SmallVector.h" 15 #include "llvm/ADT/StringRef.h" 16 #include "llvm/ADT/iterator.h" 17 #include "llvm/ADT/iterator_range.h" 18 #include "llvm/MC/MCDwarf.h" 19 #include "llvm/MC/MCSymbol.h" 20 #include "llvm/Support/Compiler.h" 21 #include "llvm/Support/SMLoc.h" 22 #include <algorithm> 23 #include <cassert> 24 #include <cstddef> 25 #include <cstdint> 26 #include <memory> 27 #include <string> 28 #include <tuple> 29 #include <utility> 30 #include <vector> 31 32 namespace llvm { 33 34 class MCBoundaryAlignFragment; 35 class MCCVDefRangeFragment; 36 class MCCVInlineLineTableFragment; 37 class MCDwarfCallFrameFragment; 38 class MCDwarfLineAddrFragment; 39 class MCEncodedFragment; 40 class MCFixup; 41 class MCLEBFragment; 42 class MCPseudoProbeAddrFragment; 43 class MCRelaxableFragment; 44 class MCSymbolRefExpr; 45 class raw_ostream; 46 class MCAsmBackend; 47 class MCContext; 48 class MCCodeEmitter; 49 class MCFragment; 50 class MCObjectWriter; 51 class MCSection; 52 class MCValue; 53 54 class MCAssembler { 55 public: 56 friend class MCObjectWriter; 57 using SectionListType = SmallVector<MCSection *, 0>; 58 using const_iterator = pointee_iterator<SectionListType::const_iterator>; 59 60 private: 61 MCContext &Context; 62 63 std::unique_ptr<MCAsmBackend> Backend; 64 std::unique_ptr<MCCodeEmitter> Emitter; 65 std::unique_ptr<MCObjectWriter> Writer; 66 67 bool HasLayout = false; 68 bool HasFinalLayout = false; 69 bool RelaxAll = false; 70 71 SectionListType Sections; 72 73 SmallVector<const MCSymbol *, 0> Symbols; 74 75 mutable SmallVector<std::pair<SMLoc, std::string>, 0> PendingErrors; 76 77 MCDwarfLineTableParams LTParams; 78 79 /// The set of function symbols for which a .thumb_func directive has 80 /// been seen. 81 // 82 // FIXME: We really would like this in target specific code rather than 83 // here. Maybe when the relocation stuff moves to target specific, 84 // this can go with it? The streamer would need some target specific 85 // refactoring too. 86 mutable SmallPtrSet<const MCSymbol *, 32> ThumbFuncs; 87 88 /// The bundle alignment size currently set in the assembler. 89 /// 90 /// By default it's 0, which means bundling is disabled. 91 unsigned BundleAlignSize = 0; 92 93 /// Evaluate a fixup to a relocatable expression and the value which should be 94 /// placed into the fixup. 95 /// 96 /// \param F The fragment the fixup is inside. 97 /// \param Fixup The fixup to evaluate. 98 /// \param Target [out] On return, the relocatable expression the fixup 99 /// evaluates to. 100 /// \param Value [out] On return, the value of the fixup as currently laid 101 /// out. 102 /// \param RecordReloc Record relocation if needed. 103 /// relocation. 104 bool evaluateFixup(const MCFragment &F, MCFixup &Fixup, MCValue &Target, 105 uint64_t &Value, bool RecordReloc, 106 MutableArrayRef<char> Contents) const; 107 108 /// Check whether a fixup can be satisfied, or whether it needs to be relaxed 109 /// (increased in size, in order to hold its value correctly). 110 bool fixupNeedsRelaxation(const MCRelaxableFragment &, const MCFixup &) const; 111 112 void layoutSection(MCSection &Sec); 113 /// Perform one layout iteration and return the index of the first stable 114 /// section for subsequent optimization. 115 unsigned relaxOnce(unsigned FirstStable); 116 117 /// Perform relaxation on a single fragment. 118 bool relaxFragment(MCFragment &F); 119 bool relaxInstruction(MCRelaxableFragment &IF); 120 bool relaxLEB(MCLEBFragment &IF); 121 bool relaxBoundaryAlign(MCBoundaryAlignFragment &BF); 122 bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF); 123 bool relaxDwarfCallFrameFragment(MCDwarfCallFrameFragment &DF); 124 bool relaxCVInlineLineTable(MCCVInlineLineTableFragment &DF); 125 bool relaxCVDefRange(MCCVDefRangeFragment &DF); 126 bool relaxFill(MCFillFragment &F); 127 bool relaxPseudoProbeAddr(MCPseudoProbeAddrFragment &DF); 128 129 public: 130 /// Construct a new assembler instance. 131 // 132 // FIXME: How are we going to parameterize this? Two obvious options are stay 133 // concrete and require clients to pass in a target like object. The other 134 // option is to make this abstract, and have targets provide concrete 135 // implementations as we do with AsmParser. 136 LLVM_ABI MCAssembler(MCContext &Context, 137 std::unique_ptr<MCAsmBackend> Backend, 138 std::unique_ptr<MCCodeEmitter> Emitter, 139 std::unique_ptr<MCObjectWriter> Writer); 140 MCAssembler(const MCAssembler &) = delete; 141 MCAssembler &operator=(const MCAssembler &) = delete; 142 143 /// Compute the effective fragment size. 144 LLVM_ABI uint64_t computeFragmentSize(const MCFragment &F) const; 145 146 LLVM_ABI void layoutBundle(MCFragment *Prev, MCFragment *F) const; 147 148 // Get the offset of the given fragment inside its containing section. getFragmentOffset(const MCFragment & F)149 uint64_t getFragmentOffset(const MCFragment &F) const { return F.Offset; } 150 151 LLVM_ABI uint64_t getSectionAddressSize(const MCSection &Sec) const; 152 LLVM_ABI uint64_t getSectionFileSize(const MCSection &Sec) const; 153 154 // Get the offset of the given symbol, as computed in the current 155 // layout. 156 // \return True on success. 157 LLVM_ABI bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const; 158 159 // Variant that reports a fatal error if the offset is not computable. 160 LLVM_ABI uint64_t getSymbolOffset(const MCSymbol &S) const; 161 162 // If this symbol is equivalent to A + Constant, return A. 163 LLVM_ABI const MCSymbol *getBaseSymbol(const MCSymbol &Symbol) const; 164 165 /// Emit the section contents to \p OS. 166 LLVM_ABI void writeSectionData(raw_ostream &OS, 167 const MCSection *Section) const; 168 169 /// Check whether a given symbol has been flagged with .thumb_func. 170 LLVM_ABI bool isThumbFunc(const MCSymbol *Func) const; 171 172 /// Flag a function symbol as the target of a .thumb_func directive. setIsThumbFunc(const MCSymbol * Func)173 void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); } 174 175 /// Reuse an assembler instance 176 /// 177 LLVM_ABI void reset(); 178 getContext()179 MCContext &getContext() const { return Context; } 180 getBackendPtr()181 MCAsmBackend *getBackendPtr() const { return Backend.get(); } 182 getEmitterPtr()183 MCCodeEmitter *getEmitterPtr() const { return Emitter.get(); } 184 getBackend()185 MCAsmBackend &getBackend() const { return *Backend; } 186 getEmitter()187 MCCodeEmitter &getEmitter() const { return *Emitter; } 188 getWriter()189 MCObjectWriter &getWriter() const { return *Writer; } 190 getDWARFLinetableParams()191 MCDwarfLineTableParams getDWARFLinetableParams() const { return LTParams; } 192 193 /// Finish - Do final processing and write the object to the output stream. 194 /// \p Writer is used for custom object writer (as the MCJIT does), 195 /// if not specified it is automatically created from backend. 196 LLVM_ABI void Finish(); 197 198 // Layout all section and prepare them for emission. 199 LLVM_ABI void layout(); 200 hasLayout()201 bool hasLayout() const { return HasLayout; } hasFinalLayout()202 bool hasFinalLayout() const { return HasFinalLayout; } getRelaxAll()203 bool getRelaxAll() const { return RelaxAll; } setRelaxAll(bool Value)204 void setRelaxAll(bool Value) { RelaxAll = Value; } 205 isBundlingEnabled()206 bool isBundlingEnabled() const { return BundleAlignSize != 0; } 207 getBundleAlignSize()208 unsigned getBundleAlignSize() const { return BundleAlignSize; } 209 setBundleAlignSize(unsigned Size)210 void setBundleAlignSize(unsigned Size) { 211 assert((Size == 0 || !(Size & (Size - 1))) && 212 "Expect a power-of-two bundle align size"); 213 BundleAlignSize = Size; 214 } 215 begin()216 const_iterator begin() const { return Sections.begin(); } end()217 const_iterator end() const { return Sections.end(); } 218 getSymbols()219 SmallVectorImpl<const MCSymbol *> &getSymbols() { return Symbols; } 220 iterator_range<pointee_iterator< 221 typename SmallVector<const MCSymbol *, 0>::const_iterator>> symbols()222 symbols() const { 223 return make_pointee_range(Symbols); 224 } 225 226 LLVM_ABI bool registerSection(MCSection &Section); 227 LLVM_ABI bool registerSymbol(const MCSymbol &Symbol); 228 229 /// Write the necessary bundle padding to \p OS. 230 /// Expects a fragment \p F containing instructions and its size \p FSize. 231 LLVM_ABI void writeFragmentPadding(raw_ostream &OS, 232 const MCEncodedFragment &F, 233 uint64_t FSize) const; 234 235 LLVM_ABI void reportError(SMLoc L, const Twine &Msg) const; 236 // Record pending errors during layout iteration, as they may go away once the 237 // layout is finalized. 238 LLVM_ABI void recordError(SMLoc L, const Twine &Msg) const; 239 LLVM_ABI void flushPendingErrors() const; 240 241 LLVM_ABI void dump() const; 242 }; 243 244 } // end namespace llvm 245 246 #endif // LLVM_MC_MCASSEMBLER_H 247