xref: /freebsd-src/contrib/llvm-project/llvm/lib/MC/MCContext.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
10*0b57cec5SDimitry Andric #include "llvm/ADT/Optional.h"
11*0b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
12*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
13*0b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h"
14*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
15*0b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
16*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/COFF.h"
17*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
18*0b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
19*0b57cec5SDimitry Andric #include "llvm/MC/MCCodeView.h"
20*0b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h"
21*0b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
22*0b57cec5SDimitry Andric #include "llvm/MC/MCFragment.h"
23*0b57cec5SDimitry Andric #include "llvm/MC/MCLabel.h"
24*0b57cec5SDimitry Andric #include "llvm/MC/MCObjectFileInfo.h"
25*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionCOFF.h"
26*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionELF.h"
27*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionMachO.h"
28*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionWasm.h"
29*0b57cec5SDimitry Andric #include "llvm/MC/MCSectionXCOFF.h"
30*0b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
31*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
32*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbolCOFF.h"
33*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbolELF.h"
34*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbolMachO.h"
35*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbolWasm.h"
36*0b57cec5SDimitry Andric #include "llvm/MC/MCSymbolXCOFF.h"
37*0b57cec5SDimitry Andric #include "llvm/MC/SectionKind.h"
38*0b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
39*0b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
40*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
41*0b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
42*0b57cec5SDimitry Andric #include "llvm/Support/Path.h"
43*0b57cec5SDimitry Andric #include "llvm/Support/Signals.h"
44*0b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h"
45*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
46*0b57cec5SDimitry Andric #include <cassert>
47*0b57cec5SDimitry Andric #include <cstdlib>
48*0b57cec5SDimitry Andric #include <tuple>
49*0b57cec5SDimitry Andric #include <utility>
50*0b57cec5SDimitry Andric 
51*0b57cec5SDimitry Andric using namespace llvm;
52*0b57cec5SDimitry Andric 
53*0b57cec5SDimitry Andric static cl::opt<char*>
54*0b57cec5SDimitry Andric AsSecureLogFileName("as-secure-log-file-name",
55*0b57cec5SDimitry Andric         cl::desc("As secure log file name (initialized from "
56*0b57cec5SDimitry Andric                  "AS_SECURE_LOG_FILE env variable)"),
57*0b57cec5SDimitry Andric         cl::init(getenv("AS_SECURE_LOG_FILE")), cl::Hidden);
58*0b57cec5SDimitry Andric 
59*0b57cec5SDimitry Andric MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
60*0b57cec5SDimitry Andric                      const MCObjectFileInfo *mofi, const SourceMgr *mgr,
61*0b57cec5SDimitry Andric                      bool DoAutoReset)
62*0b57cec5SDimitry Andric     : SrcMgr(mgr), InlineSrcMgr(nullptr), MAI(mai), MRI(mri), MOFI(mofi),
63*0b57cec5SDimitry Andric       Symbols(Allocator), UsedNames(Allocator),
64*0b57cec5SDimitry Andric       InlineAsmUsedLabelNames(Allocator),
65*0b57cec5SDimitry Andric       CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0),
66*0b57cec5SDimitry Andric       AutoReset(DoAutoReset) {
67*0b57cec5SDimitry Andric   SecureLogFile = AsSecureLogFileName;
68*0b57cec5SDimitry Andric 
69*0b57cec5SDimitry Andric   if (SrcMgr && SrcMgr->getNumBuffers())
70*0b57cec5SDimitry Andric     MainFileName =
71*0b57cec5SDimitry Andric         SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())->getBufferIdentifier();
72*0b57cec5SDimitry Andric }
73*0b57cec5SDimitry Andric 
74*0b57cec5SDimitry Andric MCContext::~MCContext() {
75*0b57cec5SDimitry Andric   if (AutoReset)
76*0b57cec5SDimitry Andric     reset();
77*0b57cec5SDimitry Andric 
78*0b57cec5SDimitry Andric   // NOTE: The symbols are all allocated out of a bump pointer allocator,
79*0b57cec5SDimitry Andric   // we don't need to free them here.
80*0b57cec5SDimitry Andric }
81*0b57cec5SDimitry Andric 
82*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
83*0b57cec5SDimitry Andric // Module Lifetime Management
84*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
85*0b57cec5SDimitry Andric 
86*0b57cec5SDimitry Andric void MCContext::reset() {
87*0b57cec5SDimitry Andric   // Call the destructors so the fragments are freed
88*0b57cec5SDimitry Andric   COFFAllocator.DestroyAll();
89*0b57cec5SDimitry Andric   ELFAllocator.DestroyAll();
90*0b57cec5SDimitry Andric   MachOAllocator.DestroyAll();
91*0b57cec5SDimitry Andric   XCOFFAllocator.DestroyAll();
92*0b57cec5SDimitry Andric 
93*0b57cec5SDimitry Andric   MCSubtargetAllocator.DestroyAll();
94*0b57cec5SDimitry Andric   InlineAsmUsedLabelNames.clear();
95*0b57cec5SDimitry Andric   UsedNames.clear();
96*0b57cec5SDimitry Andric   Symbols.clear();
97*0b57cec5SDimitry Andric   Allocator.Reset();
98*0b57cec5SDimitry Andric   Instances.clear();
99*0b57cec5SDimitry Andric   CompilationDir.clear();
100*0b57cec5SDimitry Andric   MainFileName.clear();
101*0b57cec5SDimitry Andric   MCDwarfLineTablesCUMap.clear();
102*0b57cec5SDimitry Andric   SectionsForRanges.clear();
103*0b57cec5SDimitry Andric   MCGenDwarfLabelEntries.clear();
104*0b57cec5SDimitry Andric   DwarfDebugFlags = StringRef();
105*0b57cec5SDimitry Andric   DwarfCompileUnitID = 0;
106*0b57cec5SDimitry Andric   CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0);
107*0b57cec5SDimitry Andric 
108*0b57cec5SDimitry Andric   CVContext.reset();
109*0b57cec5SDimitry Andric 
110*0b57cec5SDimitry Andric   MachOUniquingMap.clear();
111*0b57cec5SDimitry Andric   ELFUniquingMap.clear();
112*0b57cec5SDimitry Andric   COFFUniquingMap.clear();
113*0b57cec5SDimitry Andric   WasmUniquingMap.clear();
114*0b57cec5SDimitry Andric   XCOFFUniquingMap.clear();
115*0b57cec5SDimitry Andric 
116*0b57cec5SDimitry Andric   NextID.clear();
117*0b57cec5SDimitry Andric   AllowTemporaryLabels = true;
118*0b57cec5SDimitry Andric   DwarfLocSeen = false;
119*0b57cec5SDimitry Andric   GenDwarfForAssembly = false;
120*0b57cec5SDimitry Andric   GenDwarfFileNumber = 0;
121*0b57cec5SDimitry Andric 
122*0b57cec5SDimitry Andric   HadError = false;
123*0b57cec5SDimitry Andric }
124*0b57cec5SDimitry Andric 
125*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
126*0b57cec5SDimitry Andric // Symbol Manipulation
127*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
128*0b57cec5SDimitry Andric 
129*0b57cec5SDimitry Andric MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) {
130*0b57cec5SDimitry Andric   SmallString<128> NameSV;
131*0b57cec5SDimitry Andric   StringRef NameRef = Name.toStringRef(NameSV);
132*0b57cec5SDimitry Andric 
133*0b57cec5SDimitry Andric   assert(!NameRef.empty() && "Normal symbols cannot be unnamed!");
134*0b57cec5SDimitry Andric 
135*0b57cec5SDimitry Andric   MCSymbol *&Sym = Symbols[NameRef];
136*0b57cec5SDimitry Andric   if (!Sym)
137*0b57cec5SDimitry Andric     Sym = createSymbol(NameRef, false, false);
138*0b57cec5SDimitry Andric 
139*0b57cec5SDimitry Andric   return Sym;
140*0b57cec5SDimitry Andric }
141*0b57cec5SDimitry Andric 
142*0b57cec5SDimitry Andric MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName,
143*0b57cec5SDimitry Andric                                                  unsigned Idx) {
144*0b57cec5SDimitry Andric   return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
145*0b57cec5SDimitry Andric                            "$frame_escape_" + Twine(Idx));
146*0b57cec5SDimitry Andric }
147*0b57cec5SDimitry Andric 
148*0b57cec5SDimitry Andric MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName) {
149*0b57cec5SDimitry Andric   return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
150*0b57cec5SDimitry Andric                            "$parent_frame_offset");
151*0b57cec5SDimitry Andric }
152*0b57cec5SDimitry Andric 
153*0b57cec5SDimitry Andric MCSymbol *MCContext::getOrCreateLSDASymbol(StringRef FuncName) {
154*0b57cec5SDimitry Andric   return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + "__ehtable$" +
155*0b57cec5SDimitry Andric                            FuncName);
156*0b57cec5SDimitry Andric }
157*0b57cec5SDimitry Andric 
158*0b57cec5SDimitry Andric MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name,
159*0b57cec5SDimitry Andric                                       bool IsTemporary) {
160*0b57cec5SDimitry Andric   if (MOFI) {
161*0b57cec5SDimitry Andric     switch (MOFI->getObjectFileType()) {
162*0b57cec5SDimitry Andric     case MCObjectFileInfo::IsCOFF:
163*0b57cec5SDimitry Andric       return new (Name, *this) MCSymbolCOFF(Name, IsTemporary);
164*0b57cec5SDimitry Andric     case MCObjectFileInfo::IsELF:
165*0b57cec5SDimitry Andric       return new (Name, *this) MCSymbolELF(Name, IsTemporary);
166*0b57cec5SDimitry Andric     case MCObjectFileInfo::IsMachO:
167*0b57cec5SDimitry Andric       return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
168*0b57cec5SDimitry Andric     case MCObjectFileInfo::IsWasm:
169*0b57cec5SDimitry Andric       return new (Name, *this) MCSymbolWasm(Name, IsTemporary);
170*0b57cec5SDimitry Andric     case MCObjectFileInfo::IsXCOFF:
171*0b57cec5SDimitry Andric       return new (Name, *this) MCSymbolXCOFF(Name, IsTemporary);
172*0b57cec5SDimitry Andric     }
173*0b57cec5SDimitry Andric   }
174*0b57cec5SDimitry Andric   return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name,
175*0b57cec5SDimitry Andric                                     IsTemporary);
176*0b57cec5SDimitry Andric }
177*0b57cec5SDimitry Andric 
178*0b57cec5SDimitry Andric MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix,
179*0b57cec5SDimitry Andric                                   bool CanBeUnnamed) {
180*0b57cec5SDimitry Andric   if (CanBeUnnamed && !UseNamesOnTempLabels)
181*0b57cec5SDimitry Andric     return createSymbolImpl(nullptr, true);
182*0b57cec5SDimitry Andric 
183*0b57cec5SDimitry Andric   // Determine whether this is a user written assembler temporary or normal
184*0b57cec5SDimitry Andric   // label, if used.
185*0b57cec5SDimitry Andric   bool IsTemporary = CanBeUnnamed;
186*0b57cec5SDimitry Andric   if (AllowTemporaryLabels && !IsTemporary)
187*0b57cec5SDimitry Andric     IsTemporary = Name.startswith(MAI->getPrivateGlobalPrefix());
188*0b57cec5SDimitry Andric 
189*0b57cec5SDimitry Andric   SmallString<128> NewName = Name;
190*0b57cec5SDimitry Andric   bool AddSuffix = AlwaysAddSuffix;
191*0b57cec5SDimitry Andric   unsigned &NextUniqueID = NextID[Name];
192*0b57cec5SDimitry Andric   while (true) {
193*0b57cec5SDimitry Andric     if (AddSuffix) {
194*0b57cec5SDimitry Andric       NewName.resize(Name.size());
195*0b57cec5SDimitry Andric       raw_svector_ostream(NewName) << NextUniqueID++;
196*0b57cec5SDimitry Andric     }
197*0b57cec5SDimitry Andric     auto NameEntry = UsedNames.insert(std::make_pair(NewName, true));
198*0b57cec5SDimitry Andric     if (NameEntry.second || !NameEntry.first->second) {
199*0b57cec5SDimitry Andric       // Ok, we found a name.
200*0b57cec5SDimitry Andric       // Mark it as used for a non-section symbol.
201*0b57cec5SDimitry Andric       NameEntry.first->second = true;
202*0b57cec5SDimitry Andric       // Have the MCSymbol object itself refer to the copy of the string that is
203*0b57cec5SDimitry Andric       // embedded in the UsedNames entry.
204*0b57cec5SDimitry Andric       return createSymbolImpl(&*NameEntry.first, IsTemporary);
205*0b57cec5SDimitry Andric     }
206*0b57cec5SDimitry Andric     assert(IsTemporary && "Cannot rename non-temporary symbols");
207*0b57cec5SDimitry Andric     AddSuffix = true;
208*0b57cec5SDimitry Andric   }
209*0b57cec5SDimitry Andric   llvm_unreachable("Infinite loop");
210*0b57cec5SDimitry Andric }
211*0b57cec5SDimitry Andric 
212*0b57cec5SDimitry Andric MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix,
213*0b57cec5SDimitry Andric                                       bool CanBeUnnamed) {
214*0b57cec5SDimitry Andric   SmallString<128> NameSV;
215*0b57cec5SDimitry Andric   raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name;
216*0b57cec5SDimitry Andric   return createSymbol(NameSV, AlwaysAddSuffix, CanBeUnnamed);
217*0b57cec5SDimitry Andric }
218*0b57cec5SDimitry Andric 
219*0b57cec5SDimitry Andric MCSymbol *MCContext::createLinkerPrivateTempSymbol() {
220*0b57cec5SDimitry Andric   SmallString<128> NameSV;
221*0b57cec5SDimitry Andric   raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp";
222*0b57cec5SDimitry Andric   return createSymbol(NameSV, true, false);
223*0b57cec5SDimitry Andric }
224*0b57cec5SDimitry Andric 
225*0b57cec5SDimitry Andric MCSymbol *MCContext::createTempSymbol(bool CanBeUnnamed) {
226*0b57cec5SDimitry Andric   return createTempSymbol("tmp", true, CanBeUnnamed);
227*0b57cec5SDimitry Andric }
228*0b57cec5SDimitry Andric 
229*0b57cec5SDimitry Andric unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
230*0b57cec5SDimitry Andric   MCLabel *&Label = Instances[LocalLabelVal];
231*0b57cec5SDimitry Andric   if (!Label)
232*0b57cec5SDimitry Andric     Label = new (*this) MCLabel(0);
233*0b57cec5SDimitry Andric   return Label->incInstance();
234*0b57cec5SDimitry Andric }
235*0b57cec5SDimitry Andric 
236*0b57cec5SDimitry Andric unsigned MCContext::GetInstance(unsigned LocalLabelVal) {
237*0b57cec5SDimitry Andric   MCLabel *&Label = Instances[LocalLabelVal];
238*0b57cec5SDimitry Andric   if (!Label)
239*0b57cec5SDimitry Andric     Label = new (*this) MCLabel(0);
240*0b57cec5SDimitry Andric   return Label->getInstance();
241*0b57cec5SDimitry Andric }
242*0b57cec5SDimitry Andric 
243*0b57cec5SDimitry Andric MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
244*0b57cec5SDimitry Andric                                                        unsigned Instance) {
245*0b57cec5SDimitry Andric   MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)];
246*0b57cec5SDimitry Andric   if (!Sym)
247*0b57cec5SDimitry Andric     Sym = createTempSymbol(false);
248*0b57cec5SDimitry Andric   return Sym;
249*0b57cec5SDimitry Andric }
250*0b57cec5SDimitry Andric 
251*0b57cec5SDimitry Andric MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) {
252*0b57cec5SDimitry Andric   unsigned Instance = NextInstance(LocalLabelVal);
253*0b57cec5SDimitry Andric   return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
254*0b57cec5SDimitry Andric }
255*0b57cec5SDimitry Andric 
256*0b57cec5SDimitry Andric MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal,
257*0b57cec5SDimitry Andric                                                bool Before) {
258*0b57cec5SDimitry Andric   unsigned Instance = GetInstance(LocalLabelVal);
259*0b57cec5SDimitry Andric   if (!Before)
260*0b57cec5SDimitry Andric     ++Instance;
261*0b57cec5SDimitry Andric   return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
262*0b57cec5SDimitry Andric }
263*0b57cec5SDimitry Andric 
264*0b57cec5SDimitry Andric MCSymbol *MCContext::lookupSymbol(const Twine &Name) const {
265*0b57cec5SDimitry Andric   SmallString<128> NameSV;
266*0b57cec5SDimitry Andric   StringRef NameRef = Name.toStringRef(NameSV);
267*0b57cec5SDimitry Andric   return Symbols.lookup(NameRef);
268*0b57cec5SDimitry Andric }
269*0b57cec5SDimitry Andric 
270*0b57cec5SDimitry Andric void MCContext::setSymbolValue(MCStreamer &Streamer,
271*0b57cec5SDimitry Andric                               StringRef Sym,
272*0b57cec5SDimitry Andric                               uint64_t Val) {
273*0b57cec5SDimitry Andric   auto Symbol = getOrCreateSymbol(Sym);
274*0b57cec5SDimitry Andric   Streamer.EmitAssignment(Symbol, MCConstantExpr::create(Val, *this));
275*0b57cec5SDimitry Andric }
276*0b57cec5SDimitry Andric 
277*0b57cec5SDimitry Andric void MCContext::registerInlineAsmLabel(MCSymbol *Sym) {
278*0b57cec5SDimitry Andric   InlineAsmUsedLabelNames[Sym->getName()] = Sym;
279*0b57cec5SDimitry Andric }
280*0b57cec5SDimitry Andric 
281*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
282*0b57cec5SDimitry Andric // Section Management
283*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
284*0b57cec5SDimitry Andric 
285*0b57cec5SDimitry Andric MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
286*0b57cec5SDimitry Andric                                            unsigned TypeAndAttributes,
287*0b57cec5SDimitry Andric                                            unsigned Reserved2, SectionKind Kind,
288*0b57cec5SDimitry Andric                                            const char *BeginSymName) {
289*0b57cec5SDimitry Andric   // We unique sections by their segment/section pair.  The returned section
290*0b57cec5SDimitry Andric   // may not have the same flags as the requested section, if so this should be
291*0b57cec5SDimitry Andric   // diagnosed by the client as an error.
292*0b57cec5SDimitry Andric 
293*0b57cec5SDimitry Andric   // Form the name to look up.
294*0b57cec5SDimitry Andric   SmallString<64> Name;
295*0b57cec5SDimitry Andric   Name += Segment;
296*0b57cec5SDimitry Andric   Name.push_back(',');
297*0b57cec5SDimitry Andric   Name += Section;
298*0b57cec5SDimitry Andric 
299*0b57cec5SDimitry Andric   // Do the lookup, if we have a hit, return it.
300*0b57cec5SDimitry Andric   MCSectionMachO *&Entry = MachOUniquingMap[Name];
301*0b57cec5SDimitry Andric   if (Entry)
302*0b57cec5SDimitry Andric     return Entry;
303*0b57cec5SDimitry Andric 
304*0b57cec5SDimitry Andric   MCSymbol *Begin = nullptr;
305*0b57cec5SDimitry Andric   if (BeginSymName)
306*0b57cec5SDimitry Andric     Begin = createTempSymbol(BeginSymName, false);
307*0b57cec5SDimitry Andric 
308*0b57cec5SDimitry Andric   // Otherwise, return a new section.
309*0b57cec5SDimitry Andric   return Entry = new (MachOAllocator.Allocate()) MCSectionMachO(
310*0b57cec5SDimitry Andric              Segment, Section, TypeAndAttributes, Reserved2, Kind, Begin);
311*0b57cec5SDimitry Andric }
312*0b57cec5SDimitry Andric 
313*0b57cec5SDimitry Andric void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) {
314*0b57cec5SDimitry Andric   StringRef GroupName;
315*0b57cec5SDimitry Andric   if (const MCSymbol *Group = Section->getGroup())
316*0b57cec5SDimitry Andric     GroupName = Group->getName();
317*0b57cec5SDimitry Andric 
318*0b57cec5SDimitry Andric   unsigned UniqueID = Section->getUniqueID();
319*0b57cec5SDimitry Andric   ELFUniquingMap.erase(
320*0b57cec5SDimitry Andric       ELFSectionKey{Section->getSectionName(), GroupName, UniqueID});
321*0b57cec5SDimitry Andric   auto I = ELFUniquingMap.insert(std::make_pair(
322*0b57cec5SDimitry Andric                                      ELFSectionKey{Name, GroupName, UniqueID},
323*0b57cec5SDimitry Andric                                      Section))
324*0b57cec5SDimitry Andric                .first;
325*0b57cec5SDimitry Andric   StringRef CachedName = I->first.SectionName;
326*0b57cec5SDimitry Andric   const_cast<MCSectionELF *>(Section)->setSectionName(CachedName);
327*0b57cec5SDimitry Andric }
328*0b57cec5SDimitry Andric 
329*0b57cec5SDimitry Andric MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
330*0b57cec5SDimitry Andric                                               unsigned Flags, SectionKind K,
331*0b57cec5SDimitry Andric                                               unsigned EntrySize,
332*0b57cec5SDimitry Andric                                               const MCSymbolELF *Group,
333*0b57cec5SDimitry Andric                                               unsigned UniqueID,
334*0b57cec5SDimitry Andric                                               const MCSymbolELF *Associated) {
335*0b57cec5SDimitry Andric   MCSymbolELF *R;
336*0b57cec5SDimitry Andric   MCSymbol *&Sym = Symbols[Section];
337*0b57cec5SDimitry Andric   // A section symbol can not redefine regular symbols. There may be multiple
338*0b57cec5SDimitry Andric   // sections with the same name, in which case the first such section wins.
339*0b57cec5SDimitry Andric   if (Sym && Sym->isDefined() &&
340*0b57cec5SDimitry Andric       (!Sym->isInSection() || Sym->getSection().getBeginSymbol() != Sym))
341*0b57cec5SDimitry Andric     reportError(SMLoc(), "invalid symbol redefinition");
342*0b57cec5SDimitry Andric   if (Sym && Sym->isUndefined()) {
343*0b57cec5SDimitry Andric     R = cast<MCSymbolELF>(Sym);
344*0b57cec5SDimitry Andric   } else {
345*0b57cec5SDimitry Andric     auto NameIter = UsedNames.insert(std::make_pair(Section, false)).first;
346*0b57cec5SDimitry Andric     R = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false);
347*0b57cec5SDimitry Andric     if (!Sym)
348*0b57cec5SDimitry Andric       Sym = R;
349*0b57cec5SDimitry Andric   }
350*0b57cec5SDimitry Andric   R->setBinding(ELF::STB_LOCAL);
351*0b57cec5SDimitry Andric   R->setType(ELF::STT_SECTION);
352*0b57cec5SDimitry Andric 
353*0b57cec5SDimitry Andric   auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF(
354*0b57cec5SDimitry Andric       Section, Type, Flags, K, EntrySize, Group, UniqueID, R, Associated);
355*0b57cec5SDimitry Andric 
356*0b57cec5SDimitry Andric   auto *F = new MCDataFragment();
357*0b57cec5SDimitry Andric   Ret->getFragmentList().insert(Ret->begin(), F);
358*0b57cec5SDimitry Andric   F->setParent(Ret);
359*0b57cec5SDimitry Andric   R->setFragment(F);
360*0b57cec5SDimitry Andric 
361*0b57cec5SDimitry Andric   return Ret;
362*0b57cec5SDimitry Andric }
363*0b57cec5SDimitry Andric 
364*0b57cec5SDimitry Andric MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type,
365*0b57cec5SDimitry Andric                                              unsigned Flags, unsigned EntrySize,
366*0b57cec5SDimitry Andric                                              const MCSymbolELF *Group,
367*0b57cec5SDimitry Andric                                              const MCSectionELF *RelInfoSection) {
368*0b57cec5SDimitry Andric   StringMap<bool>::iterator I;
369*0b57cec5SDimitry Andric   bool Inserted;
370*0b57cec5SDimitry Andric   std::tie(I, Inserted) =
371*0b57cec5SDimitry Andric       RelSecNames.insert(std::make_pair(Name.str(), true));
372*0b57cec5SDimitry Andric 
373*0b57cec5SDimitry Andric   return createELFSectionImpl(
374*0b57cec5SDimitry Andric       I->getKey(), Type, Flags, SectionKind::getReadOnly(), EntrySize, Group,
375*0b57cec5SDimitry Andric       true, cast<MCSymbolELF>(RelInfoSection->getBeginSymbol()));
376*0b57cec5SDimitry Andric }
377*0b57cec5SDimitry Andric 
378*0b57cec5SDimitry Andric MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
379*0b57cec5SDimitry Andric                                             const Twine &Suffix, unsigned Type,
380*0b57cec5SDimitry Andric                                             unsigned Flags,
381*0b57cec5SDimitry Andric                                             unsigned EntrySize) {
382*0b57cec5SDimitry Andric   return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix);
383*0b57cec5SDimitry Andric }
384*0b57cec5SDimitry Andric 
385*0b57cec5SDimitry Andric MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
386*0b57cec5SDimitry Andric                                        unsigned Flags, unsigned EntrySize,
387*0b57cec5SDimitry Andric                                        const Twine &Group, unsigned UniqueID,
388*0b57cec5SDimitry Andric                                        const MCSymbolELF *Associated) {
389*0b57cec5SDimitry Andric   MCSymbolELF *GroupSym = nullptr;
390*0b57cec5SDimitry Andric   if (!Group.isTriviallyEmpty() && !Group.str().empty())
391*0b57cec5SDimitry Andric     GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
392*0b57cec5SDimitry Andric 
393*0b57cec5SDimitry Andric   return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID,
394*0b57cec5SDimitry Andric                        Associated);
395*0b57cec5SDimitry Andric }
396*0b57cec5SDimitry Andric 
397*0b57cec5SDimitry Andric MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
398*0b57cec5SDimitry Andric                                        unsigned Flags, unsigned EntrySize,
399*0b57cec5SDimitry Andric                                        const MCSymbolELF *GroupSym,
400*0b57cec5SDimitry Andric                                        unsigned UniqueID,
401*0b57cec5SDimitry Andric                                        const MCSymbolELF *Associated) {
402*0b57cec5SDimitry Andric   StringRef Group = "";
403*0b57cec5SDimitry Andric   if (GroupSym)
404*0b57cec5SDimitry Andric     Group = GroupSym->getName();
405*0b57cec5SDimitry Andric   // Do the lookup, if we have a hit, return it.
406*0b57cec5SDimitry Andric   auto IterBool = ELFUniquingMap.insert(
407*0b57cec5SDimitry Andric       std::make_pair(ELFSectionKey{Section.str(), Group, UniqueID}, nullptr));
408*0b57cec5SDimitry Andric   auto &Entry = *IterBool.first;
409*0b57cec5SDimitry Andric   if (!IterBool.second)
410*0b57cec5SDimitry Andric     return Entry.second;
411*0b57cec5SDimitry Andric 
412*0b57cec5SDimitry Andric   StringRef CachedName = Entry.first.SectionName;
413*0b57cec5SDimitry Andric 
414*0b57cec5SDimitry Andric   SectionKind Kind;
415*0b57cec5SDimitry Andric   if (Flags & ELF::SHF_ARM_PURECODE)
416*0b57cec5SDimitry Andric     Kind = SectionKind::getExecuteOnly();
417*0b57cec5SDimitry Andric   else if (Flags & ELF::SHF_EXECINSTR)
418*0b57cec5SDimitry Andric     Kind = SectionKind::getText();
419*0b57cec5SDimitry Andric   else
420*0b57cec5SDimitry Andric     Kind = SectionKind::getReadOnly();
421*0b57cec5SDimitry Andric 
422*0b57cec5SDimitry Andric   MCSectionELF *Result = createELFSectionImpl(
423*0b57cec5SDimitry Andric       CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID, Associated);
424*0b57cec5SDimitry Andric   Entry.second = Result;
425*0b57cec5SDimitry Andric   return Result;
426*0b57cec5SDimitry Andric }
427*0b57cec5SDimitry Andric 
428*0b57cec5SDimitry Andric MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) {
429*0b57cec5SDimitry Andric   return createELFSectionImpl(".group", ELF::SHT_GROUP, 0,
430*0b57cec5SDimitry Andric                               SectionKind::getReadOnly(), 4, Group, ~0,
431*0b57cec5SDimitry Andric                               nullptr);
432*0b57cec5SDimitry Andric }
433*0b57cec5SDimitry Andric 
434*0b57cec5SDimitry Andric MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
435*0b57cec5SDimitry Andric                                          unsigned Characteristics,
436*0b57cec5SDimitry Andric                                          SectionKind Kind,
437*0b57cec5SDimitry Andric                                          StringRef COMDATSymName, int Selection,
438*0b57cec5SDimitry Andric                                          unsigned UniqueID,
439*0b57cec5SDimitry Andric                                          const char *BeginSymName) {
440*0b57cec5SDimitry Andric   MCSymbol *COMDATSymbol = nullptr;
441*0b57cec5SDimitry Andric   if (!COMDATSymName.empty()) {
442*0b57cec5SDimitry Andric     COMDATSymbol = getOrCreateSymbol(COMDATSymName);
443*0b57cec5SDimitry Andric     COMDATSymName = COMDATSymbol->getName();
444*0b57cec5SDimitry Andric   }
445*0b57cec5SDimitry Andric 
446*0b57cec5SDimitry Andric 
447*0b57cec5SDimitry Andric   // Do the lookup, if we have a hit, return it.
448*0b57cec5SDimitry Andric   COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID};
449*0b57cec5SDimitry Andric   auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));
450*0b57cec5SDimitry Andric   auto Iter = IterBool.first;
451*0b57cec5SDimitry Andric   if (!IterBool.second)
452*0b57cec5SDimitry Andric     return Iter->second;
453*0b57cec5SDimitry Andric 
454*0b57cec5SDimitry Andric   MCSymbol *Begin = nullptr;
455*0b57cec5SDimitry Andric   if (BeginSymName)
456*0b57cec5SDimitry Andric     Begin = createTempSymbol(BeginSymName, false);
457*0b57cec5SDimitry Andric 
458*0b57cec5SDimitry Andric   StringRef CachedName = Iter->first.SectionName;
459*0b57cec5SDimitry Andric   MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
460*0b57cec5SDimitry Andric       CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin);
461*0b57cec5SDimitry Andric 
462*0b57cec5SDimitry Andric   Iter->second = Result;
463*0b57cec5SDimitry Andric   return Result;
464*0b57cec5SDimitry Andric }
465*0b57cec5SDimitry Andric 
466*0b57cec5SDimitry Andric MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
467*0b57cec5SDimitry Andric                                          unsigned Characteristics,
468*0b57cec5SDimitry Andric                                          SectionKind Kind,
469*0b57cec5SDimitry Andric                                          const char *BeginSymName) {
470*0b57cec5SDimitry Andric   return getCOFFSection(Section, Characteristics, Kind, "", 0, GenericSectionID,
471*0b57cec5SDimitry Andric                         BeginSymName);
472*0b57cec5SDimitry Andric }
473*0b57cec5SDimitry Andric 
474*0b57cec5SDimitry Andric MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
475*0b57cec5SDimitry Andric                                                     const MCSymbol *KeySym,
476*0b57cec5SDimitry Andric                                                     unsigned UniqueID) {
477*0b57cec5SDimitry Andric   // Return the normal section if we don't have to be associative or unique.
478*0b57cec5SDimitry Andric   if (!KeySym && UniqueID == GenericSectionID)
479*0b57cec5SDimitry Andric     return Sec;
480*0b57cec5SDimitry Andric 
481*0b57cec5SDimitry Andric   // If we have a key symbol, make an associative section with the same name and
482*0b57cec5SDimitry Andric   // kind as the normal section.
483*0b57cec5SDimitry Andric   unsigned Characteristics = Sec->getCharacteristics();
484*0b57cec5SDimitry Andric   if (KeySym) {
485*0b57cec5SDimitry Andric     Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
486*0b57cec5SDimitry Andric     return getCOFFSection(Sec->getSectionName(), Characteristics,
487*0b57cec5SDimitry Andric                           Sec->getKind(), KeySym->getName(),
488*0b57cec5SDimitry Andric                           COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
489*0b57cec5SDimitry Andric   }
490*0b57cec5SDimitry Andric 
491*0b57cec5SDimitry Andric   return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(),
492*0b57cec5SDimitry Andric                         "", 0, UniqueID);
493*0b57cec5SDimitry Andric }
494*0b57cec5SDimitry Andric 
495*0b57cec5SDimitry Andric MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind K,
496*0b57cec5SDimitry Andric                                          const Twine &Group, unsigned UniqueID,
497*0b57cec5SDimitry Andric                                          const char *BeginSymName) {
498*0b57cec5SDimitry Andric   MCSymbolWasm *GroupSym = nullptr;
499*0b57cec5SDimitry Andric   if (!Group.isTriviallyEmpty() && !Group.str().empty()) {
500*0b57cec5SDimitry Andric     GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group));
501*0b57cec5SDimitry Andric     GroupSym->setComdat(true);
502*0b57cec5SDimitry Andric   }
503*0b57cec5SDimitry Andric 
504*0b57cec5SDimitry Andric   return getWasmSection(Section, K, GroupSym, UniqueID, BeginSymName);
505*0b57cec5SDimitry Andric }
506*0b57cec5SDimitry Andric 
507*0b57cec5SDimitry Andric MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
508*0b57cec5SDimitry Andric                                          const MCSymbolWasm *GroupSym,
509*0b57cec5SDimitry Andric                                          unsigned UniqueID,
510*0b57cec5SDimitry Andric                                          const char *BeginSymName) {
511*0b57cec5SDimitry Andric   StringRef Group = "";
512*0b57cec5SDimitry Andric   if (GroupSym)
513*0b57cec5SDimitry Andric     Group = GroupSym->getName();
514*0b57cec5SDimitry Andric   // Do the lookup, if we have a hit, return it.
515*0b57cec5SDimitry Andric   auto IterBool = WasmUniquingMap.insert(
516*0b57cec5SDimitry Andric       std::make_pair(WasmSectionKey{Section.str(), Group, UniqueID}, nullptr));
517*0b57cec5SDimitry Andric   auto &Entry = *IterBool.first;
518*0b57cec5SDimitry Andric   if (!IterBool.second)
519*0b57cec5SDimitry Andric     return Entry.second;
520*0b57cec5SDimitry Andric 
521*0b57cec5SDimitry Andric   StringRef CachedName = Entry.first.SectionName;
522*0b57cec5SDimitry Andric 
523*0b57cec5SDimitry Andric   MCSymbol *Begin = createSymbol(CachedName, false, false);
524*0b57cec5SDimitry Andric   cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
525*0b57cec5SDimitry Andric 
526*0b57cec5SDimitry Andric   MCSectionWasm *Result = new (WasmAllocator.Allocate())
527*0b57cec5SDimitry Andric       MCSectionWasm(CachedName, Kind, GroupSym, UniqueID, Begin);
528*0b57cec5SDimitry Andric   Entry.second = Result;
529*0b57cec5SDimitry Andric 
530*0b57cec5SDimitry Andric   auto *F = new MCDataFragment();
531*0b57cec5SDimitry Andric   Result->getFragmentList().insert(Result->begin(), F);
532*0b57cec5SDimitry Andric   F->setParent(Result);
533*0b57cec5SDimitry Andric   Begin->setFragment(F);
534*0b57cec5SDimitry Andric 
535*0b57cec5SDimitry Andric   return Result;
536*0b57cec5SDimitry Andric }
537*0b57cec5SDimitry Andric 
538*0b57cec5SDimitry Andric MCSectionXCOFF *MCContext::getXCOFFSection(StringRef Section,
539*0b57cec5SDimitry Andric                                            XCOFF::StorageMappingClass SMC,
540*0b57cec5SDimitry Andric                                            SectionKind Kind,
541*0b57cec5SDimitry Andric                                            const char *BeginSymName) {
542*0b57cec5SDimitry Andric   // Do the lookup. If we have a hit, return it.
543*0b57cec5SDimitry Andric   auto IterBool = XCOFFUniquingMap.insert(
544*0b57cec5SDimitry Andric       std::make_pair(XCOFFSectionKey{Section.str(), SMC}, nullptr));
545*0b57cec5SDimitry Andric   auto &Entry = *IterBool.first;
546*0b57cec5SDimitry Andric   if (!IterBool.second)
547*0b57cec5SDimitry Andric     return Entry.second;
548*0b57cec5SDimitry Andric 
549*0b57cec5SDimitry Andric   // Otherwise, return a new section.
550*0b57cec5SDimitry Andric   StringRef CachedName = Entry.first.SectionName;
551*0b57cec5SDimitry Andric 
552*0b57cec5SDimitry Andric   MCSymbol *Begin = nullptr;
553*0b57cec5SDimitry Andric   if (BeginSymName)
554*0b57cec5SDimitry Andric     Begin = createTempSymbol(BeginSymName, false);
555*0b57cec5SDimitry Andric 
556*0b57cec5SDimitry Andric   MCSectionXCOFF *Result = new (XCOFFAllocator.Allocate())
557*0b57cec5SDimitry Andric       MCSectionXCOFF(CachedName, SMC, Kind, Begin);
558*0b57cec5SDimitry Andric   Entry.second = Result;
559*0b57cec5SDimitry Andric 
560*0b57cec5SDimitry Andric   auto *F = new MCDataFragment();
561*0b57cec5SDimitry Andric   Result->getFragmentList().insert(Result->begin(), F);
562*0b57cec5SDimitry Andric   F->setParent(Result);
563*0b57cec5SDimitry Andric 
564*0b57cec5SDimitry Andric   if (Begin)
565*0b57cec5SDimitry Andric     Begin->setFragment(F);
566*0b57cec5SDimitry Andric 
567*0b57cec5SDimitry Andric   return Result;
568*0b57cec5SDimitry Andric }
569*0b57cec5SDimitry Andric 
570*0b57cec5SDimitry Andric MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
571*0b57cec5SDimitry Andric   return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
572*0b57cec5SDimitry Andric }
573*0b57cec5SDimitry Andric 
574*0b57cec5SDimitry Andric void MCContext::addDebugPrefixMapEntry(const std::string &From,
575*0b57cec5SDimitry Andric                                        const std::string &To) {
576*0b57cec5SDimitry Andric   DebugPrefixMap.insert(std::make_pair(From, To));
577*0b57cec5SDimitry Andric }
578*0b57cec5SDimitry Andric 
579*0b57cec5SDimitry Andric void MCContext::RemapDebugPaths() {
580*0b57cec5SDimitry Andric   const auto &DebugPrefixMap = this->DebugPrefixMap;
581*0b57cec5SDimitry Andric   const auto RemapDebugPath = [&DebugPrefixMap](std::string &Path) {
582*0b57cec5SDimitry Andric     for (const auto &Entry : DebugPrefixMap)
583*0b57cec5SDimitry Andric       if (StringRef(Path).startswith(Entry.first)) {
584*0b57cec5SDimitry Andric         std::string RemappedPath =
585*0b57cec5SDimitry Andric             (Twine(Entry.second) + Path.substr(Entry.first.size())).str();
586*0b57cec5SDimitry Andric         Path.swap(RemappedPath);
587*0b57cec5SDimitry Andric       }
588*0b57cec5SDimitry Andric   };
589*0b57cec5SDimitry Andric 
590*0b57cec5SDimitry Andric   // Remap compilation directory.
591*0b57cec5SDimitry Andric   std::string CompDir = CompilationDir.str();
592*0b57cec5SDimitry Andric   RemapDebugPath(CompDir);
593*0b57cec5SDimitry Andric   CompilationDir = CompDir;
594*0b57cec5SDimitry Andric 
595*0b57cec5SDimitry Andric   // Remap MCDwarfDirs in all compilation units.
596*0b57cec5SDimitry Andric   for (auto &CUIDTablePair : MCDwarfLineTablesCUMap)
597*0b57cec5SDimitry Andric     for (auto &Dir : CUIDTablePair.second.getMCDwarfDirs())
598*0b57cec5SDimitry Andric       RemapDebugPath(Dir);
599*0b57cec5SDimitry Andric }
600*0b57cec5SDimitry Andric 
601*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
602*0b57cec5SDimitry Andric // Dwarf Management
603*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
604*0b57cec5SDimitry Andric 
605*0b57cec5SDimitry Andric void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) {
606*0b57cec5SDimitry Andric   // MCDwarf needs the root file as well as the compilation directory.
607*0b57cec5SDimitry Andric   // If we find a '.file 0' directive that will supersede these values.
608*0b57cec5SDimitry Andric   Optional<MD5::MD5Result> Cksum;
609*0b57cec5SDimitry Andric   if (getDwarfVersion() >= 5) {
610*0b57cec5SDimitry Andric     MD5 Hash;
611*0b57cec5SDimitry Andric     MD5::MD5Result Sum;
612*0b57cec5SDimitry Andric     Hash.update(Buffer);
613*0b57cec5SDimitry Andric     Hash.final(Sum);
614*0b57cec5SDimitry Andric     Cksum = Sum;
615*0b57cec5SDimitry Andric   }
616*0b57cec5SDimitry Andric   // Canonicalize the root filename. It cannot be empty, and should not
617*0b57cec5SDimitry Andric   // repeat the compilation dir.
618*0b57cec5SDimitry Andric   // The MCContext ctor initializes MainFileName to the name associated with
619*0b57cec5SDimitry Andric   // the SrcMgr's main file ID, which might be the same as InputFileName (and
620*0b57cec5SDimitry Andric   // possibly include directory components).
621*0b57cec5SDimitry Andric   // Or, MainFileName might have been overridden by a -main-file-name option,
622*0b57cec5SDimitry Andric   // which is supposed to be just a base filename with no directory component.
623*0b57cec5SDimitry Andric   // So, if the InputFileName and MainFileName are not equal, assume
624*0b57cec5SDimitry Andric   // MainFileName is a substitute basename and replace the last component.
625*0b57cec5SDimitry Andric   SmallString<1024> FileNameBuf = InputFileName;
626*0b57cec5SDimitry Andric   if (FileNameBuf.empty() || FileNameBuf == "-")
627*0b57cec5SDimitry Andric     FileNameBuf = "<stdin>";
628*0b57cec5SDimitry Andric   if (!getMainFileName().empty() && FileNameBuf != getMainFileName()) {
629*0b57cec5SDimitry Andric     llvm::sys::path::remove_filename(FileNameBuf);
630*0b57cec5SDimitry Andric     llvm::sys::path::append(FileNameBuf, getMainFileName());
631*0b57cec5SDimitry Andric   }
632*0b57cec5SDimitry Andric   StringRef FileName = FileNameBuf;
633*0b57cec5SDimitry Andric   if (FileName.consume_front(getCompilationDir()))
634*0b57cec5SDimitry Andric     if (llvm::sys::path::is_separator(FileName.front()))
635*0b57cec5SDimitry Andric       FileName = FileName.drop_front();
636*0b57cec5SDimitry Andric   assert(!FileName.empty());
637*0b57cec5SDimitry Andric   setMCLineTableRootFile(
638*0b57cec5SDimitry Andric       /*CUID=*/0, getCompilationDir(), FileName, Cksum, None);
639*0b57cec5SDimitry Andric }
640*0b57cec5SDimitry Andric 
641*0b57cec5SDimitry Andric /// getDwarfFile - takes a file name and number to place in the dwarf file and
642*0b57cec5SDimitry Andric /// directory tables.  If the file number has already been allocated it is an
643*0b57cec5SDimitry Andric /// error and zero is returned and the client reports the error, else the
644*0b57cec5SDimitry Andric /// allocated file number is returned.  The file numbers may be in any order.
645*0b57cec5SDimitry Andric Expected<unsigned> MCContext::getDwarfFile(StringRef Directory,
646*0b57cec5SDimitry Andric                                            StringRef FileName,
647*0b57cec5SDimitry Andric                                            unsigned FileNumber,
648*0b57cec5SDimitry Andric                                            Optional<MD5::MD5Result> Checksum,
649*0b57cec5SDimitry Andric                                            Optional<StringRef> Source,
650*0b57cec5SDimitry Andric                                            unsigned CUID) {
651*0b57cec5SDimitry Andric   MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
652*0b57cec5SDimitry Andric   return Table.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
653*0b57cec5SDimitry Andric                           FileNumber);
654*0b57cec5SDimitry Andric }
655*0b57cec5SDimitry Andric 
656*0b57cec5SDimitry Andric /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
657*0b57cec5SDimitry Andric /// currently is assigned and false otherwise.
658*0b57cec5SDimitry Andric bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
659*0b57cec5SDimitry Andric   const MCDwarfLineTable &LineTable = getMCDwarfLineTable(CUID);
660*0b57cec5SDimitry Andric   if (FileNumber == 0)
661*0b57cec5SDimitry Andric     return getDwarfVersion() >= 5;
662*0b57cec5SDimitry Andric   if (FileNumber >= LineTable.getMCDwarfFiles().size())
663*0b57cec5SDimitry Andric     return false;
664*0b57cec5SDimitry Andric 
665*0b57cec5SDimitry Andric   return !LineTable.getMCDwarfFiles()[FileNumber].Name.empty();
666*0b57cec5SDimitry Andric }
667*0b57cec5SDimitry Andric 
668*0b57cec5SDimitry Andric /// Remove empty sections from SectionsForRanges, to avoid generating
669*0b57cec5SDimitry Andric /// useless debug info for them.
670*0b57cec5SDimitry Andric void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
671*0b57cec5SDimitry Andric   SectionsForRanges.remove_if(
672*0b57cec5SDimitry Andric       [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); });
673*0b57cec5SDimitry Andric }
674*0b57cec5SDimitry Andric 
675*0b57cec5SDimitry Andric CodeViewContext &MCContext::getCVContext() {
676*0b57cec5SDimitry Andric   if (!CVContext.get())
677*0b57cec5SDimitry Andric     CVContext.reset(new CodeViewContext);
678*0b57cec5SDimitry Andric   return *CVContext.get();
679*0b57cec5SDimitry Andric }
680*0b57cec5SDimitry Andric 
681*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
682*0b57cec5SDimitry Andric // Error Reporting
683*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
684*0b57cec5SDimitry Andric 
685*0b57cec5SDimitry Andric void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
686*0b57cec5SDimitry Andric   HadError = true;
687*0b57cec5SDimitry Andric 
688*0b57cec5SDimitry Andric   // If we have a source manager use it. Otherwise, try using the inline source
689*0b57cec5SDimitry Andric   // manager.
690*0b57cec5SDimitry Andric   // If that fails, use the generic report_fatal_error().
691*0b57cec5SDimitry Andric   if (SrcMgr)
692*0b57cec5SDimitry Andric     SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
693*0b57cec5SDimitry Andric   else if (InlineSrcMgr)
694*0b57cec5SDimitry Andric     InlineSrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
695*0b57cec5SDimitry Andric   else
696*0b57cec5SDimitry Andric     report_fatal_error(Msg, false);
697*0b57cec5SDimitry Andric }
698*0b57cec5SDimitry Andric 
699*0b57cec5SDimitry Andric void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) {
700*0b57cec5SDimitry Andric   reportError(Loc, Msg);
701*0b57cec5SDimitry Andric 
702*0b57cec5SDimitry Andric   // If we reached here, we are failing ungracefully. Run the interrupt handlers
703*0b57cec5SDimitry Andric   // to make sure any special cleanups get done, in particular that we remove
704*0b57cec5SDimitry Andric   // files registered with RemoveFileOnSignal.
705*0b57cec5SDimitry Andric   sys::RunInterruptHandlers();
706*0b57cec5SDimitry Andric   exit(1);
707*0b57cec5SDimitry Andric }
708