17330f729Sjoerg //===- lib/MC/MCSectionCOFF.cpp - COFF Code Section Representation --------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg
97330f729Sjoerg #include "llvm/MC/MCSectionCOFF.h"
107330f729Sjoerg #include "llvm/BinaryFormat/COFF.h"
117330f729Sjoerg #include "llvm/MC/MCSymbol.h"
127330f729Sjoerg #include "llvm/Support/raw_ostream.h"
137330f729Sjoerg #include <cassert>
147330f729Sjoerg
157330f729Sjoerg using namespace llvm;
167330f729Sjoerg
177330f729Sjoerg // ShouldOmitSectionDirective - Decides whether a '.section' directive
187330f729Sjoerg // should be printed before the section name
ShouldOmitSectionDirective(StringRef Name,const MCAsmInfo & MAI) const197330f729Sjoerg bool MCSectionCOFF::ShouldOmitSectionDirective(StringRef Name,
207330f729Sjoerg const MCAsmInfo &MAI) const {
217330f729Sjoerg if (COMDATSymbol)
227330f729Sjoerg return false;
237330f729Sjoerg
247330f729Sjoerg // FIXME: Does .section .bss/.data/.text work everywhere??
257330f729Sjoerg if (Name == ".text" || Name == ".data" || Name == ".bss")
267330f729Sjoerg return true;
277330f729Sjoerg
287330f729Sjoerg return false;
297330f729Sjoerg }
307330f729Sjoerg
setSelection(int Selection) const317330f729Sjoerg void MCSectionCOFF::setSelection(int Selection) const {
327330f729Sjoerg assert(Selection != 0 && "invalid COMDAT selection type");
337330f729Sjoerg this->Selection = Selection;
347330f729Sjoerg Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
357330f729Sjoerg }
367330f729Sjoerg
PrintSwitchToSection(const MCAsmInfo & MAI,const Triple & T,raw_ostream & OS,const MCExpr * Subsection) const377330f729Sjoerg void MCSectionCOFF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
387330f729Sjoerg raw_ostream &OS,
397330f729Sjoerg const MCExpr *Subsection) const {
407330f729Sjoerg // standard sections don't require the '.section'
41*82d56013Sjoerg if (ShouldOmitSectionDirective(getName(), MAI)) {
42*82d56013Sjoerg OS << '\t' << getName() << '\n';
437330f729Sjoerg return;
447330f729Sjoerg }
457330f729Sjoerg
46*82d56013Sjoerg OS << "\t.section\t" << getName() << ",\"";
477330f729Sjoerg if (getCharacteristics() & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
487330f729Sjoerg OS << 'd';
497330f729Sjoerg if (getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
507330f729Sjoerg OS << 'b';
517330f729Sjoerg if (getCharacteristics() & COFF::IMAGE_SCN_MEM_EXECUTE)
527330f729Sjoerg OS << 'x';
537330f729Sjoerg if (getCharacteristics() & COFF::IMAGE_SCN_MEM_WRITE)
547330f729Sjoerg OS << 'w';
557330f729Sjoerg else if (getCharacteristics() & COFF::IMAGE_SCN_MEM_READ)
567330f729Sjoerg OS << 'r';
577330f729Sjoerg else
587330f729Sjoerg OS << 'y';
597330f729Sjoerg if (getCharacteristics() & COFF::IMAGE_SCN_LNK_REMOVE)
607330f729Sjoerg OS << 'n';
617330f729Sjoerg if (getCharacteristics() & COFF::IMAGE_SCN_MEM_SHARED)
627330f729Sjoerg OS << 's';
637330f729Sjoerg if ((getCharacteristics() & COFF::IMAGE_SCN_MEM_DISCARDABLE) &&
64*82d56013Sjoerg !isImplicitlyDiscardable(getName()))
657330f729Sjoerg OS << 'D';
667330f729Sjoerg OS << '"';
677330f729Sjoerg
687330f729Sjoerg if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
697330f729Sjoerg if (COMDATSymbol)
707330f729Sjoerg OS << ",";
717330f729Sjoerg else
727330f729Sjoerg OS << "\n\t.linkonce\t";
737330f729Sjoerg switch (Selection) {
747330f729Sjoerg case COFF::IMAGE_COMDAT_SELECT_NODUPLICATES:
757330f729Sjoerg OS << "one_only";
767330f729Sjoerg break;
777330f729Sjoerg case COFF::IMAGE_COMDAT_SELECT_ANY:
787330f729Sjoerg OS << "discard";
797330f729Sjoerg break;
807330f729Sjoerg case COFF::IMAGE_COMDAT_SELECT_SAME_SIZE:
817330f729Sjoerg OS << "same_size";
827330f729Sjoerg break;
837330f729Sjoerg case COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH:
847330f729Sjoerg OS << "same_contents";
857330f729Sjoerg break;
867330f729Sjoerg case COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE:
877330f729Sjoerg OS << "associative";
887330f729Sjoerg break;
897330f729Sjoerg case COFF::IMAGE_COMDAT_SELECT_LARGEST:
907330f729Sjoerg OS << "largest";
917330f729Sjoerg break;
927330f729Sjoerg case COFF::IMAGE_COMDAT_SELECT_NEWEST:
937330f729Sjoerg OS << "newest";
947330f729Sjoerg break;
957330f729Sjoerg default:
967330f729Sjoerg assert(false && "unsupported COFF selection type");
977330f729Sjoerg break;
987330f729Sjoerg }
997330f729Sjoerg if (COMDATSymbol) {
1007330f729Sjoerg OS << ",";
1017330f729Sjoerg COMDATSymbol->print(OS, &MAI);
1027330f729Sjoerg }
1037330f729Sjoerg }
1047330f729Sjoerg OS << '\n';
1057330f729Sjoerg }
1067330f729Sjoerg
UseCodeAlign() const1077330f729Sjoerg bool MCSectionCOFF::UseCodeAlign() const {
1087330f729Sjoerg return getKind().isText();
1097330f729Sjoerg }
1107330f729Sjoerg
isVirtualSection() const1117330f729Sjoerg bool MCSectionCOFF::isVirtualSection() const {
1127330f729Sjoerg return getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA;
1137330f729Sjoerg }
114*82d56013Sjoerg
getVirtualSectionKind() const115*82d56013Sjoerg StringRef MCSectionCOFF::getVirtualSectionKind() const {
116*82d56013Sjoerg return "IMAGE_SCN_CNT_UNINITIALIZED_DATA";
117*82d56013Sjoerg }
118