xref: /freebsd-src/contrib/llvm-project/llvm/lib/MC/MCSectionCOFF.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- lib/MC/MCSectionCOFF.cpp - COFF 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/MCSectionCOFF.h"
100b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h"
110b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
120b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
130b57cec5SDimitry Andric #include <cassert>
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric using namespace llvm;
160b57cec5SDimitry Andric 
1781ad6265SDimitry Andric // shouldOmitSectionDirective - Decides whether a '.section' directive
180b57cec5SDimitry Andric // should be printed before the section name
1981ad6265SDimitry Andric bool MCSectionCOFF::shouldOmitSectionDirective(StringRef Name,
200b57cec5SDimitry Andric                                                const MCAsmInfo &MAI) const {
210b57cec5SDimitry Andric   if (COMDATSymbol)
220b57cec5SDimitry Andric     return false;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric   // FIXME: Does .section .bss/.data/.text work everywhere??
250b57cec5SDimitry Andric   if (Name == ".text" || Name == ".data" || Name == ".bss")
260b57cec5SDimitry Andric     return true;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric   return false;
290b57cec5SDimitry Andric }
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric void MCSectionCOFF::setSelection(int Selection) const {
320b57cec5SDimitry Andric   assert(Selection != 0 && "invalid COMDAT selection type");
330b57cec5SDimitry Andric   this->Selection = Selection;
340b57cec5SDimitry Andric   Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
350b57cec5SDimitry Andric }
360b57cec5SDimitry Andric 
3781ad6265SDimitry Andric void MCSectionCOFF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
380b57cec5SDimitry Andric                                          raw_ostream &OS,
39*0fca6ea1SDimitry Andric                                          uint32_t Subsection) const {
400b57cec5SDimitry Andric   // standard sections don't require the '.section'
4181ad6265SDimitry Andric   if (shouldOmitSectionDirective(getName(), MAI)) {
425ffd83dbSDimitry Andric     OS << '\t' << getName() << '\n';
430b57cec5SDimitry Andric     return;
440b57cec5SDimitry Andric   }
450b57cec5SDimitry Andric 
465ffd83dbSDimitry Andric   OS << "\t.section\t" << getName() << ",\"";
470b57cec5SDimitry Andric   if (getCharacteristics() & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)
480b57cec5SDimitry Andric     OS << 'd';
490b57cec5SDimitry Andric   if (getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)
500b57cec5SDimitry Andric     OS << 'b';
510b57cec5SDimitry Andric   if (getCharacteristics() & COFF::IMAGE_SCN_MEM_EXECUTE)
520b57cec5SDimitry Andric     OS << 'x';
530b57cec5SDimitry Andric   if (getCharacteristics() & COFF::IMAGE_SCN_MEM_WRITE)
540b57cec5SDimitry Andric     OS << 'w';
550b57cec5SDimitry Andric   else if (getCharacteristics() & COFF::IMAGE_SCN_MEM_READ)
560b57cec5SDimitry Andric     OS << 'r';
570b57cec5SDimitry Andric   else
580b57cec5SDimitry Andric     OS << 'y';
590b57cec5SDimitry Andric   if (getCharacteristics() & COFF::IMAGE_SCN_LNK_REMOVE)
600b57cec5SDimitry Andric     OS << 'n';
610b57cec5SDimitry Andric   if (getCharacteristics() & COFF::IMAGE_SCN_MEM_SHARED)
620b57cec5SDimitry Andric     OS << 's';
630b57cec5SDimitry Andric   if ((getCharacteristics() & COFF::IMAGE_SCN_MEM_DISCARDABLE) &&
645ffd83dbSDimitry Andric       !isImplicitlyDiscardable(getName()))
650b57cec5SDimitry Andric     OS << 'D';
66bdd1243dSDimitry Andric   if (getCharacteristics() & COFF::IMAGE_SCN_LNK_INFO)
67bdd1243dSDimitry Andric     OS << 'i';
680b57cec5SDimitry Andric   OS << '"';
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   if (getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
710b57cec5SDimitry Andric     if (COMDATSymbol)
720b57cec5SDimitry Andric       OS << ",";
730b57cec5SDimitry Andric     else
740b57cec5SDimitry Andric       OS << "\n\t.linkonce\t";
750b57cec5SDimitry Andric     switch (Selection) {
760b57cec5SDimitry Andric       case COFF::IMAGE_COMDAT_SELECT_NODUPLICATES:
770b57cec5SDimitry Andric         OS << "one_only";
780b57cec5SDimitry Andric         break;
790b57cec5SDimitry Andric       case COFF::IMAGE_COMDAT_SELECT_ANY:
800b57cec5SDimitry Andric         OS << "discard";
810b57cec5SDimitry Andric         break;
820b57cec5SDimitry Andric       case COFF::IMAGE_COMDAT_SELECT_SAME_SIZE:
830b57cec5SDimitry Andric         OS << "same_size";
840b57cec5SDimitry Andric         break;
850b57cec5SDimitry Andric       case COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH:
860b57cec5SDimitry Andric         OS << "same_contents";
870b57cec5SDimitry Andric         break;
880b57cec5SDimitry Andric       case COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE:
890b57cec5SDimitry Andric         OS << "associative";
900b57cec5SDimitry Andric         break;
910b57cec5SDimitry Andric       case COFF::IMAGE_COMDAT_SELECT_LARGEST:
920b57cec5SDimitry Andric         OS << "largest";
930b57cec5SDimitry Andric         break;
940b57cec5SDimitry Andric       case COFF::IMAGE_COMDAT_SELECT_NEWEST:
950b57cec5SDimitry Andric         OS << "newest";
960b57cec5SDimitry Andric         break;
970b57cec5SDimitry Andric       default:
980b57cec5SDimitry Andric         assert(false && "unsupported COFF selection type");
990b57cec5SDimitry Andric         break;
1000b57cec5SDimitry Andric     }
1010b57cec5SDimitry Andric     if (COMDATSymbol) {
1020b57cec5SDimitry Andric       OS << ",";
1030b57cec5SDimitry Andric       COMDATSymbol->print(OS, &MAI);
1040b57cec5SDimitry Andric     }
1050b57cec5SDimitry Andric   }
1060b57cec5SDimitry Andric   OS << '\n';
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
109*0fca6ea1SDimitry Andric bool MCSectionCOFF::useCodeAlign() const { return isText(); }
1105ffd83dbSDimitry Andric 
1115ffd83dbSDimitry Andric StringRef MCSectionCOFF::getVirtualSectionKind() const {
1125ffd83dbSDimitry Andric   return "IMAGE_SCN_CNT_UNINITIALIZED_DATA";
1135ffd83dbSDimitry Andric }
114