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