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 report_fatal_error("Unhandled storage-mapping class for .rodata csect."); 39 printCsectDirective(OS); 40 return; 41 } 42 43 // Initialized TLS data. 44 if (getKind().isThreadData()) { 45 // We only expect XMC_TL here for initialized TLS data. 46 if (getMappingClass() != XCOFF::XMC_TL) 47 report_fatal_error("Unhandled storage-mapping class for .tdata csect."); 48 printCsectDirective(OS); 49 return; 50 } 51 52 if (getKind().isData()) { 53 switch (getMappingClass()) { 54 case XCOFF::XMC_RW: 55 case XCOFF::XMC_DS: 56 printCsectDirective(OS); 57 break; 58 case XCOFF::XMC_TC: 59 case XCOFF::XMC_TE: 60 break; 61 case XCOFF::XMC_TC0: 62 OS << "\t.toc\n"; 63 break; 64 default: 65 report_fatal_error( 66 "Unhandled storage-mapping class for .data csect."); 67 } 68 return; 69 } 70 71 // Common csect type (uninitialized storage) does not have to print csect 72 // directive for section switching. 73 if (isCsect() && getCSectType() == XCOFF::XTY_CM) { 74 assert((getMappingClass() == XCOFF::XMC_RW || 75 getMappingClass() == XCOFF::XMC_BS || 76 getMappingClass() == XCOFF::XMC_UL) && 77 "Generated a storage-mapping class for a common/bss/tbss csect we " 78 "don't " 79 "understand how to switch to."); 80 // Common symbols and local zero-initialized symbols for TLS and Non-TLS are 81 // eligible for .bss/.tbss csect, getKind().isThreadBSS() is used to cover 82 // TLS common and zero-initialized local symbols since linkage type (in the 83 // GlobalVariable) is not accessible in this class. 84 assert((getKind().isBSSLocal() || getKind().isCommon() || 85 getKind().isThreadBSS()) && 86 "wrong symbol type for .bss/.tbss csect"); 87 // Don't have to print a directive for switching to section for commons and 88 // zero-initialized TLS data. The '.comm' and '.lcomm' directives of the 89 // variable will create the needed csect. 90 return; 91 } 92 93 // Zero-initialized TLS data with weak or external linkage are not eligible to 94 // be put into common csect. 95 if (getKind().isThreadBSS()) { 96 printCsectDirective(OS); 97 return; 98 } 99 100 // XCOFF debug sections. 101 if (getKind().isMetadata() && isDwarfSect()) { 102 OS << "\n\t.dwsect " 103 << format("0x%" PRIx32, getDwarfSubtypeFlags().getValue()) << '\n'; 104 OS << MAI.getPrivateLabelPrefix() << getName() << ':' << '\n'; 105 return; 106 } 107 108 report_fatal_error("Printing for this SectionKind is unimplemented."); 109 } 110 111 bool MCSectionXCOFF::UseCodeAlign() const { return getKind().isText(); } 112 113 bool MCSectionXCOFF::isVirtualSection() const { 114 assert(isCsect() && "Only csect section can be virtual!"); 115 return XCOFF::XTY_CM == CsectProp->Type; 116 } 117