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