diff options
Diffstat (limited to 'llvm/lib/MC/MCSectionXCOFF.cpp')
-rw-r--r-- | llvm/lib/MC/MCSectionXCOFF.cpp | 63 |
1 files changed, 54 insertions, 9 deletions
diff --git a/llvm/lib/MC/MCSectionXCOFF.cpp b/llvm/lib/MC/MCSectionXCOFF.cpp index 17b7b60a04ab..648efc14da06 100644 --- a/llvm/lib/MC/MCSectionXCOFF.cpp +++ b/llvm/lib/MC/MCSectionXCOFF.cpp @@ -9,6 +9,8 @@ #include "llvm/MC/MCSectionXCOFF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCExpr.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -38,10 +40,20 @@ void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, 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: @@ -57,16 +69,46 @@ void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, return; } - if (getKind().isBSSLocal() || getKind().isCommon()) { + if (isCsect() && getMappingClass() == XCOFF::XMC_TD) { + assert((getKind().isBSSExtern() || getKind().isBSSLocal()) && + "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) && - "Generated a storage-mapping class for a common/bss csect we don't " + 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."); - assert(getCSectType() == XCOFF::XTY_CM && - "wrong csect type for .bss csect"); - // Don't have to print a directive for switching to section for commons. - // '.comm' and '.lcomm' directives for the variable will create the needed - // csect. + // 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().getValue()) << '\n'; + OS << MAI.getPrivateLabelPrefix() << getName() << ':' << '\n'; return; } @@ -75,4 +117,7 @@ void MCSectionXCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, bool MCSectionXCOFF::UseCodeAlign() const { return getKind().isText(); } -bool MCSectionXCOFF::isVirtualSection() const { return XCOFF::XTY_CM == Type; } +bool MCSectionXCOFF::isVirtualSection() const { + assert(isCsect() && "Only csect section can be virtual!"); + return XCOFF::XTY_CM == CsectProp->Type; +} |