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 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 107 bool MCSectionCOFF::useCodeAlign() const { return getKind().isText(); } 108 109 bool MCSectionCOFF::isVirtualSection() const { 110 return getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 111 } 112 113 StringRef MCSectionCOFF::getVirtualSectionKind() const { 114 return "IMAGE_SCN_CNT_UNINITIALIZED_DATA"; 115 } 116