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