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