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" 11fe6060f1SDimitry Andric #include "llvm/Support/Format.h" 120b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 13*81ad6265SDimitry Andric namespace llvm { 14*81ad6265SDimitry Andric class MCExpr; 15*81ad6265SDimitry Andric class Triple; 16*81ad6265SDimitry Andric } // namespace llvm 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric using namespace llvm; 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric MCSectionXCOFF::~MCSectionXCOFF() = default; 210b57cec5SDimitry Andric 225ffd83dbSDimitry Andric void MCSectionXCOFF::printCsectDirective(raw_ostream &OS) const { 235ffd83dbSDimitry Andric OS << "\t.csect " << QualName->getName() << "," << Log2_32(getAlignment()) 245ffd83dbSDimitry Andric << '\n'; 255ffd83dbSDimitry Andric } 268bcb0991SDimitry Andric 27*81ad6265SDimitry Andric void MCSectionXCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, 280b57cec5SDimitry Andric raw_ostream &OS, 290b57cec5SDimitry Andric const MCExpr *Subsection) const { 300b57cec5SDimitry Andric if (getKind().isText()) { 318bcb0991SDimitry Andric if (getMappingClass() != XCOFF::XMC_PR) 328bcb0991SDimitry Andric report_fatal_error("Unhandled storage-mapping class for .text csect"); 338bcb0991SDimitry Andric 345ffd83dbSDimitry Andric printCsectDirective(OS); 35480093f4SDimitry Andric return; 36480093f4SDimitry Andric } 37480093f4SDimitry Andric 38480093f4SDimitry Andric if (getKind().isReadOnly()) { 3904eeddc0SDimitry Andric if (getMappingClass() != XCOFF::XMC_RO && 4004eeddc0SDimitry Andric getMappingClass() != XCOFF::XMC_TD) 41480093f4SDimitry Andric report_fatal_error("Unhandled storage-mapping class for .rodata csect."); 425ffd83dbSDimitry Andric printCsectDirective(OS); 430b57cec5SDimitry Andric return; 440b57cec5SDimitry Andric } 450b57cec5SDimitry Andric 46fe6060f1SDimitry Andric // Initialized TLS data. 47fe6060f1SDimitry Andric if (getKind().isThreadData()) { 48fe6060f1SDimitry Andric // We only expect XMC_TL here for initialized TLS data. 49fe6060f1SDimitry Andric if (getMappingClass() != XCOFF::XMC_TL) 50fe6060f1SDimitry Andric report_fatal_error("Unhandled storage-mapping class for .tdata csect."); 51fe6060f1SDimitry Andric printCsectDirective(OS); 52fe6060f1SDimitry Andric return; 53fe6060f1SDimitry Andric } 54fe6060f1SDimitry Andric 558bcb0991SDimitry Andric if (getKind().isData()) { 568bcb0991SDimitry Andric switch (getMappingClass()) { 578bcb0991SDimitry Andric case XCOFF::XMC_RW: 588bcb0991SDimitry Andric case XCOFF::XMC_DS: 59fe6060f1SDimitry Andric case XCOFF::XMC_TD: 605ffd83dbSDimitry Andric printCsectDirective(OS); 61480093f4SDimitry Andric break; 62480093f4SDimitry Andric case XCOFF::XMC_TC: 63e8d8bef9SDimitry Andric case XCOFF::XMC_TE: 648bcb0991SDimitry Andric break; 658bcb0991SDimitry Andric case XCOFF::XMC_TC0: 668bcb0991SDimitry Andric OS << "\t.toc\n"; 678bcb0991SDimitry Andric break; 688bcb0991SDimitry Andric default: 698bcb0991SDimitry Andric report_fatal_error( 708bcb0991SDimitry Andric "Unhandled storage-mapping class for .data csect."); 718bcb0991SDimitry Andric } 728bcb0991SDimitry Andric return; 738bcb0991SDimitry Andric } 748bcb0991SDimitry Andric 75fe6060f1SDimitry Andric if (isCsect() && getMappingClass() == XCOFF::XMC_TD) { 7604eeddc0SDimitry Andric assert((getKind().isBSSExtern() || getKind().isBSSLocal() || 7704eeddc0SDimitry Andric getKind().isReadOnlyWithRel()) && 78fe6060f1SDimitry Andric "Unexepected section kind for toc-data"); 79fe6060f1SDimitry Andric printCsectDirective(OS); 80fe6060f1SDimitry Andric return; 81fe6060f1SDimitry Andric } 82fe6060f1SDimitry Andric // Common csect type (uninitialized storage) does not have to print csect 83fe6060f1SDimitry Andric // directive for section switching. 84fe6060f1SDimitry Andric if (isCsect() && getCSectType() == XCOFF::XTY_CM) { 858bcb0991SDimitry Andric assert((getMappingClass() == XCOFF::XMC_RW || 86fe6060f1SDimitry Andric getMappingClass() == XCOFF::XMC_BS || 87fe6060f1SDimitry Andric getMappingClass() == XCOFF::XMC_UL) && 88fe6060f1SDimitry Andric "Generated a storage-mapping class for a common/bss/tbss csect we " 89fe6060f1SDimitry Andric "don't " 908bcb0991SDimitry Andric "understand how to switch to."); 91fe6060f1SDimitry Andric // Common symbols and local zero-initialized symbols for TLS and Non-TLS are 92fe6060f1SDimitry Andric // eligible for .bss/.tbss csect, getKind().isThreadBSS() is used to cover 93fe6060f1SDimitry Andric // TLS common and zero-initialized local symbols since linkage type (in the 94fe6060f1SDimitry Andric // GlobalVariable) is not accessible in this class. 95fe6060f1SDimitry Andric assert((getKind().isBSSLocal() || getKind().isCommon() || 96fe6060f1SDimitry Andric getKind().isThreadBSS()) && 97fe6060f1SDimitry Andric "wrong symbol type for .bss/.tbss csect"); 98fe6060f1SDimitry Andric // Don't have to print a directive for switching to section for commons and 99fe6060f1SDimitry Andric // zero-initialized TLS data. The '.comm' and '.lcomm' directives of the 100fe6060f1SDimitry Andric // variable will create the needed csect. 101fe6060f1SDimitry Andric return; 102fe6060f1SDimitry Andric } 103fe6060f1SDimitry Andric 104fe6060f1SDimitry Andric // Zero-initialized TLS data with weak or external linkage are not eligible to 105fe6060f1SDimitry Andric // be put into common csect. 106fe6060f1SDimitry Andric if (getKind().isThreadBSS()) { 107fe6060f1SDimitry Andric printCsectDirective(OS); 108fe6060f1SDimitry Andric return; 109fe6060f1SDimitry Andric } 110fe6060f1SDimitry Andric 111fe6060f1SDimitry Andric // XCOFF debug sections. 112fe6060f1SDimitry Andric if (getKind().isMetadata() && isDwarfSect()) { 113fe6060f1SDimitry Andric OS << "\n\t.dwsect " 114fe6060f1SDimitry Andric << format("0x%" PRIx32, getDwarfSubtypeFlags().getValue()) << '\n'; 115fe6060f1SDimitry Andric OS << MAI.getPrivateLabelPrefix() << getName() << ':' << '\n'; 1168bcb0991SDimitry Andric return; 1178bcb0991SDimitry Andric } 1188bcb0991SDimitry Andric 1190b57cec5SDimitry Andric report_fatal_error("Printing for this SectionKind is unimplemented."); 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric 122*81ad6265SDimitry Andric bool MCSectionXCOFF::useCodeAlign() const { return getKind().isText(); } 1230b57cec5SDimitry Andric 124fe6060f1SDimitry Andric bool MCSectionXCOFF::isVirtualSection() const { 125349cc55cSDimitry Andric // DWARF sections are always not virtual. 126349cc55cSDimitry Andric if (isDwarfSect()) 127349cc55cSDimitry Andric return false; 128349cc55cSDimitry Andric assert(isCsect() && 129349cc55cSDimitry Andric "Handling for isVirtualSection not implemented for this section!"); 130fe6060f1SDimitry Andric return XCOFF::XTY_CM == CsectProp->Type; 131fe6060f1SDimitry Andric } 132