1*0b57cec5SDimitry Andric //===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 10*0b57cec5SDimitry Andric #include "llvm/ADT/Optional.h" 11*0b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 12*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 13*0b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h" 14*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 15*0b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 16*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h" 17*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h" 18*0b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 19*0b57cec5SDimitry Andric #include "llvm/MC/MCCodeView.h" 20*0b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h" 21*0b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 22*0b57cec5SDimitry Andric #include "llvm/MC/MCFragment.h" 23*0b57cec5SDimitry Andric #include "llvm/MC/MCLabel.h" 24*0b57cec5SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h" 25*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionCOFF.h" 26*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionELF.h" 27*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h" 28*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionWasm.h" 29*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionXCOFF.h" 30*0b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 31*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 32*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbolCOFF.h" 33*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h" 34*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbolMachO.h" 35*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbolWasm.h" 36*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbolXCOFF.h" 37*0b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h" 38*0b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 39*0b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 40*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 41*0b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 42*0b57cec5SDimitry Andric #include "llvm/Support/Path.h" 43*0b57cec5SDimitry Andric #include "llvm/Support/Signals.h" 44*0b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h" 45*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 46*0b57cec5SDimitry Andric #include <cassert> 47*0b57cec5SDimitry Andric #include <cstdlib> 48*0b57cec5SDimitry Andric #include <tuple> 49*0b57cec5SDimitry Andric #include <utility> 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric using namespace llvm; 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric static cl::opt<char*> 54*0b57cec5SDimitry Andric AsSecureLogFileName("as-secure-log-file-name", 55*0b57cec5SDimitry Andric cl::desc("As secure log file name (initialized from " 56*0b57cec5SDimitry Andric "AS_SECURE_LOG_FILE env variable)"), 57*0b57cec5SDimitry Andric cl::init(getenv("AS_SECURE_LOG_FILE")), cl::Hidden); 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri, 60*0b57cec5SDimitry Andric const MCObjectFileInfo *mofi, const SourceMgr *mgr, 61*0b57cec5SDimitry Andric bool DoAutoReset) 62*0b57cec5SDimitry Andric : SrcMgr(mgr), InlineSrcMgr(nullptr), MAI(mai), MRI(mri), MOFI(mofi), 63*0b57cec5SDimitry Andric Symbols(Allocator), UsedNames(Allocator), 64*0b57cec5SDimitry Andric InlineAsmUsedLabelNames(Allocator), 65*0b57cec5SDimitry Andric CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), 66*0b57cec5SDimitry Andric AutoReset(DoAutoReset) { 67*0b57cec5SDimitry Andric SecureLogFile = AsSecureLogFileName; 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric if (SrcMgr && SrcMgr->getNumBuffers()) 70*0b57cec5SDimitry Andric MainFileName = 71*0b57cec5SDimitry Andric SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())->getBufferIdentifier(); 72*0b57cec5SDimitry Andric } 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric MCContext::~MCContext() { 75*0b57cec5SDimitry Andric if (AutoReset) 76*0b57cec5SDimitry Andric reset(); 77*0b57cec5SDimitry Andric 78*0b57cec5SDimitry Andric // NOTE: The symbols are all allocated out of a bump pointer allocator, 79*0b57cec5SDimitry Andric // we don't need to free them here. 80*0b57cec5SDimitry Andric } 81*0b57cec5SDimitry Andric 82*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 83*0b57cec5SDimitry Andric // Module Lifetime Management 84*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andric void MCContext::reset() { 87*0b57cec5SDimitry Andric // Call the destructors so the fragments are freed 88*0b57cec5SDimitry Andric COFFAllocator.DestroyAll(); 89*0b57cec5SDimitry Andric ELFAllocator.DestroyAll(); 90*0b57cec5SDimitry Andric MachOAllocator.DestroyAll(); 91*0b57cec5SDimitry Andric XCOFFAllocator.DestroyAll(); 92*0b57cec5SDimitry Andric 93*0b57cec5SDimitry Andric MCSubtargetAllocator.DestroyAll(); 94*0b57cec5SDimitry Andric InlineAsmUsedLabelNames.clear(); 95*0b57cec5SDimitry Andric UsedNames.clear(); 96*0b57cec5SDimitry Andric Symbols.clear(); 97*0b57cec5SDimitry Andric Allocator.Reset(); 98*0b57cec5SDimitry Andric Instances.clear(); 99*0b57cec5SDimitry Andric CompilationDir.clear(); 100*0b57cec5SDimitry Andric MainFileName.clear(); 101*0b57cec5SDimitry Andric MCDwarfLineTablesCUMap.clear(); 102*0b57cec5SDimitry Andric SectionsForRanges.clear(); 103*0b57cec5SDimitry Andric MCGenDwarfLabelEntries.clear(); 104*0b57cec5SDimitry Andric DwarfDebugFlags = StringRef(); 105*0b57cec5SDimitry Andric DwarfCompileUnitID = 0; 106*0b57cec5SDimitry Andric CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0); 107*0b57cec5SDimitry Andric 108*0b57cec5SDimitry Andric CVContext.reset(); 109*0b57cec5SDimitry Andric 110*0b57cec5SDimitry Andric MachOUniquingMap.clear(); 111*0b57cec5SDimitry Andric ELFUniquingMap.clear(); 112*0b57cec5SDimitry Andric COFFUniquingMap.clear(); 113*0b57cec5SDimitry Andric WasmUniquingMap.clear(); 114*0b57cec5SDimitry Andric XCOFFUniquingMap.clear(); 115*0b57cec5SDimitry Andric 116*0b57cec5SDimitry Andric NextID.clear(); 117*0b57cec5SDimitry Andric AllowTemporaryLabels = true; 118*0b57cec5SDimitry Andric DwarfLocSeen = false; 119*0b57cec5SDimitry Andric GenDwarfForAssembly = false; 120*0b57cec5SDimitry Andric GenDwarfFileNumber = 0; 121*0b57cec5SDimitry Andric 122*0b57cec5SDimitry Andric HadError = false; 123*0b57cec5SDimitry Andric } 124*0b57cec5SDimitry Andric 125*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 126*0b57cec5SDimitry Andric // Symbol Manipulation 127*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 128*0b57cec5SDimitry Andric 129*0b57cec5SDimitry Andric MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) { 130*0b57cec5SDimitry Andric SmallString<128> NameSV; 131*0b57cec5SDimitry Andric StringRef NameRef = Name.toStringRef(NameSV); 132*0b57cec5SDimitry Andric 133*0b57cec5SDimitry Andric assert(!NameRef.empty() && "Normal symbols cannot be unnamed!"); 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric MCSymbol *&Sym = Symbols[NameRef]; 136*0b57cec5SDimitry Andric if (!Sym) 137*0b57cec5SDimitry Andric Sym = createSymbol(NameRef, false, false); 138*0b57cec5SDimitry Andric 139*0b57cec5SDimitry Andric return Sym; 140*0b57cec5SDimitry Andric } 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName, 143*0b57cec5SDimitry Andric unsigned Idx) { 144*0b57cec5SDimitry Andric return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName + 145*0b57cec5SDimitry Andric "$frame_escape_" + Twine(Idx)); 146*0b57cec5SDimitry Andric } 147*0b57cec5SDimitry Andric 148*0b57cec5SDimitry Andric MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName) { 149*0b57cec5SDimitry Andric return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName + 150*0b57cec5SDimitry Andric "$parent_frame_offset"); 151*0b57cec5SDimitry Andric } 152*0b57cec5SDimitry Andric 153*0b57cec5SDimitry Andric MCSymbol *MCContext::getOrCreateLSDASymbol(StringRef FuncName) { 154*0b57cec5SDimitry Andric return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + "__ehtable$" + 155*0b57cec5SDimitry Andric FuncName); 156*0b57cec5SDimitry Andric } 157*0b57cec5SDimitry Andric 158*0b57cec5SDimitry Andric MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name, 159*0b57cec5SDimitry Andric bool IsTemporary) { 160*0b57cec5SDimitry Andric if (MOFI) { 161*0b57cec5SDimitry Andric switch (MOFI->getObjectFileType()) { 162*0b57cec5SDimitry Andric case MCObjectFileInfo::IsCOFF: 163*0b57cec5SDimitry Andric return new (Name, *this) MCSymbolCOFF(Name, IsTemporary); 164*0b57cec5SDimitry Andric case MCObjectFileInfo::IsELF: 165*0b57cec5SDimitry Andric return new (Name, *this) MCSymbolELF(Name, IsTemporary); 166*0b57cec5SDimitry Andric case MCObjectFileInfo::IsMachO: 167*0b57cec5SDimitry Andric return new (Name, *this) MCSymbolMachO(Name, IsTemporary); 168*0b57cec5SDimitry Andric case MCObjectFileInfo::IsWasm: 169*0b57cec5SDimitry Andric return new (Name, *this) MCSymbolWasm(Name, IsTemporary); 170*0b57cec5SDimitry Andric case MCObjectFileInfo::IsXCOFF: 171*0b57cec5SDimitry Andric return new (Name, *this) MCSymbolXCOFF(Name, IsTemporary); 172*0b57cec5SDimitry Andric } 173*0b57cec5SDimitry Andric } 174*0b57cec5SDimitry Andric return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name, 175*0b57cec5SDimitry Andric IsTemporary); 176*0b57cec5SDimitry Andric } 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix, 179*0b57cec5SDimitry Andric bool CanBeUnnamed) { 180*0b57cec5SDimitry Andric if (CanBeUnnamed && !UseNamesOnTempLabels) 181*0b57cec5SDimitry Andric return createSymbolImpl(nullptr, true); 182*0b57cec5SDimitry Andric 183*0b57cec5SDimitry Andric // Determine whether this is a user written assembler temporary or normal 184*0b57cec5SDimitry Andric // label, if used. 185*0b57cec5SDimitry Andric bool IsTemporary = CanBeUnnamed; 186*0b57cec5SDimitry Andric if (AllowTemporaryLabels && !IsTemporary) 187*0b57cec5SDimitry Andric IsTemporary = Name.startswith(MAI->getPrivateGlobalPrefix()); 188*0b57cec5SDimitry Andric 189*0b57cec5SDimitry Andric SmallString<128> NewName = Name; 190*0b57cec5SDimitry Andric bool AddSuffix = AlwaysAddSuffix; 191*0b57cec5SDimitry Andric unsigned &NextUniqueID = NextID[Name]; 192*0b57cec5SDimitry Andric while (true) { 193*0b57cec5SDimitry Andric if (AddSuffix) { 194*0b57cec5SDimitry Andric NewName.resize(Name.size()); 195*0b57cec5SDimitry Andric raw_svector_ostream(NewName) << NextUniqueID++; 196*0b57cec5SDimitry Andric } 197*0b57cec5SDimitry Andric auto NameEntry = UsedNames.insert(std::make_pair(NewName, true)); 198*0b57cec5SDimitry Andric if (NameEntry.second || !NameEntry.first->second) { 199*0b57cec5SDimitry Andric // Ok, we found a name. 200*0b57cec5SDimitry Andric // Mark it as used for a non-section symbol. 201*0b57cec5SDimitry Andric NameEntry.first->second = true; 202*0b57cec5SDimitry Andric // Have the MCSymbol object itself refer to the copy of the string that is 203*0b57cec5SDimitry Andric // embedded in the UsedNames entry. 204*0b57cec5SDimitry Andric return createSymbolImpl(&*NameEntry.first, IsTemporary); 205*0b57cec5SDimitry Andric } 206*0b57cec5SDimitry Andric assert(IsTemporary && "Cannot rename non-temporary symbols"); 207*0b57cec5SDimitry Andric AddSuffix = true; 208*0b57cec5SDimitry Andric } 209*0b57cec5SDimitry Andric llvm_unreachable("Infinite loop"); 210*0b57cec5SDimitry Andric } 211*0b57cec5SDimitry Andric 212*0b57cec5SDimitry Andric MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix, 213*0b57cec5SDimitry Andric bool CanBeUnnamed) { 214*0b57cec5SDimitry Andric SmallString<128> NameSV; 215*0b57cec5SDimitry Andric raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name; 216*0b57cec5SDimitry Andric return createSymbol(NameSV, AlwaysAddSuffix, CanBeUnnamed); 217*0b57cec5SDimitry Andric } 218*0b57cec5SDimitry Andric 219*0b57cec5SDimitry Andric MCSymbol *MCContext::createLinkerPrivateTempSymbol() { 220*0b57cec5SDimitry Andric SmallString<128> NameSV; 221*0b57cec5SDimitry Andric raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp"; 222*0b57cec5SDimitry Andric return createSymbol(NameSV, true, false); 223*0b57cec5SDimitry Andric } 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andric MCSymbol *MCContext::createTempSymbol(bool CanBeUnnamed) { 226*0b57cec5SDimitry Andric return createTempSymbol("tmp", true, CanBeUnnamed); 227*0b57cec5SDimitry Andric } 228*0b57cec5SDimitry Andric 229*0b57cec5SDimitry Andric unsigned MCContext::NextInstance(unsigned LocalLabelVal) { 230*0b57cec5SDimitry Andric MCLabel *&Label = Instances[LocalLabelVal]; 231*0b57cec5SDimitry Andric if (!Label) 232*0b57cec5SDimitry Andric Label = new (*this) MCLabel(0); 233*0b57cec5SDimitry Andric return Label->incInstance(); 234*0b57cec5SDimitry Andric } 235*0b57cec5SDimitry Andric 236*0b57cec5SDimitry Andric unsigned MCContext::GetInstance(unsigned LocalLabelVal) { 237*0b57cec5SDimitry Andric MCLabel *&Label = Instances[LocalLabelVal]; 238*0b57cec5SDimitry Andric if (!Label) 239*0b57cec5SDimitry Andric Label = new (*this) MCLabel(0); 240*0b57cec5SDimitry Andric return Label->getInstance(); 241*0b57cec5SDimitry Andric } 242*0b57cec5SDimitry Andric 243*0b57cec5SDimitry Andric MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, 244*0b57cec5SDimitry Andric unsigned Instance) { 245*0b57cec5SDimitry Andric MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)]; 246*0b57cec5SDimitry Andric if (!Sym) 247*0b57cec5SDimitry Andric Sym = createTempSymbol(false); 248*0b57cec5SDimitry Andric return Sym; 249*0b57cec5SDimitry Andric } 250*0b57cec5SDimitry Andric 251*0b57cec5SDimitry Andric MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) { 252*0b57cec5SDimitry Andric unsigned Instance = NextInstance(LocalLabelVal); 253*0b57cec5SDimitry Andric return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); 254*0b57cec5SDimitry Andric } 255*0b57cec5SDimitry Andric 256*0b57cec5SDimitry Andric MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal, 257*0b57cec5SDimitry Andric bool Before) { 258*0b57cec5SDimitry Andric unsigned Instance = GetInstance(LocalLabelVal); 259*0b57cec5SDimitry Andric if (!Before) 260*0b57cec5SDimitry Andric ++Instance; 261*0b57cec5SDimitry Andric return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); 262*0b57cec5SDimitry Andric } 263*0b57cec5SDimitry Andric 264*0b57cec5SDimitry Andric MCSymbol *MCContext::lookupSymbol(const Twine &Name) const { 265*0b57cec5SDimitry Andric SmallString<128> NameSV; 266*0b57cec5SDimitry Andric StringRef NameRef = Name.toStringRef(NameSV); 267*0b57cec5SDimitry Andric return Symbols.lookup(NameRef); 268*0b57cec5SDimitry Andric } 269*0b57cec5SDimitry Andric 270*0b57cec5SDimitry Andric void MCContext::setSymbolValue(MCStreamer &Streamer, 271*0b57cec5SDimitry Andric StringRef Sym, 272*0b57cec5SDimitry Andric uint64_t Val) { 273*0b57cec5SDimitry Andric auto Symbol = getOrCreateSymbol(Sym); 274*0b57cec5SDimitry Andric Streamer.EmitAssignment(Symbol, MCConstantExpr::create(Val, *this)); 275*0b57cec5SDimitry Andric } 276*0b57cec5SDimitry Andric 277*0b57cec5SDimitry Andric void MCContext::registerInlineAsmLabel(MCSymbol *Sym) { 278*0b57cec5SDimitry Andric InlineAsmUsedLabelNames[Sym->getName()] = Sym; 279*0b57cec5SDimitry Andric } 280*0b57cec5SDimitry Andric 281*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 282*0b57cec5SDimitry Andric // Section Management 283*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 284*0b57cec5SDimitry Andric 285*0b57cec5SDimitry Andric MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section, 286*0b57cec5SDimitry Andric unsigned TypeAndAttributes, 287*0b57cec5SDimitry Andric unsigned Reserved2, SectionKind Kind, 288*0b57cec5SDimitry Andric const char *BeginSymName) { 289*0b57cec5SDimitry Andric // We unique sections by their segment/section pair. The returned section 290*0b57cec5SDimitry Andric // may not have the same flags as the requested section, if so this should be 291*0b57cec5SDimitry Andric // diagnosed by the client as an error. 292*0b57cec5SDimitry Andric 293*0b57cec5SDimitry Andric // Form the name to look up. 294*0b57cec5SDimitry Andric SmallString<64> Name; 295*0b57cec5SDimitry Andric Name += Segment; 296*0b57cec5SDimitry Andric Name.push_back(','); 297*0b57cec5SDimitry Andric Name += Section; 298*0b57cec5SDimitry Andric 299*0b57cec5SDimitry Andric // Do the lookup, if we have a hit, return it. 300*0b57cec5SDimitry Andric MCSectionMachO *&Entry = MachOUniquingMap[Name]; 301*0b57cec5SDimitry Andric if (Entry) 302*0b57cec5SDimitry Andric return Entry; 303*0b57cec5SDimitry Andric 304*0b57cec5SDimitry Andric MCSymbol *Begin = nullptr; 305*0b57cec5SDimitry Andric if (BeginSymName) 306*0b57cec5SDimitry Andric Begin = createTempSymbol(BeginSymName, false); 307*0b57cec5SDimitry Andric 308*0b57cec5SDimitry Andric // Otherwise, return a new section. 309*0b57cec5SDimitry Andric return Entry = new (MachOAllocator.Allocate()) MCSectionMachO( 310*0b57cec5SDimitry Andric Segment, Section, TypeAndAttributes, Reserved2, Kind, Begin); 311*0b57cec5SDimitry Andric } 312*0b57cec5SDimitry Andric 313*0b57cec5SDimitry Andric void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) { 314*0b57cec5SDimitry Andric StringRef GroupName; 315*0b57cec5SDimitry Andric if (const MCSymbol *Group = Section->getGroup()) 316*0b57cec5SDimitry Andric GroupName = Group->getName(); 317*0b57cec5SDimitry Andric 318*0b57cec5SDimitry Andric unsigned UniqueID = Section->getUniqueID(); 319*0b57cec5SDimitry Andric ELFUniquingMap.erase( 320*0b57cec5SDimitry Andric ELFSectionKey{Section->getSectionName(), GroupName, UniqueID}); 321*0b57cec5SDimitry Andric auto I = ELFUniquingMap.insert(std::make_pair( 322*0b57cec5SDimitry Andric ELFSectionKey{Name, GroupName, UniqueID}, 323*0b57cec5SDimitry Andric Section)) 324*0b57cec5SDimitry Andric .first; 325*0b57cec5SDimitry Andric StringRef CachedName = I->first.SectionName; 326*0b57cec5SDimitry Andric const_cast<MCSectionELF *>(Section)->setSectionName(CachedName); 327*0b57cec5SDimitry Andric } 328*0b57cec5SDimitry Andric 329*0b57cec5SDimitry Andric MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type, 330*0b57cec5SDimitry Andric unsigned Flags, SectionKind K, 331*0b57cec5SDimitry Andric unsigned EntrySize, 332*0b57cec5SDimitry Andric const MCSymbolELF *Group, 333*0b57cec5SDimitry Andric unsigned UniqueID, 334*0b57cec5SDimitry Andric const MCSymbolELF *Associated) { 335*0b57cec5SDimitry Andric MCSymbolELF *R; 336*0b57cec5SDimitry Andric MCSymbol *&Sym = Symbols[Section]; 337*0b57cec5SDimitry Andric // A section symbol can not redefine regular symbols. There may be multiple 338*0b57cec5SDimitry Andric // sections with the same name, in which case the first such section wins. 339*0b57cec5SDimitry Andric if (Sym && Sym->isDefined() && 340*0b57cec5SDimitry Andric (!Sym->isInSection() || Sym->getSection().getBeginSymbol() != Sym)) 341*0b57cec5SDimitry Andric reportError(SMLoc(), "invalid symbol redefinition"); 342*0b57cec5SDimitry Andric if (Sym && Sym->isUndefined()) { 343*0b57cec5SDimitry Andric R = cast<MCSymbolELF>(Sym); 344*0b57cec5SDimitry Andric } else { 345*0b57cec5SDimitry Andric auto NameIter = UsedNames.insert(std::make_pair(Section, false)).first; 346*0b57cec5SDimitry Andric R = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false); 347*0b57cec5SDimitry Andric if (!Sym) 348*0b57cec5SDimitry Andric Sym = R; 349*0b57cec5SDimitry Andric } 350*0b57cec5SDimitry Andric R->setBinding(ELF::STB_LOCAL); 351*0b57cec5SDimitry Andric R->setType(ELF::STT_SECTION); 352*0b57cec5SDimitry Andric 353*0b57cec5SDimitry Andric auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF( 354*0b57cec5SDimitry Andric Section, Type, Flags, K, EntrySize, Group, UniqueID, R, Associated); 355*0b57cec5SDimitry Andric 356*0b57cec5SDimitry Andric auto *F = new MCDataFragment(); 357*0b57cec5SDimitry Andric Ret->getFragmentList().insert(Ret->begin(), F); 358*0b57cec5SDimitry Andric F->setParent(Ret); 359*0b57cec5SDimitry Andric R->setFragment(F); 360*0b57cec5SDimitry Andric 361*0b57cec5SDimitry Andric return Ret; 362*0b57cec5SDimitry Andric } 363*0b57cec5SDimitry Andric 364*0b57cec5SDimitry Andric MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type, 365*0b57cec5SDimitry Andric unsigned Flags, unsigned EntrySize, 366*0b57cec5SDimitry Andric const MCSymbolELF *Group, 367*0b57cec5SDimitry Andric const MCSectionELF *RelInfoSection) { 368*0b57cec5SDimitry Andric StringMap<bool>::iterator I; 369*0b57cec5SDimitry Andric bool Inserted; 370*0b57cec5SDimitry Andric std::tie(I, Inserted) = 371*0b57cec5SDimitry Andric RelSecNames.insert(std::make_pair(Name.str(), true)); 372*0b57cec5SDimitry Andric 373*0b57cec5SDimitry Andric return createELFSectionImpl( 374*0b57cec5SDimitry Andric I->getKey(), Type, Flags, SectionKind::getReadOnly(), EntrySize, Group, 375*0b57cec5SDimitry Andric true, cast<MCSymbolELF>(RelInfoSection->getBeginSymbol())); 376*0b57cec5SDimitry Andric } 377*0b57cec5SDimitry Andric 378*0b57cec5SDimitry Andric MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix, 379*0b57cec5SDimitry Andric const Twine &Suffix, unsigned Type, 380*0b57cec5SDimitry Andric unsigned Flags, 381*0b57cec5SDimitry Andric unsigned EntrySize) { 382*0b57cec5SDimitry Andric return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix); 383*0b57cec5SDimitry Andric } 384*0b57cec5SDimitry Andric 385*0b57cec5SDimitry Andric MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, 386*0b57cec5SDimitry Andric unsigned Flags, unsigned EntrySize, 387*0b57cec5SDimitry Andric const Twine &Group, unsigned UniqueID, 388*0b57cec5SDimitry Andric const MCSymbolELF *Associated) { 389*0b57cec5SDimitry Andric MCSymbolELF *GroupSym = nullptr; 390*0b57cec5SDimitry Andric if (!Group.isTriviallyEmpty() && !Group.str().empty()) 391*0b57cec5SDimitry Andric GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group)); 392*0b57cec5SDimitry Andric 393*0b57cec5SDimitry Andric return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID, 394*0b57cec5SDimitry Andric Associated); 395*0b57cec5SDimitry Andric } 396*0b57cec5SDimitry Andric 397*0b57cec5SDimitry Andric MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, 398*0b57cec5SDimitry Andric unsigned Flags, unsigned EntrySize, 399*0b57cec5SDimitry Andric const MCSymbolELF *GroupSym, 400*0b57cec5SDimitry Andric unsigned UniqueID, 401*0b57cec5SDimitry Andric const MCSymbolELF *Associated) { 402*0b57cec5SDimitry Andric StringRef Group = ""; 403*0b57cec5SDimitry Andric if (GroupSym) 404*0b57cec5SDimitry Andric Group = GroupSym->getName(); 405*0b57cec5SDimitry Andric // Do the lookup, if we have a hit, return it. 406*0b57cec5SDimitry Andric auto IterBool = ELFUniquingMap.insert( 407*0b57cec5SDimitry Andric std::make_pair(ELFSectionKey{Section.str(), Group, UniqueID}, nullptr)); 408*0b57cec5SDimitry Andric auto &Entry = *IterBool.first; 409*0b57cec5SDimitry Andric if (!IterBool.second) 410*0b57cec5SDimitry Andric return Entry.second; 411*0b57cec5SDimitry Andric 412*0b57cec5SDimitry Andric StringRef CachedName = Entry.first.SectionName; 413*0b57cec5SDimitry Andric 414*0b57cec5SDimitry Andric SectionKind Kind; 415*0b57cec5SDimitry Andric if (Flags & ELF::SHF_ARM_PURECODE) 416*0b57cec5SDimitry Andric Kind = SectionKind::getExecuteOnly(); 417*0b57cec5SDimitry Andric else if (Flags & ELF::SHF_EXECINSTR) 418*0b57cec5SDimitry Andric Kind = SectionKind::getText(); 419*0b57cec5SDimitry Andric else 420*0b57cec5SDimitry Andric Kind = SectionKind::getReadOnly(); 421*0b57cec5SDimitry Andric 422*0b57cec5SDimitry Andric MCSectionELF *Result = createELFSectionImpl( 423*0b57cec5SDimitry Andric CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID, Associated); 424*0b57cec5SDimitry Andric Entry.second = Result; 425*0b57cec5SDimitry Andric return Result; 426*0b57cec5SDimitry Andric } 427*0b57cec5SDimitry Andric 428*0b57cec5SDimitry Andric MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) { 429*0b57cec5SDimitry Andric return createELFSectionImpl(".group", ELF::SHT_GROUP, 0, 430*0b57cec5SDimitry Andric SectionKind::getReadOnly(), 4, Group, ~0, 431*0b57cec5SDimitry Andric nullptr); 432*0b57cec5SDimitry Andric } 433*0b57cec5SDimitry Andric 434*0b57cec5SDimitry Andric MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, 435*0b57cec5SDimitry Andric unsigned Characteristics, 436*0b57cec5SDimitry Andric SectionKind Kind, 437*0b57cec5SDimitry Andric StringRef COMDATSymName, int Selection, 438*0b57cec5SDimitry Andric unsigned UniqueID, 439*0b57cec5SDimitry Andric const char *BeginSymName) { 440*0b57cec5SDimitry Andric MCSymbol *COMDATSymbol = nullptr; 441*0b57cec5SDimitry Andric if (!COMDATSymName.empty()) { 442*0b57cec5SDimitry Andric COMDATSymbol = getOrCreateSymbol(COMDATSymName); 443*0b57cec5SDimitry Andric COMDATSymName = COMDATSymbol->getName(); 444*0b57cec5SDimitry Andric } 445*0b57cec5SDimitry Andric 446*0b57cec5SDimitry Andric 447*0b57cec5SDimitry Andric // Do the lookup, if we have a hit, return it. 448*0b57cec5SDimitry Andric COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID}; 449*0b57cec5SDimitry Andric auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr)); 450*0b57cec5SDimitry Andric auto Iter = IterBool.first; 451*0b57cec5SDimitry Andric if (!IterBool.second) 452*0b57cec5SDimitry Andric return Iter->second; 453*0b57cec5SDimitry Andric 454*0b57cec5SDimitry Andric MCSymbol *Begin = nullptr; 455*0b57cec5SDimitry Andric if (BeginSymName) 456*0b57cec5SDimitry Andric Begin = createTempSymbol(BeginSymName, false); 457*0b57cec5SDimitry Andric 458*0b57cec5SDimitry Andric StringRef CachedName = Iter->first.SectionName; 459*0b57cec5SDimitry Andric MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF( 460*0b57cec5SDimitry Andric CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin); 461*0b57cec5SDimitry Andric 462*0b57cec5SDimitry Andric Iter->second = Result; 463*0b57cec5SDimitry Andric return Result; 464*0b57cec5SDimitry Andric } 465*0b57cec5SDimitry Andric 466*0b57cec5SDimitry Andric MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, 467*0b57cec5SDimitry Andric unsigned Characteristics, 468*0b57cec5SDimitry Andric SectionKind Kind, 469*0b57cec5SDimitry Andric const char *BeginSymName) { 470*0b57cec5SDimitry Andric return getCOFFSection(Section, Characteristics, Kind, "", 0, GenericSectionID, 471*0b57cec5SDimitry Andric BeginSymName); 472*0b57cec5SDimitry Andric } 473*0b57cec5SDimitry Andric 474*0b57cec5SDimitry Andric MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec, 475*0b57cec5SDimitry Andric const MCSymbol *KeySym, 476*0b57cec5SDimitry Andric unsigned UniqueID) { 477*0b57cec5SDimitry Andric // Return the normal section if we don't have to be associative or unique. 478*0b57cec5SDimitry Andric if (!KeySym && UniqueID == GenericSectionID) 479*0b57cec5SDimitry Andric return Sec; 480*0b57cec5SDimitry Andric 481*0b57cec5SDimitry Andric // If we have a key symbol, make an associative section with the same name and 482*0b57cec5SDimitry Andric // kind as the normal section. 483*0b57cec5SDimitry Andric unsigned Characteristics = Sec->getCharacteristics(); 484*0b57cec5SDimitry Andric if (KeySym) { 485*0b57cec5SDimitry Andric Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; 486*0b57cec5SDimitry Andric return getCOFFSection(Sec->getSectionName(), Characteristics, 487*0b57cec5SDimitry Andric Sec->getKind(), KeySym->getName(), 488*0b57cec5SDimitry Andric COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); 489*0b57cec5SDimitry Andric } 490*0b57cec5SDimitry Andric 491*0b57cec5SDimitry Andric return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(), 492*0b57cec5SDimitry Andric "", 0, UniqueID); 493*0b57cec5SDimitry Andric } 494*0b57cec5SDimitry Andric 495*0b57cec5SDimitry Andric MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind K, 496*0b57cec5SDimitry Andric const Twine &Group, unsigned UniqueID, 497*0b57cec5SDimitry Andric const char *BeginSymName) { 498*0b57cec5SDimitry Andric MCSymbolWasm *GroupSym = nullptr; 499*0b57cec5SDimitry Andric if (!Group.isTriviallyEmpty() && !Group.str().empty()) { 500*0b57cec5SDimitry Andric GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group)); 501*0b57cec5SDimitry Andric GroupSym->setComdat(true); 502*0b57cec5SDimitry Andric } 503*0b57cec5SDimitry Andric 504*0b57cec5SDimitry Andric return getWasmSection(Section, K, GroupSym, UniqueID, BeginSymName); 505*0b57cec5SDimitry Andric } 506*0b57cec5SDimitry Andric 507*0b57cec5SDimitry Andric MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind, 508*0b57cec5SDimitry Andric const MCSymbolWasm *GroupSym, 509*0b57cec5SDimitry Andric unsigned UniqueID, 510*0b57cec5SDimitry Andric const char *BeginSymName) { 511*0b57cec5SDimitry Andric StringRef Group = ""; 512*0b57cec5SDimitry Andric if (GroupSym) 513*0b57cec5SDimitry Andric Group = GroupSym->getName(); 514*0b57cec5SDimitry Andric // Do the lookup, if we have a hit, return it. 515*0b57cec5SDimitry Andric auto IterBool = WasmUniquingMap.insert( 516*0b57cec5SDimitry Andric std::make_pair(WasmSectionKey{Section.str(), Group, UniqueID}, nullptr)); 517*0b57cec5SDimitry Andric auto &Entry = *IterBool.first; 518*0b57cec5SDimitry Andric if (!IterBool.second) 519*0b57cec5SDimitry Andric return Entry.second; 520*0b57cec5SDimitry Andric 521*0b57cec5SDimitry Andric StringRef CachedName = Entry.first.SectionName; 522*0b57cec5SDimitry Andric 523*0b57cec5SDimitry Andric MCSymbol *Begin = createSymbol(CachedName, false, false); 524*0b57cec5SDimitry Andric cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION); 525*0b57cec5SDimitry Andric 526*0b57cec5SDimitry Andric MCSectionWasm *Result = new (WasmAllocator.Allocate()) 527*0b57cec5SDimitry Andric MCSectionWasm(CachedName, Kind, GroupSym, UniqueID, Begin); 528*0b57cec5SDimitry Andric Entry.second = Result; 529*0b57cec5SDimitry Andric 530*0b57cec5SDimitry Andric auto *F = new MCDataFragment(); 531*0b57cec5SDimitry Andric Result->getFragmentList().insert(Result->begin(), F); 532*0b57cec5SDimitry Andric F->setParent(Result); 533*0b57cec5SDimitry Andric Begin->setFragment(F); 534*0b57cec5SDimitry Andric 535*0b57cec5SDimitry Andric return Result; 536*0b57cec5SDimitry Andric } 537*0b57cec5SDimitry Andric 538*0b57cec5SDimitry Andric MCSectionXCOFF *MCContext::getXCOFFSection(StringRef Section, 539*0b57cec5SDimitry Andric XCOFF::StorageMappingClass SMC, 540*0b57cec5SDimitry Andric SectionKind Kind, 541*0b57cec5SDimitry Andric const char *BeginSymName) { 542*0b57cec5SDimitry Andric // Do the lookup. If we have a hit, return it. 543*0b57cec5SDimitry Andric auto IterBool = XCOFFUniquingMap.insert( 544*0b57cec5SDimitry Andric std::make_pair(XCOFFSectionKey{Section.str(), SMC}, nullptr)); 545*0b57cec5SDimitry Andric auto &Entry = *IterBool.first; 546*0b57cec5SDimitry Andric if (!IterBool.second) 547*0b57cec5SDimitry Andric return Entry.second; 548*0b57cec5SDimitry Andric 549*0b57cec5SDimitry Andric // Otherwise, return a new section. 550*0b57cec5SDimitry Andric StringRef CachedName = Entry.first.SectionName; 551*0b57cec5SDimitry Andric 552*0b57cec5SDimitry Andric MCSymbol *Begin = nullptr; 553*0b57cec5SDimitry Andric if (BeginSymName) 554*0b57cec5SDimitry Andric Begin = createTempSymbol(BeginSymName, false); 555*0b57cec5SDimitry Andric 556*0b57cec5SDimitry Andric MCSectionXCOFF *Result = new (XCOFFAllocator.Allocate()) 557*0b57cec5SDimitry Andric MCSectionXCOFF(CachedName, SMC, Kind, Begin); 558*0b57cec5SDimitry Andric Entry.second = Result; 559*0b57cec5SDimitry Andric 560*0b57cec5SDimitry Andric auto *F = new MCDataFragment(); 561*0b57cec5SDimitry Andric Result->getFragmentList().insert(Result->begin(), F); 562*0b57cec5SDimitry Andric F->setParent(Result); 563*0b57cec5SDimitry Andric 564*0b57cec5SDimitry Andric if (Begin) 565*0b57cec5SDimitry Andric Begin->setFragment(F); 566*0b57cec5SDimitry Andric 567*0b57cec5SDimitry Andric return Result; 568*0b57cec5SDimitry Andric } 569*0b57cec5SDimitry Andric 570*0b57cec5SDimitry Andric MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) { 571*0b57cec5SDimitry Andric return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI); 572*0b57cec5SDimitry Andric } 573*0b57cec5SDimitry Andric 574*0b57cec5SDimitry Andric void MCContext::addDebugPrefixMapEntry(const std::string &From, 575*0b57cec5SDimitry Andric const std::string &To) { 576*0b57cec5SDimitry Andric DebugPrefixMap.insert(std::make_pair(From, To)); 577*0b57cec5SDimitry Andric } 578*0b57cec5SDimitry Andric 579*0b57cec5SDimitry Andric void MCContext::RemapDebugPaths() { 580*0b57cec5SDimitry Andric const auto &DebugPrefixMap = this->DebugPrefixMap; 581*0b57cec5SDimitry Andric const auto RemapDebugPath = [&DebugPrefixMap](std::string &Path) { 582*0b57cec5SDimitry Andric for (const auto &Entry : DebugPrefixMap) 583*0b57cec5SDimitry Andric if (StringRef(Path).startswith(Entry.first)) { 584*0b57cec5SDimitry Andric std::string RemappedPath = 585*0b57cec5SDimitry Andric (Twine(Entry.second) + Path.substr(Entry.first.size())).str(); 586*0b57cec5SDimitry Andric Path.swap(RemappedPath); 587*0b57cec5SDimitry Andric } 588*0b57cec5SDimitry Andric }; 589*0b57cec5SDimitry Andric 590*0b57cec5SDimitry Andric // Remap compilation directory. 591*0b57cec5SDimitry Andric std::string CompDir = CompilationDir.str(); 592*0b57cec5SDimitry Andric RemapDebugPath(CompDir); 593*0b57cec5SDimitry Andric CompilationDir = CompDir; 594*0b57cec5SDimitry Andric 595*0b57cec5SDimitry Andric // Remap MCDwarfDirs in all compilation units. 596*0b57cec5SDimitry Andric for (auto &CUIDTablePair : MCDwarfLineTablesCUMap) 597*0b57cec5SDimitry Andric for (auto &Dir : CUIDTablePair.second.getMCDwarfDirs()) 598*0b57cec5SDimitry Andric RemapDebugPath(Dir); 599*0b57cec5SDimitry Andric } 600*0b57cec5SDimitry Andric 601*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 602*0b57cec5SDimitry Andric // Dwarf Management 603*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 604*0b57cec5SDimitry Andric 605*0b57cec5SDimitry Andric void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) { 606*0b57cec5SDimitry Andric // MCDwarf needs the root file as well as the compilation directory. 607*0b57cec5SDimitry Andric // If we find a '.file 0' directive that will supersede these values. 608*0b57cec5SDimitry Andric Optional<MD5::MD5Result> Cksum; 609*0b57cec5SDimitry Andric if (getDwarfVersion() >= 5) { 610*0b57cec5SDimitry Andric MD5 Hash; 611*0b57cec5SDimitry Andric MD5::MD5Result Sum; 612*0b57cec5SDimitry Andric Hash.update(Buffer); 613*0b57cec5SDimitry Andric Hash.final(Sum); 614*0b57cec5SDimitry Andric Cksum = Sum; 615*0b57cec5SDimitry Andric } 616*0b57cec5SDimitry Andric // Canonicalize the root filename. It cannot be empty, and should not 617*0b57cec5SDimitry Andric // repeat the compilation dir. 618*0b57cec5SDimitry Andric // The MCContext ctor initializes MainFileName to the name associated with 619*0b57cec5SDimitry Andric // the SrcMgr's main file ID, which might be the same as InputFileName (and 620*0b57cec5SDimitry Andric // possibly include directory components). 621*0b57cec5SDimitry Andric // Or, MainFileName might have been overridden by a -main-file-name option, 622*0b57cec5SDimitry Andric // which is supposed to be just a base filename with no directory component. 623*0b57cec5SDimitry Andric // So, if the InputFileName and MainFileName are not equal, assume 624*0b57cec5SDimitry Andric // MainFileName is a substitute basename and replace the last component. 625*0b57cec5SDimitry Andric SmallString<1024> FileNameBuf = InputFileName; 626*0b57cec5SDimitry Andric if (FileNameBuf.empty() || FileNameBuf == "-") 627*0b57cec5SDimitry Andric FileNameBuf = "<stdin>"; 628*0b57cec5SDimitry Andric if (!getMainFileName().empty() && FileNameBuf != getMainFileName()) { 629*0b57cec5SDimitry Andric llvm::sys::path::remove_filename(FileNameBuf); 630*0b57cec5SDimitry Andric llvm::sys::path::append(FileNameBuf, getMainFileName()); 631*0b57cec5SDimitry Andric } 632*0b57cec5SDimitry Andric StringRef FileName = FileNameBuf; 633*0b57cec5SDimitry Andric if (FileName.consume_front(getCompilationDir())) 634*0b57cec5SDimitry Andric if (llvm::sys::path::is_separator(FileName.front())) 635*0b57cec5SDimitry Andric FileName = FileName.drop_front(); 636*0b57cec5SDimitry Andric assert(!FileName.empty()); 637*0b57cec5SDimitry Andric setMCLineTableRootFile( 638*0b57cec5SDimitry Andric /*CUID=*/0, getCompilationDir(), FileName, Cksum, None); 639*0b57cec5SDimitry Andric } 640*0b57cec5SDimitry Andric 641*0b57cec5SDimitry Andric /// getDwarfFile - takes a file name and number to place in the dwarf file and 642*0b57cec5SDimitry Andric /// directory tables. If the file number has already been allocated it is an 643*0b57cec5SDimitry Andric /// error and zero is returned and the client reports the error, else the 644*0b57cec5SDimitry Andric /// allocated file number is returned. The file numbers may be in any order. 645*0b57cec5SDimitry Andric Expected<unsigned> MCContext::getDwarfFile(StringRef Directory, 646*0b57cec5SDimitry Andric StringRef FileName, 647*0b57cec5SDimitry Andric unsigned FileNumber, 648*0b57cec5SDimitry Andric Optional<MD5::MD5Result> Checksum, 649*0b57cec5SDimitry Andric Optional<StringRef> Source, 650*0b57cec5SDimitry Andric unsigned CUID) { 651*0b57cec5SDimitry Andric MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; 652*0b57cec5SDimitry Andric return Table.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion, 653*0b57cec5SDimitry Andric FileNumber); 654*0b57cec5SDimitry Andric } 655*0b57cec5SDimitry Andric 656*0b57cec5SDimitry Andric /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it 657*0b57cec5SDimitry Andric /// currently is assigned and false otherwise. 658*0b57cec5SDimitry Andric bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) { 659*0b57cec5SDimitry Andric const MCDwarfLineTable &LineTable = getMCDwarfLineTable(CUID); 660*0b57cec5SDimitry Andric if (FileNumber == 0) 661*0b57cec5SDimitry Andric return getDwarfVersion() >= 5; 662*0b57cec5SDimitry Andric if (FileNumber >= LineTable.getMCDwarfFiles().size()) 663*0b57cec5SDimitry Andric return false; 664*0b57cec5SDimitry Andric 665*0b57cec5SDimitry Andric return !LineTable.getMCDwarfFiles()[FileNumber].Name.empty(); 666*0b57cec5SDimitry Andric } 667*0b57cec5SDimitry Andric 668*0b57cec5SDimitry Andric /// Remove empty sections from SectionsForRanges, to avoid generating 669*0b57cec5SDimitry Andric /// useless debug info for them. 670*0b57cec5SDimitry Andric void MCContext::finalizeDwarfSections(MCStreamer &MCOS) { 671*0b57cec5SDimitry Andric SectionsForRanges.remove_if( 672*0b57cec5SDimitry Andric [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); }); 673*0b57cec5SDimitry Andric } 674*0b57cec5SDimitry Andric 675*0b57cec5SDimitry Andric CodeViewContext &MCContext::getCVContext() { 676*0b57cec5SDimitry Andric if (!CVContext.get()) 677*0b57cec5SDimitry Andric CVContext.reset(new CodeViewContext); 678*0b57cec5SDimitry Andric return *CVContext.get(); 679*0b57cec5SDimitry Andric } 680*0b57cec5SDimitry Andric 681*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 682*0b57cec5SDimitry Andric // Error Reporting 683*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 684*0b57cec5SDimitry Andric 685*0b57cec5SDimitry Andric void MCContext::reportError(SMLoc Loc, const Twine &Msg) { 686*0b57cec5SDimitry Andric HadError = true; 687*0b57cec5SDimitry Andric 688*0b57cec5SDimitry Andric // If we have a source manager use it. Otherwise, try using the inline source 689*0b57cec5SDimitry Andric // manager. 690*0b57cec5SDimitry Andric // If that fails, use the generic report_fatal_error(). 691*0b57cec5SDimitry Andric if (SrcMgr) 692*0b57cec5SDimitry Andric SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg); 693*0b57cec5SDimitry Andric else if (InlineSrcMgr) 694*0b57cec5SDimitry Andric InlineSrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg); 695*0b57cec5SDimitry Andric else 696*0b57cec5SDimitry Andric report_fatal_error(Msg, false); 697*0b57cec5SDimitry Andric } 698*0b57cec5SDimitry Andric 699*0b57cec5SDimitry Andric void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) { 700*0b57cec5SDimitry Andric reportError(Loc, Msg); 701*0b57cec5SDimitry Andric 702*0b57cec5SDimitry Andric // If we reached here, we are failing ungracefully. Run the interrupt handlers 703*0b57cec5SDimitry Andric // to make sure any special cleanups get done, in particular that we remove 704*0b57cec5SDimitry Andric // files registered with RemoveFileOnSignal. 705*0b57cec5SDimitry Andric sys::RunInterruptHandlers(); 706*0b57cec5SDimitry Andric exit(1); 707*0b57cec5SDimitry Andric } 708