10b57cec5SDimitry Andric //===- lib/MC/MCSectionXCOFF.cpp - XCOFF Code Section Representation ------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/MC/MCSectionXCOFF.h" 100b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 110b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 12fe6060f1SDimitry Andric #include "llvm/Support/Debug.h" 13fe6060f1SDimitry Andric #include "llvm/Support/Format.h" 140b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric using namespace llvm; 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric MCSectionXCOFF::~MCSectionXCOFF() = default; 190b57cec5SDimitry Andric 205ffd83dbSDimitry Andric void MCSectionXCOFF::printCsectDirective(raw_ostream &OS) const { 215ffd83dbSDimitry Andric OS << "\t.csect " << QualName->getName() << "," << Log2_32(getAlignment()) 225ffd83dbSDimitry Andric << '\n'; 235ffd83dbSDimitry Andric } 248bcb0991SDimitry Andric 250b57cec5SDimitry Andric void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, 260b57cec5SDimitry Andric raw_ostream &OS, 270b57cec5SDimitry Andric const MCExpr *Subsection) const { 280b57cec5SDimitry Andric if (getKind().isText()) { 298bcb0991SDimitry Andric if (getMappingClass() != XCOFF::XMC_PR) 308bcb0991SDimitry Andric report_fatal_error("Unhandled storage-mapping class for .text csect"); 318bcb0991SDimitry Andric 325ffd83dbSDimitry Andric printCsectDirective(OS); 33480093f4SDimitry Andric return; 34480093f4SDimitry Andric } 35480093f4SDimitry Andric 36480093f4SDimitry Andric if (getKind().isReadOnly()) { 37480093f4SDimitry Andric if (getMappingClass() != XCOFF::XMC_RO) 38480093f4SDimitry Andric report_fatal_error("Unhandled storage-mapping class for .rodata csect."); 395ffd83dbSDimitry Andric printCsectDirective(OS); 400b57cec5SDimitry Andric return; 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 43fe6060f1SDimitry Andric // Initialized TLS data. 44fe6060f1SDimitry Andric if (getKind().isThreadData()) { 45fe6060f1SDimitry Andric // We only expect XMC_TL here for initialized TLS data. 46fe6060f1SDimitry Andric if (getMappingClass() != XCOFF::XMC_TL) 47fe6060f1SDimitry Andric report_fatal_error("Unhandled storage-mapping class for .tdata csect."); 48fe6060f1SDimitry Andric printCsectDirective(OS); 49fe6060f1SDimitry Andric return; 50fe6060f1SDimitry Andric } 51fe6060f1SDimitry Andric 528bcb0991SDimitry Andric if (getKind().isData()) { 538bcb0991SDimitry Andric switch (getMappingClass()) { 548bcb0991SDimitry Andric case XCOFF::XMC_RW: 558bcb0991SDimitry Andric case XCOFF::XMC_DS: 56fe6060f1SDimitry Andric case XCOFF::XMC_TD: 575ffd83dbSDimitry Andric printCsectDirective(OS); 58480093f4SDimitry Andric break; 59480093f4SDimitry Andric case XCOFF::XMC_TC: 60e8d8bef9SDimitry Andric case XCOFF::XMC_TE: 618bcb0991SDimitry Andric break; 628bcb0991SDimitry Andric case XCOFF::XMC_TC0: 638bcb0991SDimitry Andric OS << "\t.toc\n"; 648bcb0991SDimitry Andric break; 658bcb0991SDimitry Andric default: 668bcb0991SDimitry Andric report_fatal_error( 678bcb0991SDimitry Andric "Unhandled storage-mapping class for .data csect."); 688bcb0991SDimitry Andric } 698bcb0991SDimitry Andric return; 708bcb0991SDimitry Andric } 718bcb0991SDimitry Andric 72fe6060f1SDimitry Andric if (isCsect() && getMappingClass() == XCOFF::XMC_TD) { 73fe6060f1SDimitry Andric assert((getKind().isBSSExtern() || getKind().isBSSLocal()) && 74fe6060f1SDimitry Andric "Unexepected section kind for toc-data"); 75fe6060f1SDimitry Andric printCsectDirective(OS); 76fe6060f1SDimitry Andric return; 77fe6060f1SDimitry Andric } 78fe6060f1SDimitry Andric // Common csect type (uninitialized storage) does not have to print csect 79fe6060f1SDimitry Andric // directive for section switching. 80fe6060f1SDimitry Andric if (isCsect() && getCSectType() == XCOFF::XTY_CM) { 818bcb0991SDimitry Andric assert((getMappingClass() == XCOFF::XMC_RW || 82fe6060f1SDimitry Andric getMappingClass() == XCOFF::XMC_BS || 83fe6060f1SDimitry Andric getMappingClass() == XCOFF::XMC_UL) && 84fe6060f1SDimitry Andric "Generated a storage-mapping class for a common/bss/tbss csect we " 85fe6060f1SDimitry Andric "don't " 868bcb0991SDimitry Andric "understand how to switch to."); 87fe6060f1SDimitry Andric // Common symbols and local zero-initialized symbols for TLS and Non-TLS are 88fe6060f1SDimitry Andric // eligible for .bss/.tbss csect, getKind().isThreadBSS() is used to cover 89fe6060f1SDimitry Andric // TLS common and zero-initialized local symbols since linkage type (in the 90fe6060f1SDimitry Andric // GlobalVariable) is not accessible in this class. 91fe6060f1SDimitry Andric assert((getKind().isBSSLocal() || getKind().isCommon() || 92fe6060f1SDimitry Andric getKind().isThreadBSS()) && 93fe6060f1SDimitry Andric "wrong symbol type for .bss/.tbss csect"); 94fe6060f1SDimitry Andric // Don't have to print a directive for switching to section for commons and 95fe6060f1SDimitry Andric // zero-initialized TLS data. The '.comm' and '.lcomm' directives of the 96fe6060f1SDimitry Andric // variable will create the needed csect. 97fe6060f1SDimitry Andric return; 98fe6060f1SDimitry Andric } 99fe6060f1SDimitry Andric 100fe6060f1SDimitry Andric // Zero-initialized TLS data with weak or external linkage are not eligible to 101fe6060f1SDimitry Andric // be put into common csect. 102fe6060f1SDimitry Andric if (getKind().isThreadBSS()) { 103fe6060f1SDimitry Andric printCsectDirective(OS); 104fe6060f1SDimitry Andric return; 105fe6060f1SDimitry Andric } 106fe6060f1SDimitry Andric 107fe6060f1SDimitry Andric // XCOFF debug sections. 108fe6060f1SDimitry Andric if (getKind().isMetadata() && isDwarfSect()) { 109fe6060f1SDimitry Andric OS << "\n\t.dwsect " 110fe6060f1SDimitry Andric << format("0x%" PRIx32, getDwarfSubtypeFlags().getValue()) << '\n'; 111fe6060f1SDimitry Andric OS << MAI.getPrivateLabelPrefix() << getName() << ':' << '\n'; 1128bcb0991SDimitry Andric return; 1138bcb0991SDimitry Andric } 1148bcb0991SDimitry Andric 1150b57cec5SDimitry Andric report_fatal_error("Printing for this SectionKind is unimplemented."); 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric bool MCSectionXCOFF::UseCodeAlign() const { return getKind().isText(); } 1190b57cec5SDimitry Andric 120fe6060f1SDimitry Andric bool MCSectionXCOFF::isVirtualSection() const { 121*349cc55cSDimitry Andric // DWARF sections are always not virtual. 122*349cc55cSDimitry Andric if (isDwarfSect()) 123*349cc55cSDimitry Andric return false; 124*349cc55cSDimitry Andric assert(isCsect() && 125*349cc55cSDimitry Andric "Handling for isVirtualSection not implemented for this section!"); 126fe6060f1SDimitry Andric return XCOFF::XTY_CM == CsectProp->Type; 127fe6060f1SDimitry Andric } 128