LLVM API Documentation
00001 //===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "llvm/MC/MCContext.h" 00011 #include "llvm/ADT/SmallString.h" 00012 #include "llvm/ADT/Twine.h" 00013 #include "llvm/MC/MCAsmInfo.h" 00014 #include "llvm/MC/MCDwarf.h" 00015 #include "llvm/MC/MCLabel.h" 00016 #include "llvm/MC/MCObjectFileInfo.h" 00017 #include "llvm/MC/MCRegisterInfo.h" 00018 #include "llvm/MC/MCSectionCOFF.h" 00019 #include "llvm/MC/MCSectionELF.h" 00020 #include "llvm/MC/MCSectionMachO.h" 00021 #include "llvm/MC/MCSymbol.h" 00022 #include "llvm/Support/ELF.h" 00023 #include "llvm/Support/ErrorHandling.h" 00024 #include "llvm/Support/FileSystem.h" 00025 #include "llvm/Support/MemoryBuffer.h" 00026 #include "llvm/Support/Signals.h" 00027 #include "llvm/Support/SourceMgr.h" 00028 #include <map> 00029 00030 using namespace llvm; 00031 00032 MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri, 00033 const MCObjectFileInfo *mofi, const SourceMgr *mgr, 00034 bool DoAutoReset) 00035 : SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(), 00036 Symbols(Allocator), UsedNames(Allocator), NextUniqueID(0), 00037 CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false), 00038 GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4), 00039 AllowTemporaryLabels(true), DwarfCompileUnitID(0), 00040 AutoReset(DoAutoReset) { 00041 00042 std::error_code EC = llvm::sys::fs::current_path(CompilationDir); 00043 if (EC) 00044 CompilationDir.clear(); 00045 00046 SecureLogFile = getenv("AS_SECURE_LOG_FILE"); 00047 SecureLog = nullptr; 00048 SecureLogUsed = false; 00049 00050 if (SrcMgr && SrcMgr->getNumBuffers()) 00051 MainFileName = 00052 SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())->getBufferIdentifier(); 00053 } 00054 00055 MCContext::~MCContext() { 00056 00057 if (AutoReset) 00058 reset(); 00059 00060 // NOTE: The symbols are all allocated out of a bump pointer allocator, 00061 // we don't need to free them here. 00062 00063 // If the stream for the .secure_log_unique directive was created free it. 00064 delete (raw_ostream*)SecureLog; 00065 } 00066 00067 //===----------------------------------------------------------------------===// 00068 // Module Lifetime Management 00069 //===----------------------------------------------------------------------===// 00070 00071 void MCContext::reset() { 00072 UsedNames.clear(); 00073 Symbols.clear(); 00074 Allocator.Reset(); 00075 Instances.clear(); 00076 CompilationDir.clear(); 00077 MainFileName.clear(); 00078 MCDwarfLineTablesCUMap.clear(); 00079 SectionStartEndSyms.clear(); 00080 MCGenDwarfLabelEntries.clear(); 00081 DwarfDebugFlags = StringRef(); 00082 DwarfCompileUnitID = 0; 00083 CurrentDwarfLoc = MCDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0); 00084 00085 MachOUniquingMap.clear(); 00086 ELFUniquingMap.clear(); 00087 COFFUniquingMap.clear(); 00088 00089 NextUniqueID = 0; 00090 AllowTemporaryLabels = true; 00091 DwarfLocSeen = false; 00092 GenDwarfForAssembly = false; 00093 GenDwarfFileNumber = 0; 00094 } 00095 00096 //===----------------------------------------------------------------------===// 00097 // Symbol Manipulation 00098 //===----------------------------------------------------------------------===// 00099 00100 MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) { 00101 assert(!Name.empty() && "Normal symbols cannot be unnamed!"); 00102 00103 // Do the lookup and get the entire StringMapEntry. We want access to the 00104 // key if we are creating the entry. 00105 StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name); 00106 MCSymbol *Sym = Entry.getValue(); 00107 00108 if (Sym) 00109 return Sym; 00110 00111 Sym = CreateSymbol(Name); 00112 Entry.setValue(Sym); 00113 return Sym; 00114 } 00115 00116 MCSymbol *MCContext::CreateSymbol(StringRef Name) { 00117 // Determine whether this is an assembler temporary or normal label, if used. 00118 bool isTemporary = false; 00119 if (AllowTemporaryLabels) 00120 isTemporary = Name.startswith(MAI->getPrivateGlobalPrefix()); 00121 00122 StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name); 00123 if (NameEntry->getValue()) { 00124 assert(isTemporary && "Cannot rename non-temporary symbols"); 00125 SmallString<128> NewName = Name; 00126 do { 00127 NewName.resize(Name.size()); 00128 raw_svector_ostream(NewName) << NextUniqueID++; 00129 NameEntry = &UsedNames.GetOrCreateValue(NewName); 00130 } while (NameEntry->getValue()); 00131 } 00132 NameEntry->setValue(true); 00133 00134 // Ok, the entry doesn't already exist. Have the MCSymbol object itself refer 00135 // to the copy of the string that is embedded in the UsedNames entry. 00136 MCSymbol *Result = new (*this) MCSymbol(NameEntry->getKey(), isTemporary); 00137 00138 return Result; 00139 } 00140 00141 MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) { 00142 SmallString<128> NameSV; 00143 return GetOrCreateSymbol(Name.toStringRef(NameSV)); 00144 } 00145 00146 MCSymbol *MCContext::CreateLinkerPrivateTempSymbol() { 00147 SmallString<128> NameSV; 00148 raw_svector_ostream(NameSV) 00149 << MAI->getLinkerPrivateGlobalPrefix() << "tmp" << NextUniqueID++; 00150 return CreateSymbol(NameSV); 00151 } 00152 00153 MCSymbol *MCContext::CreateTempSymbol() { 00154 SmallString<128> NameSV; 00155 raw_svector_ostream(NameSV) 00156 << MAI->getPrivateGlobalPrefix() << "tmp" << NextUniqueID++; 00157 return CreateSymbol(NameSV); 00158 } 00159 00160 unsigned MCContext::NextInstance(unsigned LocalLabelVal) { 00161 MCLabel *&Label = Instances[LocalLabelVal]; 00162 if (!Label) 00163 Label = new (*this) MCLabel(0); 00164 return Label->incInstance(); 00165 } 00166 00167 unsigned MCContext::GetInstance(unsigned LocalLabelVal) { 00168 MCLabel *&Label = Instances[LocalLabelVal]; 00169 if (!Label) 00170 Label = new (*this) MCLabel(0); 00171 return Label->getInstance(); 00172 } 00173 00174 MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, 00175 unsigned Instance) { 00176 MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)]; 00177 if (!Sym) 00178 Sym = CreateTempSymbol(); 00179 return Sym; 00180 } 00181 00182 MCSymbol *MCContext::CreateDirectionalLocalSymbol(unsigned LocalLabelVal) { 00183 unsigned Instance = NextInstance(LocalLabelVal); 00184 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); 00185 } 00186 00187 MCSymbol *MCContext::GetDirectionalLocalSymbol(unsigned LocalLabelVal, 00188 bool Before) { 00189 unsigned Instance = GetInstance(LocalLabelVal); 00190 if (!Before) 00191 ++Instance; 00192 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); 00193 } 00194 00195 MCSymbol *MCContext::LookupSymbol(StringRef Name) const { 00196 return Symbols.lookup(Name); 00197 } 00198 00199 MCSymbol *MCContext::LookupSymbol(const Twine &Name) const { 00200 SmallString<128> NameSV; 00201 Name.toVector(NameSV); 00202 return LookupSymbol(NameSV.str()); 00203 } 00204 00205 //===----------------------------------------------------------------------===// 00206 // Section Management 00207 //===----------------------------------------------------------------------===// 00208 00209 const MCSectionMachO *MCContext:: 00210 getMachOSection(StringRef Segment, StringRef Section, 00211 unsigned TypeAndAttributes, 00212 unsigned Reserved2, SectionKind Kind) { 00213 00214 // We unique sections by their segment/section pair. The returned section 00215 // may not have the same flags as the requested section, if so this should be 00216 // diagnosed by the client as an error. 00217 00218 // Form the name to look up. 00219 SmallString<64> Name; 00220 Name += Segment; 00221 Name.push_back(','); 00222 Name += Section; 00223 00224 // Do the lookup, if we have a hit, return it. 00225 const MCSectionMachO *&Entry = MachOUniquingMap[Name.str()]; 00226 if (Entry) return Entry; 00227 00228 // Otherwise, return a new section. 00229 return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes, 00230 Reserved2, Kind); 00231 } 00232 00233 const MCSectionELF *MCContext:: 00234 getELFSection(StringRef Section, unsigned Type, unsigned Flags, 00235 SectionKind Kind) { 00236 return getELFSection(Section, Type, Flags, Kind, 0, ""); 00237 } 00238 00239 void MCContext::renameELFSection(const MCSectionELF *Section, StringRef Name) { 00240 StringRef GroupName; 00241 if (const MCSymbol *Group = Section->getGroup()) 00242 GroupName = Group->getName(); 00243 00244 ELFUniquingMap.erase(SectionGroupPair(Section->getSectionName(), GroupName)); 00245 auto I = 00246 ELFUniquingMap.insert(std::make_pair(SectionGroupPair(Name, GroupName), 00247 Section)).first; 00248 StringRef CachedName = I->first.first; 00249 const_cast<MCSectionELF*>(Section)->setSectionName(CachedName); 00250 } 00251 00252 const MCSectionELF *MCContext:: 00253 getELFSection(StringRef Section, unsigned Type, unsigned Flags, 00254 SectionKind Kind, unsigned EntrySize, StringRef Group) { 00255 // Do the lookup, if we have a hit, return it. 00256 auto IterBool = ELFUniquingMap.insert( 00257 std::make_pair(SectionGroupPair(Section, Group), nullptr)); 00258 auto &Entry = *IterBool.first; 00259 if (!IterBool.second) return Entry.second; 00260 00261 // Possibly refine the entry size first. 00262 if (!EntrySize) { 00263 EntrySize = MCSectionELF::DetermineEntrySize(Kind); 00264 } 00265 00266 MCSymbol *GroupSym = nullptr; 00267 if (!Group.empty()) 00268 GroupSym = GetOrCreateSymbol(Group); 00269 00270 StringRef CachedName = Entry.first.first; 00271 MCSectionELF *Result = new (*this) 00272 MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym); 00273 Entry.second = Result; 00274 return Result; 00275 } 00276 00277 const MCSectionELF *MCContext::CreateELFGroupSection() { 00278 MCSectionELF *Result = 00279 new (*this) MCSectionELF(".group", ELF::SHT_GROUP, 0, 00280 SectionKind::getReadOnly(), 4, nullptr); 00281 return Result; 00282 } 00283 00284 const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, 00285 unsigned Characteristics, 00286 SectionKind Kind, 00287 StringRef COMDATSymName, 00288 int Selection) { 00289 // Do the lookup, if we have a hit, return it. 00290 00291 SectionGroupTriple T(Section, COMDATSymName, Selection); 00292 auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr)); 00293 auto Iter = IterBool.first; 00294 if (!IterBool.second) 00295 return Iter->second; 00296 00297 MCSymbol *COMDATSymbol = nullptr; 00298 if (!COMDATSymName.empty()) 00299 COMDATSymbol = GetOrCreateSymbol(COMDATSymName); 00300 00301 StringRef CachedName = std::get<0>(Iter->first); 00302 MCSectionCOFF *Result = new (*this) 00303 MCSectionCOFF(CachedName, Characteristics, COMDATSymbol, Selection, Kind); 00304 00305 Iter->second = Result; 00306 return Result; 00307 } 00308 00309 const MCSectionCOFF * 00310 MCContext::getCOFFSection(StringRef Section, unsigned Characteristics, 00311 SectionKind Kind) { 00312 return getCOFFSection(Section, Characteristics, Kind, "", 0); 00313 } 00314 00315 const MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) { 00316 SectionGroupTriple T(Section, "", 0); 00317 auto Iter = COFFUniquingMap.find(T); 00318 if (Iter == COFFUniquingMap.end()) 00319 return nullptr; 00320 return Iter->second; 00321 } 00322 00323 const MCSectionCOFF * 00324 MCContext::getAssociativeCOFFSection(const MCSectionCOFF *Sec, 00325 const MCSymbol *KeySym) { 00326 // Return the normal section if we don't have to be associative. 00327 if (!KeySym) 00328 return Sec; 00329 00330 // Make an associative section with the same name and kind as the normal 00331 // section. 00332 unsigned Characteristics = 00333 Sec->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT; 00334 return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(), 00335 KeySym->getName(), 00336 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE); 00337 } 00338 00339 //===----------------------------------------------------------------------===// 00340 // Dwarf Management 00341 //===----------------------------------------------------------------------===// 00342 00343 /// GetDwarfFile - takes a file name an number to place in the dwarf file and 00344 /// directory tables. If the file number has already been allocated it is an 00345 /// error and zero is returned and the client reports the error, else the 00346 /// allocated file number is returned. The file numbers may be in any order. 00347 unsigned MCContext::GetDwarfFile(StringRef Directory, StringRef FileName, 00348 unsigned FileNumber, unsigned CUID) { 00349 MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; 00350 return Table.getFile(Directory, FileName, FileNumber); 00351 } 00352 00353 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it 00354 /// currently is assigned and false otherwise. 00355 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) { 00356 const SmallVectorImpl<MCDwarfFile>& MCDwarfFiles = getMCDwarfFiles(CUID); 00357 if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size()) 00358 return false; 00359 00360 return !MCDwarfFiles[FileNumber].Name.empty(); 00361 } 00362 00363 /// finalizeDwarfSections - Emit end symbols for each non-empty code section. 00364 /// Also remove empty sections from SectionStartEndSyms, to avoid generating 00365 /// useless debug info for them. 00366 void MCContext::finalizeDwarfSections(MCStreamer &MCOS) { 00367 MCContext &context = MCOS.getContext(); 00368 00369 auto sec = SectionStartEndSyms.begin(); 00370 while (sec != SectionStartEndSyms.end()) { 00371 assert(sec->second.first && "Start symbol must be set by now"); 00372 MCOS.SwitchSection(sec->first); 00373 if (MCOS.mayHaveInstructions()) { 00374 MCSymbol *SectionEndSym = context.CreateTempSymbol(); 00375 MCOS.EmitLabel(SectionEndSym); 00376 sec->second.second = SectionEndSym; 00377 ++sec; 00378 } else { 00379 MapVector<const MCSection *, std::pair<MCSymbol *, MCSymbol *> >::iterator 00380 to_erase = sec; 00381 sec = SectionStartEndSyms.erase(to_erase); 00382 } 00383 } 00384 } 00385 00386 void MCContext::FatalError(SMLoc Loc, const Twine &Msg) const { 00387 // If we have a source manager and a location, use it. Otherwise just 00388 // use the generic report_fatal_error(). 00389 if (!SrcMgr || Loc == SMLoc()) 00390 report_fatal_error(Msg, false); 00391 00392 // Use the source manager to print the message. 00393 SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg); 00394 00395 // If we reached here, we are failing ungracefully. Run the interrupt handlers 00396 // to make sure any special cleanups get done, in particular that we remove 00397 // files registered with RemoveFileOnSignal. 00398 sys::RunInterruptHandlers(); 00399 exit(1); 00400 }