1 //===- lib/MC/MCSectionXCOFF.cpp - XCOFF 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/MCSectionXCOFF.h" 10 #include "llvm/MC/MCAsmInfo.h" 11 #include "llvm/Support/Format.h" 12 #include "llvm/Support/raw_ostream.h" 13 namespace llvm { 14 class MCExpr; 15 class Triple; 16 } // namespace llvm 17 18 using namespace llvm; 19 20 MCSectionXCOFF::~MCSectionXCOFF() = default; 21 22 void MCSectionXCOFF::printCsectDirective(raw_ostream &OS) const { 23 OS << "\t.csect " << QualName->getName() << "," << Log2_32(getAlignment()) 24 << '\n'; 25 } 26 27 void MCSectionXCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, 28 raw_ostream &OS, 29 const MCExpr *Subsection) const { 30 if (getKind().isText()) { 31 if (getMappingClass() != XCOFF::XMC_PR) 32 report_fatal_error("Unhandled storage-mapping class for .text csect"); 33 34 printCsectDirective(OS); 35 return; 36 } 37 38 if (getKind().isReadOnly()) { 39 if (getMappingClass() != XCOFF::XMC_RO && 40 getMappingClass() != XCOFF::XMC_TD) 41 report_fatal_error("Unhandled storage-mapping class for .rodata csect."); 42 printCsectDirective(OS); 43 return; 44 } 45 46 // Initialized TLS data. 47 if (getKind().isThreadData()) { 48 // We only expect XMC_TL here for initialized TLS data. 49 if (getMappingClass() != XCOFF::XMC_TL) 50 report_fatal_error("Unhandled storage-mapping class for .tdata csect."); 51 printCsectDirective(OS); 52 return; 53 } 54 55 if (getKind().isData()) { 56 switch (getMappingClass()) { 57 case XCOFF::XMC_RW: 58 case XCOFF::XMC_DS: 59 case XCOFF::XMC_TD: 60 printCsectDirective(OS); 61 break; 62 case XCOFF::XMC_TC: 63 case XCOFF::XMC_TE: 64 break; 65 case XCOFF::XMC_TC0: 66 OS << "\t.toc\n"; 67 break; 68 default: 69 report_fatal_error( 70 "Unhandled storage-mapping class for .data csect."); 71 } 72 return; 73 } 74 75 if (isCsect() && getMappingClass() == XCOFF::XMC_TD) { 76 assert((getKind().isBSSExtern() || getKind().isBSSLocal() || 77 getKind().isReadOnlyWithRel()) && 78 "Unexepected section kind for toc-data"); 79 printCsectDirective(OS); 80 return; 81 } 82 // Common csect type (uninitialized storage) does not have to print csect 83 // directive for section switching. 84 if (isCsect() && getCSectType() == XCOFF::XTY_CM) { 85 assert((getMappingClass() == XCOFF::XMC_RW || 86 getMappingClass() == XCOFF::XMC_BS || 87 getMappingClass() == XCOFF::XMC_UL) && 88 "Generated a storage-mapping class for a common/bss/tbss csect we " 89 "don't " 90 "understand how to switch to."); 91 // Common symbols and local zero-initialized symbols for TLS and Non-TLS are 92 // eligible for .bss/.tbss csect, getKind().isThreadBSS() is used to cover 93 // TLS common and zero-initialized local symbols since linkage type (in the 94 // GlobalVariable) is not accessible in this class. 95 assert((getKind().isBSSLocal() || getKind().isCommon() || 96 getKind().isThreadBSS()) && 97 "wrong symbol type for .bss/.tbss csect"); 98 // Don't have to print a directive for switching to section for commons and 99 // zero-initialized TLS data. The '.comm' and '.lcomm' directives of the 100 // variable will create the needed csect. 101 return; 102 } 103 104 // Zero-initialized TLS data with weak or external linkage are not eligible to 105 // be put into common csect. 106 if (getKind().isThreadBSS()) { 107 printCsectDirective(OS); 108 return; 109 } 110 111 // XCOFF debug sections. 112 if (getKind().isMetadata() && isDwarfSect()) { 113 OS << "\n\t.dwsect " << format("0x%" PRIx32, getDwarfSubtypeFlags().value()) 114 << '\n'; 115 OS << MAI.getPrivateLabelPrefix() << getName() << ':' << '\n'; 116 return; 117 } 118 119 report_fatal_error("Printing for this SectionKind is unimplemented."); 120 } 121 122 bool MCSectionXCOFF::useCodeAlign() const { return getKind().isText(); } 123 124 bool MCSectionXCOFF::isVirtualSection() const { 125 // DWARF sections are always not virtual. 126 if (isDwarfSect()) 127 return false; 128 assert(isCsect() && 129 "Handling for isVirtualSection not implemented for this section!"); 130 return XCOFF::XTY_CM == CsectProp->Type; 131 } 132