MCContext.cpp revision 9f44724be058d17944dcd9ef6a6b57734b3744b8
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/MC/MCAsmInfo.h" 12#include "llvm/MC/MCSectionMachO.h" 13#include "llvm/MC/MCSectionELF.h" 14#include "llvm/MC/MCSectionCOFF.h" 15#include "llvm/MC/MCSymbol.h" 16#include "llvm/MC/MCLabel.h" 17#include "llvm/MC/MCDwarf.h" 18#include "llvm/ADT/SmallString.h" 19#include "llvm/ADT/Twine.h" 20using namespace llvm; 21 22typedef StringMap<const MCSectionMachO*> MachOUniqueMapTy; 23typedef StringMap<const MCSectionELF*> ELFUniqueMapTy; 24typedef StringMap<const MCSectionCOFF*> COFFUniqueMapTy; 25 26 27MCContext::MCContext(const MCAsmInfo &mai) : MAI(mai), NextUniqueID(0), 28 CurrentDwarfLoc(0,0,0,DWARF2_FLAG_IS_STMT,0,0) { 29 MachOUniquingMap = 0; 30 ELFUniquingMap = 0; 31 COFFUniquingMap = 0; 32 33 SecureLogFile = getenv("AS_SECURE_LOG_FILE"); 34 SecureLog = 0; 35 SecureLogUsed = false; 36 37 DwarfLocSeen = false; 38} 39 40MCContext::~MCContext() { 41 // NOTE: The symbols are all allocated out of a bump pointer allocator, 42 // we don't need to free them here. 43 44 // If we have the MachO uniquing map, free it. 45 delete (MachOUniqueMapTy*)MachOUniquingMap; 46 delete (ELFUniqueMapTy*)ELFUniquingMap; 47 delete (COFFUniqueMapTy*)COFFUniquingMap; 48 49 // If the stream for the .secure_log_unique directive was created free it. 50 delete (raw_ostream*)SecureLog; 51} 52 53//===----------------------------------------------------------------------===// 54// Symbol Manipulation 55//===----------------------------------------------------------------------===// 56 57MCSymbol *MCContext::GetOrCreateSymbol(StringRef Name) { 58 assert(!Name.empty() && "Normal symbols cannot be unnamed!"); 59 60 // Do the lookup and get the entire StringMapEntry. We want access to the 61 // key if we are creating the entry. 62 StringMapEntry<MCSymbol*> &Entry = Symbols.GetOrCreateValue(Name); 63 MCSymbol *Sym = Entry.getValue(); 64 65 if (Sym) 66 return Sym; 67 68 Sym = CreateSymbol(Name); 69 Entry.setValue(Sym); 70 return Sym; 71} 72 73MCSymbol *MCContext::CreateSymbol(StringRef Name) { 74 // Determine whether this is an assembler temporary or normal label. 75 bool isTemporary = Name.startswith(MAI.getPrivateGlobalPrefix()); 76 77 StringMapEntry<bool> *NameEntry = &UsedNames.GetOrCreateValue(Name); 78 if (NameEntry->getValue()) { 79 assert(isTemporary && "Cannot rename non temporary symbols"); 80 SmallString<128> NewName; 81 do { 82 Twine T = Name + Twine(NextUniqueID++); 83 T.toVector(NewName); 84 StringRef foo = NewName; 85 NameEntry = &UsedNames.GetOrCreateValue(foo); 86 } while (NameEntry->getValue()); 87 } 88 NameEntry->setValue(true); 89 90 // Ok, the entry doesn't already exist. Have the MCSymbol object itself refer 91 // to the copy of the string that is embedded in the UsedNames entry. 92 MCSymbol *Result = new (*this) MCSymbol(NameEntry->getKey(), isTemporary); 93 94 return Result; 95} 96 97MCSymbol *MCContext::GetOrCreateSymbol(const Twine &Name) { 98 SmallString<128> NameSV; 99 Name.toVector(NameSV); 100 return GetOrCreateSymbol(NameSV.str()); 101} 102 103MCSymbol *MCContext::CreateTempSymbol() { 104 SmallString<128> NameSV; 105 Twine Name = Twine(MAI.getPrivateGlobalPrefix()) + "tmp" + 106 Twine(NextUniqueID++); 107 Name.toVector(NameSV); 108 return CreateSymbol(NameSV); 109} 110 111unsigned MCContext::NextInstance(int64_t LocalLabelVal) { 112 MCLabel *&Label = Instances[LocalLabelVal]; 113 if (!Label) 114 Label = new (*this) MCLabel(0); 115 return Label->incInstance(); 116} 117 118unsigned MCContext::GetInstance(int64_t LocalLabelVal) { 119 MCLabel *&Label = Instances[LocalLabelVal]; 120 if (!Label) 121 Label = new (*this) MCLabel(0); 122 return Label->getInstance(); 123} 124 125MCSymbol *MCContext::CreateDirectionalLocalSymbol(int64_t LocalLabelVal) { 126 return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) + 127 Twine(LocalLabelVal) + 128 "\2" + 129 Twine(NextInstance(LocalLabelVal))); 130} 131MCSymbol *MCContext::GetDirectionalLocalSymbol(int64_t LocalLabelVal, 132 int bORf) { 133 return GetOrCreateSymbol(Twine(MAI.getPrivateGlobalPrefix()) + 134 Twine(LocalLabelVal) + 135 "\2" + 136 Twine(GetInstance(LocalLabelVal) + bORf)); 137} 138 139MCSymbol *MCContext::LookupSymbol(StringRef Name) const { 140 return Symbols.lookup(Name); 141} 142 143//===----------------------------------------------------------------------===// 144// Section Management 145//===----------------------------------------------------------------------===// 146 147const MCSectionMachO *MCContext:: 148getMachOSection(StringRef Segment, StringRef Section, 149 unsigned TypeAndAttributes, 150 unsigned Reserved2, SectionKind Kind) { 151 152 // We unique sections by their segment/section pair. The returned section 153 // may not have the same flags as the requested section, if so this should be 154 // diagnosed by the client as an error. 155 156 // Create the map if it doesn't already exist. 157 if (MachOUniquingMap == 0) 158 MachOUniquingMap = new MachOUniqueMapTy(); 159 MachOUniqueMapTy &Map = *(MachOUniqueMapTy*)MachOUniquingMap; 160 161 // Form the name to look up. 162 SmallString<64> Name; 163 Name += Segment; 164 Name.push_back(','); 165 Name += Section; 166 167 // Do the lookup, if we have a hit, return it. 168 const MCSectionMachO *&Entry = Map[Name.str()]; 169 if (Entry) return Entry; 170 171 // Otherwise, return a new section. 172 return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes, 173 Reserved2, Kind); 174} 175 176const MCSectionELF *MCContext:: 177getELFSection(StringRef Section, unsigned Type, unsigned Flags, 178 SectionKind Kind) { 179 return getELFSection(Section, Type, Flags, Kind, 0, ""); 180} 181 182const MCSectionELF *MCContext:: 183getELFSection(StringRef Section, unsigned Type, unsigned Flags, 184 SectionKind Kind, unsigned EntrySize, StringRef Group) { 185 if (ELFUniquingMap == 0) 186 ELFUniquingMap = new ELFUniqueMapTy(); 187 ELFUniqueMapTy &Map = *(ELFUniqueMapTy*)ELFUniquingMap; 188 189 // Do the lookup, if we have a hit, return it. 190 StringMapEntry<const MCSectionELF*> &Entry = Map.GetOrCreateValue(Section); 191 if (Entry.getValue()) return Entry.getValue(); 192 193 // Possibly refine the entry size first. 194 if (!EntrySize) { 195 EntrySize = MCSectionELF::DetermineEntrySize(Kind); 196 } 197 198 MCSymbol *GroupSym = NULL; 199 if (!Group.empty()) 200 GroupSym = GetOrCreateSymbol(Group); 201 202 MCSectionELF *Result = new (*this) MCSectionELF(Entry.getKey(), Type, Flags, 203 Kind, EntrySize, GroupSym); 204 Entry.setValue(Result); 205 return Result; 206} 207 208const MCSectionELF *MCContext::CreateELFGroupSection() { 209 MCSectionELF *Result = 210 new (*this) MCSectionELF(".group", MCSectionELF::SHT_GROUP, 0, 211 SectionKind::getReadOnly(), 4, NULL); 212 return Result; 213} 214 215const MCSection *MCContext::getCOFFSection(StringRef Section, 216 unsigned Characteristics, 217 int Selection, 218 SectionKind Kind) { 219 if (COFFUniquingMap == 0) 220 COFFUniquingMap = new COFFUniqueMapTy(); 221 COFFUniqueMapTy &Map = *(COFFUniqueMapTy*)COFFUniquingMap; 222 223 // Do the lookup, if we have a hit, return it. 224 StringMapEntry<const MCSectionCOFF*> &Entry = Map.GetOrCreateValue(Section); 225 if (Entry.getValue()) return Entry.getValue(); 226 227 MCSectionCOFF *Result = new (*this) MCSectionCOFF(Entry.getKey(), 228 Characteristics, 229 Selection, Kind); 230 231 Entry.setValue(Result); 232 return Result; 233} 234 235//===----------------------------------------------------------------------===// 236// Dwarf Management 237//===----------------------------------------------------------------------===// 238 239/// GetDwarfFile - takes a file name an number to place in the dwarf file and 240/// directory tables. If the file number has already been allocated it is an 241/// error and zero is returned and the client reports the error, else the 242/// allocated file number is returned. The file numbers may be in any order. 243unsigned MCContext::GetDwarfFile(StringRef FileName, unsigned FileNumber) { 244 // TODO: a FileNumber of zero says to use the next available file number. 245 // Note: in GenericAsmParser::ParseDirectiveFile() FileNumber was checked 246 // to not be less than one. This needs to be change to be not less than zero. 247 248 // Make space for this FileNumber in the MCDwarfFiles vector if needed. 249 if (FileNumber >= MCDwarfFiles.size()) { 250 MCDwarfFiles.resize(FileNumber + 1); 251 } else { 252 MCDwarfFile *&ExistingFile = MCDwarfFiles[FileNumber]; 253 if (ExistingFile) 254 // It is an error to use see the same number more than once. 255 return 0; 256 } 257 258 // Get the new MCDwarfFile slot for this FileNumber. 259 MCDwarfFile *&File = MCDwarfFiles[FileNumber]; 260 261 // Separate the directory part from the basename of the FileName. 262 std::pair<StringRef, StringRef> Slash = FileName.rsplit('/'); 263 264 // Find or make a entry in the MCDwarfDirs vector for this Directory. 265 StringRef Name; 266 unsigned DirIndex; 267 // Capture directory name. 268 if (Slash.second.empty()) { 269 Name = Slash.first; 270 DirIndex = 0; // For FileNames with no directories a DirIndex of 0 is used. 271 } else { 272 StringRef Directory = Slash.first; 273 Name = Slash.second; 274 for (DirIndex = 0; DirIndex < MCDwarfDirs.size(); DirIndex++) { 275 if (Directory == MCDwarfDirs[DirIndex]) 276 break; 277 } 278 if (DirIndex >= MCDwarfDirs.size()) { 279 char *Buf = static_cast<char *>(Allocate(Directory.size())); 280 memcpy(Buf, Directory.data(), Directory.size()); 281 MCDwarfDirs.push_back(StringRef(Buf, Directory.size())); 282 } 283 // The DirIndex is one based, as DirIndex of 0 is used for FileNames with 284 // no directories. MCDwarfDirs[] is unlike MCDwarfFiles[] in that the 285 // directory names are stored at MCDwarfDirs[DirIndex-1] where FileNames are 286 // stored at MCDwarfFiles[FileNumber].Name . 287 DirIndex++; 288 } 289 290 // Now make the MCDwarfFile entry and place it in the slot in the MCDwarfFiles 291 // vector. 292 char *Buf = static_cast<char *>(Allocate(Name.size())); 293 memcpy(Buf, Name.data(), Name.size()); 294 File = new (*this) MCDwarfFile(StringRef(Buf, Name.size()), DirIndex); 295 296 // return the allocated FileNumber. 297 return FileNumber; 298} 299 300/// isValidDwarfFileNumber - takes a dwarf file number and returns true if it 301/// currently is assigned and false otherwise. 302bool MCContext::isValidDwarfFileNumber(unsigned FileNumber) { 303 if(FileNumber == 0 || FileNumber >= MCDwarfFiles.size()) 304 return false; 305 306 return MCDwarfFiles[FileNumber] != 0; 307} 308