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