• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- MCFragment.h - Fragment type hierarchy -------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_MC_MCFRAGMENT_H
11 #define LLVM_MC_MCFRAGMENT_H
12 
13 #include "llvm/ADT/SmallString.h"
14 #include "llvm/ADT/ilist.h"
15 #include "llvm/ADT/ilist_node.h"
16 #include "llvm/ADT/iterator.h"
17 #include "llvm/MC/MCFixup.h"
18 #include "llvm/MC/MCInst.h"
19 
20 namespace llvm {
21 class MCSection;
22 class MCSymbol;
23 class MCSubtargetInfo;
24 
25 class MCFragment : public ilist_node_with_parent<MCFragment, MCSection> {
26   friend class MCAsmLayout;
27 
28   MCFragment(const MCFragment &) = delete;
29   void operator=(const MCFragment &) = delete;
30 
31 public:
32   enum FragmentType : uint8_t {
33     FT_Align,
34     FT_Data,
35     FT_CompactEncodedInst,
36     FT_Fill,
37     FT_Relaxable,
38     FT_Org,
39     FT_Dwarf,
40     FT_DwarfFrame,
41     FT_LEB,
42     FT_SafeSEH,
43     FT_CVInlineLines,
44     FT_CVDefRange,
45     FT_Dummy
46   };
47 
48 private:
49   FragmentType Kind;
50 
51 protected:
52   bool HasInstructions;
53 
54 private:
55   /// \brief Should this fragment be aligned to the end of a bundle?
56   bool AlignToBundleEnd;
57 
58   uint8_t BundlePadding;
59 
60   /// LayoutOrder - The layout order of this fragment.
61   unsigned LayoutOrder;
62 
63   /// The data for the section this fragment is in.
64   MCSection *Parent;
65 
66   /// Atom - The atom this fragment is in, as represented by it's defining
67   /// symbol.
68   const MCSymbol *Atom;
69 
70   /// \name Assembler Backend Data
71   /// @{
72   //
73   // FIXME: This could all be kept private to the assembler implementation.
74 
75   /// Offset - The offset of this fragment in its section. This is ~0 until
76   /// initialized.
77   uint64_t Offset;
78 
79   /// @}
80 
81 protected:
82   MCFragment(FragmentType Kind, bool HasInstructions,
83              uint8_t BundlePadding, MCSection *Parent = nullptr);
84 
85   ~MCFragment();
86 private:
87 
88   // This is a friend so that the sentinal can be created.
89   friend struct ilist_sentinel_traits<MCFragment>;
90   MCFragment();
91 
92 public:
93   /// Destroys the current fragment.
94   ///
95   /// This must be used instead of delete as MCFragment is non-virtual.
96   /// This method will dispatch to the appropriate subclass.
97   void destroy();
98 
99   FragmentType getKind() const { return Kind; }
100 
101   MCSection *getParent() const { return Parent; }
102   void setParent(MCSection *Value) { Parent = Value; }
103 
104   const MCSymbol *getAtom() const { return Atom; }
105   void setAtom(const MCSymbol *Value) { Atom = Value; }
106 
107   unsigned getLayoutOrder() const { return LayoutOrder; }
108   void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
109 
110   /// \brief Does this fragment have instructions emitted into it? By default
111   /// this is false, but specific fragment types may set it to true.
112   bool hasInstructions() const { return HasInstructions; }
113 
114   /// \brief Should this fragment be placed at the end of an aligned bundle?
115   bool alignToBundleEnd() const { return AlignToBundleEnd; }
116   void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
117 
118   /// \brief Get the padding size that must be inserted before this fragment.
119   /// Used for bundling. By default, no padding is inserted.
120   /// Note that padding size is restricted to 8 bits. This is an optimization
121   /// to reduce the amount of space used for each fragment. In practice, larger
122   /// padding should never be required.
123   uint8_t getBundlePadding() const { return BundlePadding; }
124 
125   /// \brief Set the padding size for this fragment. By default it's a no-op,
126   /// and only some fragments have a meaningful implementation.
127   void setBundlePadding(uint8_t N) { BundlePadding = N; }
128 
129   /// \brief Return true if given frgment has FT_Dummy type.
130   bool isDummy() const { return Kind == FT_Dummy; }
131 
132   void dump();
133 };
134 
135 class MCDummyFragment : public MCFragment {
136 public:
137   explicit MCDummyFragment(MCSection *Sec)
138       : MCFragment(FT_Dummy, false, 0, Sec){};
139   static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; }
140 };
141 
142 /// Interface implemented by fragments that contain encoded instructions and/or
143 /// data.
144 ///
145 class MCEncodedFragment : public MCFragment {
146 protected:
147   MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
148                     MCSection *Sec)
149       : MCFragment(FType, HasInstructions, 0, Sec) {}
150 
151 public:
152   static bool classof(const MCFragment *F) {
153     MCFragment::FragmentType Kind = F->getKind();
154     switch (Kind) {
155     default:
156       return false;
157     case MCFragment::FT_Relaxable:
158     case MCFragment::FT_CompactEncodedInst:
159     case MCFragment::FT_Data:
160       return true;
161     }
162   }
163 };
164 
165 /// Interface implemented by fragments that contain encoded instructions and/or
166 /// data.
167 ///
168 template<unsigned ContentsSize>
169 class MCEncodedFragmentWithContents : public MCEncodedFragment {
170   SmallVector<char, ContentsSize> Contents;
171 
172 protected:
173   MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
174                                 bool HasInstructions,
175                                 MCSection *Sec)
176       : MCEncodedFragment(FType, HasInstructions, Sec) {}
177 
178 public:
179   SmallVectorImpl<char> &getContents() { return Contents; }
180   const SmallVectorImpl<char> &getContents() const { return Contents; }
181 };
182 
183 /// Interface implemented by fragments that contain encoded instructions and/or
184 /// data and also have fixups registered.
185 ///
186 template<unsigned ContentsSize, unsigned FixupsSize>
187 class MCEncodedFragmentWithFixups :
188   public MCEncodedFragmentWithContents<ContentsSize> {
189 
190   /// Fixups - The list of fixups in this fragment.
191   SmallVector<MCFixup, FixupsSize> Fixups;
192 
193 protected:
194   MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
195                               bool HasInstructions,
196                               MCSection *Sec)
197       : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
198                                                     Sec) {}
199 
200 public:
201   typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
202   typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
203 
204   SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
205   const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
206 
207   fixup_iterator fixup_begin() { return Fixups.begin(); }
208   const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
209 
210   fixup_iterator fixup_end() { return Fixups.end(); }
211   const_fixup_iterator fixup_end() const { return Fixups.end(); }
212 
213   static bool classof(const MCFragment *F) {
214     MCFragment::FragmentType Kind = F->getKind();
215     return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
216            Kind == MCFragment::FT_CVDefRange;
217   }
218 };
219 
220 /// Fragment for data and encoded instructions.
221 ///
222 class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
223 public:
224   MCDataFragment(MCSection *Sec = nullptr)
225       : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
226 
227   void setHasInstructions(bool V) { HasInstructions = V; }
228 
229   static bool classof(const MCFragment *F) {
230     return F->getKind() == MCFragment::FT_Data;
231   }
232 };
233 
234 /// This is a compact (memory-size-wise) fragment for holding an encoded
235 /// instruction (non-relaxable) that has no fixups registered. When applicable,
236 /// it can be used instead of MCDataFragment and lead to lower memory
237 /// consumption.
238 ///
239 class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> {
240 public:
241   MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
242       : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
243   }
244 
245   static bool classof(const MCFragment *F) {
246     return F->getKind() == MCFragment::FT_CompactEncodedInst;
247   }
248 };
249 
250 /// A relaxable fragment holds on to its MCInst, since it may need to be
251 /// relaxed during the assembler layout and relaxation stage.
252 ///
253 class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
254 
255   /// Inst - The instruction this is a fragment for.
256   MCInst Inst;
257 
258   /// STI - The MCSubtargetInfo in effect when the instruction was encoded.
259   const MCSubtargetInfo &STI;
260 
261 public:
262   MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
263                       MCSection *Sec = nullptr)
264       : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
265         Inst(Inst), STI(STI) {}
266 
267   const MCInst &getInst() const { return Inst; }
268   void setInst(const MCInst &Value) { Inst = Value; }
269 
270   const MCSubtargetInfo &getSubtargetInfo() { return STI; }
271 
272   static bool classof(const MCFragment *F) {
273     return F->getKind() == MCFragment::FT_Relaxable;
274   }
275 };
276 
277 class MCAlignFragment : public MCFragment {
278 
279   /// Alignment - The alignment to ensure, in bytes.
280   unsigned Alignment;
281 
282   /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
283   /// of using the provided value. The exact interpretation of this flag is
284   /// target dependent.
285   bool EmitNops : 1;
286 
287   /// Value - Value to use for filling padding bytes.
288   int64_t Value;
289 
290   /// ValueSize - The size of the integer (in bytes) of \p Value.
291   unsigned ValueSize;
292 
293   /// MaxBytesToEmit - The maximum number of bytes to emit; if the alignment
294   /// cannot be satisfied in this width then this fragment is ignored.
295   unsigned MaxBytesToEmit;
296 
297 public:
298   MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
299                   unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
300       : MCFragment(FT_Align, false, 0, Sec), Alignment(Alignment),
301         EmitNops(false), Value(Value),
302         ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
303 
304   /// \name Accessors
305   /// @{
306 
307   unsigned getAlignment() const { return Alignment; }
308 
309   int64_t getValue() const { return Value; }
310 
311   unsigned getValueSize() const { return ValueSize; }
312 
313   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
314 
315   bool hasEmitNops() const { return EmitNops; }
316   void setEmitNops(bool Value) { EmitNops = Value; }
317 
318   /// @}
319 
320   static bool classof(const MCFragment *F) {
321     return F->getKind() == MCFragment::FT_Align;
322   }
323 };
324 
325 class MCFillFragment : public MCFragment {
326 
327   /// Value to use for filling bytes.
328   uint8_t Value;
329 
330   /// The number of bytes to insert.
331   uint64_t Size;
332 
333 public:
334   MCFillFragment(uint8_t Value, uint64_t Size, MCSection *Sec = nullptr)
335       : MCFragment(FT_Fill, false, 0, Sec), Value(Value), Size(Size) {}
336 
337   uint8_t getValue() const { return Value; }
338   uint64_t getSize() const { return Size; }
339 
340   static bool classof(const MCFragment *F) {
341     return F->getKind() == MCFragment::FT_Fill;
342   }
343 };
344 
345 class MCOrgFragment : public MCFragment {
346 
347   /// Offset - The offset this fragment should start at.
348   const MCExpr *Offset;
349 
350   /// Value - Value to use for filling bytes.
351   int8_t Value;
352 
353 public:
354   MCOrgFragment(const MCExpr &Offset, int8_t Value, MCSection *Sec = nullptr)
355       : MCFragment(FT_Org, false, 0, Sec), Offset(&Offset), Value(Value) {}
356 
357   /// \name Accessors
358   /// @{
359 
360   const MCExpr &getOffset() const { return *Offset; }
361 
362   uint8_t getValue() const { return Value; }
363 
364   /// @}
365 
366   static bool classof(const MCFragment *F) {
367     return F->getKind() == MCFragment::FT_Org;
368   }
369 };
370 
371 class MCLEBFragment : public MCFragment {
372 
373   /// Value - The value this fragment should contain.
374   const MCExpr *Value;
375 
376   /// IsSigned - True if this is a sleb128, false if uleb128.
377   bool IsSigned;
378 
379   SmallString<8> Contents;
380 
381 public:
382   MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
383       : MCFragment(FT_LEB, false, 0, Sec), Value(&Value_), IsSigned(IsSigned_) {
384     Contents.push_back(0);
385   }
386 
387   /// \name Accessors
388   /// @{
389 
390   const MCExpr &getValue() const { return *Value; }
391 
392   bool isSigned() const { return IsSigned; }
393 
394   SmallString<8> &getContents() { return Contents; }
395   const SmallString<8> &getContents() const { return Contents; }
396 
397   /// @}
398 
399   static bool classof(const MCFragment *F) {
400     return F->getKind() == MCFragment::FT_LEB;
401   }
402 };
403 
404 class MCDwarfLineAddrFragment : public MCFragment {
405 
406   /// LineDelta - the value of the difference between the two line numbers
407   /// between two .loc dwarf directives.
408   int64_t LineDelta;
409 
410   /// AddrDelta - The expression for the difference of the two symbols that
411   /// make up the address delta between two .loc dwarf directives.
412   const MCExpr *AddrDelta;
413 
414   SmallString<8> Contents;
415 
416 public:
417   MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
418                           MCSection *Sec = nullptr)
419       : MCFragment(FT_Dwarf, false, 0, Sec), LineDelta(LineDelta),
420         AddrDelta(&AddrDelta) {
421     Contents.push_back(0);
422   }
423 
424   /// \name Accessors
425   /// @{
426 
427   int64_t getLineDelta() const { return LineDelta; }
428 
429   const MCExpr &getAddrDelta() const { return *AddrDelta; }
430 
431   SmallString<8> &getContents() { return Contents; }
432   const SmallString<8> &getContents() const { return Contents; }
433 
434   /// @}
435 
436   static bool classof(const MCFragment *F) {
437     return F->getKind() == MCFragment::FT_Dwarf;
438   }
439 };
440 
441 class MCDwarfCallFrameFragment : public MCFragment {
442 
443   /// AddrDelta - The expression for the difference of the two symbols that
444   /// make up the address delta between two .cfi_* dwarf directives.
445   const MCExpr *AddrDelta;
446 
447   SmallString<8> Contents;
448 
449 public:
450   MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
451       : MCFragment(FT_DwarfFrame, false, 0, Sec), AddrDelta(&AddrDelta) {
452     Contents.push_back(0);
453   }
454 
455   /// \name Accessors
456   /// @{
457 
458   const MCExpr &getAddrDelta() const { return *AddrDelta; }
459 
460   SmallString<8> &getContents() { return Contents; }
461   const SmallString<8> &getContents() const { return Contents; }
462 
463   /// @}
464 
465   static bool classof(const MCFragment *F) {
466     return F->getKind() == MCFragment::FT_DwarfFrame;
467   }
468 };
469 
470 class MCSafeSEHFragment : public MCFragment {
471   const MCSymbol *Sym;
472 
473 public:
474   MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
475       : MCFragment(FT_SafeSEH, false, 0, Sec), Sym(Sym) {}
476 
477   /// \name Accessors
478   /// @{
479 
480   const MCSymbol *getSymbol() { return Sym; }
481   const MCSymbol *getSymbol() const { return Sym; }
482 
483   /// @}
484 
485   static bool classof(const MCFragment *F) {
486     return F->getKind() == MCFragment::FT_SafeSEH;
487   }
488 };
489 
490 /// Fragment representing the binary annotations produced by the
491 /// .cv_inline_linetable directive.
492 class MCCVInlineLineTableFragment : public MCFragment {
493   unsigned SiteFuncId;
494   unsigned StartFileId;
495   unsigned StartLineNum;
496   const MCSymbol *FnStartSym;
497   const MCSymbol *FnEndSym;
498   SmallVector<unsigned, 3> SecondaryFuncs;
499   SmallString<8> Contents;
500 
501   /// CodeViewContext has the real knowledge about this format, so let it access
502   /// our members.
503   friend class CodeViewContext;
504 
505 public:
506   MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId,
507                               unsigned StartLineNum, const MCSymbol *FnStartSym,
508                               const MCSymbol *FnEndSym,
509                               ArrayRef<unsigned> SecondaryFuncs,
510                               MCSection *Sec = nullptr)
511       : MCFragment(FT_CVInlineLines, false, 0, Sec), SiteFuncId(SiteFuncId),
512         StartFileId(StartFileId), StartLineNum(StartLineNum),
513         FnStartSym(FnStartSym), FnEndSym(FnEndSym),
514         SecondaryFuncs(SecondaryFuncs.begin(), SecondaryFuncs.end()) {}
515 
516   /// \name Accessors
517   /// @{
518 
519   const MCSymbol *getFnStartSym() const { return FnStartSym; }
520   const MCSymbol *getFnEndSym() const { return FnEndSym; }
521 
522   SmallString<8> &getContents() { return Contents; }
523   const SmallString<8> &getContents() const { return Contents; }
524 
525   /// @}
526 
527   static bool classof(const MCFragment *F) {
528     return F->getKind() == MCFragment::FT_CVInlineLines;
529   }
530 };
531 
532 /// Fragment representing the .cv_def_range directive.
533 class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {
534   SmallVector<std::pair<const MCSymbol *, const MCSymbol *>, 2> Ranges;
535   SmallString<32> FixedSizePortion;
536 
537   /// CodeViewContext has the real knowledge about this format, so let it access
538   /// our members.
539   friend class CodeViewContext;
540 
541 public:
542   MCCVDefRangeFragment(
543       ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
544       StringRef FixedSizePortion, MCSection *Sec = nullptr)
545       : MCEncodedFragmentWithFixups<32, 4>(FT_CVDefRange, false, Sec),
546         Ranges(Ranges.begin(), Ranges.end()),
547         FixedSizePortion(FixedSizePortion) {}
548 
549   /// \name Accessors
550   /// @{
551   ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const {
552     return Ranges;
553   }
554 
555   StringRef getFixedSizePortion() const { return FixedSizePortion; }
556   /// @}
557 
558   static bool classof(const MCFragment *F) {
559     return F->getKind() == MCFragment::FT_CVDefRange;
560   }
561 };
562 
563 } // end namespace llvm
564 
565 #endif
566