MCFragment.h 19 KB

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