10b57cec5SDimitry Andric //===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===// 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/MCContext.h" 100b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 110b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 120b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h" 130b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 140b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 150b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h" 160b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 1781ad6265SDimitry Andric #include "llvm/BinaryFormat/Wasm.h" 18480093f4SDimitry Andric #include "llvm/BinaryFormat/XCOFF.h" 190b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCCodeView.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCFragment.h" 2481ad6265SDimitry Andric #include "llvm/MC/MCInst.h" 250b57cec5SDimitry Andric #include "llvm/MC/MCLabel.h" 260b57cec5SDimitry Andric #include "llvm/MC/MCSectionCOFF.h" 2781ad6265SDimitry Andric #include "llvm/MC/MCSectionDXContainer.h" 280b57cec5SDimitry Andric #include "llvm/MC/MCSectionELF.h" 29fe6060f1SDimitry Andric #include "llvm/MC/MCSectionGOFF.h" 300b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h" 3181ad6265SDimitry Andric #include "llvm/MC/MCSectionSPIRV.h" 320b57cec5SDimitry Andric #include "llvm/MC/MCSectionWasm.h" 330b57cec5SDimitry Andric #include "llvm/MC/MCSectionXCOFF.h" 340b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 3581ad6265SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 360b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 370b57cec5SDimitry Andric #include "llvm/MC/MCSymbolCOFF.h" 380b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 39fe6060f1SDimitry Andric #include "llvm/MC/MCSymbolGOFF.h" 400b57cec5SDimitry Andric #include "llvm/MC/MCSymbolMachO.h" 410b57cec5SDimitry Andric #include "llvm/MC/MCSymbolWasm.h" 420b57cec5SDimitry Andric #include "llvm/MC/MCSymbolXCOFF.h" 4381ad6265SDimitry Andric #include "llvm/MC/MCTargetOptions.h" 440b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h" 450b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 460b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 47*0fca6ea1SDimitry Andric #include "llvm/Support/EndianStream.h" 480b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 490b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 500b57cec5SDimitry Andric #include "llvm/Support/Path.h" 5181ad6265SDimitry Andric #include "llvm/Support/SMLoc.h" 520b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h" 530b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 540b57cec5SDimitry Andric #include <cassert> 550b57cec5SDimitry Andric #include <cstdlib> 56bdd1243dSDimitry Andric #include <optional> 570b57cec5SDimitry Andric #include <tuple> 580b57cec5SDimitry Andric #include <utility> 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric using namespace llvm; 610b57cec5SDimitry Andric 62fe6060f1SDimitry Andric static void defaultDiagHandler(const SMDiagnostic &SMD, bool, const SourceMgr &, 63fe6060f1SDimitry Andric std::vector<const MDNode *> &) { 64fe6060f1SDimitry Andric SMD.print(nullptr, errs()); 65fe6060f1SDimitry Andric } 66fe6060f1SDimitry Andric 67fe6060f1SDimitry Andric MCContext::MCContext(const Triple &TheTriple, const MCAsmInfo *mai, 68fe6060f1SDimitry Andric const MCRegisterInfo *mri, const MCSubtargetInfo *msti, 69fe6060f1SDimitry Andric const SourceMgr *mgr, MCTargetOptions const *TargetOpts, 701fd87a68SDimitry Andric bool DoAutoReset, StringRef Swift5ReflSegmentName) 711fd87a68SDimitry Andric : Swift5ReflectionSegmentName(Swift5ReflSegmentName), TT(TheTriple), 721fd87a68SDimitry Andric SrcMgr(mgr), InlineSrcMgr(nullptr), DiagHandler(defaultDiagHandler), 73*0fca6ea1SDimitry Andric MAI(mai), MRI(mri), MSTI(msti), Symbols(Allocator), 740b57cec5SDimitry Andric InlineAsmUsedLabelNames(Allocator), 750b57cec5SDimitry Andric CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), 768bcb0991SDimitry Andric AutoReset(DoAutoReset), TargetOptions(TargetOpts) { 77*0fca6ea1SDimitry Andric SaveTempLabels = TargetOptions && TargetOptions->MCSaveTempLabels; 78bdd1243dSDimitry Andric SecureLogFile = TargetOptions ? TargetOptions->AsSecureLogFile : ""; 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric if (SrcMgr && SrcMgr->getNumBuffers()) 815ffd83dbSDimitry Andric MainFileName = std::string(SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID()) 825ffd83dbSDimitry Andric ->getBufferIdentifier()); 83fe6060f1SDimitry Andric 84fe6060f1SDimitry Andric switch (TheTriple.getObjectFormat()) { 85fe6060f1SDimitry Andric case Triple::MachO: 86fe6060f1SDimitry Andric Env = IsMachO; 87fe6060f1SDimitry Andric break; 88fe6060f1SDimitry Andric case Triple::COFF: 8906c3fb27SDimitry Andric if (!TheTriple.isOSWindows() && !TheTriple.isUEFI()) 90fe6060f1SDimitry Andric report_fatal_error( 91fe6060f1SDimitry Andric "Cannot initialize MC for non-Windows COFF object files."); 92fe6060f1SDimitry Andric 93fe6060f1SDimitry Andric Env = IsCOFF; 94fe6060f1SDimitry Andric break; 95fe6060f1SDimitry Andric case Triple::ELF: 96fe6060f1SDimitry Andric Env = IsELF; 97fe6060f1SDimitry Andric break; 98fe6060f1SDimitry Andric case Triple::Wasm: 99fe6060f1SDimitry Andric Env = IsWasm; 100fe6060f1SDimitry Andric break; 101fe6060f1SDimitry Andric case Triple::XCOFF: 102fe6060f1SDimitry Andric Env = IsXCOFF; 103fe6060f1SDimitry Andric break; 104fe6060f1SDimitry Andric case Triple::GOFF: 105fe6060f1SDimitry Andric Env = IsGOFF; 106fe6060f1SDimitry Andric break; 10781ad6265SDimitry Andric case Triple::DXContainer: 10881ad6265SDimitry Andric Env = IsDXContainer; 10981ad6265SDimitry Andric break; 11081ad6265SDimitry Andric case Triple::SPIRV: 11181ad6265SDimitry Andric Env = IsSPIRV; 11281ad6265SDimitry Andric break; 113fe6060f1SDimitry Andric case Triple::UnknownObjectFormat: 114fe6060f1SDimitry Andric report_fatal_error("Cannot initialize MC for unknown object file format."); 115fe6060f1SDimitry Andric break; 116fe6060f1SDimitry Andric } 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric MCContext::~MCContext() { 1200b57cec5SDimitry Andric if (AutoReset) 1210b57cec5SDimitry Andric reset(); 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric // NOTE: The symbols are all allocated out of a bump pointer allocator, 1240b57cec5SDimitry Andric // we don't need to free them here. 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric 127fe6060f1SDimitry Andric void MCContext::initInlineSourceManager() { 128fe6060f1SDimitry Andric if (!InlineSrcMgr) 129fe6060f1SDimitry Andric InlineSrcMgr.reset(new SourceMgr()); 130fe6060f1SDimitry Andric } 131fe6060f1SDimitry Andric 1320b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1330b57cec5SDimitry Andric // Module Lifetime Management 1340b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric void MCContext::reset() { 137fe6060f1SDimitry Andric SrcMgr = nullptr; 138fe6060f1SDimitry Andric InlineSrcMgr.reset(); 139fe6060f1SDimitry Andric LocInfos.clear(); 140fe6060f1SDimitry Andric DiagHandler = defaultDiagHandler; 141fe6060f1SDimitry Andric 1420b57cec5SDimitry Andric // Call the destructors so the fragments are freed 1430b57cec5SDimitry Andric COFFAllocator.DestroyAll(); 14481ad6265SDimitry Andric DXCAllocator.DestroyAll(); 1450b57cec5SDimitry Andric ELFAllocator.DestroyAll(); 146fe6060f1SDimitry Andric GOFFAllocator.DestroyAll(); 1470b57cec5SDimitry Andric MachOAllocator.DestroyAll(); 14881ad6265SDimitry Andric WasmAllocator.DestroyAll(); 1490b57cec5SDimitry Andric XCOFFAllocator.DestroyAll(); 150e8d8bef9SDimitry Andric MCInstAllocator.DestroyAll(); 15181ad6265SDimitry Andric SPIRVAllocator.DestroyAll(); 152*0fca6ea1SDimitry Andric WasmSignatureAllocator.DestroyAll(); 153*0fca6ea1SDimitry Andric 154*0fca6ea1SDimitry Andric // ~CodeViewContext may destroy a MCFragment outside of sections and need to 155*0fca6ea1SDimitry Andric // be reset before FragmentAllocator. 156*0fca6ea1SDimitry Andric CVContext.reset(); 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric MCSubtargetAllocator.DestroyAll(); 1590b57cec5SDimitry Andric InlineAsmUsedLabelNames.clear(); 1600b57cec5SDimitry Andric Symbols.clear(); 1610b57cec5SDimitry Andric Allocator.Reset(); 162*0fca6ea1SDimitry Andric FragmentAllocator.Reset(); 1630b57cec5SDimitry Andric Instances.clear(); 1640b57cec5SDimitry Andric CompilationDir.clear(); 1650b57cec5SDimitry Andric MainFileName.clear(); 1660b57cec5SDimitry Andric MCDwarfLineTablesCUMap.clear(); 1670b57cec5SDimitry Andric SectionsForRanges.clear(); 1680b57cec5SDimitry Andric MCGenDwarfLabelEntries.clear(); 1690b57cec5SDimitry Andric DwarfDebugFlags = StringRef(); 1700b57cec5SDimitry Andric DwarfCompileUnitID = 0; 1710b57cec5SDimitry Andric CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0); 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric MachOUniquingMap.clear(); 1740b57cec5SDimitry Andric ELFUniquingMap.clear(); 175fe6060f1SDimitry Andric GOFFUniquingMap.clear(); 1760b57cec5SDimitry Andric COFFUniquingMap.clear(); 1770b57cec5SDimitry Andric WasmUniquingMap.clear(); 1780b57cec5SDimitry Andric XCOFFUniquingMap.clear(); 17981ad6265SDimitry Andric DXCUniquingMap.clear(); 1800b57cec5SDimitry Andric 1815ffd83dbSDimitry Andric ELFEntrySizeMap.clear(); 1825ffd83dbSDimitry Andric ELFSeenGenericMergeableSections.clear(); 1835ffd83dbSDimitry Andric 1840b57cec5SDimitry Andric DwarfLocSeen = false; 1850b57cec5SDimitry Andric GenDwarfForAssembly = false; 1860b57cec5SDimitry Andric GenDwarfFileNumber = 0; 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric HadError = false; 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 192e8d8bef9SDimitry Andric // MCInst Management 193e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 194e8d8bef9SDimitry Andric 195e8d8bef9SDimitry Andric MCInst *MCContext::createMCInst() { 196e8d8bef9SDimitry Andric return new (MCInstAllocator.Allocate()) MCInst; 197e8d8bef9SDimitry Andric } 198e8d8bef9SDimitry Andric 199*0fca6ea1SDimitry Andric // Allocate the initial MCDataFragment for the begin symbol. 200*0fca6ea1SDimitry Andric MCDataFragment *MCContext::allocInitialFragment(MCSection &Sec) { 201*0fca6ea1SDimitry Andric assert(!Sec.curFragList()->Head); 202*0fca6ea1SDimitry Andric auto *F = allocFragment<MCDataFragment>(); 203*0fca6ea1SDimitry Andric F->setParent(&Sec); 204*0fca6ea1SDimitry Andric Sec.curFragList()->Head = F; 205*0fca6ea1SDimitry Andric Sec.curFragList()->Tail = F; 206*0fca6ea1SDimitry Andric return F; 207*0fca6ea1SDimitry Andric } 208*0fca6ea1SDimitry Andric 209e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 2100b57cec5SDimitry Andric // Symbol Manipulation 2110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) { 2140b57cec5SDimitry Andric SmallString<128> NameSV; 2150b57cec5SDimitry Andric StringRef NameRef = Name.toStringRef(NameSV); 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric assert(!NameRef.empty() && "Normal symbols cannot be unnamed!"); 2180b57cec5SDimitry Andric 219*0fca6ea1SDimitry Andric MCSymbolTableEntry &Entry = getSymbolTableEntry(NameRef); 220*0fca6ea1SDimitry Andric if (!Entry.second.Symbol) { 221*0fca6ea1SDimitry Andric bool IsRenamable = NameRef.starts_with(MAI->getPrivateGlobalPrefix()); 222*0fca6ea1SDimitry Andric bool IsTemporary = IsRenamable && !SaveTempLabels; 223*0fca6ea1SDimitry Andric if (!Entry.second.Used) { 224*0fca6ea1SDimitry Andric Entry.second.Used = true; 225*0fca6ea1SDimitry Andric Entry.second.Symbol = createSymbolImpl(&Entry, IsTemporary); 226*0fca6ea1SDimitry Andric } else { 227*0fca6ea1SDimitry Andric assert(IsRenamable && "cannot rename non-private symbol"); 228*0fca6ea1SDimitry Andric // Slow path: we need to rename a temp symbol from the user. 229*0fca6ea1SDimitry Andric Entry.second.Symbol = createRenamableSymbol(NameRef, false, IsTemporary); 230*0fca6ea1SDimitry Andric } 231*0fca6ea1SDimitry Andric } 2320b57cec5SDimitry Andric 233*0fca6ea1SDimitry Andric return Entry.second.Symbol; 2340b57cec5SDimitry Andric } 2350b57cec5SDimitry Andric 23606c3fb27SDimitry Andric MCSymbol *MCContext::getOrCreateFrameAllocSymbol(const Twine &FuncName, 2370b57cec5SDimitry Andric unsigned Idx) { 23806c3fb27SDimitry Andric return getOrCreateSymbol(MAI->getPrivateGlobalPrefix() + FuncName + 2390b57cec5SDimitry Andric "$frame_escape_" + Twine(Idx)); 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric 24206c3fb27SDimitry Andric MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(const Twine &FuncName) { 24306c3fb27SDimitry Andric return getOrCreateSymbol(MAI->getPrivateGlobalPrefix() + FuncName + 2440b57cec5SDimitry Andric "$parent_frame_offset"); 2450b57cec5SDimitry Andric } 2460b57cec5SDimitry Andric 24706c3fb27SDimitry Andric MCSymbol *MCContext::getOrCreateLSDASymbol(const Twine &FuncName) { 24806c3fb27SDimitry Andric return getOrCreateSymbol(MAI->getPrivateGlobalPrefix() + "__ehtable$" + 2490b57cec5SDimitry Andric FuncName); 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric 252*0fca6ea1SDimitry Andric MCSymbolTableEntry &MCContext::getSymbolTableEntry(StringRef Name) { 253*0fca6ea1SDimitry Andric return *Symbols.try_emplace(Name, MCSymbolTableValue{}).first; 254*0fca6ea1SDimitry Andric } 255*0fca6ea1SDimitry Andric 256*0fca6ea1SDimitry Andric MCSymbol *MCContext::createSymbolImpl(const MCSymbolTableEntry *Name, 2570b57cec5SDimitry Andric bool IsTemporary) { 2585ffd83dbSDimitry Andric static_assert(std::is_trivially_destructible<MCSymbolCOFF>(), 2595ffd83dbSDimitry Andric "MCSymbol classes must be trivially destructible"); 2605ffd83dbSDimitry Andric static_assert(std::is_trivially_destructible<MCSymbolELF>(), 2615ffd83dbSDimitry Andric "MCSymbol classes must be trivially destructible"); 2625ffd83dbSDimitry Andric static_assert(std::is_trivially_destructible<MCSymbolMachO>(), 2635ffd83dbSDimitry Andric "MCSymbol classes must be trivially destructible"); 2645ffd83dbSDimitry Andric static_assert(std::is_trivially_destructible<MCSymbolWasm>(), 2655ffd83dbSDimitry Andric "MCSymbol classes must be trivially destructible"); 2665ffd83dbSDimitry Andric static_assert(std::is_trivially_destructible<MCSymbolXCOFF>(), 2675ffd83dbSDimitry Andric "MCSymbol classes must be trivially destructible"); 268fe6060f1SDimitry Andric 269fe6060f1SDimitry Andric switch (getObjectFileType()) { 270fe6060f1SDimitry Andric case MCContext::IsCOFF: 2710b57cec5SDimitry Andric return new (Name, *this) MCSymbolCOFF(Name, IsTemporary); 272fe6060f1SDimitry Andric case MCContext::IsELF: 2730b57cec5SDimitry Andric return new (Name, *this) MCSymbolELF(Name, IsTemporary); 274fe6060f1SDimitry Andric case MCContext::IsGOFF: 275fe6060f1SDimitry Andric return new (Name, *this) MCSymbolGOFF(Name, IsTemporary); 276fe6060f1SDimitry Andric case MCContext::IsMachO: 2770b57cec5SDimitry Andric return new (Name, *this) MCSymbolMachO(Name, IsTemporary); 278fe6060f1SDimitry Andric case MCContext::IsWasm: 2790b57cec5SDimitry Andric return new (Name, *this) MCSymbolWasm(Name, IsTemporary); 280fe6060f1SDimitry Andric case MCContext::IsXCOFF: 2815ffd83dbSDimitry Andric return createXCOFFSymbolImpl(Name, IsTemporary); 28281ad6265SDimitry Andric case MCContext::IsDXContainer: 28381ad6265SDimitry Andric break; 28481ad6265SDimitry Andric case MCContext::IsSPIRV: 28581ad6265SDimitry Andric return new (Name, *this) 28681ad6265SDimitry Andric MCSymbol(MCSymbol::SymbolKindUnset, Name, IsTemporary); 2870b57cec5SDimitry Andric } 28806c3fb27SDimitry Andric return new (Name, *this) 28906c3fb27SDimitry Andric MCSymbol(MCSymbol::SymbolKindUnset, Name, IsTemporary); 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 292*0fca6ea1SDimitry Andric MCSymbol *MCContext::createRenamableSymbol(const Twine &Name, 293*0fca6ea1SDimitry Andric bool AlwaysAddSuffix, 294*0fca6ea1SDimitry Andric bool IsTemporary) { 295*0fca6ea1SDimitry Andric SmallString<128> NewName; 296*0fca6ea1SDimitry Andric Name.toVector(NewName); 297*0fca6ea1SDimitry Andric size_t NameLen = NewName.size(); 2980b57cec5SDimitry Andric 299*0fca6ea1SDimitry Andric MCSymbolTableEntry &NameEntry = getSymbolTableEntry(NewName.str()); 300*0fca6ea1SDimitry Andric MCSymbolTableEntry *EntryPtr = &NameEntry; 301*0fca6ea1SDimitry Andric while (AlwaysAddSuffix || EntryPtr->second.Used) { 302*0fca6ea1SDimitry Andric AlwaysAddSuffix = false; 3030b57cec5SDimitry Andric 304*0fca6ea1SDimitry Andric NewName.resize(NameLen); 305*0fca6ea1SDimitry Andric raw_svector_ostream(NewName) << NameEntry.second.NextUniqueID++; 306*0fca6ea1SDimitry Andric EntryPtr = &getSymbolTableEntry(NewName.str()); 3070b57cec5SDimitry Andric } 308*0fca6ea1SDimitry Andric 309*0fca6ea1SDimitry Andric EntryPtr->second.Used = true; 310*0fca6ea1SDimitry Andric return createSymbolImpl(EntryPtr, IsTemporary); 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric 313e8d8bef9SDimitry Andric MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix) { 314*0fca6ea1SDimitry Andric if (!UseNamesOnTempLabels) 315*0fca6ea1SDimitry Andric return createSymbolImpl(nullptr, /*IsTemporary=*/true); 316*0fca6ea1SDimitry Andric return createRenamableSymbol(MAI->getPrivateGlobalPrefix() + Name, 317*0fca6ea1SDimitry Andric AlwaysAddSuffix, /*IsTemporary=*/true); 318e8d8bef9SDimitry Andric } 319e8d8bef9SDimitry Andric 320e8d8bef9SDimitry Andric MCSymbol *MCContext::createNamedTempSymbol(const Twine &Name) { 321*0fca6ea1SDimitry Andric return createRenamableSymbol(MAI->getPrivateGlobalPrefix() + Name, true, 322*0fca6ea1SDimitry Andric /*IsTemporary=*/!SaveTempLabels); 323*0fca6ea1SDimitry Andric } 324*0fca6ea1SDimitry Andric 325*0fca6ea1SDimitry Andric MCSymbol *MCContext::createBlockSymbol(const Twine &Name, bool AlwaysEmit) { 326*0fca6ea1SDimitry Andric if (AlwaysEmit) 327*0fca6ea1SDimitry Andric return getOrCreateSymbol(MAI->getPrivateLabelPrefix() + Name); 328*0fca6ea1SDimitry Andric 329*0fca6ea1SDimitry Andric bool IsTemporary = !SaveTempLabels; 330*0fca6ea1SDimitry Andric if (IsTemporary && !UseNamesOnTempLabels) 331*0fca6ea1SDimitry Andric return createSymbolImpl(nullptr, IsTemporary); 332*0fca6ea1SDimitry Andric return createRenamableSymbol(MAI->getPrivateLabelPrefix() + Name, 333*0fca6ea1SDimitry Andric /*AlwaysAddSuffix=*/false, IsTemporary); 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric MCSymbol *MCContext::createLinkerPrivateTempSymbol() { 33706c3fb27SDimitry Andric return createLinkerPrivateSymbol("tmp"); 33806c3fb27SDimitry Andric } 33906c3fb27SDimitry Andric 34006c3fb27SDimitry Andric MCSymbol *MCContext::createLinkerPrivateSymbol(const Twine &Name) { 341*0fca6ea1SDimitry Andric return createRenamableSymbol(MAI->getLinkerPrivateGlobalPrefix() + Name, 342*0fca6ea1SDimitry Andric /*AlwaysAddSuffix=*/true, 343*0fca6ea1SDimitry Andric /*IsTemporary=*/false); 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric 346e8d8bef9SDimitry Andric MCSymbol *MCContext::createTempSymbol() { return createTempSymbol("tmp"); } 347e8d8bef9SDimitry Andric 348e8d8bef9SDimitry Andric MCSymbol *MCContext::createNamedTempSymbol() { 349e8d8bef9SDimitry Andric return createNamedTempSymbol("tmp"); 3500b57cec5SDimitry Andric } 3510b57cec5SDimitry Andric 352*0fca6ea1SDimitry Andric MCSymbol *MCContext::createLocalSymbol(StringRef Name) { 353*0fca6ea1SDimitry Andric MCSymbolTableEntry &NameEntry = getSymbolTableEntry(Name); 354*0fca6ea1SDimitry Andric return createSymbolImpl(&NameEntry, /*IsTemporary=*/false); 355*0fca6ea1SDimitry Andric } 356*0fca6ea1SDimitry Andric 3570b57cec5SDimitry Andric unsigned MCContext::NextInstance(unsigned LocalLabelVal) { 3580b57cec5SDimitry Andric MCLabel *&Label = Instances[LocalLabelVal]; 3590b57cec5SDimitry Andric if (!Label) 3600b57cec5SDimitry Andric Label = new (*this) MCLabel(0); 3610b57cec5SDimitry Andric return Label->incInstance(); 3620b57cec5SDimitry Andric } 3630b57cec5SDimitry Andric 3640b57cec5SDimitry Andric unsigned MCContext::GetInstance(unsigned LocalLabelVal) { 3650b57cec5SDimitry Andric MCLabel *&Label = Instances[LocalLabelVal]; 3660b57cec5SDimitry Andric if (!Label) 3670b57cec5SDimitry Andric Label = new (*this) MCLabel(0); 3680b57cec5SDimitry Andric return Label->getInstance(); 3690b57cec5SDimitry Andric } 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, 3720b57cec5SDimitry Andric unsigned Instance) { 3730b57cec5SDimitry Andric MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)]; 3740b57cec5SDimitry Andric if (!Sym) 375e8d8bef9SDimitry Andric Sym = createNamedTempSymbol(); 3760b57cec5SDimitry Andric return Sym; 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) { 3800b57cec5SDimitry Andric unsigned Instance = NextInstance(LocalLabelVal); 3810b57cec5SDimitry Andric return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal, 3850b57cec5SDimitry Andric bool Before) { 3860b57cec5SDimitry Andric unsigned Instance = GetInstance(LocalLabelVal); 3870b57cec5SDimitry Andric if (!Before) 3880b57cec5SDimitry Andric ++Instance; 3890b57cec5SDimitry Andric return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); 3900b57cec5SDimitry Andric } 3910b57cec5SDimitry Andric 392*0fca6ea1SDimitry Andric template <typename Symbol> 393*0fca6ea1SDimitry Andric Symbol *MCContext::getOrCreateSectionSymbol(StringRef Section) { 394*0fca6ea1SDimitry Andric Symbol *R; 395*0fca6ea1SDimitry Andric auto &SymEntry = getSymbolTableEntry(Section); 396*0fca6ea1SDimitry Andric MCSymbol *Sym = SymEntry.second.Symbol; 397*0fca6ea1SDimitry Andric // A section symbol can not redefine regular symbols. There may be multiple 398*0fca6ea1SDimitry Andric // sections with the same name, in which case the first such section wins. 399*0fca6ea1SDimitry Andric if (Sym && Sym->isDefined() && 400*0fca6ea1SDimitry Andric (!Sym->isInSection() || Sym->getSection().getBeginSymbol() != Sym)) 401*0fca6ea1SDimitry Andric reportError(SMLoc(), "invalid symbol redefinition"); 402*0fca6ea1SDimitry Andric if (Sym && Sym->isUndefined()) { 403*0fca6ea1SDimitry Andric R = cast<Symbol>(Sym); 404*0fca6ea1SDimitry Andric } else { 405*0fca6ea1SDimitry Andric SymEntry.second.Used = true; 406*0fca6ea1SDimitry Andric R = new (&SymEntry, *this) Symbol(&SymEntry, /*isTemporary=*/false); 407*0fca6ea1SDimitry Andric if (!Sym) 408*0fca6ea1SDimitry Andric SymEntry.second.Symbol = R; 409*0fca6ea1SDimitry Andric } 410*0fca6ea1SDimitry Andric return R; 411*0fca6ea1SDimitry Andric } 412*0fca6ea1SDimitry Andric 4130b57cec5SDimitry Andric MCSymbol *MCContext::lookupSymbol(const Twine &Name) const { 4140b57cec5SDimitry Andric SmallString<128> NameSV; 4150b57cec5SDimitry Andric StringRef NameRef = Name.toStringRef(NameSV); 416*0fca6ea1SDimitry Andric return Symbols.lookup(NameRef).Symbol; 4170b57cec5SDimitry Andric } 4180b57cec5SDimitry Andric 41906c3fb27SDimitry Andric void MCContext::setSymbolValue(MCStreamer &Streamer, const Twine &Sym, 4200b57cec5SDimitry Andric uint64_t Val) { 4210b57cec5SDimitry Andric auto Symbol = getOrCreateSymbol(Sym); 4225ffd83dbSDimitry Andric Streamer.emitAssignment(Symbol, MCConstantExpr::create(Val, *this)); 4230b57cec5SDimitry Andric } 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric void MCContext::registerInlineAsmLabel(MCSymbol *Sym) { 4260b57cec5SDimitry Andric InlineAsmUsedLabelNames[Sym->getName()] = Sym; 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric 429*0fca6ea1SDimitry Andric wasm::WasmSignature *MCContext::createWasmSignature() { 430*0fca6ea1SDimitry Andric return new (WasmSignatureAllocator.Allocate()) wasm::WasmSignature; 431*0fca6ea1SDimitry Andric } 432*0fca6ea1SDimitry Andric 433*0fca6ea1SDimitry Andric MCSymbolXCOFF *MCContext::createXCOFFSymbolImpl(const MCSymbolTableEntry *Name, 4345ffd83dbSDimitry Andric bool IsTemporary) { 4355ffd83dbSDimitry Andric if (!Name) 4365ffd83dbSDimitry Andric return new (nullptr, *this) MCSymbolXCOFF(nullptr, IsTemporary); 4375ffd83dbSDimitry Andric 4385ffd83dbSDimitry Andric StringRef OriginalName = Name->first(); 4395f757f3fSDimitry Andric if (OriginalName.starts_with("._Renamed..") || 4405f757f3fSDimitry Andric OriginalName.starts_with("_Renamed..")) 4415ffd83dbSDimitry Andric reportError(SMLoc(), "invalid symbol name from source"); 4425ffd83dbSDimitry Andric 4435ffd83dbSDimitry Andric if (MAI->isValidUnquotedName(OriginalName)) 4445ffd83dbSDimitry Andric return new (Name, *this) MCSymbolXCOFF(Name, IsTemporary); 4455ffd83dbSDimitry Andric 4465ffd83dbSDimitry Andric // Now we have a name that contains invalid character(s) for XCOFF symbol. 4475ffd83dbSDimitry Andric // Let's replace with something valid, but save the original name so that 4485ffd83dbSDimitry Andric // we could still use the original name in the symbol table. 4495ffd83dbSDimitry Andric SmallString<128> InvalidName(OriginalName); 4505ffd83dbSDimitry Andric 4515ffd83dbSDimitry Andric // If it's an entry point symbol, we will keep the '.' 4525ffd83dbSDimitry Andric // in front for the convention purpose. Otherwise, add "_Renamed.." 4535ffd83dbSDimitry Andric // as prefix to signal this is an renamed symbol. 454*0fca6ea1SDimitry Andric const bool IsEntryPoint = InvalidName.starts_with("."); 4555ffd83dbSDimitry Andric SmallString<128> ValidName = 4565ffd83dbSDimitry Andric StringRef(IsEntryPoint ? "._Renamed.." : "_Renamed.."); 4575ffd83dbSDimitry Andric 4585ffd83dbSDimitry Andric // Append the hex values of '_' and invalid characters with "_Renamed.."; 4595ffd83dbSDimitry Andric // at the same time replace invalid characters with '_'. 4605ffd83dbSDimitry Andric for (size_t I = 0; I < InvalidName.size(); ++I) { 4615ffd83dbSDimitry Andric if (!MAI->isAcceptableChar(InvalidName[I]) || InvalidName[I] == '_') { 4625ffd83dbSDimitry Andric raw_svector_ostream(ValidName).write_hex(InvalidName[I]); 4635ffd83dbSDimitry Andric InvalidName[I] = '_'; 4645ffd83dbSDimitry Andric } 4655ffd83dbSDimitry Andric } 4665ffd83dbSDimitry Andric 4675ffd83dbSDimitry Andric // Skip entry point symbol's '.' as we already have a '.' in front of 4685ffd83dbSDimitry Andric // "_Renamed". 4695ffd83dbSDimitry Andric if (IsEntryPoint) 4705ffd83dbSDimitry Andric ValidName.append(InvalidName.substr(1, InvalidName.size() - 1)); 4715ffd83dbSDimitry Andric else 4725ffd83dbSDimitry Andric ValidName.append(InvalidName); 4735ffd83dbSDimitry Andric 474*0fca6ea1SDimitry Andric MCSymbolTableEntry &NameEntry = getSymbolTableEntry(ValidName.str()); 475*0fca6ea1SDimitry Andric assert(!NameEntry.second.Used && "This name is used somewhere else."); 476*0fca6ea1SDimitry Andric NameEntry.second.Used = true; 4775ffd83dbSDimitry Andric // Have the MCSymbol object itself refer to the copy of the string 478*0fca6ea1SDimitry Andric // that is embedded in the symbol table entry. 479*0fca6ea1SDimitry Andric MCSymbolXCOFF *XSym = 480*0fca6ea1SDimitry Andric new (&NameEntry, *this) MCSymbolXCOFF(&NameEntry, IsTemporary); 4815ffd83dbSDimitry Andric XSym->setSymbolTableName(MCSymbolXCOFF::getUnqualifiedName(OriginalName)); 4825ffd83dbSDimitry Andric return XSym; 4835ffd83dbSDimitry Andric } 4845ffd83dbSDimitry Andric 4850b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4860b57cec5SDimitry Andric // Section Management 4870b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section, 4900b57cec5SDimitry Andric unsigned TypeAndAttributes, 4910b57cec5SDimitry Andric unsigned Reserved2, SectionKind Kind, 4920b57cec5SDimitry Andric const char *BeginSymName) { 4930b57cec5SDimitry Andric // We unique sections by their segment/section pair. The returned section 4940b57cec5SDimitry Andric // may not have the same flags as the requested section, if so this should be 4950b57cec5SDimitry Andric // diagnosed by the client as an error. 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric // Form the name to look up. 4985ffd83dbSDimitry Andric assert(Section.size() <= 16 && "section name is too long"); 4995ffd83dbSDimitry Andric assert(!memchr(Section.data(), '\0', Section.size()) && 5005ffd83dbSDimitry Andric "section name cannot contain NUL"); 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric // Do the lookup, if we have a hit, return it. 5035ffd83dbSDimitry Andric auto R = MachOUniquingMap.try_emplace((Segment + Twine(',') + Section).str()); 5045ffd83dbSDimitry Andric if (!R.second) 5055ffd83dbSDimitry Andric return R.first->second; 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric MCSymbol *Begin = nullptr; 5080b57cec5SDimitry Andric if (BeginSymName) 5090b57cec5SDimitry Andric Begin = createTempSymbol(BeginSymName, false); 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric // Otherwise, return a new section. 5125ffd83dbSDimitry Andric StringRef Name = R.first->first(); 513*0fca6ea1SDimitry Andric auto *Ret = new (MachOAllocator.Allocate()) 5145ffd83dbSDimitry Andric MCSectionMachO(Segment, Name.substr(Name.size() - Section.size()), 5155ffd83dbSDimitry Andric TypeAndAttributes, Reserved2, Kind, Begin); 516*0fca6ea1SDimitry Andric R.first->second = Ret; 517*0fca6ea1SDimitry Andric allocInitialFragment(*Ret); 518*0fca6ea1SDimitry Andric return Ret; 5190b57cec5SDimitry Andric } 5200b57cec5SDimitry Andric 5210b57cec5SDimitry Andric MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type, 522*0fca6ea1SDimitry Andric unsigned Flags, 5230b57cec5SDimitry Andric unsigned EntrySize, 5240b57cec5SDimitry Andric const MCSymbolELF *Group, 525fe6060f1SDimitry Andric bool Comdat, unsigned UniqueID, 5265ffd83dbSDimitry Andric const MCSymbolELF *LinkedToSym) { 527*0fca6ea1SDimitry Andric auto *R = getOrCreateSectionSymbol<MCSymbolELF>(Section); 5280b57cec5SDimitry Andric R->setBinding(ELF::STB_LOCAL); 5290b57cec5SDimitry Andric R->setType(ELF::STT_SECTION); 5300b57cec5SDimitry Andric 531*0fca6ea1SDimitry Andric auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF( 532*0fca6ea1SDimitry Andric Section, Type, Flags, EntrySize, Group, Comdat, UniqueID, R, LinkedToSym); 5330b57cec5SDimitry Andric 534*0fca6ea1SDimitry Andric auto *F = allocInitialFragment(*Ret); 5350b57cec5SDimitry Andric R->setFragment(F); 5360b57cec5SDimitry Andric return Ret; 5370b57cec5SDimitry Andric } 5380b57cec5SDimitry Andric 53906c3fb27SDimitry Andric MCSectionELF * 54006c3fb27SDimitry Andric MCContext::createELFRelSection(const Twine &Name, unsigned Type, unsigned Flags, 54106c3fb27SDimitry Andric unsigned EntrySize, const MCSymbolELF *Group, 5420b57cec5SDimitry Andric const MCSectionELF *RelInfoSection) { 5430b57cec5SDimitry Andric StringMap<bool>::iterator I; 5440b57cec5SDimitry Andric bool Inserted; 54506c3fb27SDimitry Andric std::tie(I, Inserted) = RelSecNames.insert(std::make_pair(Name.str(), true)); 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric return createELFSectionImpl( 548*0fca6ea1SDimitry Andric I->getKey(), Type, Flags, EntrySize, Group, true, true, 549*0fca6ea1SDimitry Andric cast<MCSymbolELF>(RelInfoSection->getBeginSymbol())); 5500b57cec5SDimitry Andric } 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andric MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix, 5530b57cec5SDimitry Andric const Twine &Suffix, unsigned Type, 5540b57cec5SDimitry Andric unsigned Flags, 5550b57cec5SDimitry Andric unsigned EntrySize) { 556fe6060f1SDimitry Andric return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix, 557fe6060f1SDimitry Andric /*IsComdat=*/true); 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, 5610b57cec5SDimitry Andric unsigned Flags, unsigned EntrySize, 562fe6060f1SDimitry Andric const Twine &Group, bool IsComdat, 563fe6060f1SDimitry Andric unsigned UniqueID, 5645ffd83dbSDimitry Andric const MCSymbolELF *LinkedToSym) { 5650b57cec5SDimitry Andric MCSymbolELF *GroupSym = nullptr; 5660b57cec5SDimitry Andric if (!Group.isTriviallyEmpty() && !Group.str().empty()) 5670b57cec5SDimitry Andric GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group)); 5680b57cec5SDimitry Andric 569fe6060f1SDimitry Andric return getELFSection(Section, Type, Flags, EntrySize, GroupSym, IsComdat, 570fe6060f1SDimitry Andric UniqueID, LinkedToSym); 5710b57cec5SDimitry Andric } 5720b57cec5SDimitry Andric 5730b57cec5SDimitry Andric MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, 5740b57cec5SDimitry Andric unsigned Flags, unsigned EntrySize, 5750b57cec5SDimitry Andric const MCSymbolELF *GroupSym, 576fe6060f1SDimitry Andric bool IsComdat, unsigned UniqueID, 5775ffd83dbSDimitry Andric const MCSymbolELF *LinkedToSym) { 5780b57cec5SDimitry Andric StringRef Group = ""; 5790b57cec5SDimitry Andric if (GroupSym) 5800b57cec5SDimitry Andric Group = GroupSym->getName(); 5815ffd83dbSDimitry Andric assert(!(LinkedToSym && LinkedToSym->getName().empty())); 5820b57cec5SDimitry Andric 583*0fca6ea1SDimitry Andric // Sections are differentiated by the quadruple (section_name, group_name, 584*0fca6ea1SDimitry Andric // unique_id, link_to_symbol_name). Sections sharing the same quadruple are 585*0fca6ea1SDimitry Andric // combined into one section. As an optimization, non-unique sections without 586*0fca6ea1SDimitry Andric // group or linked-to symbol have a shorter unique-ing key. 587*0fca6ea1SDimitry Andric std::pair<StringMap<MCSectionELF *>::iterator, bool> EntryNewPair; 588*0fca6ea1SDimitry Andric // Length of the section name, which are the first SectionLen bytes of the key 589*0fca6ea1SDimitry Andric unsigned SectionLen; 590*0fca6ea1SDimitry Andric if (GroupSym || LinkedToSym || UniqueID != MCSection::NonUniqueID) { 591*0fca6ea1SDimitry Andric SmallString<128> Buffer; 592*0fca6ea1SDimitry Andric Section.toVector(Buffer); 593*0fca6ea1SDimitry Andric SectionLen = Buffer.size(); 594*0fca6ea1SDimitry Andric Buffer.push_back(0); // separator which cannot occur in the name 595*0fca6ea1SDimitry Andric if (GroupSym) 596*0fca6ea1SDimitry Andric Buffer.append(GroupSym->getName()); 597*0fca6ea1SDimitry Andric Buffer.push_back(0); // separator which cannot occur in the name 598*0fca6ea1SDimitry Andric if (LinkedToSym) 599*0fca6ea1SDimitry Andric Buffer.append(LinkedToSym->getName()); 600*0fca6ea1SDimitry Andric support::endian::write(Buffer, UniqueID, endianness::native); 601*0fca6ea1SDimitry Andric StringRef UniqueMapKey = StringRef(Buffer); 602*0fca6ea1SDimitry Andric EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr)); 603*0fca6ea1SDimitry Andric } else if (!Section.isSingleStringRef()) { 604*0fca6ea1SDimitry Andric SmallString<128> Buffer; 605*0fca6ea1SDimitry Andric StringRef UniqueMapKey = Section.toStringRef(Buffer); 606*0fca6ea1SDimitry Andric SectionLen = UniqueMapKey.size(); 607*0fca6ea1SDimitry Andric EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr)); 608*0fca6ea1SDimitry Andric } else { 609*0fca6ea1SDimitry Andric StringRef UniqueMapKey = Section.getSingleStringRef(); 610*0fca6ea1SDimitry Andric SectionLen = UniqueMapKey.size(); 611*0fca6ea1SDimitry Andric EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr)); 612*0fca6ea1SDimitry Andric } 6130b57cec5SDimitry Andric 614*0fca6ea1SDimitry Andric if (!EntryNewPair.second) 615*0fca6ea1SDimitry Andric return EntryNewPair.first->second; 616*0fca6ea1SDimitry Andric 617*0fca6ea1SDimitry Andric StringRef CachedName = EntryNewPair.first->getKey().take_front(SectionLen); 6180b57cec5SDimitry Andric 6195ffd83dbSDimitry Andric MCSectionELF *Result = 620*0fca6ea1SDimitry Andric createELFSectionImpl(CachedName, Type, Flags, EntrySize, GroupSym, 621fe6060f1SDimitry Andric IsComdat, UniqueID, LinkedToSym); 622*0fca6ea1SDimitry Andric EntryNewPair.first->second = Result; 6235ffd83dbSDimitry Andric 6245ffd83dbSDimitry Andric recordELFMergeableSectionInfo(Result->getName(), Result->getFlags(), 6255ffd83dbSDimitry Andric Result->getUniqueID(), Result->getEntrySize()); 6265ffd83dbSDimitry Andric 6270b57cec5SDimitry Andric return Result; 6280b57cec5SDimitry Andric } 6290b57cec5SDimitry Andric 630fe6060f1SDimitry Andric MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group, 631fe6060f1SDimitry Andric bool IsComdat) { 632*0fca6ea1SDimitry Andric return createELFSectionImpl(".group", ELF::SHT_GROUP, 0, 4, Group, IsComdat, 6335ffd83dbSDimitry Andric MCSection::NonUniqueID, nullptr); 6345ffd83dbSDimitry Andric } 6355ffd83dbSDimitry Andric 6365ffd83dbSDimitry Andric void MCContext::recordELFMergeableSectionInfo(StringRef SectionName, 6375ffd83dbSDimitry Andric unsigned Flags, unsigned UniqueID, 6385ffd83dbSDimitry Andric unsigned EntrySize) { 6395ffd83dbSDimitry Andric bool IsMergeable = Flags & ELF::SHF_MERGE; 640*0fca6ea1SDimitry Andric if (UniqueID == GenericSectionID) { 6415ffd83dbSDimitry Andric ELFSeenGenericMergeableSections.insert(SectionName); 642*0fca6ea1SDimitry Andric // Minor performance optimization: avoid hash map lookup in 643*0fca6ea1SDimitry Andric // isELFGenericMergeableSection, which will return true for SectionName. 644*0fca6ea1SDimitry Andric IsMergeable = true; 645*0fca6ea1SDimitry Andric } 6465ffd83dbSDimitry Andric 6475ffd83dbSDimitry Andric // For mergeable sections or non-mergeable sections with a generic mergeable 6485ffd83dbSDimitry Andric // section name we enter their Unique ID into the ELFEntrySizeMap so that 6495ffd83dbSDimitry Andric // compatible globals can be assigned to the same section. 650*0fca6ea1SDimitry Andric 6515ffd83dbSDimitry Andric if (IsMergeable || isELFGenericMergeableSection(SectionName)) { 6525ffd83dbSDimitry Andric ELFEntrySizeMap.insert(std::make_pair( 653*0fca6ea1SDimitry Andric std::make_tuple(SectionName, Flags, EntrySize), UniqueID)); 6545ffd83dbSDimitry Andric } 6555ffd83dbSDimitry Andric } 6565ffd83dbSDimitry Andric 6575ffd83dbSDimitry Andric bool MCContext::isELFImplicitMergeableSectionNamePrefix(StringRef SectionName) { 6585f757f3fSDimitry Andric return SectionName.starts_with(".rodata.str") || 6595f757f3fSDimitry Andric SectionName.starts_with(".rodata.cst"); 6605ffd83dbSDimitry Andric } 6615ffd83dbSDimitry Andric 6625ffd83dbSDimitry Andric bool MCContext::isELFGenericMergeableSection(StringRef SectionName) { 6635ffd83dbSDimitry Andric return isELFImplicitMergeableSectionNamePrefix(SectionName) || 6645ffd83dbSDimitry Andric ELFSeenGenericMergeableSections.count(SectionName); 6655ffd83dbSDimitry Andric } 6665ffd83dbSDimitry Andric 667bdd1243dSDimitry Andric std::optional<unsigned> 668bdd1243dSDimitry Andric MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags, 6695ffd83dbSDimitry Andric unsigned EntrySize) { 670*0fca6ea1SDimitry Andric auto I = ELFEntrySizeMap.find(std::make_tuple(SectionName, Flags, EntrySize)); 671bdd1243dSDimitry Andric return (I != ELFEntrySizeMap.end()) ? std::optional<unsigned>(I->second) 672bdd1243dSDimitry Andric : std::nullopt; 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric 67581ad6265SDimitry Andric MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind, 67681ad6265SDimitry Andric MCSection *Parent, 677*0fca6ea1SDimitry Andric uint32_t Subsection) { 678fe6060f1SDimitry Andric // Do the lookup. If we don't have a hit, return a new section. 679cb14a3feSDimitry Andric auto IterBool = 680cb14a3feSDimitry Andric GOFFUniquingMap.insert(std::make_pair(Section.str(), nullptr)); 681cb14a3feSDimitry Andric auto Iter = IterBool.first; 682cb14a3feSDimitry Andric if (!IterBool.second) 683cb14a3feSDimitry Andric return Iter->second; 684cb14a3feSDimitry Andric 685cb14a3feSDimitry Andric StringRef CachedName = Iter->first; 686cb14a3feSDimitry Andric MCSectionGOFF *GOFFSection = new (GOFFAllocator.Allocate()) 687*0fca6ea1SDimitry Andric MCSectionGOFF(CachedName, Kind, Parent, Subsection); 688cb14a3feSDimitry Andric Iter->second = GOFFSection; 689*0fca6ea1SDimitry Andric allocInitialFragment(*GOFFSection); 690fe6060f1SDimitry Andric return GOFFSection; 691fe6060f1SDimitry Andric } 692fe6060f1SDimitry Andric 6930b57cec5SDimitry Andric MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, 6940b57cec5SDimitry Andric unsigned Characteristics, 6950b57cec5SDimitry Andric StringRef COMDATSymName, int Selection, 696*0fca6ea1SDimitry Andric unsigned UniqueID) { 6970b57cec5SDimitry Andric MCSymbol *COMDATSymbol = nullptr; 6980b57cec5SDimitry Andric if (!COMDATSymName.empty()) { 6990b57cec5SDimitry Andric COMDATSymbol = getOrCreateSymbol(COMDATSymName); 7000b57cec5SDimitry Andric COMDATSymName = COMDATSymbol->getName(); 701*0fca6ea1SDimitry Andric // A non-associative COMDAT is considered to define the COMDAT symbol. Check 702*0fca6ea1SDimitry Andric // the redefinition error. 703*0fca6ea1SDimitry Andric if (Selection != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE && COMDATSymbol && 704*0fca6ea1SDimitry Andric COMDATSymbol->isDefined() && 705*0fca6ea1SDimitry Andric (!COMDATSymbol->isInSection() || 706*0fca6ea1SDimitry Andric cast<MCSectionCOFF>(COMDATSymbol->getSection()).getCOMDATSymbol() != 707*0fca6ea1SDimitry Andric COMDATSymbol)) 708*0fca6ea1SDimitry Andric reportError(SMLoc(), "invalid symbol redefinition"); 7090b57cec5SDimitry Andric } 7100b57cec5SDimitry Andric 7110b57cec5SDimitry Andric // Do the lookup, if we have a hit, return it. 7120b57cec5SDimitry Andric COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID}; 7130b57cec5SDimitry Andric auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr)); 7140b57cec5SDimitry Andric auto Iter = IterBool.first; 7150b57cec5SDimitry Andric if (!IterBool.second) 7160b57cec5SDimitry Andric return Iter->second; 7170b57cec5SDimitry Andric 7180b57cec5SDimitry Andric StringRef CachedName = Iter->first.SectionName; 719*0fca6ea1SDimitry Andric MCSymbol *Begin = getOrCreateSectionSymbol<MCSymbolCOFF>(Section); 7200b57cec5SDimitry Andric MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF( 721*0fca6ea1SDimitry Andric CachedName, Characteristics, COMDATSymbol, Selection, Begin); 7220b57cec5SDimitry Andric Iter->second = Result; 723*0fca6ea1SDimitry Andric auto *F = allocInitialFragment(*Result); 724*0fca6ea1SDimitry Andric Begin->setFragment(F); 7250b57cec5SDimitry Andric return Result; 7260b57cec5SDimitry Andric } 7270b57cec5SDimitry Andric 7280b57cec5SDimitry Andric MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, 729*0fca6ea1SDimitry Andric unsigned Characteristics) { 730*0fca6ea1SDimitry Andric return getCOFFSection(Section, Characteristics, "", 0, GenericSectionID); 7310b57cec5SDimitry Andric } 7320b57cec5SDimitry Andric 7330b57cec5SDimitry Andric MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec, 7340b57cec5SDimitry Andric const MCSymbol *KeySym, 7350b57cec5SDimitry Andric unsigned UniqueID) { 7360b57cec5SDimitry Andric // Return the normal section if we don't have to be associative or unique. 7370b57cec5SDimitry Andric if (!KeySym && UniqueID == GenericSectionID) 7380b57cec5SDimitry Andric return Sec; 7390b57cec5SDimitry Andric 7400b57cec5SDimitry Andric // If we have a key symbol, make an associative section with the same name and 7410b57cec5SDimitry Andric // kind as the normal section. 7420b57cec5SDimitry Andric unsigned Characteristics = Sec->getCharacteristics(); 7430b57cec5SDimitry Andric if (KeySym) { 7440b57cec5SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 745*0fca6ea1SDimitry Andric return getCOFFSection(Sec->getName(), Characteristics, KeySym->getName(), 7460b57cec5SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); 7470b57cec5SDimitry Andric } 7480b57cec5SDimitry Andric 749*0fca6ea1SDimitry Andric return getCOFFSection(Sec->getName(), Characteristics, "", 0, UniqueID); 7500b57cec5SDimitry Andric } 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind K, 753fe6060f1SDimitry Andric unsigned Flags, const Twine &Group, 754*0fca6ea1SDimitry Andric unsigned UniqueID) { 7550b57cec5SDimitry Andric MCSymbolWasm *GroupSym = nullptr; 7560b57cec5SDimitry Andric if (!Group.isTriviallyEmpty() && !Group.str().empty()) { 7570b57cec5SDimitry Andric GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group)); 7580b57cec5SDimitry Andric GroupSym->setComdat(true); 7590b57cec5SDimitry Andric } 7600b57cec5SDimitry Andric 761*0fca6ea1SDimitry Andric return getWasmSection(Section, K, Flags, GroupSym, UniqueID); 7620b57cec5SDimitry Andric } 7630b57cec5SDimitry Andric 7640b57cec5SDimitry Andric MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind, 765fe6060f1SDimitry Andric unsigned Flags, 7660b57cec5SDimitry Andric const MCSymbolWasm *GroupSym, 767*0fca6ea1SDimitry Andric unsigned UniqueID) { 7680b57cec5SDimitry Andric StringRef Group = ""; 7690b57cec5SDimitry Andric if (GroupSym) 7700b57cec5SDimitry Andric Group = GroupSym->getName(); 7710b57cec5SDimitry Andric // Do the lookup, if we have a hit, return it. 7720b57cec5SDimitry Andric auto IterBool = WasmUniquingMap.insert( 7730b57cec5SDimitry Andric std::make_pair(WasmSectionKey{Section.str(), Group, UniqueID}, nullptr)); 7740b57cec5SDimitry Andric auto &Entry = *IterBool.first; 7750b57cec5SDimitry Andric if (!IterBool.second) 7760b57cec5SDimitry Andric return Entry.second; 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric StringRef CachedName = Entry.first.SectionName; 7790b57cec5SDimitry Andric 780*0fca6ea1SDimitry Andric MCSymbol *Begin = createRenamableSymbol(CachedName, true, false); 781*0fca6ea1SDimitry Andric // Begin always has a different name than CachedName... see #48596. 782*0fca6ea1SDimitry Andric getSymbolTableEntry(Begin->getName()).second.Symbol = Begin; 7830b57cec5SDimitry Andric cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION); 7840b57cec5SDimitry Andric 7850b57cec5SDimitry Andric MCSectionWasm *Result = new (WasmAllocator.Allocate()) 786fe6060f1SDimitry Andric MCSectionWasm(CachedName, Kind, Flags, GroupSym, UniqueID, Begin); 7870b57cec5SDimitry Andric Entry.second = Result; 7880b57cec5SDimitry Andric 789*0fca6ea1SDimitry Andric auto *F = allocInitialFragment(*Result); 7900b57cec5SDimitry Andric Begin->setFragment(F); 7910b57cec5SDimitry Andric return Result; 7920b57cec5SDimitry Andric } 7930b57cec5SDimitry Andric 79481ad6265SDimitry Andric bool MCContext::hasXCOFFSection(StringRef Section, 79581ad6265SDimitry Andric XCOFF::CsectProperties CsectProp) const { 79681ad6265SDimitry Andric return XCOFFUniquingMap.count( 79781ad6265SDimitry Andric XCOFFSectionKey(Section.str(), CsectProp.MappingClass)) != 0; 79881ad6265SDimitry Andric } 79981ad6265SDimitry Andric 800fe6060f1SDimitry Andric MCSectionXCOFF *MCContext::getXCOFFSection( 801fe6060f1SDimitry Andric StringRef Section, SectionKind Kind, 802bdd1243dSDimitry Andric std::optional<XCOFF::CsectProperties> CsectProp, bool MultiSymbolsAllowed, 803bdd1243dSDimitry Andric std::optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSectionSubtypeFlags) { 80481ad6265SDimitry Andric bool IsDwarfSec = DwarfSectionSubtypeFlags.has_value(); 80581ad6265SDimitry Andric assert((IsDwarfSec != CsectProp.has_value()) && "Invalid XCOFF section!"); 806fe6060f1SDimitry Andric 8070b57cec5SDimitry Andric // Do the lookup. If we have a hit, return it. 808fe6060f1SDimitry Andric auto IterBool = XCOFFUniquingMap.insert(std::make_pair( 809bdd1243dSDimitry Andric IsDwarfSec ? XCOFFSectionKey(Section.str(), *DwarfSectionSubtypeFlags) 810fe6060f1SDimitry Andric : XCOFFSectionKey(Section.str(), CsectProp->MappingClass), 811fe6060f1SDimitry Andric nullptr)); 8120b57cec5SDimitry Andric auto &Entry = *IterBool.first; 813e8d8bef9SDimitry Andric if (!IterBool.second) { 814e8d8bef9SDimitry Andric MCSectionXCOFF *ExistedEntry = Entry.second; 815e8d8bef9SDimitry Andric if (ExistedEntry->isMultiSymbolsAllowed() != MultiSymbolsAllowed) 816e8d8bef9SDimitry Andric report_fatal_error("section's multiply symbols policy does not match"); 817e8d8bef9SDimitry Andric 818e8d8bef9SDimitry Andric return ExistedEntry; 819e8d8bef9SDimitry Andric } 8200b57cec5SDimitry Andric 8210b57cec5SDimitry Andric // Otherwise, return a new section. 8220b57cec5SDimitry Andric StringRef CachedName = Entry.first.SectionName; 823fe6060f1SDimitry Andric MCSymbolXCOFF *QualName = nullptr; 824fe6060f1SDimitry Andric // Debug section don't have storage class attribute. 825fe6060f1SDimitry Andric if (IsDwarfSec) 826fe6060f1SDimitry Andric QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(CachedName)); 827fe6060f1SDimitry Andric else 828fe6060f1SDimitry Andric QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol( 829fe6060f1SDimitry Andric CachedName + "[" + 830fe6060f1SDimitry Andric XCOFF::getMappingClassString(CsectProp->MappingClass) + "]")); 8310b57cec5SDimitry Andric 8325ffd83dbSDimitry Andric // QualName->getUnqualifiedName() and CachedName are the same except when 8335ffd83dbSDimitry Andric // CachedName contains invalid character(s) such as '$' for an XCOFF symbol. 834fe6060f1SDimitry Andric MCSectionXCOFF *Result = nullptr; 835fe6060f1SDimitry Andric if (IsDwarfSec) 836bdd1243dSDimitry Andric Result = new (XCOFFAllocator.Allocate()) MCSectionXCOFF( 837bdd1243dSDimitry Andric QualName->getUnqualifiedName(), Kind, QualName, 838*0fca6ea1SDimitry Andric *DwarfSectionSubtypeFlags, QualName, CachedName, MultiSymbolsAllowed); 839fe6060f1SDimitry Andric else 840fe6060f1SDimitry Andric Result = new (XCOFFAllocator.Allocate()) 841fe6060f1SDimitry Andric MCSectionXCOFF(QualName->getUnqualifiedName(), CsectProp->MappingClass, 842*0fca6ea1SDimitry Andric CsectProp->Type, Kind, QualName, nullptr, CachedName, 843fe6060f1SDimitry Andric MultiSymbolsAllowed); 844fe6060f1SDimitry Andric 8450b57cec5SDimitry Andric Entry.second = Result; 8460b57cec5SDimitry Andric 847*0fca6ea1SDimitry Andric auto *F = allocInitialFragment(*Result); 8480b57cec5SDimitry Andric 849bdd1243dSDimitry Andric // We might miss calculating the symbols difference as absolute value before 850bdd1243dSDimitry Andric // adding fixups when symbol_A without the fragment set is the csect itself 851bdd1243dSDimitry Andric // and symbol_B is in it. 852*0fca6ea1SDimitry Andric // TODO: Currently we only set the fragment for XMC_PR csects and DWARF 853*0fca6ea1SDimitry Andric // sections because we don't have other cases that hit this problem yet. 854*0fca6ea1SDimitry Andric if (IsDwarfSec || CsectProp->MappingClass == XCOFF::XMC_PR) 855bdd1243dSDimitry Andric QualName->setFragment(F); 856bdd1243dSDimitry Andric 8570b57cec5SDimitry Andric return Result; 8580b57cec5SDimitry Andric } 8590b57cec5SDimitry Andric 86081ad6265SDimitry Andric MCSectionSPIRV *MCContext::getSPIRVSection() { 861*0fca6ea1SDimitry Andric MCSectionSPIRV *Result = new (SPIRVAllocator.Allocate()) MCSectionSPIRV(); 86281ad6265SDimitry Andric 863*0fca6ea1SDimitry Andric allocInitialFragment(*Result); 86481ad6265SDimitry Andric return Result; 86581ad6265SDimitry Andric } 86681ad6265SDimitry Andric 86781ad6265SDimitry Andric MCSectionDXContainer *MCContext::getDXContainerSection(StringRef Section, 86881ad6265SDimitry Andric SectionKind K) { 86981ad6265SDimitry Andric // Do the lookup, if we have a hit, return it. 87081ad6265SDimitry Andric auto ItInsertedPair = DXCUniquingMap.try_emplace(Section); 87181ad6265SDimitry Andric if (!ItInsertedPair.second) 87281ad6265SDimitry Andric return ItInsertedPair.first->second; 87381ad6265SDimitry Andric 87481ad6265SDimitry Andric auto MapIt = ItInsertedPair.first; 87581ad6265SDimitry Andric // Grab the name from the StringMap. Since the Section is going to keep a 87681ad6265SDimitry Andric // copy of this StringRef we need to make sure the underlying string stays 87781ad6265SDimitry Andric // alive as long as we need it. 87881ad6265SDimitry Andric StringRef Name = MapIt->first(); 87981ad6265SDimitry Andric MapIt->second = 88081ad6265SDimitry Andric new (DXCAllocator.Allocate()) MCSectionDXContainer(Name, K, nullptr); 88181ad6265SDimitry Andric 88281ad6265SDimitry Andric // The first fragment will store the header 883*0fca6ea1SDimitry Andric allocInitialFragment(*MapIt->second); 88481ad6265SDimitry Andric return MapIt->second; 88581ad6265SDimitry Andric } 88681ad6265SDimitry Andric 8870b57cec5SDimitry Andric MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) { 8880b57cec5SDimitry Andric return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI); 8890b57cec5SDimitry Andric } 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric void MCContext::addDebugPrefixMapEntry(const std::string &From, 8920b57cec5SDimitry Andric const std::string &To) { 89306c3fb27SDimitry Andric DebugPrefixMap.emplace_back(From, To); 8940b57cec5SDimitry Andric } 8950b57cec5SDimitry Andric 896a4a491e2SDimitry Andric void MCContext::remapDebugPath(SmallVectorImpl<char> &Path) { 89706c3fb27SDimitry Andric for (const auto &[From, To] : llvm::reverse(DebugPrefixMap)) 898bdd1243dSDimitry Andric if (llvm::sys::path::replace_path_prefix(Path, From, To)) 899a4a491e2SDimitry Andric break; 900a4a491e2SDimitry Andric } 901a4a491e2SDimitry Andric 9020b57cec5SDimitry Andric void MCContext::RemapDebugPaths() { 9030b57cec5SDimitry Andric const auto &DebugPrefixMap = this->DebugPrefixMap; 9045ffd83dbSDimitry Andric if (DebugPrefixMap.empty()) 9055ffd83dbSDimitry Andric return; 9065ffd83dbSDimitry Andric 9070b57cec5SDimitry Andric // Remap compilation directory. 908a4a491e2SDimitry Andric remapDebugPath(CompilationDir); 9090b57cec5SDimitry Andric 910a4a491e2SDimitry Andric // Remap MCDwarfDirs and RootFile.Name in all compilation units. 911a4a491e2SDimitry Andric SmallString<256> P; 912a4a491e2SDimitry Andric for (auto &CUIDTablePair : MCDwarfLineTablesCUMap) { 913a4a491e2SDimitry Andric for (auto &Dir : CUIDTablePair.second.getMCDwarfDirs()) { 914a4a491e2SDimitry Andric P = Dir; 915a4a491e2SDimitry Andric remapDebugPath(P); 916a4a491e2SDimitry Andric Dir = std::string(P); 917a4a491e2SDimitry Andric } 918a4a491e2SDimitry Andric 919a4a491e2SDimitry Andric // Used by DW_TAG_compile_unit's DT_AT_name and DW_TAG_label's 920a4a491e2SDimitry Andric // DW_AT_decl_file for DWARF v5 generated for assembly source. 921a4a491e2SDimitry Andric P = CUIDTablePair.second.getRootFile().Name; 922a4a491e2SDimitry Andric remapDebugPath(P); 923a4a491e2SDimitry Andric CUIDTablePair.second.getRootFile().Name = std::string(P); 924a4a491e2SDimitry Andric } 9250b57cec5SDimitry Andric } 9260b57cec5SDimitry Andric 9270b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9280b57cec5SDimitry Andric // Dwarf Management 9290b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9300b57cec5SDimitry Andric 93181ad6265SDimitry Andric EmitDwarfUnwindType MCContext::emitDwarfUnwindInfo() const { 93281ad6265SDimitry Andric if (!TargetOptions) 93381ad6265SDimitry Andric return EmitDwarfUnwindType::Default; 93481ad6265SDimitry Andric return TargetOptions->EmitDwarfUnwind; 93581ad6265SDimitry Andric } 93681ad6265SDimitry Andric 93706c3fb27SDimitry Andric bool MCContext::emitCompactUnwindNonCanonical() const { 93806c3fb27SDimitry Andric if (TargetOptions) 93906c3fb27SDimitry Andric return TargetOptions->EmitCompactUnwindNonCanonical; 94006c3fb27SDimitry Andric return false; 94106c3fb27SDimitry Andric } 94206c3fb27SDimitry Andric 9430b57cec5SDimitry Andric void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) { 9440b57cec5SDimitry Andric // MCDwarf needs the root file as well as the compilation directory. 9450b57cec5SDimitry Andric // If we find a '.file 0' directive that will supersede these values. 946bdd1243dSDimitry Andric std::optional<MD5::MD5Result> Cksum; 9470b57cec5SDimitry Andric if (getDwarfVersion() >= 5) { 9480b57cec5SDimitry Andric MD5 Hash; 9490b57cec5SDimitry Andric MD5::MD5Result Sum; 9500b57cec5SDimitry Andric Hash.update(Buffer); 9510b57cec5SDimitry Andric Hash.final(Sum); 9520b57cec5SDimitry Andric Cksum = Sum; 9530b57cec5SDimitry Andric } 9540b57cec5SDimitry Andric // Canonicalize the root filename. It cannot be empty, and should not 9550b57cec5SDimitry Andric // repeat the compilation dir. 9560b57cec5SDimitry Andric // The MCContext ctor initializes MainFileName to the name associated with 9570b57cec5SDimitry Andric // the SrcMgr's main file ID, which might be the same as InputFileName (and 9580b57cec5SDimitry Andric // possibly include directory components). 9590b57cec5SDimitry Andric // Or, MainFileName might have been overridden by a -main-file-name option, 9600b57cec5SDimitry Andric // which is supposed to be just a base filename with no directory component. 9610b57cec5SDimitry Andric // So, if the InputFileName and MainFileName are not equal, assume 9620b57cec5SDimitry Andric // MainFileName is a substitute basename and replace the last component. 9630b57cec5SDimitry Andric SmallString<1024> FileNameBuf = InputFileName; 9640b57cec5SDimitry Andric if (FileNameBuf.empty() || FileNameBuf == "-") 9650b57cec5SDimitry Andric FileNameBuf = "<stdin>"; 9660b57cec5SDimitry Andric if (!getMainFileName().empty() && FileNameBuf != getMainFileName()) { 9670b57cec5SDimitry Andric llvm::sys::path::remove_filename(FileNameBuf); 9680b57cec5SDimitry Andric llvm::sys::path::append(FileNameBuf, getMainFileName()); 9690b57cec5SDimitry Andric } 9700b57cec5SDimitry Andric StringRef FileName = FileNameBuf; 9710b57cec5SDimitry Andric if (FileName.consume_front(getCompilationDir())) 9720b57cec5SDimitry Andric if (llvm::sys::path::is_separator(FileName.front())) 9730b57cec5SDimitry Andric FileName = FileName.drop_front(); 9740b57cec5SDimitry Andric assert(!FileName.empty()); 9750b57cec5SDimitry Andric setMCLineTableRootFile( 976bdd1243dSDimitry Andric /*CUID=*/0, getCompilationDir(), FileName, Cksum, std::nullopt); 9770b57cec5SDimitry Andric } 9780b57cec5SDimitry Andric 9790b57cec5SDimitry Andric /// getDwarfFile - takes a file name and number to place in the dwarf file and 9800b57cec5SDimitry Andric /// directory tables. If the file number has already been allocated it is an 9810b57cec5SDimitry Andric /// error and zero is returned and the client reports the error, else the 9820b57cec5SDimitry Andric /// allocated file number is returned. The file numbers may be in any order. 983bdd1243dSDimitry Andric Expected<unsigned> 984bdd1243dSDimitry Andric MCContext::getDwarfFile(StringRef Directory, StringRef FileName, 9850b57cec5SDimitry Andric unsigned FileNumber, 986bdd1243dSDimitry Andric std::optional<MD5::MD5Result> Checksum, 987bdd1243dSDimitry Andric std::optional<StringRef> Source, unsigned CUID) { 9880b57cec5SDimitry Andric MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; 9890b57cec5SDimitry Andric return Table.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion, 9900b57cec5SDimitry Andric FileNumber); 9910b57cec5SDimitry Andric } 9920b57cec5SDimitry Andric 9930b57cec5SDimitry Andric /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it 9940b57cec5SDimitry Andric /// currently is assigned and false otherwise. 9950b57cec5SDimitry Andric bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) { 9960b57cec5SDimitry Andric const MCDwarfLineTable &LineTable = getMCDwarfLineTable(CUID); 9970b57cec5SDimitry Andric if (FileNumber == 0) 9980b57cec5SDimitry Andric return getDwarfVersion() >= 5; 9990b57cec5SDimitry Andric if (FileNumber >= LineTable.getMCDwarfFiles().size()) 10000b57cec5SDimitry Andric return false; 10010b57cec5SDimitry Andric 10020b57cec5SDimitry Andric return !LineTable.getMCDwarfFiles()[FileNumber].Name.empty(); 10030b57cec5SDimitry Andric } 10040b57cec5SDimitry Andric 10050b57cec5SDimitry Andric /// Remove empty sections from SectionsForRanges, to avoid generating 10060b57cec5SDimitry Andric /// useless debug info for them. 10070b57cec5SDimitry Andric void MCContext::finalizeDwarfSections(MCStreamer &MCOS) { 10080b57cec5SDimitry Andric SectionsForRanges.remove_if( 10090b57cec5SDimitry Andric [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); }); 10100b57cec5SDimitry Andric } 10110b57cec5SDimitry Andric 10120b57cec5SDimitry Andric CodeViewContext &MCContext::getCVContext() { 101381ad6265SDimitry Andric if (!CVContext) 1014*0fca6ea1SDimitry Andric CVContext.reset(new CodeViewContext(this)); 101581ad6265SDimitry Andric return *CVContext; 10160b57cec5SDimitry Andric } 10170b57cec5SDimitry Andric 10180b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 10190b57cec5SDimitry Andric // Error Reporting 10200b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 10210b57cec5SDimitry Andric 1022fe6060f1SDimitry Andric void MCContext::diagnose(const SMDiagnostic &SMD) { 1023fe6060f1SDimitry Andric assert(DiagHandler && "MCContext::DiagHandler is not set"); 1024fe6060f1SDimitry Andric bool UseInlineSrcMgr = false; 1025fe6060f1SDimitry Andric const SourceMgr *SMP = nullptr; 1026fe6060f1SDimitry Andric if (SrcMgr) { 1027fe6060f1SDimitry Andric SMP = SrcMgr; 1028fe6060f1SDimitry Andric } else if (InlineSrcMgr) { 1029fe6060f1SDimitry Andric SMP = InlineSrcMgr.get(); 1030fe6060f1SDimitry Andric UseInlineSrcMgr = true; 1031fe6060f1SDimitry Andric } else 1032fe6060f1SDimitry Andric llvm_unreachable("Either SourceMgr should be available"); 1033fe6060f1SDimitry Andric DiagHandler(SMD, UseInlineSrcMgr, *SMP, LocInfos); 1034fe6060f1SDimitry Andric } 1035fe6060f1SDimitry Andric 1036fe6060f1SDimitry Andric void MCContext::reportCommon( 1037fe6060f1SDimitry Andric SMLoc Loc, 1038fe6060f1SDimitry Andric std::function<void(SMDiagnostic &, const SourceMgr *)> GetMessage) { 1039fe6060f1SDimitry Andric // * MCContext::SrcMgr is null when the MC layer emits machine code for input 1040fe6060f1SDimitry Andric // other than assembly file, say, for .c/.cpp/.ll/.bc. 1041fe6060f1SDimitry Andric // * MCContext::InlineSrcMgr is null when the inline asm is not used. 1042fe6060f1SDimitry Andric // * A default SourceMgr is needed for diagnosing when both MCContext::SrcMgr 1043fe6060f1SDimitry Andric // and MCContext::InlineSrcMgr are null. 1044fe6060f1SDimitry Andric SourceMgr SM; 1045fe6060f1SDimitry Andric const SourceMgr *SMP = &SM; 1046fe6060f1SDimitry Andric bool UseInlineSrcMgr = false; 1047fe6060f1SDimitry Andric 1048fe6060f1SDimitry Andric // FIXME: Simplify these by combining InlineSrcMgr & SrcMgr. 1049fe6060f1SDimitry Andric // For MC-only execution, only SrcMgr is used; 1050fe6060f1SDimitry Andric // For non MC-only execution, InlineSrcMgr is only ctor'd if there is 1051fe6060f1SDimitry Andric // inline asm in the IR. 1052fe6060f1SDimitry Andric if (Loc.isValid()) { 1053fe6060f1SDimitry Andric if (SrcMgr) { 1054fe6060f1SDimitry Andric SMP = SrcMgr; 1055fe6060f1SDimitry Andric } else if (InlineSrcMgr) { 1056fe6060f1SDimitry Andric SMP = InlineSrcMgr.get(); 1057fe6060f1SDimitry Andric UseInlineSrcMgr = true; 1058fe6060f1SDimitry Andric } else 1059fe6060f1SDimitry Andric llvm_unreachable("Either SourceMgr should be available"); 1060fe6060f1SDimitry Andric } 1061fe6060f1SDimitry Andric 1062fe6060f1SDimitry Andric SMDiagnostic D; 1063fe6060f1SDimitry Andric GetMessage(D, SMP); 1064fe6060f1SDimitry Andric DiagHandler(D, UseInlineSrcMgr, *SMP, LocInfos); 1065fe6060f1SDimitry Andric } 1066fe6060f1SDimitry Andric 10670b57cec5SDimitry Andric void MCContext::reportError(SMLoc Loc, const Twine &Msg) { 10680b57cec5SDimitry Andric HadError = true; 1069fe6060f1SDimitry Andric reportCommon(Loc, [&](SMDiagnostic &D, const SourceMgr *SMP) { 1070fe6060f1SDimitry Andric D = SMP->GetMessage(Loc, SourceMgr::DK_Error, Msg); 1071fe6060f1SDimitry Andric }); 10720b57cec5SDimitry Andric } 10730b57cec5SDimitry Andric 10748bcb0991SDimitry Andric void MCContext::reportWarning(SMLoc Loc, const Twine &Msg) { 10758bcb0991SDimitry Andric if (TargetOptions && TargetOptions->MCNoWarn) 10768bcb0991SDimitry Andric return; 1077fe6060f1SDimitry Andric if (TargetOptions && TargetOptions->MCFatalWarnings) { 10788bcb0991SDimitry Andric reportError(Loc, Msg); 1079fe6060f1SDimitry Andric } else { 1080fe6060f1SDimitry Andric reportCommon(Loc, [&](SMDiagnostic &D, const SourceMgr *SMP) { 1081fe6060f1SDimitry Andric D = SMP->GetMessage(Loc, SourceMgr::DK_Warning, Msg); 1082fe6060f1SDimitry Andric }); 10838bcb0991SDimitry Andric } 10848bcb0991SDimitry Andric } 1085