Path: blob/main/contrib/llvm-project/llvm/lib/MC/MCContext.cpp
35234 views
//===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/MC/MCContext.h"9#include "llvm/ADT/SmallString.h"10#include "llvm/ADT/SmallVector.h"11#include "llvm/ADT/StringMap.h"12#include "llvm/ADT/StringRef.h"13#include "llvm/ADT/Twine.h"14#include "llvm/BinaryFormat/COFF.h"15#include "llvm/BinaryFormat/ELF.h"16#include "llvm/BinaryFormat/Wasm.h"17#include "llvm/BinaryFormat/XCOFF.h"18#include "llvm/MC/MCAsmInfo.h"19#include "llvm/MC/MCCodeView.h"20#include "llvm/MC/MCDwarf.h"21#include "llvm/MC/MCExpr.h"22#include "llvm/MC/MCFragment.h"23#include "llvm/MC/MCInst.h"24#include "llvm/MC/MCLabel.h"25#include "llvm/MC/MCSectionCOFF.h"26#include "llvm/MC/MCSectionDXContainer.h"27#include "llvm/MC/MCSectionELF.h"28#include "llvm/MC/MCSectionGOFF.h"29#include "llvm/MC/MCSectionMachO.h"30#include "llvm/MC/MCSectionSPIRV.h"31#include "llvm/MC/MCSectionWasm.h"32#include "llvm/MC/MCSectionXCOFF.h"33#include "llvm/MC/MCStreamer.h"34#include "llvm/MC/MCSubtargetInfo.h"35#include "llvm/MC/MCSymbol.h"36#include "llvm/MC/MCSymbolCOFF.h"37#include "llvm/MC/MCSymbolELF.h"38#include "llvm/MC/MCSymbolGOFF.h"39#include "llvm/MC/MCSymbolMachO.h"40#include "llvm/MC/MCSymbolWasm.h"41#include "llvm/MC/MCSymbolXCOFF.h"42#include "llvm/MC/MCTargetOptions.h"43#include "llvm/MC/SectionKind.h"44#include "llvm/Support/Casting.h"45#include "llvm/Support/CommandLine.h"46#include "llvm/Support/EndianStream.h"47#include "llvm/Support/ErrorHandling.h"48#include "llvm/Support/MemoryBuffer.h"49#include "llvm/Support/Path.h"50#include "llvm/Support/SMLoc.h"51#include "llvm/Support/SourceMgr.h"52#include "llvm/Support/raw_ostream.h"53#include <cassert>54#include <cstdlib>55#include <optional>56#include <tuple>57#include <utility>5859using namespace llvm;6061static void defaultDiagHandler(const SMDiagnostic &SMD, bool, const SourceMgr &,62std::vector<const MDNode *> &) {63SMD.print(nullptr, errs());64}6566MCContext::MCContext(const Triple &TheTriple, const MCAsmInfo *mai,67const MCRegisterInfo *mri, const MCSubtargetInfo *msti,68const SourceMgr *mgr, MCTargetOptions const *TargetOpts,69bool DoAutoReset, StringRef Swift5ReflSegmentName)70: Swift5ReflectionSegmentName(Swift5ReflSegmentName), TT(TheTriple),71SrcMgr(mgr), InlineSrcMgr(nullptr), DiagHandler(defaultDiagHandler),72MAI(mai), MRI(mri), MSTI(msti), Symbols(Allocator),73InlineAsmUsedLabelNames(Allocator),74CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0),75AutoReset(DoAutoReset), TargetOptions(TargetOpts) {76SaveTempLabels = TargetOptions && TargetOptions->MCSaveTempLabels;77SecureLogFile = TargetOptions ? TargetOptions->AsSecureLogFile : "";7879if (SrcMgr && SrcMgr->getNumBuffers())80MainFileName = std::string(SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())81->getBufferIdentifier());8283switch (TheTriple.getObjectFormat()) {84case Triple::MachO:85Env = IsMachO;86break;87case Triple::COFF:88if (!TheTriple.isOSWindows() && !TheTriple.isUEFI())89report_fatal_error(90"Cannot initialize MC for non-Windows COFF object files.");9192Env = IsCOFF;93break;94case Triple::ELF:95Env = IsELF;96break;97case Triple::Wasm:98Env = IsWasm;99break;100case Triple::XCOFF:101Env = IsXCOFF;102break;103case Triple::GOFF:104Env = IsGOFF;105break;106case Triple::DXContainer:107Env = IsDXContainer;108break;109case Triple::SPIRV:110Env = IsSPIRV;111break;112case Triple::UnknownObjectFormat:113report_fatal_error("Cannot initialize MC for unknown object file format.");114break;115}116}117118MCContext::~MCContext() {119if (AutoReset)120reset();121122// NOTE: The symbols are all allocated out of a bump pointer allocator,123// we don't need to free them here.124}125126void MCContext::initInlineSourceManager() {127if (!InlineSrcMgr)128InlineSrcMgr.reset(new SourceMgr());129}130131//===----------------------------------------------------------------------===//132// Module Lifetime Management133//===----------------------------------------------------------------------===//134135void MCContext::reset() {136SrcMgr = nullptr;137InlineSrcMgr.reset();138LocInfos.clear();139DiagHandler = defaultDiagHandler;140141// Call the destructors so the fragments are freed142COFFAllocator.DestroyAll();143DXCAllocator.DestroyAll();144ELFAllocator.DestroyAll();145GOFFAllocator.DestroyAll();146MachOAllocator.DestroyAll();147WasmAllocator.DestroyAll();148XCOFFAllocator.DestroyAll();149MCInstAllocator.DestroyAll();150SPIRVAllocator.DestroyAll();151WasmSignatureAllocator.DestroyAll();152153// ~CodeViewContext may destroy a MCFragment outside of sections and need to154// be reset before FragmentAllocator.155CVContext.reset();156157MCSubtargetAllocator.DestroyAll();158InlineAsmUsedLabelNames.clear();159Symbols.clear();160Allocator.Reset();161FragmentAllocator.Reset();162Instances.clear();163CompilationDir.clear();164MainFileName.clear();165MCDwarfLineTablesCUMap.clear();166SectionsForRanges.clear();167MCGenDwarfLabelEntries.clear();168DwarfDebugFlags = StringRef();169DwarfCompileUnitID = 0;170CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0);171172MachOUniquingMap.clear();173ELFUniquingMap.clear();174GOFFUniquingMap.clear();175COFFUniquingMap.clear();176WasmUniquingMap.clear();177XCOFFUniquingMap.clear();178DXCUniquingMap.clear();179180ELFEntrySizeMap.clear();181ELFSeenGenericMergeableSections.clear();182183DwarfLocSeen = false;184GenDwarfForAssembly = false;185GenDwarfFileNumber = 0;186187HadError = false;188}189190//===----------------------------------------------------------------------===//191// MCInst Management192//===----------------------------------------------------------------------===//193194MCInst *MCContext::createMCInst() {195return new (MCInstAllocator.Allocate()) MCInst;196}197198// Allocate the initial MCDataFragment for the begin symbol.199MCDataFragment *MCContext::allocInitialFragment(MCSection &Sec) {200assert(!Sec.curFragList()->Head);201auto *F = allocFragment<MCDataFragment>();202F->setParent(&Sec);203Sec.curFragList()->Head = F;204Sec.curFragList()->Tail = F;205return F;206}207208//===----------------------------------------------------------------------===//209// Symbol Manipulation210//===----------------------------------------------------------------------===//211212MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) {213SmallString<128> NameSV;214StringRef NameRef = Name.toStringRef(NameSV);215216assert(!NameRef.empty() && "Normal symbols cannot be unnamed!");217218MCSymbolTableEntry &Entry = getSymbolTableEntry(NameRef);219if (!Entry.second.Symbol) {220bool IsRenamable = NameRef.starts_with(MAI->getPrivateGlobalPrefix());221bool IsTemporary = IsRenamable && !SaveTempLabels;222if (!Entry.second.Used) {223Entry.second.Used = true;224Entry.second.Symbol = createSymbolImpl(&Entry, IsTemporary);225} else {226assert(IsRenamable && "cannot rename non-private symbol");227// Slow path: we need to rename a temp symbol from the user.228Entry.second.Symbol = createRenamableSymbol(NameRef, false, IsTemporary);229}230}231232return Entry.second.Symbol;233}234235MCSymbol *MCContext::getOrCreateFrameAllocSymbol(const Twine &FuncName,236unsigned Idx) {237return getOrCreateSymbol(MAI->getPrivateGlobalPrefix() + FuncName +238"$frame_escape_" + Twine(Idx));239}240241MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(const Twine &FuncName) {242return getOrCreateSymbol(MAI->getPrivateGlobalPrefix() + FuncName +243"$parent_frame_offset");244}245246MCSymbol *MCContext::getOrCreateLSDASymbol(const Twine &FuncName) {247return getOrCreateSymbol(MAI->getPrivateGlobalPrefix() + "__ehtable$" +248FuncName);249}250251MCSymbolTableEntry &MCContext::getSymbolTableEntry(StringRef Name) {252return *Symbols.try_emplace(Name, MCSymbolTableValue{}).first;253}254255MCSymbol *MCContext::createSymbolImpl(const MCSymbolTableEntry *Name,256bool IsTemporary) {257static_assert(std::is_trivially_destructible<MCSymbolCOFF>(),258"MCSymbol classes must be trivially destructible");259static_assert(std::is_trivially_destructible<MCSymbolELF>(),260"MCSymbol classes must be trivially destructible");261static_assert(std::is_trivially_destructible<MCSymbolMachO>(),262"MCSymbol classes must be trivially destructible");263static_assert(std::is_trivially_destructible<MCSymbolWasm>(),264"MCSymbol classes must be trivially destructible");265static_assert(std::is_trivially_destructible<MCSymbolXCOFF>(),266"MCSymbol classes must be trivially destructible");267268switch (getObjectFileType()) {269case MCContext::IsCOFF:270return new (Name, *this) MCSymbolCOFF(Name, IsTemporary);271case MCContext::IsELF:272return new (Name, *this) MCSymbolELF(Name, IsTemporary);273case MCContext::IsGOFF:274return new (Name, *this) MCSymbolGOFF(Name, IsTemporary);275case MCContext::IsMachO:276return new (Name, *this) MCSymbolMachO(Name, IsTemporary);277case MCContext::IsWasm:278return new (Name, *this) MCSymbolWasm(Name, IsTemporary);279case MCContext::IsXCOFF:280return createXCOFFSymbolImpl(Name, IsTemporary);281case MCContext::IsDXContainer:282break;283case MCContext::IsSPIRV:284return new (Name, *this)285MCSymbol(MCSymbol::SymbolKindUnset, Name, IsTemporary);286}287return new (Name, *this)288MCSymbol(MCSymbol::SymbolKindUnset, Name, IsTemporary);289}290291MCSymbol *MCContext::createRenamableSymbol(const Twine &Name,292bool AlwaysAddSuffix,293bool IsTemporary) {294SmallString<128> NewName;295Name.toVector(NewName);296size_t NameLen = NewName.size();297298MCSymbolTableEntry &NameEntry = getSymbolTableEntry(NewName.str());299MCSymbolTableEntry *EntryPtr = &NameEntry;300while (AlwaysAddSuffix || EntryPtr->second.Used) {301AlwaysAddSuffix = false;302303NewName.resize(NameLen);304raw_svector_ostream(NewName) << NameEntry.second.NextUniqueID++;305EntryPtr = &getSymbolTableEntry(NewName.str());306}307308EntryPtr->second.Used = true;309return createSymbolImpl(EntryPtr, IsTemporary);310}311312MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix) {313if (!UseNamesOnTempLabels)314return createSymbolImpl(nullptr, /*IsTemporary=*/true);315return createRenamableSymbol(MAI->getPrivateGlobalPrefix() + Name,316AlwaysAddSuffix, /*IsTemporary=*/true);317}318319MCSymbol *MCContext::createNamedTempSymbol(const Twine &Name) {320return createRenamableSymbol(MAI->getPrivateGlobalPrefix() + Name, true,321/*IsTemporary=*/!SaveTempLabels);322}323324MCSymbol *MCContext::createBlockSymbol(const Twine &Name, bool AlwaysEmit) {325if (AlwaysEmit)326return getOrCreateSymbol(MAI->getPrivateLabelPrefix() + Name);327328bool IsTemporary = !SaveTempLabels;329if (IsTemporary && !UseNamesOnTempLabels)330return createSymbolImpl(nullptr, IsTemporary);331return createRenamableSymbol(MAI->getPrivateLabelPrefix() + Name,332/*AlwaysAddSuffix=*/false, IsTemporary);333}334335MCSymbol *MCContext::createLinkerPrivateTempSymbol() {336return createLinkerPrivateSymbol("tmp");337}338339MCSymbol *MCContext::createLinkerPrivateSymbol(const Twine &Name) {340return createRenamableSymbol(MAI->getLinkerPrivateGlobalPrefix() + Name,341/*AlwaysAddSuffix=*/true,342/*IsTemporary=*/false);343}344345MCSymbol *MCContext::createTempSymbol() { return createTempSymbol("tmp"); }346347MCSymbol *MCContext::createNamedTempSymbol() {348return createNamedTempSymbol("tmp");349}350351MCSymbol *MCContext::createLocalSymbol(StringRef Name) {352MCSymbolTableEntry &NameEntry = getSymbolTableEntry(Name);353return createSymbolImpl(&NameEntry, /*IsTemporary=*/false);354}355356unsigned MCContext::NextInstance(unsigned LocalLabelVal) {357MCLabel *&Label = Instances[LocalLabelVal];358if (!Label)359Label = new (*this) MCLabel(0);360return Label->incInstance();361}362363unsigned MCContext::GetInstance(unsigned LocalLabelVal) {364MCLabel *&Label = Instances[LocalLabelVal];365if (!Label)366Label = new (*this) MCLabel(0);367return Label->getInstance();368}369370MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,371unsigned Instance) {372MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)];373if (!Sym)374Sym = createNamedTempSymbol();375return Sym;376}377378MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) {379unsigned Instance = NextInstance(LocalLabelVal);380return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);381}382383MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal,384bool Before) {385unsigned Instance = GetInstance(LocalLabelVal);386if (!Before)387++Instance;388return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);389}390391template <typename Symbol>392Symbol *MCContext::getOrCreateSectionSymbol(StringRef Section) {393Symbol *R;394auto &SymEntry = getSymbolTableEntry(Section);395MCSymbol *Sym = SymEntry.second.Symbol;396// A section symbol can not redefine regular symbols. There may be multiple397// sections with the same name, in which case the first such section wins.398if (Sym && Sym->isDefined() &&399(!Sym->isInSection() || Sym->getSection().getBeginSymbol() != Sym))400reportError(SMLoc(), "invalid symbol redefinition");401if (Sym && Sym->isUndefined()) {402R = cast<Symbol>(Sym);403} else {404SymEntry.second.Used = true;405R = new (&SymEntry, *this) Symbol(&SymEntry, /*isTemporary=*/false);406if (!Sym)407SymEntry.second.Symbol = R;408}409return R;410}411412MCSymbol *MCContext::lookupSymbol(const Twine &Name) const {413SmallString<128> NameSV;414StringRef NameRef = Name.toStringRef(NameSV);415return Symbols.lookup(NameRef).Symbol;416}417418void MCContext::setSymbolValue(MCStreamer &Streamer, const Twine &Sym,419uint64_t Val) {420auto Symbol = getOrCreateSymbol(Sym);421Streamer.emitAssignment(Symbol, MCConstantExpr::create(Val, *this));422}423424void MCContext::registerInlineAsmLabel(MCSymbol *Sym) {425InlineAsmUsedLabelNames[Sym->getName()] = Sym;426}427428wasm::WasmSignature *MCContext::createWasmSignature() {429return new (WasmSignatureAllocator.Allocate()) wasm::WasmSignature;430}431432MCSymbolXCOFF *MCContext::createXCOFFSymbolImpl(const MCSymbolTableEntry *Name,433bool IsTemporary) {434if (!Name)435return new (nullptr, *this) MCSymbolXCOFF(nullptr, IsTemporary);436437StringRef OriginalName = Name->first();438if (OriginalName.starts_with("._Renamed..") ||439OriginalName.starts_with("_Renamed.."))440reportError(SMLoc(), "invalid symbol name from source");441442if (MAI->isValidUnquotedName(OriginalName))443return new (Name, *this) MCSymbolXCOFF(Name, IsTemporary);444445// Now we have a name that contains invalid character(s) for XCOFF symbol.446// Let's replace with something valid, but save the original name so that447// we could still use the original name in the symbol table.448SmallString<128> InvalidName(OriginalName);449450// If it's an entry point symbol, we will keep the '.'451// in front for the convention purpose. Otherwise, add "_Renamed.."452// as prefix to signal this is an renamed symbol.453const bool IsEntryPoint = InvalidName.starts_with(".");454SmallString<128> ValidName =455StringRef(IsEntryPoint ? "._Renamed.." : "_Renamed..");456457// Append the hex values of '_' and invalid characters with "_Renamed..";458// at the same time replace invalid characters with '_'.459for (size_t I = 0; I < InvalidName.size(); ++I) {460if (!MAI->isAcceptableChar(InvalidName[I]) || InvalidName[I] == '_') {461raw_svector_ostream(ValidName).write_hex(InvalidName[I]);462InvalidName[I] = '_';463}464}465466// Skip entry point symbol's '.' as we already have a '.' in front of467// "_Renamed".468if (IsEntryPoint)469ValidName.append(InvalidName.substr(1, InvalidName.size() - 1));470else471ValidName.append(InvalidName);472473MCSymbolTableEntry &NameEntry = getSymbolTableEntry(ValidName.str());474assert(!NameEntry.second.Used && "This name is used somewhere else.");475NameEntry.second.Used = true;476// Have the MCSymbol object itself refer to the copy of the string477// that is embedded in the symbol table entry.478MCSymbolXCOFF *XSym =479new (&NameEntry, *this) MCSymbolXCOFF(&NameEntry, IsTemporary);480XSym->setSymbolTableName(MCSymbolXCOFF::getUnqualifiedName(OriginalName));481return XSym;482}483484//===----------------------------------------------------------------------===//485// Section Management486//===----------------------------------------------------------------------===//487488MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,489unsigned TypeAndAttributes,490unsigned Reserved2, SectionKind Kind,491const char *BeginSymName) {492// We unique sections by their segment/section pair. The returned section493// may not have the same flags as the requested section, if so this should be494// diagnosed by the client as an error.495496// Form the name to look up.497assert(Section.size() <= 16 && "section name is too long");498assert(!memchr(Section.data(), '\0', Section.size()) &&499"section name cannot contain NUL");500501// Do the lookup, if we have a hit, return it.502auto R = MachOUniquingMap.try_emplace((Segment + Twine(',') + Section).str());503if (!R.second)504return R.first->second;505506MCSymbol *Begin = nullptr;507if (BeginSymName)508Begin = createTempSymbol(BeginSymName, false);509510// Otherwise, return a new section.511StringRef Name = R.first->first();512auto *Ret = new (MachOAllocator.Allocate())513MCSectionMachO(Segment, Name.substr(Name.size() - Section.size()),514TypeAndAttributes, Reserved2, Kind, Begin);515R.first->second = Ret;516allocInitialFragment(*Ret);517return Ret;518}519520MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,521unsigned Flags,522unsigned EntrySize,523const MCSymbolELF *Group,524bool Comdat, unsigned UniqueID,525const MCSymbolELF *LinkedToSym) {526auto *R = getOrCreateSectionSymbol<MCSymbolELF>(Section);527R->setBinding(ELF::STB_LOCAL);528R->setType(ELF::STT_SECTION);529530auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF(531Section, Type, Flags, EntrySize, Group, Comdat, UniqueID, R, LinkedToSym);532533auto *F = allocInitialFragment(*Ret);534R->setFragment(F);535return Ret;536}537538MCSectionELF *539MCContext::createELFRelSection(const Twine &Name, unsigned Type, unsigned Flags,540unsigned EntrySize, const MCSymbolELF *Group,541const MCSectionELF *RelInfoSection) {542StringMap<bool>::iterator I;543bool Inserted;544std::tie(I, Inserted) = RelSecNames.insert(std::make_pair(Name.str(), true));545546return createELFSectionImpl(547I->getKey(), Type, Flags, EntrySize, Group, true, true,548cast<MCSymbolELF>(RelInfoSection->getBeginSymbol()));549}550551MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,552const Twine &Suffix, unsigned Type,553unsigned Flags,554unsigned EntrySize) {555return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix,556/*IsComdat=*/true);557}558559MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,560unsigned Flags, unsigned EntrySize,561const Twine &Group, bool IsComdat,562unsigned UniqueID,563const MCSymbolELF *LinkedToSym) {564MCSymbolELF *GroupSym = nullptr;565if (!Group.isTriviallyEmpty() && !Group.str().empty())566GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));567568return getELFSection(Section, Type, Flags, EntrySize, GroupSym, IsComdat,569UniqueID, LinkedToSym);570}571572MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,573unsigned Flags, unsigned EntrySize,574const MCSymbolELF *GroupSym,575bool IsComdat, unsigned UniqueID,576const MCSymbolELF *LinkedToSym) {577StringRef Group = "";578if (GroupSym)579Group = GroupSym->getName();580assert(!(LinkedToSym && LinkedToSym->getName().empty()));581582// Sections are differentiated by the quadruple (section_name, group_name,583// unique_id, link_to_symbol_name). Sections sharing the same quadruple are584// combined into one section. As an optimization, non-unique sections without585// group or linked-to symbol have a shorter unique-ing key.586std::pair<StringMap<MCSectionELF *>::iterator, bool> EntryNewPair;587// Length of the section name, which are the first SectionLen bytes of the key588unsigned SectionLen;589if (GroupSym || LinkedToSym || UniqueID != MCSection::NonUniqueID) {590SmallString<128> Buffer;591Section.toVector(Buffer);592SectionLen = Buffer.size();593Buffer.push_back(0); // separator which cannot occur in the name594if (GroupSym)595Buffer.append(GroupSym->getName());596Buffer.push_back(0); // separator which cannot occur in the name597if (LinkedToSym)598Buffer.append(LinkedToSym->getName());599support::endian::write(Buffer, UniqueID, endianness::native);600StringRef UniqueMapKey = StringRef(Buffer);601EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));602} else if (!Section.isSingleStringRef()) {603SmallString<128> Buffer;604StringRef UniqueMapKey = Section.toStringRef(Buffer);605SectionLen = UniqueMapKey.size();606EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));607} else {608StringRef UniqueMapKey = Section.getSingleStringRef();609SectionLen = UniqueMapKey.size();610EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));611}612613if (!EntryNewPair.second)614return EntryNewPair.first->second;615616StringRef CachedName = EntryNewPair.first->getKey().take_front(SectionLen);617618MCSectionELF *Result =619createELFSectionImpl(CachedName, Type, Flags, EntrySize, GroupSym,620IsComdat, UniqueID, LinkedToSym);621EntryNewPair.first->second = Result;622623recordELFMergeableSectionInfo(Result->getName(), Result->getFlags(),624Result->getUniqueID(), Result->getEntrySize());625626return Result;627}628629MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group,630bool IsComdat) {631return createELFSectionImpl(".group", ELF::SHT_GROUP, 0, 4, Group, IsComdat,632MCSection::NonUniqueID, nullptr);633}634635void MCContext::recordELFMergeableSectionInfo(StringRef SectionName,636unsigned Flags, unsigned UniqueID,637unsigned EntrySize) {638bool IsMergeable = Flags & ELF::SHF_MERGE;639if (UniqueID == GenericSectionID) {640ELFSeenGenericMergeableSections.insert(SectionName);641// Minor performance optimization: avoid hash map lookup in642// isELFGenericMergeableSection, which will return true for SectionName.643IsMergeable = true;644}645646// For mergeable sections or non-mergeable sections with a generic mergeable647// section name we enter their Unique ID into the ELFEntrySizeMap so that648// compatible globals can be assigned to the same section.649650if (IsMergeable || isELFGenericMergeableSection(SectionName)) {651ELFEntrySizeMap.insert(std::make_pair(652std::make_tuple(SectionName, Flags, EntrySize), UniqueID));653}654}655656bool MCContext::isELFImplicitMergeableSectionNamePrefix(StringRef SectionName) {657return SectionName.starts_with(".rodata.str") ||658SectionName.starts_with(".rodata.cst");659}660661bool MCContext::isELFGenericMergeableSection(StringRef SectionName) {662return isELFImplicitMergeableSectionNamePrefix(SectionName) ||663ELFSeenGenericMergeableSections.count(SectionName);664}665666std::optional<unsigned>667MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags,668unsigned EntrySize) {669auto I = ELFEntrySizeMap.find(std::make_tuple(SectionName, Flags, EntrySize));670return (I != ELFEntrySizeMap.end()) ? std::optional<unsigned>(I->second)671: std::nullopt;672}673674MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind,675MCSection *Parent,676uint32_t Subsection) {677// Do the lookup. If we don't have a hit, return a new section.678auto IterBool =679GOFFUniquingMap.insert(std::make_pair(Section.str(), nullptr));680auto Iter = IterBool.first;681if (!IterBool.second)682return Iter->second;683684StringRef CachedName = Iter->first;685MCSectionGOFF *GOFFSection = new (GOFFAllocator.Allocate())686MCSectionGOFF(CachedName, Kind, Parent, Subsection);687Iter->second = GOFFSection;688allocInitialFragment(*GOFFSection);689return GOFFSection;690}691692MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,693unsigned Characteristics,694StringRef COMDATSymName, int Selection,695unsigned UniqueID) {696MCSymbol *COMDATSymbol = nullptr;697if (!COMDATSymName.empty()) {698COMDATSymbol = getOrCreateSymbol(COMDATSymName);699COMDATSymName = COMDATSymbol->getName();700// A non-associative COMDAT is considered to define the COMDAT symbol. Check701// the redefinition error.702if (Selection != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE && COMDATSymbol &&703COMDATSymbol->isDefined() &&704(!COMDATSymbol->isInSection() ||705cast<MCSectionCOFF>(COMDATSymbol->getSection()).getCOMDATSymbol() !=706COMDATSymbol))707reportError(SMLoc(), "invalid symbol redefinition");708}709710// Do the lookup, if we have a hit, return it.711COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID};712auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));713auto Iter = IterBool.first;714if (!IterBool.second)715return Iter->second;716717StringRef CachedName = Iter->first.SectionName;718MCSymbol *Begin = getOrCreateSectionSymbol<MCSymbolCOFF>(Section);719MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(720CachedName, Characteristics, COMDATSymbol, Selection, Begin);721Iter->second = Result;722auto *F = allocInitialFragment(*Result);723Begin->setFragment(F);724return Result;725}726727MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,728unsigned Characteristics) {729return getCOFFSection(Section, Characteristics, "", 0, GenericSectionID);730}731732MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,733const MCSymbol *KeySym,734unsigned UniqueID) {735// Return the normal section if we don't have to be associative or unique.736if (!KeySym && UniqueID == GenericSectionID)737return Sec;738739// If we have a key symbol, make an associative section with the same name and740// kind as the normal section.741unsigned Characteristics = Sec->getCharacteristics();742if (KeySym) {743Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;744return getCOFFSection(Sec->getName(), Characteristics, KeySym->getName(),745COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);746}747748return getCOFFSection(Sec->getName(), Characteristics, "", 0, UniqueID);749}750751MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind K,752unsigned Flags, const Twine &Group,753unsigned UniqueID) {754MCSymbolWasm *GroupSym = nullptr;755if (!Group.isTriviallyEmpty() && !Group.str().empty()) {756GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group));757GroupSym->setComdat(true);758}759760return getWasmSection(Section, K, Flags, GroupSym, UniqueID);761}762763MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,764unsigned Flags,765const MCSymbolWasm *GroupSym,766unsigned UniqueID) {767StringRef Group = "";768if (GroupSym)769Group = GroupSym->getName();770// Do the lookup, if we have a hit, return it.771auto IterBool = WasmUniquingMap.insert(772std::make_pair(WasmSectionKey{Section.str(), Group, UniqueID}, nullptr));773auto &Entry = *IterBool.first;774if (!IterBool.second)775return Entry.second;776777StringRef CachedName = Entry.first.SectionName;778779MCSymbol *Begin = createRenamableSymbol(CachedName, true, false);780// Begin always has a different name than CachedName... see #48596.781getSymbolTableEntry(Begin->getName()).second.Symbol = Begin;782cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION);783784MCSectionWasm *Result = new (WasmAllocator.Allocate())785MCSectionWasm(CachedName, Kind, Flags, GroupSym, UniqueID, Begin);786Entry.second = Result;787788auto *F = allocInitialFragment(*Result);789Begin->setFragment(F);790return Result;791}792793bool MCContext::hasXCOFFSection(StringRef Section,794XCOFF::CsectProperties CsectProp) const {795return XCOFFUniquingMap.count(796XCOFFSectionKey(Section.str(), CsectProp.MappingClass)) != 0;797}798799MCSectionXCOFF *MCContext::getXCOFFSection(800StringRef Section, SectionKind Kind,801std::optional<XCOFF::CsectProperties> CsectProp, bool MultiSymbolsAllowed,802std::optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSectionSubtypeFlags) {803bool IsDwarfSec = DwarfSectionSubtypeFlags.has_value();804assert((IsDwarfSec != CsectProp.has_value()) && "Invalid XCOFF section!");805806// Do the lookup. If we have a hit, return it.807auto IterBool = XCOFFUniquingMap.insert(std::make_pair(808IsDwarfSec ? XCOFFSectionKey(Section.str(), *DwarfSectionSubtypeFlags)809: XCOFFSectionKey(Section.str(), CsectProp->MappingClass),810nullptr));811auto &Entry = *IterBool.first;812if (!IterBool.second) {813MCSectionXCOFF *ExistedEntry = Entry.second;814if (ExistedEntry->isMultiSymbolsAllowed() != MultiSymbolsAllowed)815report_fatal_error("section's multiply symbols policy does not match");816817return ExistedEntry;818}819820// Otherwise, return a new section.821StringRef CachedName = Entry.first.SectionName;822MCSymbolXCOFF *QualName = nullptr;823// Debug section don't have storage class attribute.824if (IsDwarfSec)825QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(CachedName));826else827QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(828CachedName + "[" +829XCOFF::getMappingClassString(CsectProp->MappingClass) + "]"));830831// QualName->getUnqualifiedName() and CachedName are the same except when832// CachedName contains invalid character(s) such as '$' for an XCOFF symbol.833MCSectionXCOFF *Result = nullptr;834if (IsDwarfSec)835Result = new (XCOFFAllocator.Allocate()) MCSectionXCOFF(836QualName->getUnqualifiedName(), Kind, QualName,837*DwarfSectionSubtypeFlags, QualName, CachedName, MultiSymbolsAllowed);838else839Result = new (XCOFFAllocator.Allocate())840MCSectionXCOFF(QualName->getUnqualifiedName(), CsectProp->MappingClass,841CsectProp->Type, Kind, QualName, nullptr, CachedName,842MultiSymbolsAllowed);843844Entry.second = Result;845846auto *F = allocInitialFragment(*Result);847848// We might miss calculating the symbols difference as absolute value before849// adding fixups when symbol_A without the fragment set is the csect itself850// and symbol_B is in it.851// TODO: Currently we only set the fragment for XMC_PR csects and DWARF852// sections because we don't have other cases that hit this problem yet.853if (IsDwarfSec || CsectProp->MappingClass == XCOFF::XMC_PR)854QualName->setFragment(F);855856return Result;857}858859MCSectionSPIRV *MCContext::getSPIRVSection() {860MCSectionSPIRV *Result = new (SPIRVAllocator.Allocate()) MCSectionSPIRV();861862allocInitialFragment(*Result);863return Result;864}865866MCSectionDXContainer *MCContext::getDXContainerSection(StringRef Section,867SectionKind K) {868// Do the lookup, if we have a hit, return it.869auto ItInsertedPair = DXCUniquingMap.try_emplace(Section);870if (!ItInsertedPair.second)871return ItInsertedPair.first->second;872873auto MapIt = ItInsertedPair.first;874// Grab the name from the StringMap. Since the Section is going to keep a875// copy of this StringRef we need to make sure the underlying string stays876// alive as long as we need it.877StringRef Name = MapIt->first();878MapIt->second =879new (DXCAllocator.Allocate()) MCSectionDXContainer(Name, K, nullptr);880881// The first fragment will store the header882allocInitialFragment(*MapIt->second);883return MapIt->second;884}885886MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {887return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);888}889890void MCContext::addDebugPrefixMapEntry(const std::string &From,891const std::string &To) {892DebugPrefixMap.emplace_back(From, To);893}894895void MCContext::remapDebugPath(SmallVectorImpl<char> &Path) {896for (const auto &[From, To] : llvm::reverse(DebugPrefixMap))897if (llvm::sys::path::replace_path_prefix(Path, From, To))898break;899}900901void MCContext::RemapDebugPaths() {902const auto &DebugPrefixMap = this->DebugPrefixMap;903if (DebugPrefixMap.empty())904return;905906// Remap compilation directory.907remapDebugPath(CompilationDir);908909// Remap MCDwarfDirs and RootFile.Name in all compilation units.910SmallString<256> P;911for (auto &CUIDTablePair : MCDwarfLineTablesCUMap) {912for (auto &Dir : CUIDTablePair.second.getMCDwarfDirs()) {913P = Dir;914remapDebugPath(P);915Dir = std::string(P);916}917918// Used by DW_TAG_compile_unit's DT_AT_name and DW_TAG_label's919// DW_AT_decl_file for DWARF v5 generated for assembly source.920P = CUIDTablePair.second.getRootFile().Name;921remapDebugPath(P);922CUIDTablePair.second.getRootFile().Name = std::string(P);923}924}925926//===----------------------------------------------------------------------===//927// Dwarf Management928//===----------------------------------------------------------------------===//929930EmitDwarfUnwindType MCContext::emitDwarfUnwindInfo() const {931if (!TargetOptions)932return EmitDwarfUnwindType::Default;933return TargetOptions->EmitDwarfUnwind;934}935936bool MCContext::emitCompactUnwindNonCanonical() const {937if (TargetOptions)938return TargetOptions->EmitCompactUnwindNonCanonical;939return false;940}941942void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) {943// MCDwarf needs the root file as well as the compilation directory.944// If we find a '.file 0' directive that will supersede these values.945std::optional<MD5::MD5Result> Cksum;946if (getDwarfVersion() >= 5) {947MD5 Hash;948MD5::MD5Result Sum;949Hash.update(Buffer);950Hash.final(Sum);951Cksum = Sum;952}953// Canonicalize the root filename. It cannot be empty, and should not954// repeat the compilation dir.955// The MCContext ctor initializes MainFileName to the name associated with956// the SrcMgr's main file ID, which might be the same as InputFileName (and957// possibly include directory components).958// Or, MainFileName might have been overridden by a -main-file-name option,959// which is supposed to be just a base filename with no directory component.960// So, if the InputFileName and MainFileName are not equal, assume961// MainFileName is a substitute basename and replace the last component.962SmallString<1024> FileNameBuf = InputFileName;963if (FileNameBuf.empty() || FileNameBuf == "-")964FileNameBuf = "<stdin>";965if (!getMainFileName().empty() && FileNameBuf != getMainFileName()) {966llvm::sys::path::remove_filename(FileNameBuf);967llvm::sys::path::append(FileNameBuf, getMainFileName());968}969StringRef FileName = FileNameBuf;970if (FileName.consume_front(getCompilationDir()))971if (llvm::sys::path::is_separator(FileName.front()))972FileName = FileName.drop_front();973assert(!FileName.empty());974setMCLineTableRootFile(975/*CUID=*/0, getCompilationDir(), FileName, Cksum, std::nullopt);976}977978/// getDwarfFile - takes a file name and number to place in the dwarf file and979/// directory tables. If the file number has already been allocated it is an980/// error and zero is returned and the client reports the error, else the981/// allocated file number is returned. The file numbers may be in any order.982Expected<unsigned>983MCContext::getDwarfFile(StringRef Directory, StringRef FileName,984unsigned FileNumber,985std::optional<MD5::MD5Result> Checksum,986std::optional<StringRef> Source, unsigned CUID) {987MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];988return Table.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,989FileNumber);990}991992/// isValidDwarfFileNumber - takes a dwarf file number and returns true if it993/// currently is assigned and false otherwise.994bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {995const MCDwarfLineTable &LineTable = getMCDwarfLineTable(CUID);996if (FileNumber == 0)997return getDwarfVersion() >= 5;998if (FileNumber >= LineTable.getMCDwarfFiles().size())999return false;10001001return !LineTable.getMCDwarfFiles()[FileNumber].Name.empty();1002}10031004/// Remove empty sections from SectionsForRanges, to avoid generating1005/// useless debug info for them.1006void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {1007SectionsForRanges.remove_if(1008[&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); });1009}10101011CodeViewContext &MCContext::getCVContext() {1012if (!CVContext)1013CVContext.reset(new CodeViewContext(this));1014return *CVContext;1015}10161017//===----------------------------------------------------------------------===//1018// Error Reporting1019//===----------------------------------------------------------------------===//10201021void MCContext::diagnose(const SMDiagnostic &SMD) {1022assert(DiagHandler && "MCContext::DiagHandler is not set");1023bool UseInlineSrcMgr = false;1024const SourceMgr *SMP = nullptr;1025if (SrcMgr) {1026SMP = SrcMgr;1027} else if (InlineSrcMgr) {1028SMP = InlineSrcMgr.get();1029UseInlineSrcMgr = true;1030} else1031llvm_unreachable("Either SourceMgr should be available");1032DiagHandler(SMD, UseInlineSrcMgr, *SMP, LocInfos);1033}10341035void MCContext::reportCommon(1036SMLoc Loc,1037std::function<void(SMDiagnostic &, const SourceMgr *)> GetMessage) {1038// * MCContext::SrcMgr is null when the MC layer emits machine code for input1039// other than assembly file, say, for .c/.cpp/.ll/.bc.1040// * MCContext::InlineSrcMgr is null when the inline asm is not used.1041// * A default SourceMgr is needed for diagnosing when both MCContext::SrcMgr1042// and MCContext::InlineSrcMgr are null.1043SourceMgr SM;1044const SourceMgr *SMP = &SM;1045bool UseInlineSrcMgr = false;10461047// FIXME: Simplify these by combining InlineSrcMgr & SrcMgr.1048// For MC-only execution, only SrcMgr is used;1049// For non MC-only execution, InlineSrcMgr is only ctor'd if there is1050// inline asm in the IR.1051if (Loc.isValid()) {1052if (SrcMgr) {1053SMP = SrcMgr;1054} else if (InlineSrcMgr) {1055SMP = InlineSrcMgr.get();1056UseInlineSrcMgr = true;1057} else1058llvm_unreachable("Either SourceMgr should be available");1059}10601061SMDiagnostic D;1062GetMessage(D, SMP);1063DiagHandler(D, UseInlineSrcMgr, *SMP, LocInfos);1064}10651066void MCContext::reportError(SMLoc Loc, const Twine &Msg) {1067HadError = true;1068reportCommon(Loc, [&](SMDiagnostic &D, const SourceMgr *SMP) {1069D = SMP->GetMessage(Loc, SourceMgr::DK_Error, Msg);1070});1071}10721073void MCContext::reportWarning(SMLoc Loc, const Twine &Msg) {1074if (TargetOptions && TargetOptions->MCNoWarn)1075return;1076if (TargetOptions && TargetOptions->MCFatalWarnings) {1077reportError(Loc, Msg);1078} else {1079reportCommon(Loc, [&](SMDiagnostic &D, const SourceMgr *SMP) {1080D = SMP->GetMessage(Loc, SourceMgr::DK_Warning, Msg);1081});1082}1083}108410851086