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/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"
34 
35 using namespace llvm;
36 
37 static cl::opt<char*>
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);
42 
43 
44 MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
45                      const MCObjectFileInfo *mofi, const SourceMgr *mgr,
46                      bool DoAutoReset)
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;
54   SecureLog = nullptr;
55   SecureLogUsed = false;
56 
57   if (SrcMgr && SrcMgr->getNumBuffers())
58     MainFileName =
59         SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())->getBufferIdentifier();
60 }
61 
62 MCContext::~MCContext() {
63   if (AutoReset)
64     reset();
65 
66   // NOTE: The symbols are all allocated out of a bump pointer allocator,
67   // we don't need to free them here.
68 }
69 
70 //===----------------------------------------------------------------------===//
71 // Module Lifetime Management
72 //===----------------------------------------------------------------------===//
73 
74 void MCContext::reset() {
75   // Call the destructors so the fragments are freed
76   COFFAllocator.DestroyAll();
77   ELFAllocator.DestroyAll();
78   MachOAllocator.DestroyAll();
79 
80   MCSubtargetAllocator.DestroyAll();
81   UsedNames.clear();
82   Symbols.clear();
83   SectionSymbols.clear();
84   Allocator.Reset();
85   Instances.clear();
86   CompilationDir.clear();
87   MainFileName.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);
94 
95   CVContext.reset();
96 
97   MachOUniquingMap.clear();
98   ELFUniquingMap.clear();
99   COFFUniquingMap.clear();
100 
101   NextID.clear();
102   AllowTemporaryLabels = true;
103   DwarfLocSeen = false;
104   GenDwarfForAssembly = false;
105   GenDwarfFileNumber = 0;
106 
107   HadError = false;
108 }
109 
110 //===----------------------------------------------------------------------===//
111 // Symbol Manipulation
112 //===----------------------------------------------------------------------===//
113 
114 MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) {
115   SmallString<128> NameSV;
116   StringRef NameRef = Name.toStringRef(NameSV);
117 
118   assert(!NameRef.empty() && "Normal symbols cannot be unnamed!");
119 
120   MCSymbol *&Sym = Symbols[NameRef];
121   if (!Sym)
122     Sym = createSymbol(NameRef, false, false);
123 
124   return Sym;
125 }
126 
127 MCSymbolELF *MCContext::getOrCreateSectionSymbol(const MCSectionELF &Section) {
128   MCSymbolELF *&Sym = SectionSymbols[&Section];
129   if (Sym)
130     return Sym;
131 
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);
135 
136   return Sym;
137 }
138 
139 MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName,
140                                                  unsigned Idx) {
141   return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
142                            "$frame_escape_" + Twine(Idx));
143 }
144 
145 MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName) {
146   return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
147                            "$parent_frame_offset");
148 }
149 
150 MCSymbol *MCContext::getOrCreateLSDASymbol(StringRef FuncName) {
151   return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + "__ehtable$" +
152                            FuncName);
153 }
154 
155 MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name,
156                                       bool IsTemporary) {
157   if (MOFI) {
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);
165     }
166   }
167   return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name,
168                                     IsTemporary);
169 }
170 
171 MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix,
172                                   bool CanBeUnnamed) {
173   if (CanBeUnnamed && !UseNamesOnTempLabels)
174     return createSymbolImpl(nullptr, true);
175 
176   // Determine whether this is an user writter assembler temporary or normal
177   // label, if used.
178   bool IsTemporary = CanBeUnnamed;
179   if (AllowTemporaryLabels && !IsTemporary)
180     IsTemporary = Name.startswith(MAI->getPrivateGlobalPrefix());
181 
182   SmallString<128> NewName = Name;
183   bool AddSuffix = AlwaysAddSuffix;
184   unsigned &NextUniqueID = NextID[Name];
185   for (;;) {
186     if (AddSuffix) {
187       NewName.resize(Name.size());
188       raw_svector_ostream(NewName) << NextUniqueID++;
189     }
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);
198     }
199     assert(IsTemporary && "Cannot rename non-temporary symbols");
200     AddSuffix = true;
201   }
202   llvm_unreachable("Infinite loop");
203 }
204 
205 MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix,
206                                       bool CanBeUnnamed) {
207   SmallString<128> NameSV;
208   raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name;
209   return createSymbol(NameSV, AlwaysAddSuffix, CanBeUnnamed);
210 }
211 
212 MCSymbol *MCContext::createLinkerPrivateTempSymbol() {
213   SmallString<128> NameSV;
214   raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp";
215   return createSymbol(NameSV, true, false);
216 }
217 
218 MCSymbol *MCContext::createTempSymbol(bool CanBeUnnamed) {
219   return createTempSymbol("tmp", true, CanBeUnnamed);
220 }
221 
222 unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
223   MCLabel *&Label = Instances[LocalLabelVal];
224   if (!Label)
225     Label = new (*this) MCLabel(0);
226   return Label->incInstance();
227 }
228 
229 unsigned MCContext::GetInstance(unsigned LocalLabelVal) {
230   MCLabel *&Label = Instances[LocalLabelVal];
231   if (!Label)
232     Label = new (*this) MCLabel(0);
233   return Label->getInstance();
234 }
235 
236 MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
237                                                        unsigned Instance) {
238   MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)];
239   if (!Sym)
240     Sym = createTempSymbol(false);
241   return Sym;
242 }
243 
244 MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) {
245   unsigned Instance = NextInstance(LocalLabelVal);
246   return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
247 }
248 
249 MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal,
250                                                bool Before) {
251   unsigned Instance = GetInstance(LocalLabelVal);
252   if (!Before)
253     ++Instance;
254   return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
255 }
256 
257 MCSymbol *MCContext::lookupSymbol(const Twine &Name) const {
258   SmallString<128> NameSV;
259   StringRef NameRef = Name.toStringRef(NameSV);
260   return Symbols.lookup(NameRef);
261 }
262 
263 //===----------------------------------------------------------------------===//
264 // Section Management
265 //===----------------------------------------------------------------------===//
266 
267 MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
268                                            unsigned TypeAndAttributes,
269                                            unsigned Reserved2, SectionKind Kind,
270                                            const char *BeginSymName) {
271 
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.
275 
276   // Form the name to look up.
277   SmallString<64> Name;
278   Name += Segment;
279   Name.push_back(',');
280   Name += Section;
281 
282   // Do the lookup, if we have a hit, return it.
283   MCSectionMachO *&Entry = MachOUniquingMap[Name];
284   if (Entry)
285     return Entry;
286 
287   MCSymbol *Begin = nullptr;
288   if (BeginSymName)
289     Begin = createTempSymbol(BeginSymName, false);
290 
291   // Otherwise, return a new section.
292   return Entry = new (MachOAllocator.Allocate()) MCSectionMachO(
293              Segment, Section, TypeAndAttributes, Reserved2, Kind, Begin);
294 }
295 
296 void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) {
297   StringRef GroupName;
298   if (const MCSymbol *Group = Section->getGroup())
299     GroupName = Group->getName();
300 
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},
306                                      Section))
307                .first;
308   StringRef CachedName = I->first.SectionName;
309   const_cast<MCSectionELF *>(Section)->setSectionName(CachedName);
310 }
311 
312 MCSectionELF *MCContext::createELFRelSection(StringRef Name, unsigned Type,
313                                              unsigned Flags, unsigned EntrySize,
314                                              const MCSymbolELF *Group,
315                                              const MCSectionELF *Associated) {
316   StringMap<bool>::iterator I;
317   bool Inserted;
318   std::tie(I, Inserted) = ELFRelSecNames.insert(std::make_pair(Name, true));
319 
320   return new (ELFAllocator.Allocate())
321       MCSectionELF(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
322                    EntrySize, Group, true, nullptr, Associated);
323 }
324 
325 MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
326                                        unsigned Flags, unsigned EntrySize,
327                                        StringRef Group, unsigned UniqueID,
328                                        const char *BeginSymName) {
329   MCSymbolELF *GroupSym = nullptr;
330   if (!Group.empty())
331     GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
332 
333   return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID,
334                        BeginSymName, nullptr);
335 }
336 
337 MCSectionELF *MCContext::getELFSection(StringRef Section, unsigned Type,
338                                        unsigned Flags, unsigned EntrySize,
339                                        const MCSymbolELF *GroupSym,
340                                        unsigned UniqueID,
341                                        const char *BeginSymName,
342                                        const MCSectionELF *Associated) {
343   StringRef Group = "";
344   if (GroupSym)
345     Group = GroupSym->getName();
346   // Do the lookup, if we have a hit, return it.
347   auto IterBool = ELFUniquingMap.insert(
348       std::make_pair(ELFSectionKey{Section, Group, UniqueID}, nullptr));
349   auto &Entry = *IterBool.first;
350   if (!IterBool.second)
351     return Entry.second;
352 
353   StringRef CachedName = Entry.first.SectionName;
354 
355   SectionKind Kind;
356   if (Flags & ELF::SHF_EXECINSTR)
357     Kind = SectionKind::getText();
358   else
359     Kind = SectionKind::getReadOnly();
360 
361   MCSymbol *Begin = nullptr;
362   if (BeginSymName)
363     Begin = createTempSymbol(BeginSymName, false);
364 
365   MCSectionELF *Result = new (ELFAllocator.Allocate())
366       MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID,
367                    Begin, Associated);
368   Entry.second = Result;
369   return Result;
370 }
371 
372 MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) {
373   MCSectionELF *Result = new (ELFAllocator.Allocate())
374       MCSectionELF(".group", ELF::SHT_GROUP, 0, SectionKind::getReadOnly(), 4,
375                    Group, ~0, nullptr, nullptr);
376   return Result;
377 }
378 
379 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
380                                          unsigned Characteristics,
381                                          SectionKind Kind,
382                                          StringRef COMDATSymName, int Selection,
383                                          unsigned UniqueID,
384                                          const char *BeginSymName) {
385   MCSymbol *COMDATSymbol = nullptr;
386   if (!COMDATSymName.empty()) {
387     COMDATSymbol = getOrCreateSymbol(COMDATSymName);
388     COMDATSymName = COMDATSymbol->getName();
389   }
390 
391 
392   // Do the lookup, if we have a hit, return it.
393   COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID};
394   auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));
395   auto Iter = IterBool.first;
396   if (!IterBool.second)
397     return Iter->second;
398 
399   MCSymbol *Begin = nullptr;
400   if (BeginSymName)
401     Begin = createTempSymbol(BeginSymName, false);
402 
403   StringRef CachedName = Iter->first.SectionName;
404   MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
405       CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin);
406 
407   Iter->second = Result;
408   return Result;
409 }
410 
411 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
412                                          unsigned Characteristics,
413                                          SectionKind Kind,
414                                          const char *BeginSymName) {
415   return getCOFFSection(Section, Characteristics, Kind, "", 0, GenericSectionID,
416                         BeginSymName);
417 }
418 
419 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
420   COFFSectionKey T{Section, "", 0, GenericSectionID};
421   auto Iter = COFFUniquingMap.find(T);
422   if (Iter == COFFUniquingMap.end())
423     return nullptr;
424   return Iter->second;
425 }
426 
427 MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
428                                                     const MCSymbol *KeySym,
429                                                     unsigned UniqueID) {
430   // Return the normal section if we don't have to be associative or unique.
431   if (!KeySym && UniqueID == GenericSectionID)
432     return Sec;
433 
434   // If we have a key symbol, make an associative section with the same name and
435   // kind as the normal section.
436   unsigned Characteristics = Sec->getCharacteristics();
437   if (KeySym) {
438     Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
439     return getCOFFSection(Sec->getSectionName(), Characteristics,
440                           Sec->getKind(), KeySym->getName(),
441                           COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
442   }
443 
444   return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(),
445                         "", 0, UniqueID);
446 }
447 
448 MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
449   return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
450 }
451 
452 //===----------------------------------------------------------------------===//
453 // Dwarf Management
454 //===----------------------------------------------------------------------===//
455 
456 /// getDwarfFile - takes a file name an number to place in the dwarf file and
457 /// directory tables.  If the file number has already been allocated it is an
458 /// error and zero is returned and the client reports the error, else the
459 /// allocated file number is returned.  The file numbers may be in any order.
460 unsigned MCContext::getDwarfFile(StringRef Directory, StringRef FileName,
461                                  unsigned FileNumber, unsigned CUID) {
462   MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
463   return Table.getFile(Directory, FileName, FileNumber);
464 }
465 
466 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
467 /// currently is assigned and false otherwise.
468 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
469   const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = getMCDwarfFiles(CUID);
470   if (FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
471     return false;
472 
473   return !MCDwarfFiles[FileNumber].Name.empty();
474 }
475 
476 /// Remove empty sections from SectionStartEndSyms, to avoid generating
477 /// useless debug info for them.
478 void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
479   SectionsForRanges.remove_if(
480       [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); });
481 }
482 
483 CodeViewContext &MCContext::getCVContext() {
484   if (!CVContext.get())
485     CVContext.reset(new CodeViewContext);
486   return *CVContext.get();
487 }
488 
489 unsigned MCContext::getCVFile(StringRef FileName, unsigned FileNumber) {
490   return getCVContext().addFile(FileNumber, FileName) ? FileNumber : 0;
491 }
492 
493 bool MCContext::isValidCVFileNumber(unsigned FileNumber) {
494   return getCVContext().isValidFileNumber(FileNumber);
495 }
496 
497 //===----------------------------------------------------------------------===//
498 // Error Reporting
499 //===----------------------------------------------------------------------===//
500 
501 void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
502   HadError = true;
503 
504   // If we have a source manager use it. Otherwise just use the generic
505   // report_fatal_error().
506   if (!SrcMgr)
507     report_fatal_error(Msg, false);
508 
509   // Use the source manager to print the message.
510   SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
511 }
512 
513 void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) {
514   reportError(Loc, Msg);
515 
516   // If we reached here, we are failing ungracefully. Run the interrupt handlers
517   // to make sure any special cleanups get done, in particular that we remove
518   // files registered with RemoveFileOnSignal.
519   sys::RunInterruptHandlers();
520   exit(1);
521 }
522