| //===- lib/MC/MCSectionXCOFF.cpp - XCOFF Code Section Representation ------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/MC/MCSectionXCOFF.h" | |
| #include "llvm/MC/MCAsmInfo.h" | |
| #include "llvm/Support/Format.h" | |
| #include "llvm/Support/raw_ostream.h" | |
| namespace llvm { | |
| class MCExpr; | |
| class Triple; | |
| } // namespace llvm | |
| using namespace llvm; | |
| MCSectionXCOFF::~MCSectionXCOFF() = default; | |
| void MCSectionXCOFF::printCsectDirective(raw_ostream &OS) const { | |
| OS << "\t.csect " << QualName->getName() << "," << Log2(getAlign()) << '\n'; | |
| } | |
| void MCSectionXCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T, | |
| raw_ostream &OS, | |
| const MCExpr *Subsection) const { | |
| if (getKind().isText()) { | |
| if (getMappingClass() != XCOFF::XMC_PR) | |
| report_fatal_error("Unhandled storage-mapping class for .text csect"); | |
| printCsectDirective(OS); | |
| return; | |
| } | |
| if (getKind().isReadOnly()) { | |
| if (getMappingClass() != XCOFF::XMC_RO && | |
| getMappingClass() != XCOFF::XMC_TD) | |
| report_fatal_error("Unhandled storage-mapping class for .rodata csect."); | |
| printCsectDirective(OS); | |
| return; | |
| } | |
| // Initialized TLS data. | |
| if (getKind().isThreadData()) { | |
| // We only expect XMC_TL here for initialized TLS data. | |
| if (getMappingClass() != XCOFF::XMC_TL) | |
| report_fatal_error("Unhandled storage-mapping class for .tdata csect."); | |
| printCsectDirective(OS); | |
| return; | |
| } | |
| if (getKind().isData()) { | |
| switch (getMappingClass()) { | |
| case XCOFF::XMC_RW: | |
| case XCOFF::XMC_DS: | |
| case XCOFF::XMC_TD: | |
| printCsectDirective(OS); | |
| break; | |
| case XCOFF::XMC_TC: | |
| case XCOFF::XMC_TE: | |
| break; | |
| case XCOFF::XMC_TC0: | |
| OS << "\t.toc\n"; | |
| break; | |
| default: | |
| report_fatal_error( | |
| "Unhandled storage-mapping class for .data csect."); | |
| } | |
| return; | |
| } | |
| if (isCsect() && getMappingClass() == XCOFF::XMC_TD) { | |
| assert((getKind().isBSSExtern() || getKind().isBSSLocal() || | |
| getKind().isReadOnlyWithRel()) && | |
| "Unexepected section kind for toc-data"); | |
| printCsectDirective(OS); | |
| return; | |
| } | |
| // Common csect type (uninitialized storage) does not have to print csect | |
| // directive for section switching. | |
| if (isCsect() && getCSectType() == XCOFF::XTY_CM) { | |
| assert((getMappingClass() == XCOFF::XMC_RW || | |
| getMappingClass() == XCOFF::XMC_BS || | |
| getMappingClass() == XCOFF::XMC_UL) && | |
| "Generated a storage-mapping class for a common/bss/tbss csect we " | |
| "don't " | |
| "understand how to switch to."); | |
| // Common symbols and local zero-initialized symbols for TLS and Non-TLS are | |
| // eligible for .bss/.tbss csect, getKind().isThreadBSS() is used to cover | |
| // TLS common and zero-initialized local symbols since linkage type (in the | |
| // GlobalVariable) is not accessible in this class. | |
| assert((getKind().isBSSLocal() || getKind().isCommon() || | |
| getKind().isThreadBSS()) && | |
| "wrong symbol type for .bss/.tbss csect"); | |
| // Don't have to print a directive for switching to section for commons and | |
| // zero-initialized TLS data. The '.comm' and '.lcomm' directives of the | |
| // variable will create the needed csect. | |
| return; | |
| } | |
| // Zero-initialized TLS data with weak or external linkage are not eligible to | |
| // be put into common csect. | |
| if (getKind().isThreadBSS()) { | |
| printCsectDirective(OS); | |
| return; | |
| } | |
| // XCOFF debug sections. | |
| if (getKind().isMetadata() && isDwarfSect()) { | |
| OS << "\n\t.dwsect " << format("0x%" PRIx32, *getDwarfSubtypeFlags()) | |
| << '\n'; | |
| OS << MAI.getPrivateLabelPrefix() << getName() << ':' << '\n'; | |
| return; | |
| } | |
| report_fatal_error("Printing for this SectionKind is unimplemented."); | |
| } | |
| bool MCSectionXCOFF::useCodeAlign() const { return getKind().isText(); } | |
| bool MCSectionXCOFF::isVirtualSection() const { | |
| // DWARF sections are always not virtual. | |
| if (isDwarfSect()) | |
| return false; | |
| assert(isCsect() && | |
| "Handling for isVirtualSection not implemented for this section!"); | |
| return XCOFF::XTY_CM == CsectProp->Type; | |
| } |