MCSection.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. //===- lib/MC/MCSection.cpp - Machine Code Section Representation ---------===//
  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. #include "llvm/MC/MCSection.h"
  9. #include "llvm/ADT/SmallVector.h"
  10. #include "llvm/Config/llvm-config.h"
  11. #include "llvm/MC/MCContext.h"
  12. #include "llvm/MC/MCFragment.h"
  13. #include "llvm/MC/MCSymbol.h"
  14. #include "llvm/Support/Compiler.h"
  15. #include "llvm/Support/ErrorHandling.h"
  16. #include "llvm/Support/raw_ostream.h"
  17. #include <algorithm>
  18. #include <utility>
  19. using namespace llvm;
  20. MCSection::MCSection(SectionVariant V, StringRef Name, SectionKind K,
  21. MCSymbol *Begin)
  22. : Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false),
  23. IsRegistered(false), DummyFragment(this), Name(Name), Variant(V),
  24. Kind(K) {}
  25. MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) {
  26. if (!End)
  27. End = Ctx.createTempSymbol("sec_end");
  28. return End;
  29. }
  30. bool MCSection::hasEnded() const { return End && End->isInSection(); }
  31. MCSection::~MCSection() = default;
  32. void MCSection::setBundleLockState(BundleLockStateType NewState) {
  33. if (NewState == NotBundleLocked) {
  34. if (BundleLockNestingDepth == 0) {
  35. report_fatal_error("Mismatched bundle_lock/unlock directives");
  36. }
  37. if (--BundleLockNestingDepth == 0) {
  38. BundleLockState = NotBundleLocked;
  39. }
  40. return;
  41. }
  42. // If any of the directives is an align_to_end directive, the whole nested
  43. // group is align_to_end. So don't downgrade from align_to_end to just locked.
  44. if (BundleLockState != BundleLockedAlignToEnd) {
  45. BundleLockState = NewState;
  46. }
  47. ++BundleLockNestingDepth;
  48. }
  49. MCSection::iterator
  50. MCSection::getSubsectionInsertionPoint(unsigned Subsection) {
  51. if (Subsection == 0 && SubsectionFragmentMap.empty())
  52. return end();
  53. SmallVectorImpl<std::pair<unsigned, MCFragment *>>::iterator MI = lower_bound(
  54. SubsectionFragmentMap, std::make_pair(Subsection, (MCFragment *)nullptr));
  55. bool ExactMatch = false;
  56. if (MI != SubsectionFragmentMap.end()) {
  57. ExactMatch = MI->first == Subsection;
  58. if (ExactMatch)
  59. ++MI;
  60. }
  61. iterator IP;
  62. if (MI == SubsectionFragmentMap.end())
  63. IP = end();
  64. else
  65. IP = MI->second->getIterator();
  66. if (!ExactMatch && Subsection != 0) {
  67. // The GNU as documentation claims that subsections have an alignment of 4,
  68. // although this appears not to be the case.
  69. MCFragment *F = new MCDataFragment();
  70. SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F));
  71. getFragmentList().insert(IP, F);
  72. F->setParent(this);
  73. F->setSubsectionNumber(Subsection);
  74. }
  75. return IP;
  76. }
  77. StringRef MCSection::getVirtualSectionKind() const { return "virtual"; }
  78. void MCSection::addPendingLabel(MCSymbol *label, unsigned Subsection) {
  79. PendingLabels.push_back(PendingLabel(label, Subsection));
  80. }
  81. void MCSection::flushPendingLabels(MCFragment *F, uint64_t FOffset,
  82. unsigned Subsection) {
  83. if (PendingLabels.empty())
  84. return;
  85. // Set the fragment and fragment offset for all pending symbols in the
  86. // specified Subsection, and remove those symbols from the pending list.
  87. for (auto It = PendingLabels.begin(); It != PendingLabels.end(); ++It) {
  88. PendingLabel& Label = *It;
  89. if (Label.Subsection == Subsection) {
  90. Label.Sym->setFragment(F);
  91. Label.Sym->setOffset(FOffset);
  92. PendingLabels.erase(It--);
  93. }
  94. }
  95. }
  96. void MCSection::flushPendingLabels() {
  97. // Make sure all remaining pending labels point to data fragments, by
  98. // creating new empty data fragments for each Subsection with labels pending.
  99. while (!PendingLabels.empty()) {
  100. PendingLabel& Label = PendingLabels[0];
  101. iterator CurInsertionPoint =
  102. this->getSubsectionInsertionPoint(Label.Subsection);
  103. MCFragment *F = new MCDataFragment();
  104. getFragmentList().insert(CurInsertionPoint, F);
  105. F->setParent(this);
  106. flushPendingLabels(F, 0, Label.Subsection);
  107. }
  108. }
  109. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  110. LLVM_DUMP_METHOD void MCSection::dump() const {
  111. raw_ostream &OS = errs();
  112. OS << "<MCSection";
  113. OS << " Fragments:[\n ";
  114. for (auto it = begin(), ie = end(); it != ie; ++it) {
  115. if (it != begin())
  116. OS << ",\n ";
  117. it->dump();
  118. }
  119. OS << "]>";
  120. }
  121. #endif