1c10132aaSChris Lattner //===- lib/MC/MCSection.cpp - Machine Code Section Representation ---------===//
2c10132aaSChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c10132aaSChris Lattner //
7c10132aaSChris Lattner //===----------------------------------------------------------------------===//
8c10132aaSChris Lattner
96bda14b3SChandler Carruth #include "llvm/MC/MCSection.h"
10*ef736a1cSserge-sans-paille #include "llvm/ADT/STLExtras.h"
113d8b0ebbSEugene Zelenko #include "llvm/ADT/SmallVector.h"
12432a3883SNico Weber #include "llvm/Config/llvm-config.h"
13ed0881b2SChandler Carruth #include "llvm/MC/MCContext.h"
143d8b0ebbSEugene Zelenko #include "llvm/MC/MCFragment.h"
15f2b408c6SRafael Espindola #include "llvm/MC/MCSymbol.h"
163d8b0ebbSEugene Zelenko #include "llvm/Support/Compiler.h"
173d8b0ebbSEugene Zelenko #include "llvm/Support/ErrorHandling.h"
181cb9396fSChris Lattner #include "llvm/Support/raw_ostream.h"
193d8b0ebbSEugene Zelenko #include <utility>
20c10132aaSChris Lattner
213d8b0ebbSEugene Zelenko using namespace llvm;
221cb9396fSChris Lattner
MCSection(SectionVariant V,StringRef Name,SectionKind K,MCSymbol * Begin)2390a63f6dSFangrui Song MCSection::MCSection(SectionVariant V, StringRef Name, SectionKind K,
2490a63f6dSFangrui Song MCSymbol *Begin)
25a66395e1SRafael Espindola : Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false),
2690a63f6dSFangrui Song IsRegistered(false), DummyFragment(this), Name(Name), Variant(V),
2790a63f6dSFangrui Song Kind(K) {}
28a554c05dSRafael Espindola
getEndSymbol(MCContext & Ctx)290709a7bdSRafael Espindola MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) {
30f2b408c6SRafael Espindola if (!End)
31d9a0c40bSFangrui Song End = Ctx.createTempSymbol("sec_end");
32f2b408c6SRafael Espindola return End;
33f2b408c6SRafael Espindola }
34f2b408c6SRafael Espindola
hasEnded() const35f2b408c6SRafael Espindola bool MCSection::hasEnded() const { return End && End->isInSection(); }
36f2b408c6SRafael Espindola
37f9a86505SSimon Pilgrim MCSection::~MCSection() = default;
38f9a86505SSimon Pilgrim
setBundleLockState(BundleLockStateType NewState)39b028cc80SRafael Espindola void MCSection::setBundleLockState(BundleLockStateType NewState) {
40b028cc80SRafael Espindola if (NewState == NotBundleLocked) {
41b028cc80SRafael Espindola if (BundleLockNestingDepth == 0) {
42b028cc80SRafael Espindola report_fatal_error("Mismatched bundle_lock/unlock directives");
43b028cc80SRafael Espindola }
44b028cc80SRafael Espindola if (--BundleLockNestingDepth == 0) {
45b028cc80SRafael Espindola BundleLockState = NotBundleLocked;
46b028cc80SRafael Espindola }
47b028cc80SRafael Espindola return;
48b028cc80SRafael Espindola }
49b028cc80SRafael Espindola
50b028cc80SRafael Espindola // If any of the directives is an align_to_end directive, the whole nested
51b028cc80SRafael Espindola // group is align_to_end. So don't downgrade from align_to_end to just locked.
52b028cc80SRafael Espindola if (BundleLockState != BundleLockedAlignToEnd) {
53b028cc80SRafael Espindola BundleLockState = NewState;
54b028cc80SRafael Espindola }
55b028cc80SRafael Espindola ++BundleLockNestingDepth;
56b028cc80SRafael Espindola }
5709266badSRafael Espindola
58a32d0e9eSRafael Espindola MCSection::iterator
getSubsectionInsertionPoint(unsigned Subsection)598c05c6e2SRafael Espindola MCSection::getSubsectionInsertionPoint(unsigned Subsection) {
60a32d0e9eSRafael Espindola if (Subsection == 0 && SubsectionFragmentMap.empty())
618c05c6e2SRafael Espindola return end();
628c05c6e2SRafael Espindola
631a2d67faSKazu Hirata SmallVectorImpl<std::pair<unsigned, MCFragment *>>::iterator MI = lower_bound(
641a2d67faSKazu Hirata SubsectionFragmentMap, std::make_pair(Subsection, (MCFragment *)nullptr));
658c05c6e2SRafael Espindola bool ExactMatch = false;
66a32d0e9eSRafael Espindola if (MI != SubsectionFragmentMap.end()) {
678c05c6e2SRafael Espindola ExactMatch = MI->first == Subsection;
688c05c6e2SRafael Espindola if (ExactMatch)
698c05c6e2SRafael Espindola ++MI;
708c05c6e2SRafael Espindola }
71a32d0e9eSRafael Espindola iterator IP;
72a32d0e9eSRafael Espindola if (MI == SubsectionFragmentMap.end())
738c05c6e2SRafael Espindola IP = end();
748c05c6e2SRafael Espindola else
75a5f45da2SDuncan P. N. Exon Smith IP = MI->second->getIterator();
768c05c6e2SRafael Espindola if (!ExactMatch && Subsection != 0) {
778c05c6e2SRafael Espindola // The GNU as documentation claims that subsections have an alignment of 4,
788c05c6e2SRafael Espindola // although this appears not to be the case.
798c05c6e2SRafael Espindola MCFragment *F = new MCDataFragment();
80a32d0e9eSRafael Espindola SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F));
818c05c6e2SRafael Espindola getFragmentList().insert(IP, F);
828c05c6e2SRafael Espindola F->setParent(this);
83415a4fbeSJian Cai F->setSubsectionNumber(Subsection);
848c05c6e2SRafael Espindola }
858c05c6e2SRafael Espindola
868c05c6e2SRafael Espindola return IP;
878c05c6e2SRafael Espindola }
888c05c6e2SRafael Espindola
getVirtualSectionKind() const89e13a8a1fSFangrui Song StringRef MCSection::getVirtualSectionKind() const { return "virtual"; }
90e13a8a1fSFangrui Song
addPendingLabel(MCSymbol * label,unsigned Subsection)916f95d33eSMichael Trent void MCSection::addPendingLabel(MCSymbol *label, unsigned Subsection) {
926f95d33eSMichael Trent PendingLabels.push_back(PendingLabel(label, Subsection));
936f95d33eSMichael Trent }
946f95d33eSMichael Trent
flushPendingLabels(MCFragment * F,uint64_t FOffset,unsigned Subsection)956f95d33eSMichael Trent void MCSection::flushPendingLabels(MCFragment *F, uint64_t FOffset,
966f95d33eSMichael Trent unsigned Subsection) {
976f95d33eSMichael Trent if (PendingLabels.empty())
986f95d33eSMichael Trent return;
996f95d33eSMichael Trent
1006f95d33eSMichael Trent // Set the fragment and fragment offset for all pending symbols in the
1016f95d33eSMichael Trent // specified Subsection, and remove those symbols from the pending list.
1026f95d33eSMichael Trent for (auto It = PendingLabels.begin(); It != PendingLabels.end(); ++It) {
1036f95d33eSMichael Trent PendingLabel& Label = *It;
1046f95d33eSMichael Trent if (Label.Subsection == Subsection) {
1056f95d33eSMichael Trent Label.Sym->setFragment(F);
1066f95d33eSMichael Trent Label.Sym->setOffset(FOffset);
1076f95d33eSMichael Trent PendingLabels.erase(It--);
1086f95d33eSMichael Trent }
1096f95d33eSMichael Trent }
1106f95d33eSMichael Trent }
1116f95d33eSMichael Trent
flushPendingLabels()1126f95d33eSMichael Trent void MCSection::flushPendingLabels() {
1136f95d33eSMichael Trent // Make sure all remaining pending labels point to data fragments, by
1146f95d33eSMichael Trent // creating new empty data fragments for each Subsection with labels pending.
1156f95d33eSMichael Trent while (!PendingLabels.empty()) {
1166f95d33eSMichael Trent PendingLabel& Label = PendingLabels[0];
1176f95d33eSMichael Trent iterator CurInsertionPoint =
1186f95d33eSMichael Trent this->getSubsectionInsertionPoint(Label.Subsection);
1196f95d33eSMichael Trent MCFragment *F = new MCDataFragment();
1206f95d33eSMichael Trent getFragmentList().insert(CurInsertionPoint, F);
1216f95d33eSMichael Trent F->setParent(this);
1226f95d33eSMichael Trent flushPendingLabels(F, 0, Label.Subsection);
1236f95d33eSMichael Trent }
1246f95d33eSMichael Trent }
1256f95d33eSMichael Trent
126615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const127705f798bSSam Clegg LLVM_DUMP_METHOD void MCSection::dump() const {
1283d8b0ebbSEugene Zelenko raw_ostream &OS = errs();
129a554c05dSRafael Espindola
130a32d0e9eSRafael Espindola OS << "<MCSection";
131a32d0e9eSRafael Espindola OS << " Fragments:[\n ";
132a32d0e9eSRafael Espindola for (auto it = begin(), ie = end(); it != ie; ++it) {
133a32d0e9eSRafael Espindola if (it != begin())
134a32d0e9eSRafael Espindola OS << ",\n ";
135a32d0e9eSRafael Espindola it->dump();
136a32d0e9eSRafael Espindola }
137a32d0e9eSRafael Espindola OS << "]>";
138a554c05dSRafael Espindola }
1398c209aa8SMatthias Braun #endif
140