10b57cec5SDimitry Andric //===- lib/MC/MCSectionCOFF.cpp - COFF Code Section Representation --------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/MC/MCSectionCOFF.h" 100b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h" 110b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 120b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 130b57cec5SDimitry Andric #include <cassert> 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric using namespace llvm; 160b57cec5SDimitry Andric 1781ad6265SDimitry Andric // shouldOmitSectionDirective - Decides whether a '.section' directive 180b57cec5SDimitry Andric // should be printed before the section name 1981ad6265SDimitry Andric bool MCSectionCOFF::shouldOmitSectionDirective(StringRef Name, 200b57cec5SDimitry Andric const MCAsmInfo &MAI) const { 210b57cec5SDimitry Andric if (COMDATSymbol) 220b57cec5SDimitry Andric return false; 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric // FIXME: Does .section .bss/.data/.text work everywhere?? 250b57cec5SDimitry Andric if (Name == ".text" || Name == ".data" || Name == ".bss") 260b57cec5SDimitry Andric return true; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric return false; 290b57cec5SDimitry Andric } 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric void MCSectionCOFF::setSelection(int Selection) const { 320b57cec5SDimitry Andric assert(Selection != 0 && "invalid COMDAT selection type"); 330b57cec5SDimitry Andric this->Selection = Selection; 340b57cec5SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 350b57cec5SDimitry Andric } 360b57cec5SDimitry Andric 3781ad6265SDimitry Andric void MCSectionCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, 380b57cec5SDimitry Andric raw_ostream &OS, 39*0fca6ea1SDimitry Andric uint32_t Subsection) const { 400b57cec5SDimitry Andric // standard sections don't require the '.section' 4181ad6265SDimitry Andric if (shouldOmitSectionDirective(getName(), MAI)) { 425ffd83dbSDimitry Andric OS << '\t' << getName() << '\n'; 430b57cec5SDimitry Andric return; 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric 465ffd83dbSDimitry Andric OS << "\t.section\t" << getName() << ",\""; 470b57cec5SDimitry Andric if (getCharacteristics() & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) 480b57cec5SDimitry Andric OS << 'd'; 490b57cec5SDimitry Andric if (getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) 500b57cec5SDimitry Andric OS << 'b'; 510b57cec5SDimitry Andric if (getCharacteristics() & COFF::IMAGE_SCN_MEM_EXECUTE) 520b57cec5SDimitry Andric OS << 'x'; 530b57cec5SDimitry Andric if (getCharacteristics() & COFF::IMAGE_SCN_MEM_WRITE) 540b57cec5SDimitry Andric OS << 'w'; 550b57cec5SDimitry Andric else if (getCharacteristics() & COFF::IMAGE_SCN_MEM_READ) 560b57cec5SDimitry Andric OS << 'r'; 570b57cec5SDimitry Andric else 580b57cec5SDimitry Andric OS << 'y'; 590b57cec5SDimitry Andric if (getCharacteristics() & COFF::IMAGE_SCN_LNK_REMOVE) 600b57cec5SDimitry Andric OS << 'n'; 610b57cec5SDimitry Andric if (getCharacteristics() & COFF::IMAGE_SCN_MEM_SHARED) 620b57cec5SDimitry Andric OS << 's'; 630b57cec5SDimitry Andric if ((getCharacteristics() & COFF::IMAGE_SCN_MEM_DISCARDABLE) && 645ffd83dbSDimitry Andric !isImplicitlyDiscardable(getName())) 650b57cec5SDimitry Andric OS << 'D'; 66bdd1243dSDimitry Andric if (getCharacteristics() & COFF::IMAGE_SCN_LNK_INFO) 67bdd1243dSDimitry Andric OS << 'i'; 680b57cec5SDimitry Andric OS << '"'; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) { 710b57cec5SDimitry Andric if (COMDATSymbol) 720b57cec5SDimitry Andric OS << ","; 730b57cec5SDimitry Andric else 740b57cec5SDimitry Andric OS << "\n\t.linkonce\t"; 750b57cec5SDimitry Andric switch (Selection) { 760b57cec5SDimitry Andric case COFF::IMAGE_COMDAT_SELECT_NODUPLICATES: 770b57cec5SDimitry Andric OS << "one_only"; 780b57cec5SDimitry Andric break; 790b57cec5SDimitry Andric case COFF::IMAGE_COMDAT_SELECT_ANY: 800b57cec5SDimitry Andric OS << "discard"; 810b57cec5SDimitry Andric break; 820b57cec5SDimitry Andric case COFF::IMAGE_COMDAT_SELECT_SAME_SIZE: 830b57cec5SDimitry Andric OS << "same_size"; 840b57cec5SDimitry Andric break; 850b57cec5SDimitry Andric case COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH: 860b57cec5SDimitry Andric OS << "same_contents"; 870b57cec5SDimitry Andric break; 880b57cec5SDimitry Andric case COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE: 890b57cec5SDimitry Andric OS << "associative"; 900b57cec5SDimitry Andric break; 910b57cec5SDimitry Andric case COFF::IMAGE_COMDAT_SELECT_LARGEST: 920b57cec5SDimitry Andric OS << "largest"; 930b57cec5SDimitry Andric break; 940b57cec5SDimitry Andric case COFF::IMAGE_COMDAT_SELECT_NEWEST: 950b57cec5SDimitry Andric OS << "newest"; 960b57cec5SDimitry Andric break; 970b57cec5SDimitry Andric default: 980b57cec5SDimitry Andric assert(false && "unsupported COFF selection type"); 990b57cec5SDimitry Andric break; 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric if (COMDATSymbol) { 1020b57cec5SDimitry Andric OS << ","; 1030b57cec5SDimitry Andric COMDATSymbol->print(OS, &MAI); 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric OS << '\n'; 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 109*0fca6ea1SDimitry Andric bool MCSectionCOFF::useCodeAlign() const { return isText(); } 1105ffd83dbSDimitry Andric 1115ffd83dbSDimitry Andric StringRef MCSectionCOFF::getVirtualSectionKind() const { 1125ffd83dbSDimitry Andric return "IMAGE_SCN_CNT_UNINITIALIZED_DATA"; 1135ffd83dbSDimitry Andric } 114