aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm16/lib/MC/MCSectionXCOFF.cpp
blob: e13f30ccbbdcaa1fc49f9ad0ab08370c955e464e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//===- lib/MC/MCSectionXCOFF.cpp - XCOFF Code Section Representation ------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "llvm/MC/MCSectionXCOFF.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
class MCExpr;
class Triple;
} // namespace llvm

using namespace llvm;

MCSectionXCOFF::~MCSectionXCOFF() = default;

void MCSectionXCOFF::printCsectDirective(raw_ostream &OS) const {
  OS << "\t.csect " << QualName->getName() << "," << Log2(getAlign()) << '\n';
}

void MCSectionXCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
                                          raw_ostream &OS,
                                          const MCExpr *Subsection) const {
  if (getKind().isText()) {
    if (getMappingClass() != XCOFF::XMC_PR)
      report_fatal_error("Unhandled storage-mapping class for .text csect");

    printCsectDirective(OS);
    return;
  }

  if (getKind().isReadOnly()) {
    if (getMappingClass() != XCOFF::XMC_RO &&
        getMappingClass() != XCOFF::XMC_TD)
      report_fatal_error("Unhandled storage-mapping class for .rodata csect.");
    printCsectDirective(OS);
    return;
  }

  // Initialized TLS data.
  if (getKind().isThreadData()) {
    // We only expect XMC_TL here for initialized TLS data.
    if (getMappingClass() != XCOFF::XMC_TL)
      report_fatal_error("Unhandled storage-mapping class for .tdata csect.");
    printCsectDirective(OS);
    return;
  }

  if (getKind().isData()) {
    switch (getMappingClass()) {
    case XCOFF::XMC_RW:
    case XCOFF::XMC_DS:
    case XCOFF::XMC_TD:
      printCsectDirective(OS);
      break;
    case XCOFF::XMC_TC:
    case XCOFF::XMC_TE:
      break;
    case XCOFF::XMC_TC0:
      OS << "\t.toc\n";
      break;
    default:
      report_fatal_error(
          "Unhandled storage-mapping class for .data csect.");
    }
    return;
  }

  if (isCsect() && getMappingClass() == XCOFF::XMC_TD) {
    assert((getKind().isBSSExtern() || getKind().isBSSLocal() ||
            getKind().isReadOnlyWithRel()) &&
           "Unexepected section kind for toc-data");
    printCsectDirective(OS);
    return;
  }
  // Common csect type (uninitialized storage) does not have to print csect
  // directive for section switching.
  if (isCsect() && getCSectType() == XCOFF::XTY_CM) {
    assert((getMappingClass() == XCOFF::XMC_RW ||
            getMappingClass() == XCOFF::XMC_BS ||
            getMappingClass() == XCOFF::XMC_UL) &&
           "Generated a storage-mapping class for a common/bss/tbss csect we "
           "don't "
           "understand how to switch to.");
    // Common symbols and local zero-initialized symbols for TLS and Non-TLS are
    // eligible for .bss/.tbss csect, getKind().isThreadBSS() is used to cover
    // TLS common and zero-initialized local symbols since linkage type (in the
    // GlobalVariable) is not accessible in this class.
    assert((getKind().isBSSLocal() || getKind().isCommon() ||
            getKind().isThreadBSS()) &&
           "wrong symbol type for .bss/.tbss csect");
    // Don't have to print a directive for switching to section for commons and
    // zero-initialized TLS data. The '.comm' and '.lcomm' directives of the
    // variable will create the needed csect.
    return;
  }

  // Zero-initialized TLS data with weak or external linkage are not eligible to
  // be put into common csect.
  if (getKind().isThreadBSS()) {
    printCsectDirective(OS);
    return;
  }

  // XCOFF debug sections.
  if (getKind().isMetadata() && isDwarfSect()) {
    OS << "\n\t.dwsect " << format("0x%" PRIx32, *getDwarfSubtypeFlags())
       << '\n';
    OS << MAI.getPrivateLabelPrefix() << getName() << ':' << '\n';
    return;
  }

  report_fatal_error("Printing for this SectionKind is unimplemented.");
}

bool MCSectionXCOFF::useCodeAlign() const { return getKind().isText(); }

bool MCSectionXCOFF::isVirtualSection() const {
  // DWARF sections are always not virtual.
  if (isDwarfSect())
    return false;
  assert(isCsect() &&
         "Handling for isVirtualSection not implemented for this section!");
  return XCOFF::XTY_CM == CsectProp->Type;
}