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