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