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