1 //===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/MC/MCContext.h" 11 #include "llvm/ADT/SmallString.h" 12 #include "llvm/ADT/Twine.h" 13 #include "llvm/MC/MCAssembler.h" 14 #include "llvm/MC/MCAsmInfo.h" 15 #include "llvm/MC/MCCodeView.h" 16 #include "llvm/MC/MCDwarf.h" 17 #include "llvm/MC/MCLabel.h" 18 #include "llvm/MC/MCObjectFileInfo.h" 19 #include "llvm/MC/MCRegisterInfo.h" 20 #include "llvm/MC/MCSectionCOFF.h" 21 #include "llvm/MC/MCSectionELF.h" 22 #include "llvm/MC/MCSectionMachO.h" 23 #include "llvm/MC/MCStreamer.h" 24 #include "llvm/MC/MCSymbolCOFF.h" 25 #include "llvm/MC/MCSymbolELF.h" 26 #include "llvm/MC/MCSymbolMachO.h" 27 #include "llvm/Support/COFF.h" 28 #include "llvm/Support/ELF.h" 29 #include "llvm/Support/ErrorHandling.h" 30 #include "llvm/Support/FileSystem.h" 31 #include "llvm/Support/MemoryBuffer.h" 32 #include "llvm/Support/Signals.h" 33 #include "llvm/Support/SourceMgr.h" 34 #include <map> 35 36 using namespace llvm; 37 38 MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri, 39 const MCObjectFileInfo *mofi, const SourceMgr *mgr, 40 bool DoAutoReset) 41 : SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(), 42 Symbols(Allocator), UsedNames(Allocator), 43 CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false), 44 GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4), 45 AllowTemporaryLabels(true), DwarfCompileUnitID(0), 46 AutoReset(DoAutoReset), HadError(false) { 47 SecureLogFile = getenv("AS_SECURE_LOG_FILE"); 48 SecureLog = nullptr; 49 SecureLogUsed = false; 50 51 if (SrcMgr && SrcMgr->getNumBuffers()) 52 MainFileName = 53 SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())->getBufferIdentifier(); 54 } 55 56 MCContext::~MCContext() { 57 if (AutoReset) 58 reset(); 59 60 // NOTE: The symbols are all allocated out of a bump pointer allocator, 61 // we don't need to free them here. 62 } 63 64 //===----------------------------------------------------------------------===// 65 // Module Lifetime Management 66 //===----------------------------------------------------------------------===// 67 68 void MCContext::reset() { 69 // Call the destructors so the fragments are freed 70 COFFAllocator.DestroyAll(); 71 ELFAllocator.DestroyAll(); 72 MachOAllocator.DestroyAll(); 73 74 MCSubtargetAllocator.DestroyAll(); 75 UsedNames.clear(); 76 Symbols.clear(); 77 SectionSymbols.clear(); 78 Allocator.Reset(); 79 Instances.clear(); 80 CompilationDir.clear(); 81 MainFileName.clear(); 82 MCDwarfLineTablesCUMap.clear(); 83 SectionsForRanges.clear(); 84 MCGenDwarfLabelEntries.clear(); 85 DwarfDebugFlags = StringRef(); 86 DwarfCompileUnitID = 0; 87 CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0); 88 89 CVContext.reset(); 90 91 MachOUniquingMap.clear(); 92 ELFUniquingMap.clear(); 93 COFFUniquingMap.clear(); 94 95 NextID.clear(); 96 AllowTemporaryLabels = true; 97 DwarfLocSeen = false; 98 GenDwarfForAssembly = false; 99 GenDwarfFileNumber = 0; 100 101 HadError = false; 102 } 103 104 //===----------------------------------------------------------------------===// 105 // Symbol Manipulation 106 //===----------------------------------------------------------------------===// 107 108 MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) { 109 SmallString<128> NameSV; 110 StringRef NameRef = Name.toStringRef(NameSV); 111 112 assert(!NameRef.empty() && "Normal symbols cannot be unnamed!"); 113 114 MCSymbol *&Sym = Symbols[NameRef]; 115 if (!Sym) 116 Sym = createSymbol(NameRef, false, false); 117 118 return Sym; 119 } 120 121 MCSymbolELF *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) { 122 MCSymbolELF *&Sym = SectionSymbols[&Section]; 123 if (Sym) 124 return Sym; 125 126 StringRef Name = Section.getSectionName(); 127 128 MCSymbol *&OldSym = Symbols[Name]; 129 if (OldSym && OldSym->isUndefined()) { 130 Sym = cast<MCSymbolELF>(OldSym); 131 return Sym; 132 } 133 134 auto NameIter = UsedNames.insert(std::make_pair(Name, true)).first; 135 Sym = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false); 136 137 if (!OldSym) 138 OldSym = Sym; 139 140 return Sym; 141 } 142 143 MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName, 144 unsigned Idx) { 145 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName + 146 "$frame_escape_" + Twine(Idx)); 147 } 148 149 MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName) { 150 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName + 151 "$parent_frame_offset"); 152 } 153 154 MCSymbol *MCContext::getOrCreateLSDASymbol(StringRef FuncName) { 155 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + "__ehtable$" + 156 FuncName); 157 } 158 159 MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name, 160 bool IsTemporary) { 161 if (MOFI) { 162 switch (MOFI->getObjectFileType()) { 163 case MCObjectFileInfo::IsCOFF: 164 return new (Name, *this) MCSymbolCOFF(Name, IsTemporary); 165 case MCObjectFileInfo::IsELF: 166 return new (Name, *this) MCSymbolELF(Name, IsTemporary); 167 case MCObjectFileInfo::IsMachO: 168 return new (Name, *this) MCSymbolMachO(Name, IsTemporary); 169 } 170 } 171 return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name, 172 IsTemporary); 173 } 174 175 MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix, 176 bool CanBeUnnamed) { 177 if (CanBeUnnamed && !UseNamesOnTempLabels) 178 return createSymbolImpl(nullptr, true); 179 180 // Determine whether this is an user writter assembler temporary or normal 181 // label, if used. 182 bool IsTemporary = CanBeUnnamed; 183 if (AllowTemporaryLabels && !IsTemporary) 184 IsTemporary = Name.startswith(MAI->getPrivateGlobalPrefix()); 185 186 SmallString<128> NewName = Name; 187 bool AddSuffix = AlwaysAddSuffix; 188 unsigned &NextUniqueID = NextID[Name]; 189 for (;;) { 190 if (AddSuffix) { 191 NewName.resize(Name.size()); 192 raw_svector_ostream(NewName) << NextUniqueID++; 193 } 194 auto NameEntry = UsedNames.insert(std::make_pair(NewName, true)); 195 if (NameEntry.second) { 196 // Ok, we found a name. Have the MCSymbol object itself refer to the copy 197 // of the string that is embedded in the UsedNames entry. 198 return createSymbolImpl(&*NameEntry.first, IsTemporary); 199 } 200 assert(IsTemporary && "Cannot rename non-temporary symbols"); 201 AddSuffix = true; 202 } 203 llvm_unreachable("Infinite loop"); 204 } 205 206 MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix, 207 bool CanBeUnnamed) { 208 SmallString<128> NameSV; 209 raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name; 210 return createSymbol(NameSV, AlwaysAddSuffix, CanBeUnnamed); 211 } 212 213 MCSymbol *MCContext::createLinkerPrivateTempSymbol() { 214 SmallString<128> NameSV; 215 raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp"; 216 return createSymbol(NameSV, true, false); 217 } 218 219 MCSymbol *MCContext::createTempSymbol(bool CanBeUnnamed) { 220 return createTempSymbol("tmp", true, CanBeUnnamed); 221 } 222 223 unsigned MCContext::NextInstance(unsigned LocalLabelVal) { 224 MCLabel *&Label = Instances[LocalLabelVal]; 225 if (!Label) 226 Label = new (*this) MCLabel(0); 227 return Label->incInstance(); 228 } 229 230 unsigned MCContext::GetInstance(unsigned LocalLabelVal) { 231 MCLabel *&Label = Instances[LocalLabelVal]; 232 if (!Label) 233 Label = new (*this) MCLabel(0); 234 return Label->getInstance(); 235 } 236 237 MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, 238 unsigned Instance) { 239 MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)]; 240 if (!Sym) 241 Sym = createTempSymbol(false); 242 return Sym; 243 } 244 245 MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) { 246 unsigned Instance = NextInstance(LocalLabelVal); 247 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); 248 } 249 250 MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal, 251 bool Before) { 252 unsigned Instance = GetInstance(LocalLabelVal); 253 if (!Before) 254 ++Instance; 255 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); 256 } 257 258 MCSymbol *MCContext::lookupSymbol(const Twine &Name) const { 259 SmallString<128> NameSV; 260 StringRef NameRef = Name.toStringRef(NameSV); 261 return Symbols.lookup(NameRef); 262 } 263 264 //===----------------------------------------------------------------------===// 265 // Section Management 266 //===----------------------------------------------------------------------===// 267 268 MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section, 269 unsigned TypeAndAttributes, 270 unsigned Reserved2, SectionKind Kind, 271 const char *BeginSymName) { 272 273 // We unique sections by their segment/section pair. The returned section 274 // may not have the same flags as the requested section, if so this should be 275 // diagnosed by the client as an error. 276 277 // Form the name to look up. 278 SmallString<64> Name; 279 Name += Segment; 280 Name.push_back(','); 281 Name += Section; 282 283 // Do the lookup, if we have a hit, return it. 284 MCSectionMachO *&Entry = MachOUniquingMap[Name]; 285 if (Entry) 286 return Entry; 287 288 MCSymbol *Begin = nullptr; 289 if (BeginSymName) 290 Begin = createTempSymbol(BeginSymName, false); 291 292 // Otherwise, return a new section. 293 return Entry = new (MachOAllocator.Allocate()) MCSectionMachO( 294 Segment, Section, TypeAndAttributes, Reserved2, Kind, Begin); 295 } 296 297 void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) { 298 StringRef GroupName; 299 if (const MCSymbol *Group = Section->getGroup()) 300 GroupName = Group->getName(); 301 302 unsigned UniqueID = Section->getUniqueID(); 303 ELFUniquingMap.erase( 304 ELFSectionKey{Section->getSectionName(), GroupName, UniqueID}); 305 auto I = ELFUniquingMap.insert(std::make_pair( 306 ELFSectionKey{Name, GroupName, UniqueID}, 307 Section)) 308 .first; 309 StringRef CachedName = I->first.SectionName; 310 const_cast<MCSectionELF *>(Section)->setSectionName(CachedName); 311 } 312 313 MCSectionELF *MCContext::createELFRelSection(StringRef Name, unsigned Type, 314 unsigned Flags, unsigned EntrySize, 315 const MCSymbolELF *Group, 316 const MCSectionELF *Associated) { 317 StringMap<bool>::iterator I; 318 bool Inserted; 319 std::tie(I, Inserted) = ELFRelSecNames.insert(std::make_pair(Name, true)); 320 321 return new (ELFAllocator.Allocate()) 322 MCSectionELF(I->getKey(), Type, Flags, SectionKind::getReadOnly(), 323 EntrySize, Group, true, nullptr, Associated); 324 } 325 326 MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type, 327 unsigned Flags, unsigned EntrySize, 328 StringRef Group, unsigned UniqueID, 329 const char *BeginSymName) { 330 MCSymbolELF *GroupSym = nullptr; 331 if (!Group.empty()) 332 GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group)); 333 334 return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID, 335 BeginSymName, nullptr); 336 } 337 338 MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type, 339 unsigned Flags, unsigned EntrySize, 340 const MCSymbolELF *GroupSym, 341 unsigned UniqueID, 342 const char *BeginSymName, 343 const MCSectionELF *Associated) { 344 StringRef Group = ""; 345 if (GroupSym) 346 Group = GroupSym->getName(); 347 // Do the lookup, if we have a hit, return it. 348 auto IterBool = ELFUniquingMap.insert( 349 std::make_pair(ELFSectionKey{Section, Group, UniqueID}, nullptr)); 350 auto &Entry = *IterBool.first; 351 if (!IterBool.second) 352 return Entry.second; 353 354 StringRef CachedName = Entry.first.SectionName; 355 356 SectionKind Kind; 357 if (Flags & ELF::SHF_EXECINSTR) 358 Kind = SectionKind::getText(); 359 else 360 Kind = SectionKind::getReadOnly(); 361 362 MCSymbol *Begin = nullptr; 363 if (BeginSymName) 364 Begin = createTempSymbol(BeginSymName, false); 365 366 MCSectionELF *Result = new (ELFAllocator.Allocate()) 367 MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID, 368 Begin, Associated); 369 Entry.second = Result; 370 return Result; 371 } 372 373 MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) { 374 MCSectionELF *Result = new (ELFAllocator.Allocate()) 375 MCSectionELF(".group", ELF::SHT_GROUP, 0, SectionKind::getReadOnly(), 4, 376 Group, ~0, nullptr, nullptr); 377 return Result; 378 } 379 380 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, 381 unsigned Characteristics, 382 SectionKind Kind, 383 StringRef COMDATSymName, int Selection, 384 const char *BeginSymName) { 385 MCSymbol *COMDATSymbol = nullptr; 386 if (!COMDATSymName.empty()) { 387 COMDATSymbol = getOrCreateSymbol(COMDATSymName); 388 COMDATSymName = COMDATSymbol->getName(); 389 } 390 391 // Do the lookup, if we have a hit, return it. 392 COFFSectionKey T{Section, COMDATSymName, Selection}; 393 auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr)); 394 auto Iter = IterBool.first; 395 if (!IterBool.second) 396 return Iter->second; 397 398 MCSymbol *Begin = nullptr; 399 if (BeginSymName) 400 Begin = createTempSymbol(BeginSymName, false); 401 402 StringRef CachedName = Iter->first.SectionName; 403 MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF( 404 CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin); 405 406 Iter->second = Result; 407 return Result; 408 } 409 410 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, 411 unsigned Characteristics, 412 SectionKind Kind, 413 const char *BeginSymName) { 414 return getCOFFSection(Section, Characteristics, Kind, "", 0, BeginSymName); 415 } 416 417 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) { 418 COFFSectionKey T{Section, "", 0}; 419 auto Iter = COFFUniquingMap.find(T); 420 if (Iter == COFFUniquingMap.end()) 421 return nullptr; 422 return Iter->second; 423 } 424 425 MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec, 426 const MCSymbol *KeySym) { 427 // Return the normal section if we don't have to be associative. 428 if (!KeySym) 429 return Sec; 430 431 // Make an associative section with the same name and kind as the normal 432 // section. 433 unsigned Characteristics = 434 Sec->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT; 435 return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(), 436 KeySym->getName(), 437 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE); 438 } 439 440 MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) { 441 return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI); 442 } 443 444 //===----------------------------------------------------------------------===// 445 // Dwarf Management 446 //===----------------------------------------------------------------------===// 447 448 /// getDwarfFile - takes a file name an number to place in the dwarf file and 449 /// directory tables. If the file number has already been allocated it is an 450 /// error and zero is returned and the client reports the error, else the 451 /// allocated file number is returned. The file numbers may be in any order. 452 unsigned MCContext::getDwarfFile(StringRef Directory, StringRef FileName, 453 unsigned FileNumber, unsigned CUID) { 454 MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; 455 return Table.getFile(Directory, FileName, FileNumber); 456 } 457 458 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it 459 /// currently is assigned and false otherwise. 460 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) { 461 const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = getMCDwarfFiles(CUID); 462 if (FileNumber == 0 || FileNumber >= MCDwarfFiles.size()) 463 return false; 464 465 return !MCDwarfFiles[FileNumber].Name.empty(); 466 } 467 468 /// Remove empty sections from SectionStartEndSyms, to avoid generating 469 /// useless debug info for them. 470 void MCContext::finalizeDwarfSections(MCStreamer &MCOS) { 471 SectionsForRanges.remove_if( 472 [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); }); 473 } 474 475 CodeViewContext &MCContext::getCVContext() { 476 if (!CVContext.get()) 477 CVContext.reset(new CodeViewContext); 478 return *CVContext.get(); 479 } 480 481 unsigned MCContext::getCVFile(StringRef FileName, unsigned FileNumber) { 482 return getCVContext().addFile(FileNumber, FileName) ? FileNumber : 0; 483 } 484 485 bool MCContext::isValidCVFileNumber(unsigned FileNumber) { 486 return getCVContext().isValidFileNumber(FileNumber); 487 } 488 489 //===----------------------------------------------------------------------===// 490 // Error Reporting 491 //===----------------------------------------------------------------------===// 492 493 void MCContext::reportError(SMLoc Loc, const Twine &Msg) { 494 HadError = true; 495 496 // If we have a source manager use it. Otherwise just use the generic 497 // report_fatal_error(). 498 if (!SrcMgr) 499 report_fatal_error(Msg, false); 500 501 // Use the source manager to print the message. 502 SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg); 503 } 504 505 void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) { 506 reportError(Loc, Msg); 507 508 // If we reached here, we are failing ungracefully. Run the interrupt handlers 509 // to make sure any special cleanups get done, in particular that we remove 510 // files registered with RemoveFileOnSignal. 511 sys::RunInterruptHandlers(); 512 exit(1); 513 } 514