1//===- lib/MC/MCSectionCOFF.cpp - COFF 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/MCSectionCOFF.h"
10#include "llvm/BinaryFormat/COFF.h"
11#include "llvm/MC/MCSymbol.h"
12#include "llvm/Support/raw_ostream.h"
13#include <cassert>
14
15using namespace llvm;
16
17// ShouldOmitSectionDirective - Decides whether a '.section' directive
18// should be printed before the section name
19bool MCSectionCOFF::ShouldOmitSectionDirective(StringRef Name,
20                                               const MCAsmInfo &MAI) const {
21  if (COMDATSymbol)
22    return false;
23
24  // FIXME: Does .section .bss/.data/.text work everywhere??
25  if (Name == ".text" || Name == ".data" || Name == ".bss")
26    return true;
27
28  return false;
29}
30
31void MCSectionCOFF::setSelection(int Selection) const {
32  assert(Selection != 0 && "invalid COMDAT selection type");
33  this->Selection = Selection;
34  Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
35}
36
37void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
38                                         raw_ostream &OS,
39                                         const MCExpr *Subsection) const {
40  // standard sections don't require the '.section'
41  if (ShouldOmitSectionDirective(getName(), MAI)) {
42    OS << '\t' << getName() << '\n';
43    return;
44  }
45
46  OS << "\t.section\t" << getName() << ",\"";
47  if (getCharacteristics() & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
48    OS << 'd';
49  if (getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
50    OS << 'b';
51  if (getCharacteristics() & COFF::IMAGE_SCN_MEM_EXECUTE)
52    OS << 'x';
53  if (getCharacteristics() & COFF::IMAGE_SCN_MEM_WRITE)
54    OS << 'w';
55  else if (getCharacteristics() & COFF::IMAGE_SCN_MEM_READ)
56    OS << 'r';
57  else
58    OS << 'y';
59  if (getCharacteristics() & COFF::IMAGE_SCN_LNK_REMOVE)
60    OS << 'n';
61  if (getCharacteristics() & COFF::IMAGE_SCN_MEM_SHARED)
62    OS << 's';
63  if ((getCharacteristics() & COFF::IMAGE_SCN_MEM_DISCARDABLE) &&
64      !isImplicitlyDiscardable(getName()))
65    OS << 'D';
66  OS << '"';
67
68  if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
69    if (COMDATSymbol)
70      OS << ",";
71    else
72      OS << "\n\t.linkonce\t";
73    switch (Selection) {
74      case COFF::IMAGE_COMDAT_SELECT_NODUPLICATES:
75        OS << "one_only";
76        break;
77      case COFF::IMAGE_COMDAT_SELECT_ANY:
78        OS << "discard";
79        break;
80      case COFF::IMAGE_COMDAT_SELECT_SAME_SIZE:
81        OS << "same_size";
82        break;
83      case COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH:
84        OS << "same_contents";
85        break;
86      case COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE:
87        OS << "associative";
88        break;
89      case COFF::IMAGE_COMDAT_SELECT_LARGEST:
90        OS << "largest";
91        break;
92      case COFF::IMAGE_COMDAT_SELECT_NEWEST:
93        OS << "newest";
94        break;
95      default:
96        assert(false && "unsupported COFF selection type");
97        break;
98    }
99    if (COMDATSymbol) {
100      OS << ",";
101      COMDATSymbol->print(OS, &MAI);
102    }
103  }
104  OS << '\n';
105}
106
107bool MCSectionCOFF::UseCodeAlign() const {
108  return getKind().isText();
109}
110
111bool MCSectionCOFF::isVirtualSection() const {
112  return getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
113}
114
115StringRef MCSectionCOFF::getVirtualSectionKind() const {
116  return "IMAGE_SCN_CNT_UNINITIALIZED_DATA";
117}
118