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