1f4a2713aSLionel Sambuc //===- lib/MC/MCSectionCOFF.cpp - COFF Code Section Representation --------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc 
10f4a2713aSLionel Sambuc #include "llvm/MC/MCSectionCOFF.h"
11f4a2713aSLionel Sambuc #include "llvm/MC/MCAsmInfo.h"
12f4a2713aSLionel Sambuc #include "llvm/MC/MCContext.h"
13f4a2713aSLionel Sambuc #include "llvm/MC/MCSymbol.h"
14f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
15f4a2713aSLionel Sambuc using namespace llvm;
16f4a2713aSLionel Sambuc 
~MCSectionCOFF()17f4a2713aSLionel Sambuc MCSectionCOFF::~MCSectionCOFF() {} // anchor.
18f4a2713aSLionel Sambuc 
19f4a2713aSLionel Sambuc // ShouldOmitSectionDirective - Decides whether a '.section' directive
20f4a2713aSLionel Sambuc // should be printed before the section name
ShouldOmitSectionDirective(StringRef Name,const MCAsmInfo & MAI) const21f4a2713aSLionel Sambuc bool MCSectionCOFF::ShouldOmitSectionDirective(StringRef Name,
22f4a2713aSLionel Sambuc                                                const MCAsmInfo &MAI) const {
23*0a6a1f1dSLionel Sambuc   if (COMDATSymbol)
24*0a6a1f1dSLionel Sambuc     return false;
25f4a2713aSLionel Sambuc 
26f4a2713aSLionel Sambuc   // FIXME: Does .section .bss/.data/.text work everywhere??
27f4a2713aSLionel Sambuc   if (Name == ".text" || Name == ".data" || Name == ".bss")
28f4a2713aSLionel Sambuc     return true;
29f4a2713aSLionel Sambuc 
30f4a2713aSLionel Sambuc   return false;
31f4a2713aSLionel Sambuc }
32f4a2713aSLionel Sambuc 
setSelection(int Selection) const33*0a6a1f1dSLionel Sambuc void MCSectionCOFF::setSelection(int Selection) const {
34f4a2713aSLionel Sambuc   assert(Selection != 0 && "invalid COMDAT selection type");
35f4a2713aSLionel Sambuc   this->Selection = Selection;
36f4a2713aSLionel Sambuc   Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
37f4a2713aSLionel Sambuc }
38f4a2713aSLionel Sambuc 
PrintSwitchToSection(const MCAsmInfo & MAI,raw_ostream & OS,const MCExpr * Subsection) const39f4a2713aSLionel Sambuc void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI,
40f4a2713aSLionel Sambuc                                          raw_ostream &OS,
41f4a2713aSLionel Sambuc                                          const MCExpr *Subsection) const {
42f4a2713aSLionel Sambuc 
43f4a2713aSLionel Sambuc   // standard sections don't require the '.section'
44f4a2713aSLionel Sambuc   if (ShouldOmitSectionDirective(SectionName, MAI)) {
45f4a2713aSLionel Sambuc     OS << '\t' << getSectionName() << '\n';
46f4a2713aSLionel Sambuc     return;
47f4a2713aSLionel Sambuc   }
48f4a2713aSLionel Sambuc 
49f4a2713aSLionel Sambuc   OS << "\t.section\t" << getSectionName() << ",\"";
50*0a6a1f1dSLionel Sambuc   if (getCharacteristics() & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
51*0a6a1f1dSLionel Sambuc     OS << 'd';
52*0a6a1f1dSLionel Sambuc   if (getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
53*0a6a1f1dSLionel Sambuc     OS << 'b';
54*0a6a1f1dSLionel Sambuc   if (getCharacteristics() & COFF::IMAGE_SCN_MEM_EXECUTE)
55f4a2713aSLionel Sambuc     OS << 'x';
56*0a6a1f1dSLionel Sambuc   if (getCharacteristics() & COFF::IMAGE_SCN_MEM_WRITE)
57f4a2713aSLionel Sambuc     OS << 'w';
58*0a6a1f1dSLionel Sambuc   else if (getCharacteristics() & COFF::IMAGE_SCN_MEM_READ)
59f4a2713aSLionel Sambuc     OS << 'r';
60*0a6a1f1dSLionel Sambuc   else
61*0a6a1f1dSLionel Sambuc     OS << 'y';
62*0a6a1f1dSLionel Sambuc   if (getCharacteristics() & COFF::IMAGE_SCN_LNK_REMOVE)
63f4a2713aSLionel Sambuc     OS << 'n';
64*0a6a1f1dSLionel Sambuc   if (getCharacteristics() & COFF::IMAGE_SCN_MEM_SHARED)
65*0a6a1f1dSLionel Sambuc     OS << 's';
66*0a6a1f1dSLionel Sambuc   OS << '"';
67f4a2713aSLionel Sambuc 
68f4a2713aSLionel Sambuc   if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
69*0a6a1f1dSLionel Sambuc     OS << ",";
70f4a2713aSLionel Sambuc     switch (Selection) {
71f4a2713aSLionel Sambuc       case COFF::IMAGE_COMDAT_SELECT_NODUPLICATES:
72*0a6a1f1dSLionel Sambuc         OS << "one_only,";
73f4a2713aSLionel Sambuc         break;
74f4a2713aSLionel Sambuc       case COFF::IMAGE_COMDAT_SELECT_ANY:
75*0a6a1f1dSLionel Sambuc         OS << "discard,";
76f4a2713aSLionel Sambuc         break;
77f4a2713aSLionel Sambuc       case COFF::IMAGE_COMDAT_SELECT_SAME_SIZE:
78*0a6a1f1dSLionel Sambuc         OS << "same_size,";
79f4a2713aSLionel Sambuc         break;
80f4a2713aSLionel Sambuc       case COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH:
81*0a6a1f1dSLionel Sambuc         OS << "same_contents,";
82f4a2713aSLionel Sambuc         break;
83f4a2713aSLionel Sambuc       case COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE:
84*0a6a1f1dSLionel Sambuc         OS << "associative,";
85f4a2713aSLionel Sambuc         break;
86f4a2713aSLionel Sambuc       case COFF::IMAGE_COMDAT_SELECT_LARGEST:
87*0a6a1f1dSLionel Sambuc         OS << "largest,";
88f4a2713aSLionel Sambuc         break;
89f4a2713aSLionel Sambuc       case COFF::IMAGE_COMDAT_SELECT_NEWEST:
90*0a6a1f1dSLionel Sambuc         OS << "newest,";
91f4a2713aSLionel Sambuc         break;
92f4a2713aSLionel Sambuc       default:
93f4a2713aSLionel Sambuc         assert (0 && "unsupported COFF selection type");
94f4a2713aSLionel Sambuc         break;
95f4a2713aSLionel Sambuc     }
96*0a6a1f1dSLionel Sambuc     assert(COMDATSymbol);
97*0a6a1f1dSLionel Sambuc     OS << *COMDATSymbol;
98f4a2713aSLionel Sambuc   }
99*0a6a1f1dSLionel Sambuc   OS << '\n';
100f4a2713aSLionel Sambuc }
101f4a2713aSLionel Sambuc 
UseCodeAlign() const102f4a2713aSLionel Sambuc bool MCSectionCOFF::UseCodeAlign() const {
103f4a2713aSLionel Sambuc   return getKind().isText();
104f4a2713aSLionel Sambuc }
105f4a2713aSLionel Sambuc 
isVirtualSection() const106f4a2713aSLionel Sambuc bool MCSectionCOFF::isVirtualSection() const {
107f4a2713aSLionel Sambuc   return getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
108f4a2713aSLionel Sambuc }
109