1 //===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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/MCAssembler.h"
15 #include "llvm/MC/MCCodeView.h"
16 #include "llvm/MC/MCDwarf.h"
17 #include "llvm/MC/MCLabel.h"
18 #include "llvm/MC/MCObjectFileInfo.h"
19 #include "llvm/MC/MCRegisterInfo.h"
20 #include "llvm/MC/MCSectionCOFF.h"
21 #include "llvm/MC/MCSectionELF.h"
22 #include "llvm/MC/MCSectionMachO.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSymbolCOFF.h"
25 #include "llvm/MC/MCSymbolELF.h"
26 #include "llvm/MC/MCSymbolMachO.h"
27 #include "llvm/Support/COFF.h"
28 #include "llvm/Support/CommandLine.h"
29 #include "llvm/Support/ELF.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/MemoryBuffer.h"
32 #include "llvm/Support/Signals.h"
33 #include "llvm/Support/SourceMgr.h"
38 AsSecureLogFileName("as-secure-log-file-name",
39 cl::desc("As secure log file name (initialized from "
40 "AS_SECURE_LOG_FILE env variable)"),
41 cl::init(getenv("AS_SECURE_LOG_FILE")), cl::Hidden);
44 MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
45 const MCObjectFileInfo *mofi, const SourceMgr *mgr,
47 : SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(),
48 Symbols(Allocator), UsedNames(Allocator),
49 CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false),
50 GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4),
51 AllowTemporaryLabels(true), DwarfCompileUnitID(0),
52 AutoReset(DoAutoReset), HadError(false) {
53 SecureLogFile = AsSecureLogFileName;
55 SecureLogUsed = false;
57 if (SrcMgr && SrcMgr->getNumBuffers())
59 SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())->getBufferIdentifier();
62 MCContext::~MCContext() {
66 // NOTE: The symbols are all allocated out of a bump pointer allocator,
67 // we don't need to free them here.
70 //===----------------------------------------------------------------------===//
71 // Module Lifetime Management
72 //===----------------------------------------------------------------------===//
74 void MCContext::reset() {
75 // Call the destructors so the fragments are freed
76 COFFAllocator.DestroyAll();
77 ELFAllocator.DestroyAll();
78 MachOAllocator.DestroyAll();
80 MCSubtargetAllocator.DestroyAll();
83 SectionSymbols.clear();
86 CompilationDir.clear();
88 MCDwarfLineTablesCUMap.clear();
89 SectionsForRanges.clear();
90 MCGenDwarfLabelEntries.clear();
91 DwarfDebugFlags = StringRef();
92 DwarfCompileUnitID = 0;
93 CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0);
97 MachOUniquingMap.clear();
98 ELFUniquingMap.clear();
99 COFFUniquingMap.clear();
102 AllowTemporaryLabels = true;
103 DwarfLocSeen = false;
104 GenDwarfForAssembly = false;
105 GenDwarfFileNumber = 0;
110 //===----------------------------------------------------------------------===//
111 // Symbol Manipulation
112 //===----------------------------------------------------------------------===//
114 MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) {
115 SmallString<128> NameSV;
116 StringRef NameRef = Name.toStringRef(NameSV);
118 assert(!NameRef.empty() && "Normal symbols cannot be unnamed!");
120 MCSymbol *&Sym = Symbols[NameRef];
122 Sym = createSymbol(NameRef, false, false);
127 MCSymbolELF *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) {
128 MCSymbolELF *&Sym = SectionSymbols[&Section];
132 StringRef Name = Section.getSectionName();
133 auto NameIter = UsedNames.insert(std::make_pair(Name, false)).first;
134 Sym = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false);
139 MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName,
141 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
142 "$frame_escape_" + Twine(Idx));
145 MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName) {
146 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
147 "$parent_frame_offset");
150 MCSymbol *MCContext::getOrCreateLSDASymbol(StringRef FuncName) {
151 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + "__ehtable$" +
155 MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name,
158 switch (MOFI->getObjectFileType()) {
159 case MCObjectFileInfo::IsCOFF:
160 return new (Name, *this) MCSymbolCOFF(Name, IsTemporary);
161 case MCObjectFileInfo::IsELF:
162 return new (Name, *this) MCSymbolELF(Name, IsTemporary);
163 case MCObjectFileInfo::IsMachO:
164 return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
167 return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name,
171 MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix,
173 if (CanBeUnnamed && !UseNamesOnTempLabels)
174 return createSymbolImpl(nullptr, true);
176 // Determine whether this is an user writter assembler temporary or normal
178 bool IsTemporary = CanBeUnnamed;
179 if (AllowTemporaryLabels && !IsTemporary)
180 IsTemporary = Name.startswith(MAI->getPrivateGlobalPrefix());
182 SmallString<128> NewName = Name;
183 bool AddSuffix = AlwaysAddSuffix;
184 unsigned &NextUniqueID = NextID[Name];
187 NewName.resize(Name.size());
188 raw_svector_ostream(NewName) << NextUniqueID++;
190 auto NameEntry = UsedNames.insert(std::make_pair(NewName, true));
191 if (NameEntry.second || !NameEntry.first->second) {
192 // Ok, we found a name.
193 // Mark it as used for a non-section symbol.
194 NameEntry.first->second = true;
195 // Have the MCSymbol object itself refer to the copy of the string that is
196 // embedded in the UsedNames entry.
197 return createSymbolImpl(&*NameEntry.first, IsTemporary);
199 assert(IsTemporary && "Cannot rename non-temporary symbols");
202 llvm_unreachable("Infinite loop");
205 MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix,
207 SmallString<128> NameSV;
208 raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name;
209 return createSymbol(NameSV, AlwaysAddSuffix, CanBeUnnamed);
212 MCSymbol *MCContext::createLinkerPrivateTempSymbol() {
213 SmallString<128> NameSV;
214 raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp";
215 return createSymbol(NameSV, true, false);
218 MCSymbol *MCContext::createTempSymbol(bool CanBeUnnamed) {
219 return createTempSymbol("tmp", true, CanBeUnnamed);
222 unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
223 MCLabel *&Label = Instances[LocalLabelVal];
225 Label = new (*this) MCLabel(0);
226 return Label->incInstance();
229 unsigned MCContext::GetInstance(unsigned LocalLabelVal) {
230 MCLabel *&Label = Instances[LocalLabelVal];
232 Label = new (*this) MCLabel(0);
233 return Label->getInstance();
236 MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
238 MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)];
240 Sym = createTempSymbol(false);
244 MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) {
245 unsigned Instance = NextInstance(LocalLabelVal);
246 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
249 MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal,
251 unsigned Instance = GetInstance(LocalLabelVal);
254 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
257 MCSymbol *MCContext::lookupSymbol(const Twine &Name) const {
258 SmallString<128> NameSV;
259 StringRef NameRef = Name.toStringRef(NameSV);
260 return Symbols.lookup(NameRef);
263 //===----------------------------------------------------------------------===//
264 // Section Management
265 //===----------------------------------------------------------------------===//
267 MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
268 unsigned TypeAndAttributes,
269 unsigned Reserved2, SectionKind Kind,
270 const char *BeginSymName) {
272 // We unique sections by their segment/section pair. The returned section
273 // may not have the same flags as the requested section, if so this should be
274 // diagnosed by the client as an error.
276 // Form the name to look up.
277 SmallString<64> Name;
282 // Do the lookup, if we have a hit, return it.
283 MCSectionMachO *&Entry = MachOUniquingMap[Name];
287 MCSymbol *Begin = nullptr;
289 Begin = createTempSymbol(BeginSymName, false);
291 // Otherwise, return a new section.
292 return Entry = new (MachOAllocator.Allocate()) MCSectionMachO(
293 Segment, Section, TypeAndAttributes, Reserved2, Kind, Begin);
296 void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) {
298 if (const MCSymbol *Group = Section->getGroup())
299 GroupName = Group->getName();
301 unsigned UniqueID = Section->getUniqueID();
302 ELFUniquingMap.erase(
303 ELFSectionKey{Section->getSectionName(), GroupName, UniqueID});
304 auto I = ELFUniquingMap.insert(std::make_pair(
305 ELFSectionKey{Name, GroupName, UniqueID},
308 StringRef CachedName = I->first.SectionName;
309 const_cast<MCSectionELF *>(Section)->setSectionName(CachedName);
312 MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type,
313 unsigned Flags, unsigned EntrySize,
314 const MCSymbolELF *Group,
315 const MCSectionELF *Associated) {
316 StringMap<bool>::iterator I;
318 std::tie(I, Inserted) =
319 ELFRelSecNames.insert(std::make_pair(Name.str(), true));
321 return new (ELFAllocator.Allocate())
322 MCSectionELF(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
323 EntrySize, Group, true, nullptr, Associated);
326 MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
327 const Twine &Suffix, unsigned Type,
329 unsigned EntrySize) {
330 return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix);
333 MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
334 unsigned Flags, unsigned EntrySize,
335 const Twine &Group, unsigned UniqueID,
336 const char *BeginSymName) {
337 MCSymbolELF *GroupSym = nullptr;
338 if (!Group.isTriviallyEmpty() && !Group.str().empty())
339 GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
341 return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID,
342 BeginSymName, nullptr);
345 MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
346 unsigned Flags, unsigned EntrySize,
347 const MCSymbolELF *GroupSym,
349 const char *BeginSymName,
350 const MCSectionELF *Associated) {
351 StringRef Group = "";
353 Group = GroupSym->getName();
354 // Do the lookup, if we have a hit, return it.
355 auto IterBool = ELFUniquingMap.insert(
356 std::make_pair(ELFSectionKey{Section.str(), Group, UniqueID}, nullptr));
357 auto &Entry = *IterBool.first;
358 if (!IterBool.second)
361 StringRef CachedName = Entry.first.SectionName;
364 if (Flags & ELF::SHF_EXECINSTR)
365 Kind = SectionKind::getText();
367 Kind = SectionKind::getReadOnly();
369 MCSymbol *Begin = nullptr;
371 Begin = createTempSymbol(BeginSymName, false);
373 MCSectionELF *Result = new (ELFAllocator.Allocate())
374 MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID,
376 Entry.second = Result;
380 MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) {
381 MCSectionELF *Result = new (ELFAllocator.Allocate())
382 MCSectionELF(".group", ELF::SHT_GROUP, 0, SectionKind::getReadOnly(), 4,
383 Group, ~0, nullptr, nullptr);
387 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
388 unsigned Characteristics,
390 StringRef COMDATSymName, int Selection,
392 const char *BeginSymName) {
393 MCSymbol *COMDATSymbol = nullptr;
394 if (!COMDATSymName.empty()) {
395 COMDATSymbol = getOrCreateSymbol(COMDATSymName);
396 COMDATSymName = COMDATSymbol->getName();
400 // Do the lookup, if we have a hit, return it.
401 COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID};
402 auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));
403 auto Iter = IterBool.first;
404 if (!IterBool.second)
407 MCSymbol *Begin = nullptr;
409 Begin = createTempSymbol(BeginSymName, false);
411 StringRef CachedName = Iter->first.SectionName;
412 MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
413 CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin);
415 Iter->second = Result;
419 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
420 unsigned Characteristics,
422 const char *BeginSymName) {
423 return getCOFFSection(Section, Characteristics, Kind, "", 0, GenericSectionID,
427 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
428 COFFSectionKey T{Section, "", 0, GenericSectionID};
429 auto Iter = COFFUniquingMap.find(T);
430 if (Iter == COFFUniquingMap.end())
435 MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
436 const MCSymbol *KeySym,
438 // Return the normal section if we don't have to be associative or unique.
439 if (!KeySym && UniqueID == GenericSectionID)
442 // If we have a key symbol, make an associative section with the same name and
443 // kind as the normal section.
444 unsigned Characteristics = Sec->getCharacteristics();
446 Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
447 return getCOFFSection(Sec->getSectionName(), Characteristics,
448 Sec->getKind(), KeySym->getName(),
449 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
452 return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(),
456 MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
457 return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
460 //===----------------------------------------------------------------------===//
462 //===----------------------------------------------------------------------===//
464 /// getDwarfFile - takes a file name an number to place in the dwarf file and
465 /// directory tables. If the file number has already been allocated it is an
466 /// error and zero is returned and the client reports the error, else the
467 /// allocated file number is returned. The file numbers may be in any order.
468 unsigned MCContext::getDwarfFile(StringRef Directory, StringRef FileName,
469 unsigned FileNumber, unsigned CUID) {
470 MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
471 return Table.getFile(Directory, FileName, FileNumber);
474 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
475 /// currently is assigned and false otherwise.
476 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
477 const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = getMCDwarfFiles(CUID);
478 if (FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
481 return !MCDwarfFiles[FileNumber].Name.empty();
484 /// Remove empty sections from SectionStartEndSyms, to avoid generating
485 /// useless debug info for them.
486 void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
487 SectionsForRanges.remove_if(
488 [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); });
491 CodeViewContext &MCContext::getCVContext() {
492 if (!CVContext.get())
493 CVContext.reset(new CodeViewContext);
494 return *CVContext.get();
497 unsigned MCContext::getCVFile(StringRef FileName, unsigned FileNumber) {
498 return getCVContext().addFile(FileNumber, FileName) ? FileNumber : 0;
501 bool MCContext::isValidCVFileNumber(unsigned FileNumber) {
502 return getCVContext().isValidFileNumber(FileNumber);
505 //===----------------------------------------------------------------------===//
507 //===----------------------------------------------------------------------===//
509 void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
512 // If we have a source manager use it. Otherwise just use the generic
513 // report_fatal_error().
515 report_fatal_error(Msg, false);
517 // Use the source manager to print the message.
518 SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
521 void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) {
522 reportError(Loc, Msg);
524 // If we reached here, we are failing ungracefully. Run the interrupt handlers
525 // to make sure any special cleanups get done, in particular that we remove
526 // files registered with RemoveFileOnSignal.
527 sys::RunInterruptHandlers();