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
35using namespace llvm;
36
37static cl::opt<char*>
38AsSecureLogFileName("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
44MCContext::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
62MCContext::~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
74void 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
114MCSymbol *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
127MCSymbolELF *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
139MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName,
140                                                 unsigned Idx) {
141  return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
142                           "$frame_escape_" + Twine(Idx));
143}
144
145MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName) {
146  return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
147                           "$parent_frame_offset");
148}
149
150MCSymbol *MCContext::getOrCreateLSDASymbol(StringRef FuncName) {
151  return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + "__ehtable$" +
152                           FuncName);
153}
154
155MCSymbol *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
171MCSymbol *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
205MCSymbol *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
212MCSymbol *MCContext::createLinkerPrivateTempSymbol() {
213  SmallString<128> NameSV;
214  raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp";
215  return createSymbol(NameSV, true, false);
216}
217
218MCSymbol *MCContext::createTempSymbol(bool CanBeUnnamed) {
219  return createTempSymbol("tmp", true, CanBeUnnamed);
220}
221
222unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
223  MCLabel *&Label = Instances[LocalLabelVal];
224  if (!Label)
225    Label = new (*this) MCLabel(0);
226  return Label->incInstance();
227}
228
229unsigned MCContext::GetInstance(unsigned LocalLabelVal) {
230  MCLabel *&Label = Instances[LocalLabelVal];
231  if (!Label)
232    Label = new (*this) MCLabel(0);
233  return Label->getInstance();
234}
235
236MCSymbol *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
244MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) {
245  unsigned Instance = NextInstance(LocalLabelVal);
246  return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
247}
248
249MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal,
250                                               bool Before) {
251  unsigned Instance = GetInstance(LocalLabelVal);
252  if (!Before)
253    ++Instance;
254  return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
255}
256
257MCSymbol *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
267MCSectionMachO *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
296void 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
312MCSectionELF *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;
317  bool Inserted;
318  std::tie(I, Inserted) =
319      ELFRelSecNames.insert(std::make_pair(Name.str(), true));
320
321  return new (ELFAllocator.Allocate())
322      MCSectionELF(I->getKey(), Type, Flags, SectionKind::getReadOnly(),
323                   EntrySize, Group, true, nullptr, Associated);
324}
325
326MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
327                                            const Twine &Suffix, unsigned Type,
328                                            unsigned Flags,
329                                            unsigned EntrySize) {
330  return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix);
331}
332
333MCSectionELF *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));
340
341  return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID,
342                       BeginSymName, nullptr);
343}
344
345MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
346                                       unsigned Flags, unsigned EntrySize,
347                                       const MCSymbolELF *GroupSym,
348                                       unsigned UniqueID,
349                                       const char *BeginSymName,
350                                       const MCSectionELF *Associated) {
351  StringRef Group = "";
352  if (GroupSym)
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)
359    return Entry.second;
360
361  StringRef CachedName = Entry.first.SectionName;
362
363  SectionKind Kind;
364  if (Flags & ELF::SHF_EXECINSTR)
365    Kind = SectionKind::getText();
366  else
367    Kind = SectionKind::getReadOnly();
368
369  MCSymbol *Begin = nullptr;
370  if (BeginSymName)
371    Begin = createTempSymbol(BeginSymName, false);
372
373  MCSectionELF *Result = new (ELFAllocator.Allocate())
374      MCSectionELF(CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID,
375                   Begin, Associated);
376  Entry.second = Result;
377  return Result;
378}
379
380MCSectionELF *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);
384  return Result;
385}
386
387MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
388                                         unsigned Characteristics,
389                                         SectionKind Kind,
390                                         StringRef COMDATSymName, int Selection,
391                                         unsigned UniqueID,
392                                         const char *BeginSymName) {
393  MCSymbol *COMDATSymbol = nullptr;
394  if (!COMDATSymName.empty()) {
395    COMDATSymbol = getOrCreateSymbol(COMDATSymName);
396    COMDATSymName = COMDATSymbol->getName();
397  }
398
399
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)
405    return Iter->second;
406
407  MCSymbol *Begin = nullptr;
408  if (BeginSymName)
409    Begin = createTempSymbol(BeginSymName, false);
410
411  StringRef CachedName = Iter->first.SectionName;
412  MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
413      CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin);
414
415  Iter->second = Result;
416  return Result;
417}
418
419MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
420                                         unsigned Characteristics,
421                                         SectionKind Kind,
422                                         const char *BeginSymName) {
423  return getCOFFSection(Section, Characteristics, Kind, "", 0, GenericSectionID,
424                        BeginSymName);
425}
426
427MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) {
428  COFFSectionKey T{Section, "", 0, GenericSectionID};
429  auto Iter = COFFUniquingMap.find(T);
430  if (Iter == COFFUniquingMap.end())
431    return nullptr;
432  return Iter->second;
433}
434
435MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
436                                                    const MCSymbol *KeySym,
437                                                    unsigned UniqueID) {
438  // Return the normal section if we don't have to be associative or unique.
439  if (!KeySym && UniqueID == GenericSectionID)
440    return Sec;
441
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();
445  if (KeySym) {
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);
450  }
451
452  return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(),
453                        "", 0, UniqueID);
454}
455
456MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
457  return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
458}
459
460//===----------------------------------------------------------------------===//
461// Dwarf Management
462//===----------------------------------------------------------------------===//
463
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.
468unsigned MCContext::getDwarfFile(StringRef Directory, StringRef FileName,
469                                 unsigned FileNumber, unsigned CUID) {
470  MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
471  return Table.getFile(Directory, FileName, FileNumber);
472}
473
474/// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
475/// currently is assigned and false otherwise.
476bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
477  const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = getMCDwarfFiles(CUID);
478  if (FileNumber == 0 || FileNumber >= MCDwarfFiles.size())
479    return false;
480
481  return !MCDwarfFiles[FileNumber].Name.empty();
482}
483
484/// Remove empty sections from SectionStartEndSyms, to avoid generating
485/// useless debug info for them.
486void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
487  SectionsForRanges.remove_if(
488      [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); });
489}
490
491CodeViewContext &MCContext::getCVContext() {
492  if (!CVContext.get())
493    CVContext.reset(new CodeViewContext);
494  return *CVContext.get();
495}
496
497unsigned MCContext::getCVFile(StringRef FileName, unsigned FileNumber) {
498  return getCVContext().addFile(FileNumber, FileName) ? FileNumber : 0;
499}
500
501bool MCContext::isValidCVFileNumber(unsigned FileNumber) {
502  return getCVContext().isValidFileNumber(FileNumber);
503}
504
505//===----------------------------------------------------------------------===//
506// Error Reporting
507//===----------------------------------------------------------------------===//
508
509void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
510  HadError = true;
511
512  // If we have a source manager use it. Otherwise just use the generic
513  // report_fatal_error().
514  if (!SrcMgr)
515    report_fatal_error(Msg, false);
516
517  // Use the source manager to print the message.
518  SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
519}
520
521void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) {
522  reportError(Loc, Msg);
523
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();
528  exit(1);
529}
530