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