175 lines · cpp
1//===- MCAsmInfoCOFF.cpp - COFF asm properties ----------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines target asm properties related what form asm statements10// should take in general on COFF-based targets11//12//===----------------------------------------------------------------------===//13 14#include "llvm/MC/MCAsmInfoCOFF.h"15#include "llvm/BinaryFormat/COFF.h"16#include "llvm/MC/MCDirectives.h"17#include "llvm/MC/MCSection.h"18#include "llvm/MC/MCSectionCOFF.h"19#include "llvm/MC/MCSymbol.h"20#include "llvm/Support/raw_ostream.h"21#include <cassert>22 23using namespace llvm;24 25void MCAsmInfoCOFF::anchor() {}26 27MCAsmInfoCOFF::MCAsmInfoCOFF() {28 // MingW 4.5 and later support .comm with log2 alignment, but .lcomm uses byte29 // alignment.30 COMMDirectiveAlignmentIsInBytes = false;31 LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment;32 HasDotTypeDotSizeDirective = false;33 HasSingleParameterDotFile = true;34 WeakRefDirective = "\t.weak\t";35 AvoidWeakIfComdat = true;36 37 // Doesn't support visibility:38 HiddenVisibilityAttr = HiddenDeclarationVisibilityAttr = MCSA_Invalid;39 ProtectedVisibilityAttr = MCSA_Invalid;40 41 // Set up DWARF directives42 SupportsDebugInformation = true;43 NeedsDwarfSectionOffsetDirective = true;44 45 // At least MSVC inline-asm does AShr.46 UseLogicalShr = false;47 48 // If this is a COFF target, assume that it supports associative comdats. It's49 // part of the spec.50 HasCOFFAssociativeComdats = true;51 52 // We can generate constants in comdat sections that can be shared,53 // but in order not to create null typed symbols, we actually need to54 // make them global symbols as well.55 HasCOFFComdatConstants = true;56}57 58bool MCAsmInfoCOFF::useCodeAlign(const MCSection &Sec) const {59 return Sec.isText();60}61 62void MCAsmInfoMicrosoft::anchor() {}63 64MCAsmInfoMicrosoft::MCAsmInfoMicrosoft() = default;65 66void MCAsmInfoGNUCOFF::anchor() {}67 68MCAsmInfoGNUCOFF::MCAsmInfoGNUCOFF() {69 // If this is a GNU environment (mingw or cygwin), don't use associative70 // comdats for jump tables, unwind information, and other data associated with71 // a function.72 HasCOFFAssociativeComdats = false;73 74 // We don't create constants in comdat sections for MinGW.75 HasCOFFComdatConstants = false;76}77 78bool MCSectionCOFF::shouldOmitSectionDirective(StringRef Name) const {79 if (COMDATSymbol || isUnique())80 return false;81 82 // FIXME: Does .section .bss/.data/.text work everywhere??83 if (Name == ".text" || Name == ".data" || Name == ".bss")84 return true;85 86 return false;87}88 89void MCSectionCOFF::setSelection(int Selection) const {90 assert(Selection != 0 && "invalid COMDAT selection type");91 this->Selection = Selection;92 Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;93}94 95void MCAsmInfoCOFF::printSwitchToSection(const MCSection &Section, uint32_t,96 const Triple &T,97 raw_ostream &OS) const {98 auto &Sec = static_cast<const MCSectionCOFF &>(Section);99 // standard sections don't require the '.section'100 if (Sec.shouldOmitSectionDirective(Sec.getName())) {101 OS << '\t' << Sec.getName() << '\n';102 return;103 }104 105 OS << "\t.section\t" << Sec.getName() << ",\"";106 if (Sec.getCharacteristics() & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA)107 OS << 'd';108 if (Sec.getCharacteristics() & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA)109 OS << 'b';110 if (Sec.getCharacteristics() & COFF::IMAGE_SCN_MEM_EXECUTE)111 OS << 'x';112 if (Sec.getCharacteristics() & COFF::IMAGE_SCN_MEM_WRITE)113 OS << 'w';114 else if (Sec.getCharacteristics() & COFF::IMAGE_SCN_MEM_READ)115 OS << 'r';116 else117 OS << 'y';118 if (Sec.getCharacteristics() & COFF::IMAGE_SCN_LNK_REMOVE)119 OS << 'n';120 if (Sec.getCharacteristics() & COFF::IMAGE_SCN_MEM_SHARED)121 OS << 's';122 if ((Sec.getCharacteristics() & COFF::IMAGE_SCN_MEM_DISCARDABLE) &&123 !Sec.isImplicitlyDiscardable(Sec.getName()))124 OS << 'D';125 if (Sec.getCharacteristics() & COFF::IMAGE_SCN_LNK_INFO)126 OS << 'i';127 OS << '"';128 129 // unique should be tail of .section directive.130 if (Sec.isUnique() && !Sec.COMDATSymbol)131 OS << ",unique," << Sec.UniqueID;132 133 if (Sec.getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {134 if (Sec.COMDATSymbol)135 OS << ",";136 else137 OS << "\n\t.linkonce\t";138 switch (Sec.Selection) {139 case COFF::IMAGE_COMDAT_SELECT_NODUPLICATES:140 OS << "one_only";141 break;142 case COFF::IMAGE_COMDAT_SELECT_ANY:143 OS << "discard";144 break;145 case COFF::IMAGE_COMDAT_SELECT_SAME_SIZE:146 OS << "same_size";147 break;148 case COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH:149 OS << "same_contents";150 break;151 case COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE:152 OS << "associative";153 break;154 case COFF::IMAGE_COMDAT_SELECT_LARGEST:155 OS << "largest";156 break;157 case COFF::IMAGE_COMDAT_SELECT_NEWEST:158 OS << "newest";159 break;160 default:161 assert(false && "unsupported COFF selection type");162 break;163 }164 if (Sec.COMDATSymbol) {165 OS << ",";166 Sec.COMDATSymbol->print(OS, this);167 }168 }169 170 if (Sec.isUnique() && Sec.COMDATSymbol)171 OS << ",unique," << Sec.UniqueID;172 173 OS << '\n';174}175