aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCSectionXCOFF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/MC/MCSectionXCOFF.cpp')
-rw-r--r--llvm/lib/MC/MCSectionXCOFF.cpp63
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;
+}