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/MCAssembler.h"
14 #include "llvm/MC/MCAsmInfo.h"
15 #include "llvm/MC/MCDwarf.h"
16 #include "llvm/MC/MCLabel.h"
17 #include "llvm/MC/MCObjectFileInfo.h"
18 #include "llvm/MC/MCRegisterInfo.h"
19 #include "llvm/MC/MCSectionCOFF.h"
20 #include "llvm/MC/MCSectionELF.h"
21 #include "llvm/MC/MCSectionMachO.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSymbolCOFF.h"
24 #include "llvm/MC/MCSymbolELF.h"
25 #include "llvm/Support/ELF.h"
26 #include "llvm/Support/ErrorHandling.h"
27 #include "llvm/Support/FileSystem.h"
28 #include "llvm/Support/MemoryBuffer.h"
29 #include "llvm/Support/Signals.h"
30 #include "llvm/Support/SourceMgr.h"
35 MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
36 const MCObjectFileInfo *mofi, const SourceMgr *mgr,
38 : SrcMgr(mgr), MAI(mai), MRI(mri), MOFI(mofi), Allocator(),
39 Symbols(Allocator), UsedNames(Allocator),
40 CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), DwarfLocSeen(false),
41 GenDwarfForAssembly(false), GenDwarfFileNumber(0), DwarfVersion(4),
42 AllowTemporaryLabels(true), DwarfCompileUnitID(0),
43 AutoReset(DoAutoReset) {
45 std::error_code EC = llvm::sys::fs::current_path(CompilationDir);
47 CompilationDir.clear();
49 SecureLogFile = getenv("AS_SECURE_LOG_FILE");
51 SecureLogUsed = false;
53 if (SrcMgr && SrcMgr->getNumBuffers())
55 SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())->getBufferIdentifier();
58 MCContext::~MCContext() {
62 // NOTE: The symbols are all allocated out of a bump pointer allocator,
63 // we don't need to free them here.
65 // If the stream for the .secure_log_unique directive was created free it.
66 delete (raw_ostream *)SecureLog;
69 //===----------------------------------------------------------------------===//
70 // Module Lifetime Management
71 //===----------------------------------------------------------------------===//
73 void MCContext::reset() {
74 // Call the destructors so the fragments are freed
75 for (auto &I : ELFUniquingMap)
76 I.second->~MCSectionELF();
77 for (auto &I : COFFUniquingMap)
78 I.second->~MCSectionCOFF();
79 for (auto &I : MachOUniquingMap)
80 I.second->~MCSectionMachO();
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);
95 MachOUniquingMap.clear();
96 ELFUniquingMap.clear();
97 COFFUniquingMap.clear();
100 AllowTemporaryLabels = true;
101 DwarfLocSeen = false;
102 GenDwarfForAssembly = false;
103 GenDwarfFileNumber = 0;
106 //===----------------------------------------------------------------------===//
107 // Symbol Manipulation
108 //===----------------------------------------------------------------------===//
110 MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) {
111 SmallString<128> NameSV;
112 StringRef NameRef = Name.toStringRef(NameSV);
114 assert(!NameRef.empty() && "Normal symbols cannot be unnamed!");
116 MCSymbol *&Sym = Symbols[NameRef];
118 Sym = createSymbol(NameRef, false, false);
123 MCSymbolELF *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) {
124 MCSymbolELF *&Sym = SectionSymbols[&Section];
128 StringRef Name = Section.getSectionName();
130 MCSymbol *&OldSym = Symbols[Name];
131 if (OldSym && OldSym->isUndefined()) {
132 Sym = cast<MCSymbolELF>(OldSym);
136 auto NameIter = UsedNames.insert(std::make_pair(Name, true)).first;
137 Sym = new (*this) MCSymbolELF(&*NameIter, /*isTemporary*/ false);
145 MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName,
147 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
148 "$frame_escape_" + Twine(Idx));
151 MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName) {
152 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
153 "$parent_frame_offset");
156 MCSymbol *MCContext::getOrCreateLSDASymbol(StringRef FuncName) {
157 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + "__ehtable$" +
161 MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name,
164 switch (MOFI->getObjectFileType()) {
165 case MCObjectFileInfo::IsCOFF:
166 return new (*this) MCSymbolCOFF(Name, IsTemporary);
167 case MCObjectFileInfo::IsELF:
168 return new (*this) MCSymbolELF(Name, IsTemporary);
169 case MCObjectFileInfo::IsMachO:
170 return new (*this) MCSymbol(MCSymbol::SymbolKindUnset, Name, IsTemporary);
173 return new (*this) MCSymbol(MCSymbol::SymbolKindUnset, Name, IsTemporary);
176 MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix,
178 if (IsTemporary && !UseNamesOnTempLabels)
179 return createSymbolImpl(nullptr, true);
181 // Determine whether this is an user writter assembler temporary or normal
184 if (AllowTemporaryLabels)
185 IsTemporary = Name.startswith(MAI->getPrivateGlobalPrefix());
187 SmallString<128> NewName = Name;
188 bool AddSuffix = AlwaysAddSuffix;
189 unsigned &NextUniqueID = NextID[Name];
192 NewName.resize(Name.size());
193 raw_svector_ostream(NewName) << NextUniqueID++;
195 auto NameEntry = UsedNames.insert(std::make_pair(NewName, true));
196 if (NameEntry.second) {
197 // Ok, we found a name. Have the MCSymbol object itself refer to the copy
198 // of the string that is embedded in the UsedNames entry.
199 return createSymbolImpl(&*NameEntry.first, IsTemporary);
201 assert(IsTemporary && "Cannot rename non-temporary symbols");
204 llvm_unreachable("Infinite loop");
207 MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix) {
208 SmallString<128> NameSV;
209 raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name;
210 return createSymbol(NameSV, AlwaysAddSuffix, true);
213 MCSymbol *MCContext::createLinkerPrivateTempSymbol() {
214 SmallString<128> NameSV;
215 raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp";
216 return createSymbol(NameSV, true, false);
219 MCSymbol *MCContext::createTempSymbol() {
220 return createTempSymbol("tmp", true);
223 unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
224 MCLabel *&Label = Instances[LocalLabelVal];
226 Label = new (*this) MCLabel(0);
227 return Label->incInstance();
230 unsigned MCContext::GetInstance(unsigned LocalLabelVal) {
231 MCLabel *&Label = Instances[LocalLabelVal];
233 Label = new (*this) MCLabel(0);
234 return Label->getInstance();
237 MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
239 MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)];
241 Sym = createTempSymbol();
245 MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) {
246 unsigned Instance = NextInstance(LocalLabelVal);
247 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
250 MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal,
252 unsigned Instance = GetInstance(LocalLabelVal);
255 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
258 MCSymbol *MCContext::lookupSymbol(const Twine &Name) const {
259 SmallString<128> NameSV;
260 StringRef NameRef = Name.toStringRef(NameSV);
261 return Symbols.lookup(NameRef);
264 //===----------------------------------------------------------------------===//
265 // Section Management
266 //===----------------------------------------------------------------------===//
268 MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
269 unsigned TypeAndAttributes,
270 unsigned Reserved2, SectionKind Kind,
271 const char *BeginSymName) {
273 // We unique sections by their segment/section pair. The returned section
274 // may not have the same flags as the requested section, if so this should be
275 // diagnosed by the client as an error.
277 // Form the name to look up.
278 SmallString<64> Name;
283 // Do the lookup, if we have a hit, return it.
284 MCSectionMachO *&Entry = MachOUniquingMap[Name];
288 MCSymbol *Begin = nullptr;
290 Begin = createTempSymbol(BeginSymName, false);
292 // Otherwise, return a new section.
293 return Entry = new (*this) MCSectionMachO(Segment, Section, TypeAndAttributes,
294 Reserved2, Kind, Begin);
297 void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) {
299 if (const MCSymbol *Group = Section->getGroup())
300 GroupName = Group->getName();
302 unsigned UniqueID = Section->getUniqueID();
303 ELFUniquingMap.erase(
304 ELFSectionKey{Section->getSectionName(), GroupName, UniqueID});
305 auto I = ELFUniquingMap.insert(std::make_pair(
306 ELFSectionKey{Name, GroupName, UniqueID},
309 StringRef CachedName = I->first.SectionName;
310 const_cast<MCSectionELF *>(Section)->setSectionName(CachedName);
313 MCSectionELF *MCContext::createELFRelSection(StringRef Name, unsigned Type,
314 unsigned Flags, unsigned EntrySize,
315 const MCSymbolELF *Group,
316 const MCSectionELF *Associated) {
317 StringMap<bool>::iterator I;
319 std::tie(I, Inserted) = ELFRelSecNames.insert(std::make_pair(Name, true));
322 MCSectionELF(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
323 EntrySize, Group, true, nullptr, Associated);
326 MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
327 unsigned Flags, unsigned EntrySize,
328 StringRef Group, unsigned UniqueID,
329 const char *BeginSymName) {
330 MCSymbolELF *GroupSym = nullptr;
332 GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
334 return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID,
335 BeginSymName, nullptr);
338 MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
339 unsigned Flags, unsigned EntrySize,
340 const MCSymbolELF *GroupSym,
342 const char *BeginSymName,
343 const MCSectionELF *Associated) {
344 StringRef Group = "";
346 Group = GroupSym->getName();
347 // Do the lookup, if we have a hit, return it.
348 auto IterBool = ELFUniquingMap.insert(
349 std::make_pair(ELFSectionKey{Section, Group, UniqueID}, nullptr));
350 auto &Entry = *IterBool.first;
351 if (!IterBool.second)
354 StringRef CachedName = Entry.first.SectionName;
357 if (Flags & ELF::SHF_EXECINSTR)
358 Kind = SectionKind::getText();
360 Kind = SectionKind::getReadOnly();
362 MCSymbol *Begin = nullptr;
364 Begin = createTempSymbol(BeginSymName, false);
366 MCSectionELF *Result =
367 new (*this) MCSectionELF(CachedName, Type, Flags, Kind, EntrySize,
368 GroupSym, UniqueID, Begin, Associated);
369 Entry.second = Result;
373 MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) {
374 MCSectionELF *Result = new (*this)
375 MCSectionELF(".group", ELF::SHT_GROUP, 0, SectionKind::getReadOnly(), 4,
376 Group, ~0, nullptr, nullptr);
380 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
381 unsigned Characteristics,
383 StringRef COMDATSymName, int Selection,
384 const char *BeginSymName) {
385 MCSymbol *COMDATSymbol = nullptr;
386 if (!COMDATSymName.empty()) {
387 COMDATSymbol = getOrCreateSymbol(COMDATSymName);
388 COMDATSymName = COMDATSymbol->getName();
391 // Do the lookup, if we have a hit, return it.
392 COFFSectionKey T{Section, COMDATSymName, Selection};
393 auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));
394 auto Iter = IterBool.first;
395 if (!IterBool.second)
398 MCSymbol *Begin = nullptr;
400 Begin = createTempSymbol(BeginSymName, false);
402 StringRef CachedName = Iter->first.SectionName;
403 MCSectionCOFF *Result = new (*this) MCSectionCOFF(
404 CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin);
406 Iter->second = Result;
410 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
411 unsigned Characteristics,
413 const char *BeginSymName) {
414 return getCOFFSection(Section, Characteristics, Kind, "", 0, BeginSymName);
417 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
418 COFFSectionKey T{Section, "", 0};
419 auto Iter = COFFUniquingMap.find(T);
420 if (Iter == COFFUniquingMap.end())
425 MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
426 const MCSymbol *KeySym) {
427 // Return the normal section if we don't have to be associative.
431 // Make an associative section with the same name and kind as the normal
433 unsigned Characteristics =
434 Sec->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT;
435 return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(),
437 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE);
440 //===----------------------------------------------------------------------===//
442 //===----------------------------------------------------------------------===//
444 /// getDwarfFile - takes a file name an number to place in the dwarf file and
445 /// directory tables. If the file number has already been allocated it is an
446 /// error and zero is returned and the client reports the error, else the
447 /// allocated file number is returned. The file numbers may be in any order.
448 unsigned MCContext::getDwarfFile(StringRef Directory, StringRef FileName,
449 unsigned FileNumber, unsigned CUID) {
450 MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
451 return Table.getFile(Directory, FileName, FileNumber);
454 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
455 /// currently is assigned and false otherwise.
456 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
457 const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = getMCDwarfFiles(CUID);
458 if (FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
461 return !MCDwarfFiles[FileNumber].Name.empty();
464 /// Remove empty sections from SectionStartEndSyms, to avoid generating
465 /// useless debug info for them.
466 void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
467 SectionsForRanges.remove_if(
468 [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); });
471 void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) const {
472 // If we have a source manager and a location, use it. Otherwise just
473 // use the generic report_fatal_error().
474 if (!SrcMgr || Loc == SMLoc())
475 report_fatal_error(Msg, false);
477 // Use the source manager to print the message.
478 SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
480 // If we reached here, we are failing ungracefully. Run the interrupt handlers
481 // to make sure any special cleanups get done, in particular that we remove
482 // files registered with RemoveFileOnSignal.
483 sys::RunInterruptHandlers();