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" 1381ad6265SDimitry Andric namespace llvm { 1481ad6265SDimitry Andric class MCExpr; 1581ad6265SDimitry Andric class Triple; 1681ad6265SDimitry 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 { 23bdd1243dSDimitry Andric OS << "\t.csect " << QualName->getName() << "," << Log2(getAlign()) << '\n'; 245ffd83dbSDimitry Andric } 258bcb0991SDimitry Andric 2681ad6265SDimitry Andric void MCSectionXCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, 270b57cec5SDimitry Andric raw_ostream &OS, 280b57cec5SDimitry Andric const MCExpr *Subsection) const { 290b57cec5SDimitry Andric if (getKind().isText()) { 308bcb0991SDimitry Andric if (getMappingClass() != XCOFF::XMC_PR) 318bcb0991SDimitry Andric report_fatal_error("Unhandled storage-mapping class for .text csect"); 328bcb0991SDimitry Andric 335ffd83dbSDimitry Andric printCsectDirective(OS); 34480093f4SDimitry Andric return; 35480093f4SDimitry Andric } 36480093f4SDimitry Andric 37480093f4SDimitry Andric if (getKind().isReadOnly()) { 3804eeddc0SDimitry Andric if (getMappingClass() != XCOFF::XMC_RO && 3904eeddc0SDimitry Andric getMappingClass() != XCOFF::XMC_TD) 40480093f4SDimitry Andric report_fatal_error("Unhandled storage-mapping class for .rodata csect."); 415ffd83dbSDimitry Andric printCsectDirective(OS); 420b57cec5SDimitry Andric return; 430b57cec5SDimitry Andric } 440b57cec5SDimitry Andric 45*5f757f3fSDimitry Andric if (getKind().isReadOnlyWithRel()) { 46*5f757f3fSDimitry Andric if (getMappingClass() != XCOFF::XMC_RW && 47*5f757f3fSDimitry Andric getMappingClass() != XCOFF::XMC_RO && 48*5f757f3fSDimitry Andric getMappingClass() != XCOFF::XMC_TD) 49*5f757f3fSDimitry Andric report_fatal_error( 50*5f757f3fSDimitry Andric "Unexepected storage-mapping class for ReadOnlyWithRel kind"); 51*5f757f3fSDimitry Andric printCsectDirective(OS); 52*5f757f3fSDimitry Andric return; 53*5f757f3fSDimitry Andric } 54*5f757f3fSDimitry Andric 55fe6060f1SDimitry Andric // Initialized TLS data. 56fe6060f1SDimitry Andric if (getKind().isThreadData()) { 57fe6060f1SDimitry Andric // We only expect XMC_TL here for initialized TLS data. 58fe6060f1SDimitry Andric if (getMappingClass() != XCOFF::XMC_TL) 59fe6060f1SDimitry Andric report_fatal_error("Unhandled storage-mapping class for .tdata csect."); 60fe6060f1SDimitry Andric printCsectDirective(OS); 61fe6060f1SDimitry Andric return; 62fe6060f1SDimitry Andric } 63fe6060f1SDimitry Andric 648bcb0991SDimitry Andric if (getKind().isData()) { 658bcb0991SDimitry Andric switch (getMappingClass()) { 668bcb0991SDimitry Andric case XCOFF::XMC_RW: 678bcb0991SDimitry Andric case XCOFF::XMC_DS: 68fe6060f1SDimitry Andric case XCOFF::XMC_TD: 695ffd83dbSDimitry Andric printCsectDirective(OS); 70480093f4SDimitry Andric break; 71480093f4SDimitry Andric case XCOFF::XMC_TC: 72e8d8bef9SDimitry Andric case XCOFF::XMC_TE: 738bcb0991SDimitry Andric break; 748bcb0991SDimitry Andric case XCOFF::XMC_TC0: 758bcb0991SDimitry Andric OS << "\t.toc\n"; 768bcb0991SDimitry Andric break; 778bcb0991SDimitry Andric default: 788bcb0991SDimitry Andric report_fatal_error( 798bcb0991SDimitry Andric "Unhandled storage-mapping class for .data csect."); 808bcb0991SDimitry Andric } 818bcb0991SDimitry Andric return; 828bcb0991SDimitry Andric } 838bcb0991SDimitry Andric 84fe6060f1SDimitry Andric if (isCsect() && getMappingClass() == XCOFF::XMC_TD) { 85*5f757f3fSDimitry Andric assert((getKind().isBSSExtern() || getKind().isBSSLocal()) && 86fe6060f1SDimitry Andric "Unexepected section kind for toc-data"); 87fe6060f1SDimitry Andric printCsectDirective(OS); 88fe6060f1SDimitry Andric return; 89fe6060f1SDimitry Andric } 90fe6060f1SDimitry Andric // Common csect type (uninitialized storage) does not have to print csect 91fe6060f1SDimitry Andric // directive for section switching. 92fe6060f1SDimitry Andric if (isCsect() && getCSectType() == XCOFF::XTY_CM) { 938bcb0991SDimitry Andric assert((getMappingClass() == XCOFF::XMC_RW || 94fe6060f1SDimitry Andric getMappingClass() == XCOFF::XMC_BS || 95fe6060f1SDimitry Andric getMappingClass() == XCOFF::XMC_UL) && 96fe6060f1SDimitry Andric "Generated a storage-mapping class for a common/bss/tbss csect we " 97fe6060f1SDimitry Andric "don't " 988bcb0991SDimitry Andric "understand how to switch to."); 99fe6060f1SDimitry Andric // Common symbols and local zero-initialized symbols for TLS and Non-TLS are 100fe6060f1SDimitry Andric // eligible for .bss/.tbss csect, getKind().isThreadBSS() is used to cover 101fe6060f1SDimitry Andric // TLS common and zero-initialized local symbols since linkage type (in the 102fe6060f1SDimitry Andric // GlobalVariable) is not accessible in this class. 103fe6060f1SDimitry Andric assert((getKind().isBSSLocal() || getKind().isCommon() || 104fe6060f1SDimitry Andric getKind().isThreadBSS()) && 105fe6060f1SDimitry Andric "wrong symbol type for .bss/.tbss csect"); 106fe6060f1SDimitry Andric // Don't have to print a directive for switching to section for commons and 107fe6060f1SDimitry Andric // zero-initialized TLS data. The '.comm' and '.lcomm' directives of the 108fe6060f1SDimitry Andric // variable will create the needed csect. 109fe6060f1SDimitry Andric return; 110fe6060f1SDimitry Andric } 111fe6060f1SDimitry Andric 112fe6060f1SDimitry Andric // Zero-initialized TLS data with weak or external linkage are not eligible to 113fe6060f1SDimitry Andric // be put into common csect. 114fe6060f1SDimitry Andric if (getKind().isThreadBSS()) { 115fe6060f1SDimitry Andric printCsectDirective(OS); 116fe6060f1SDimitry Andric return; 117fe6060f1SDimitry Andric } 118fe6060f1SDimitry Andric 119fe6060f1SDimitry Andric // XCOFF debug sections. 120fe6060f1SDimitry Andric if (getKind().isMetadata() && isDwarfSect()) { 121bdd1243dSDimitry Andric OS << "\n\t.dwsect " << format("0x%" PRIx32, *getDwarfSubtypeFlags()) 122753f127fSDimitry Andric << '\n'; 123fe6060f1SDimitry Andric OS << MAI.getPrivateLabelPrefix() << getName() << ':' << '\n'; 1248bcb0991SDimitry Andric return; 1258bcb0991SDimitry Andric } 1268bcb0991SDimitry Andric 1270b57cec5SDimitry Andric report_fatal_error("Printing for this SectionKind is unimplemented."); 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 13081ad6265SDimitry Andric bool MCSectionXCOFF::useCodeAlign() const { return getKind().isText(); } 1310b57cec5SDimitry Andric 132fe6060f1SDimitry Andric bool MCSectionXCOFF::isVirtualSection() const { 133349cc55cSDimitry Andric // DWARF sections are always not virtual. 134349cc55cSDimitry Andric if (isDwarfSect()) 135349cc55cSDimitry Andric return false; 136349cc55cSDimitry Andric assert(isCsect() && 137349cc55cSDimitry Andric "Handling for isVirtualSection not implemented for this section!"); 138fe6060f1SDimitry Andric return XCOFF::XTY_CM == CsectProp->Type; 139fe6060f1SDimitry Andric } 140