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