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/MCAsmInfo.h" 14 #include "llvm/MC/MCDwarf.h" 15 #include "llvm/MC/MCLabel.h" 16 #include "llvm/MC/MCObjectFileInfo.h" 17 #include "llvm/MC/MCRegisterInfo.h" 18 #include "llvm/MC/MCSectionCOFF.h" 19 #include "llvm/MC/MCSectionELF.h" 20 #include "llvm/MC/MCSectionMachO.h" 21 #include "llvm/MC/MCSymbol.h" 22 #include "llvm/Support/ELF.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/FileSystem.h" 25 #include "llvm/Support/MemoryBuffer.h" 26 #include "llvm/Support/Signals.h" 27 #include "llvm/Support/SourceMgr.h" 28 #include <map> 29 30 using namespace llvm; 31 32 MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri, 33 const MCObjectFileInfo *mofi, const SourceMgr *mgr, 34 bool DoAutoReset) 35 : SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(), 36 Symbols(Allocator), UsedNames(Allocator), NextUniqueID(0), 37 CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false), 38 GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4), 39 AllowTemporaryLabels(true), DwarfCompileUnitID(0), 40 AutoReset(DoAutoReset) { 41 42 std::error_code EC = llvm::sys::fs::current_path(CompilationDir); 43 if (EC) 44 CompilationDir.clear(); 45 46 SecureLogFile = getenv("AS_SECURE_LOG_FILE"); 47 SecureLog = nullptr; 48 SecureLogUsed = false; 49 50 if (SrcMgr && SrcMgr->getNumBuffers()) 51 MainFileName = 52 SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())->getBufferIdentifier(); 53 } 54 55 MCContext::~MCContext() { 56 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 // If the stream for the .secure_log_unique directive was created free it. 64 delete (raw_ostream*)SecureLog; 65 } 66 67 //===----------------------------------------------------------------------===// 68 // Module Lifetime Management 69 //===----------------------------------------------------------------------===// 70 71 void MCContext::reset() { 72 UsedNames.clear(); 73 Symbols.clear(); 74 Allocator.Reset(); 75 Instances.clear(); 76 MCDwarfLineTablesCUMap.clear(); 77 MCGenDwarfLabelEntries.clear(); 78 DwarfDebugFlags = StringRef(); 79 DwarfCompileUnitID = 0; 80 CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0); 81 82 MachOUniquingMap.clear(); 83 ELFUniquingMap.clear(); 84 COFFUniquingMap.clear(); 85 86 NextUniqueID = 0; 87 AllowTemporaryLabels = true; 88 DwarfLocSeen = false; 89 GenDwarfForAssembly = false; 90 GenDwarfFileNumber = 0; 91 } 92 93 //===----------------------------------------------------------------------===// 94 // Symbol Manipulation 95 //===----------------------------------------------------------------------===// 96 97 MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) { 98 assert(!Name.empty() && "Normal symbols cannot be unnamed!"); 99 100 // Do the lookup and get the entire StringMapEntry. We want access to the 101 // key if we are creating the entry. 102 StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name); 103 MCSymbol *Sym = Entry.getValue(); 104 105 if (Sym) 106 return Sym; 107 108 Sym = CreateSymbol(Name); 109 Entry.setValue(Sym); 110 return Sym; 111 } 112 113 MCSymbol *MCContext::CreateSymbol(StringRef Name) { 114 // Determine whether this is an assembler temporary or normal label, if used. 115 bool isTemporary = false; 116 if (AllowTemporaryLabels) 117 isTemporary = Name.startswith(MAI->getPrivateGlobalPrefix()); 118 119 StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name); 120 if (NameEntry->getValue()) { 121 assert(isTemporary && "Cannot rename non-temporary symbols"); 122 SmallString<128> NewName = Name; 123 do { 124 NewName.resize(Name.size()); 125 raw_svector_ostream(NewName) << NextUniqueID++; 126 NameEntry = &UsedNames.GetOrCreateValue(NewName); 127 } while (NameEntry->getValue()); 128 } 129 NameEntry->setValue(true); 130 131 // Ok, the entry doesn't already exist. Have the MCSymbol object itself refer 132 // to the copy of the string that is embedded in the UsedNames entry. 133 MCSymbol *Result = new (*this) MCSymbol(NameEntry->getKey(), isTemporary); 134 135 return Result; 136 } 137 138 MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) { 139 SmallString<128> NameSV; 140 return GetOrCreateSymbol(Name.toStringRef(NameSV)); 141 } 142 143 MCSymbol *MCContext::CreateLinkerPrivateTempSymbol() { 144 SmallString<128> NameSV; 145 raw_svector_ostream(NameSV) 146 << MAI->getLinkerPrivateGlobalPrefix() << "tmp" << NextUniqueID++; 147 return CreateSymbol(NameSV); 148 } 149 150 MCSymbol *MCContext::CreateTempSymbol() { 151 SmallString<128> NameSV; 152 raw_svector_ostream(NameSV) 153 << MAI->getPrivateGlobalPrefix() << "tmp" << NextUniqueID++; 154 return CreateSymbol(NameSV); 155 } 156 157 unsigned MCContext::NextInstance(unsigned LocalLabelVal) { 158 MCLabel *&Label = Instances[LocalLabelVal]; 159 if (!Label) 160 Label = new (*this) MCLabel(0); 161 return Label->incInstance(); 162 } 163 164 unsigned MCContext::GetInstance(unsigned LocalLabelVal) { 165 MCLabel *&Label = Instances[LocalLabelVal]; 166 if (!Label) 167 Label = new (*this) MCLabel(0); 168 return Label->getInstance(); 169 } 170 171 MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, 172 unsigned Instance) { 173 MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)]; 174 if (!Sym) 175 Sym = CreateTempSymbol(); 176 return Sym; 177 } 178 179 MCSymbol *MCContext::CreateDirectionalLocalSymbol(unsigned LocalLabelVal) { 180 unsigned Instance = NextInstance(LocalLabelVal); 181 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); 182 } 183 184 MCSymbol *MCContext::GetDirectionalLocalSymbol(unsigned LocalLabelVal, 185 bool Before) { 186 unsigned Instance = GetInstance(LocalLabelVal); 187 if (!Before) 188 ++Instance; 189 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); 190 } 191 192 MCSymbol *MCContext::LookupSymbol(StringRef Name) const { 193 return Symbols.lookup(Name); 194 } 195 196 MCSymbol *MCContext::LookupSymbol(const Twine &Name) const { 197 SmallString<128> NameSV; 198 Name.toVector(NameSV); 199 return LookupSymbol(NameSV.str()); 200 } 201 202 //===----------------------------------------------------------------------===// 203 // Section Management 204 //===----------------------------------------------------------------------===// 205 206 const MCSectionMachO *MCContext:: 207 getMachOSection(StringRef Segment, StringRef Section, 208 unsigned TypeAndAttributes, 209 unsigned Reserved2, SectionKind Kind) { 210 211 // We unique sections by their segment/section pair. The returned section 212 // may not have the same flags as the requested section, if so this should be 213 // diagnosed by the client as an error. 214 215 // Form the name to look up. 216 SmallString<64> Name; 217 Name += Segment; 218 Name.push_back(','); 219 Name += Section; 220 221 // Do the lookup, if we have a hit, return it. 222 const MCSectionMachO *&Entry = MachOUniquingMap[Name.str()]; 223 if (Entry) return Entry; 224 225 // Otherwise, return a new section. 226 return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes, 227 Reserved2, Kind); 228 } 229 230 const MCSectionELF *MCContext:: 231 getELFSection(StringRef Section, unsigned Type, unsigned Flags, 232 SectionKind Kind) { 233 return getELFSection(Section, Type, Flags, Kind, 0, ""); 234 } 235 236 void MCContext::renameELFSection(const MCSectionELF *Section, StringRef Name) { 237 StringRef GroupName; 238 if (const MCSymbol *Group = Section->getGroup()) 239 GroupName = Group->getName(); 240 241 ELFUniquingMap.erase(SectionGroupPair(Section->getSectionName(), GroupName)); 242 auto I = 243 ELFUniquingMap.insert(std::make_pair(SectionGroupPair(Name, GroupName), 244 Section)).first; 245 StringRef CachedName = I->first.first; 246 const_cast<MCSectionELF*>(Section)->setSectionName(CachedName); 247 } 248 249 const MCSectionELF *MCContext:: 250 getELFSection(StringRef Section, unsigned Type, unsigned Flags, 251 SectionKind Kind, unsigned EntrySize, StringRef Group) { 252 // Do the lookup, if we have a hit, return it. 253 auto IterBool = ELFUniquingMap.insert( 254 std::make_pair(SectionGroupPair(Section, Group), nullptr)); 255 auto &Entry = *IterBool.first; 256 if (!IterBool.second) return Entry.second; 257 258 // Possibly refine the entry size first. 259 if (!EntrySize) { 260 EntrySize = MCSectionELF::DetermineEntrySize(Kind); 261 } 262 263 MCSymbol *GroupSym = nullptr; 264 if (!Group.empty()) 265 GroupSym = GetOrCreateSymbol(Group); 266 267 StringRef CachedName = Entry.first.first; 268 MCSectionELF *Result = new (*this) 269 MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym); 270 Entry.second = Result; 271 return Result; 272 } 273 274 const MCSectionELF *MCContext::CreateELFGroupSection() { 275 MCSectionELF *Result = 276 new (*this) MCSectionELF(".group", ELF::SHT_GROUP, 0, 277 SectionKind::getReadOnly(), 4, nullptr); 278 return Result; 279 } 280 281 const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, 282 unsigned Characteristics, 283 SectionKind Kind, 284 StringRef COMDATSymName, 285 int Selection) { 286 // Do the lookup, if we have a hit, return it. 287 288 SectionGroupTriple T(Section, COMDATSymName, Selection); 289 auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr)); 290 auto Iter = IterBool.first; 291 if (!IterBool.second) 292 return Iter->second; 293 294 const MCSymbol *COMDATSymbol = nullptr; 295 if (!COMDATSymName.empty()) 296 COMDATSymbol = GetOrCreateSymbol(COMDATSymName); 297 298 StringRef CachedName = std::get<0>(Iter->first); 299 MCSectionCOFF *Result = new (*this) 300 MCSectionCOFF(CachedName, Characteristics, COMDATSymbol, Selection, Kind); 301 302 Iter->second = Result; 303 return Result; 304 } 305 306 const MCSectionCOFF * 307 MCContext::getCOFFSection(StringRef Section, unsigned Characteristics, 308 SectionKind Kind) { 309 return getCOFFSection(Section, Characteristics, Kind, "", 0); 310 } 311 312 const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) { 313 SectionGroupTriple T(Section, "", 0); 314 auto Iter = COFFUniquingMap.find(T); 315 if (Iter == COFFUniquingMap.end()) 316 return nullptr; 317 return Iter->second; 318 } 319 320 //===----------------------------------------------------------------------===// 321 // Dwarf Management 322 //===----------------------------------------------------------------------===// 323 324 /// GetDwarfFile - takes a file name an number to place in the dwarf file and 325 /// directory tables. If the file number has already been allocated it is an 326 /// error and zero is returned and the client reports the error, else the 327 /// allocated file number is returned. The file numbers may be in any order. 328 unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName, 329 unsigned FileNumber, unsigned CUID) { 330 MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; 331 return Table.getFile(Directory, FileName, FileNumber); 332 } 333 334 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it 335 /// currently is assigned and false otherwise. 336 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) { 337 const SmallVectorImpl<MCDwarfFile>& MCDwarfFiles = getMCDwarfFiles(CUID); 338 if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size()) 339 return false; 340 341 return !MCDwarfFiles[FileNumber].Name.empty(); 342 } 343 344 /// finalizeDwarfSections - Emit end symbols for each non-empty code section. 345 /// Also remove empty sections from SectionStartEndSyms, to avoid generating 346 /// useless debug info for them. 347 void MCContext::finalizeDwarfSections(MCStreamer &MCOS) { 348 MCContext &context = MCOS.getContext(); 349 350 auto sec = SectionStartEndSyms.begin(); 351 while (sec != SectionStartEndSyms.end()) { 352 assert(sec->second.first && "Start symbol must be set by now"); 353 MCOS.SwitchSection(sec->first); 354 if (MCOS.mayHaveInstructions()) { 355 MCSymbol *SectionEndSym = context.CreateTempSymbol(); 356 MCOS.EmitLabel(SectionEndSym); 357 sec->second.second = SectionEndSym; 358 ++sec; 359 } else { 360 MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> >::iterator 361 to_erase = sec; 362 sec = SectionStartEndSyms.erase(to_erase); 363 } 364 } 365 } 366 367 void MCContext::FatalError(SMLoc Loc, const Twine &Msg) const { 368 // If we have a source manager and a location, use it. Otherwise just 369 // use the generic report_fatal_error(). 370 if (!SrcMgr || Loc == SMLoc()) 371 report_fatal_error(Msg, false); 372 373 // Use the source manager to print the message. 374 SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg); 375 376 // If we reached here, we are failing ungracefully. Run the interrupt handlers 377 // to make sure any special cleanups get done, in particular that we remove 378 // files registered with RemoveFileOnSignal. 379 sys::RunInterruptHandlers(); 380 exit(1); 381 } 382