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 | |
9 | #include "llvm/MC/MCSection.h" |
10 | #include "llvm/ADT/STLExtras.h" |
11 | #include "llvm/ADT/SmallVector.h" |
12 | #include "llvm/Config/llvm-config.h" |
13 | #include "llvm/MC/MCContext.h" |
14 | #include "llvm/MC/MCFragment.h" |
15 | #include "llvm/MC/MCSymbol.h" |
16 | #include "llvm/Support/Compiler.h" |
17 | #include "llvm/Support/ErrorHandling.h" |
18 | #include "llvm/Support/raw_ostream.h" |
19 | #include <utility> |
20 | |
21 | using namespace llvm; |
22 | |
23 | MCSection::MCSection(SectionVariant V, StringRef Name, bool IsText, |
24 | bool IsVirtual, MCSymbol *Begin) |
25 | : Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false), |
26 | HasLayout(false), IsRegistered(false), IsText(IsText), |
27 | IsVirtual(IsVirtual), Name(Name), Variant(V) { |
28 | DummyFragment.setParent(this); |
29 | // The initial subsection number is 0. Create a fragment list. |
30 | CurFragList = &Subsections.emplace_back(Args: 0u, Args: FragList{}).second; |
31 | } |
32 | |
33 | MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) { |
34 | if (!End) |
35 | End = Ctx.createTempSymbol(Name: "sec_end" ); |
36 | return End; |
37 | } |
38 | |
39 | bool MCSection::hasEnded() const { return End && End->isInSection(); } |
40 | |
41 | MCSection::~MCSection() { |
42 | for (auto &[_, Chain] : Subsections) { |
43 | for (MCFragment *X = Chain.Head, *Y; X; X = Y) { |
44 | Y = X->Next; |
45 | X->destroy(); |
46 | } |
47 | } |
48 | } |
49 | |
50 | void MCSection::setBundleLockState(BundleLockStateType NewState) { |
51 | if (NewState == NotBundleLocked) { |
52 | if (BundleLockNestingDepth == 0) { |
53 | report_fatal_error(reason: "Mismatched bundle_lock/unlock directives" ); |
54 | } |
55 | if (--BundleLockNestingDepth == 0) { |
56 | BundleLockState = NotBundleLocked; |
57 | } |
58 | return; |
59 | } |
60 | |
61 | // If any of the directives is an align_to_end directive, the whole nested |
62 | // group is align_to_end. So don't downgrade from align_to_end to just locked. |
63 | if (BundleLockState != BundleLockedAlignToEnd) { |
64 | BundleLockState = NewState; |
65 | } |
66 | ++BundleLockNestingDepth; |
67 | } |
68 | |
69 | StringRef MCSection::getVirtualSectionKind() const { return "virtual" ; } |
70 | |
71 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
72 | LLVM_DUMP_METHOD void MCSection::dump() const { |
73 | raw_ostream &OS = errs(); |
74 | |
75 | OS << "<MCSection Name:" << getName(); |
76 | OS << " Fragments:[\n " ; |
77 | bool First = true; |
78 | for (auto &F : *this) { |
79 | if (First) |
80 | First = false; |
81 | else |
82 | OS << ",\n " ; |
83 | F.dump(); |
84 | } |
85 | OS << "]>" ; |
86 | } |
87 | #endif |
88 | |