LLVM API Documentation

MCContext.cpp
Go to the documentation of this file.
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 }