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 15 using namespace llvm; 16 17 // shouldOmitSectionDirective - Decides whether a '.section' directive 18 // should be printed before the section name 19 bool 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 31 void 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 37 void 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 if (getCharacteristics() & COFF::IMAGE_SCN_LNK_INFO) 67 OS << 'i'; 68 OS << '"'; 69 70 if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) { 71 if (COMDATSymbol) 72 OS << ","; 73 else 74 OS << "\n\t.linkonce\t"; 75 switch (Selection) { 76 case COFF::IMAGE_COMDAT_SELECT_NODUPLICATES: 77 OS << "one_only"; 78 break; 79 case COFF::IMAGE_COMDAT_SELECT_ANY: 80 OS << "discard"; 81 break; 82 case COFF::IMAGE_COMDAT_SELECT_SAME_SIZE: 83 OS << "same_size"; 84 break; 85 case COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH: 86 OS << "same_contents"; 87 break; 88 case COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE: 89 OS << "associative"; 90 break; 91 case COFF::IMAGE_COMDAT_SELECT_LARGEST: 92 OS << "largest"; 93 break; 94 case COFF::IMAGE_COMDAT_SELECT_NEWEST: 95 OS << "newest"; 96 break; 97 default: 98 assert(false && "unsupported COFF selection type"); 99 break; 100 } 101 if (COMDATSymbol) { 102 OS << ","; 103 COMDATSymbol->print(OS, &MAI); 104 } 105 } 106 OS << '\n'; 107 } 108 109 bool MCSectionCOFF::useCodeAlign() const { return getKind().isText(); } 110 111 bool MCSectionCOFF::isVirtualSection() const { 112 return getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 113 } 114 115 StringRef MCSectionCOFF::getVirtualSectionKind() const { 116 return "IMAGE_SCN_CNT_UNINITIALIZED_DATA"; 117 } 118