10b57cec5SDimitry Andric //===- lib/MC/MCSection.cpp - Machine Code Section Representation ---------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/MC/MCSection.h" 1081ad6265SDimitry Andric #include "llvm/ADT/STLExtras.h" 110b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 120b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h" 130b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 140b57cec5SDimitry Andric #include "llvm/MC/MCFragment.h" 150b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 160b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 170b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 180b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 190b57cec5SDimitry Andric #include <utility> 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric using namespace llvm; 220b57cec5SDimitry Andric 230fca6ea1SDimitry Andric MCSection::MCSection(SectionVariant V, StringRef Name, bool IsText, 240fca6ea1SDimitry Andric bool IsVirtual, MCSymbol *Begin) 250b57cec5SDimitry Andric : Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false), 26*52418fc2SDimitry Andric HasLayout(false), IsRegistered(false), IsText(IsText), 27*52418fc2SDimitry Andric IsVirtual(IsVirtual), Name(Name), Variant(V) { 280fca6ea1SDimitry Andric DummyFragment.setParent(this); 290fca6ea1SDimitry Andric // The initial subsection number is 0. Create a fragment list. 300fca6ea1SDimitry Andric CurFragList = &Subsections.emplace_back(0u, FragList{}).second; 310fca6ea1SDimitry Andric } 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) { 340b57cec5SDimitry Andric if (!End) 35e8d8bef9SDimitry Andric End = Ctx.createTempSymbol("sec_end"); 360b57cec5SDimitry Andric return End; 370b57cec5SDimitry Andric } 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric bool MCSection::hasEnded() const { return End && End->isInSection(); } 400b57cec5SDimitry Andric 410fca6ea1SDimitry Andric MCSection::~MCSection() { 420fca6ea1SDimitry Andric for (auto &[_, Chain] : Subsections) { 430fca6ea1SDimitry Andric for (MCFragment *X = Chain.Head, *Y; X; X = Y) { 440fca6ea1SDimitry Andric Y = X->Next; 450fca6ea1SDimitry Andric X->destroy(); 460fca6ea1SDimitry Andric } 470fca6ea1SDimitry Andric } 480fca6ea1SDimitry Andric } 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric void MCSection::setBundleLockState(BundleLockStateType NewState) { 510b57cec5SDimitry Andric if (NewState == NotBundleLocked) { 520b57cec5SDimitry Andric if (BundleLockNestingDepth == 0) { 530b57cec5SDimitry Andric report_fatal_error("Mismatched bundle_lock/unlock directives"); 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric if (--BundleLockNestingDepth == 0) { 560b57cec5SDimitry Andric BundleLockState = NotBundleLocked; 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric return; 590b57cec5SDimitry Andric } 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric // If any of the directives is an align_to_end directive, the whole nested 620b57cec5SDimitry Andric // group is align_to_end. So don't downgrade from align_to_end to just locked. 630b57cec5SDimitry Andric if (BundleLockState != BundleLockedAlignToEnd) { 640b57cec5SDimitry Andric BundleLockState = NewState; 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric ++BundleLockNestingDepth; 670b57cec5SDimitry Andric } 680b57cec5SDimitry Andric 695ffd83dbSDimitry Andric StringRef MCSection::getVirtualSectionKind() const { return "virtual"; } 705ffd83dbSDimitry Andric 710b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 720b57cec5SDimitry Andric LLVM_DUMP_METHOD void MCSection::dump() const { 730b57cec5SDimitry Andric raw_ostream &OS = errs(); 740b57cec5SDimitry Andric 750fca6ea1SDimitry Andric OS << "<MCSection Name:" << getName(); 760b57cec5SDimitry Andric OS << " Fragments:[\n "; 770fca6ea1SDimitry Andric bool First = true; 780fca6ea1SDimitry Andric for (auto &F : *this) { 790fca6ea1SDimitry Andric if (First) 800fca6ea1SDimitry Andric First = false; 810fca6ea1SDimitry Andric else 820b57cec5SDimitry Andric OS << ",\n "; 830fca6ea1SDimitry Andric F.dump(); 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric OS << "]>"; 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric #endif 88