/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/MC/MCContext.cpp
Line | Count | Source (jump to first uncovered line) |
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/SmallVector.h" |
13 | | #include "llvm/ADT/StringMap.h" |
14 | | #include "llvm/ADT/StringRef.h" |
15 | | #include "llvm/ADT/Twine.h" |
16 | | #include "llvm/BinaryFormat/COFF.h" |
17 | | #include "llvm/BinaryFormat/ELF.h" |
18 | | #include "llvm/MC/MCAsmInfo.h" |
19 | | #include "llvm/MC/MCCodeView.h" |
20 | | #include "llvm/MC/MCDwarf.h" |
21 | | #include "llvm/MC/MCExpr.h" |
22 | | #include "llvm/MC/MCFragment.h" |
23 | | #include "llvm/MC/MCLabel.h" |
24 | | #include "llvm/MC/MCObjectFileInfo.h" |
25 | | #include "llvm/MC/MCSectionCOFF.h" |
26 | | #include "llvm/MC/MCSectionELF.h" |
27 | | #include "llvm/MC/MCSectionMachO.h" |
28 | | #include "llvm/MC/MCSectionWasm.h" |
29 | | #include "llvm/MC/MCStreamer.h" |
30 | | #include "llvm/MC/MCSymbol.h" |
31 | | #include "llvm/MC/MCSymbolCOFF.h" |
32 | | #include "llvm/MC/MCSymbolELF.h" |
33 | | #include "llvm/MC/MCSymbolMachO.h" |
34 | | #include "llvm/MC/MCSymbolWasm.h" |
35 | | #include "llvm/MC/SectionKind.h" |
36 | | #include "llvm/Support/Casting.h" |
37 | | #include "llvm/Support/CommandLine.h" |
38 | | #include "llvm/Support/ErrorHandling.h" |
39 | | #include "llvm/Support/MemoryBuffer.h" |
40 | | #include "llvm/Support/Signals.h" |
41 | | #include "llvm/Support/SourceMgr.h" |
42 | | #include "llvm/Support/raw_ostream.h" |
43 | | #include <cassert> |
44 | | #include <cstdlib> |
45 | | #include <tuple> |
46 | | #include <utility> |
47 | | |
48 | | using namespace llvm; |
49 | | |
50 | | static cl::opt<char*> |
51 | | AsSecureLogFileName("as-secure-log-file-name", |
52 | | cl::desc("As secure log file name (initialized from " |
53 | | "AS_SECURE_LOG_FILE env variable)"), |
54 | | cl::init(getenv("AS_SECURE_LOG_FILE")), cl::Hidden); |
55 | | |
56 | | MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri, |
57 | | const MCObjectFileInfo *mofi, const SourceMgr *mgr, |
58 | | bool DoAutoReset) |
59 | | : SrcMgr(mgr), InlineSrcMgr(nullptr), MAI(mai), MRI(mri), MOFI(mofi), |
60 | | Symbols(Allocator), UsedNames(Allocator), |
61 | | CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0), |
62 | 41.3k | AutoReset(DoAutoReset) { |
63 | 41.3k | SecureLogFile = AsSecureLogFileName; |
64 | 41.3k | |
65 | 41.3k | if (SrcMgr && 41.3k SrcMgr->getNumBuffers()5.83k ) |
66 | 5.61k | MainFileName = |
67 | 5.61k | SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())->getBufferIdentifier(); |
68 | 41.3k | } |
69 | | |
70 | 41.1k | MCContext::~MCContext() { |
71 | 41.1k | if (AutoReset) |
72 | 7.10k | reset(); |
73 | 41.1k | |
74 | 41.1k | // NOTE: The symbols are all allocated out of a bump pointer allocator, |
75 | 41.1k | // we don't need to free them here. |
76 | 41.1k | } |
77 | | |
78 | | //===----------------------------------------------------------------------===// |
79 | | // Module Lifetime Management |
80 | | //===----------------------------------------------------------------------===// |
81 | | |
82 | 41.0k | void MCContext::reset() { |
83 | 41.0k | // Call the destructors so the fragments are freed |
84 | 41.0k | COFFAllocator.DestroyAll(); |
85 | 41.0k | ELFAllocator.DestroyAll(); |
86 | 41.0k | MachOAllocator.DestroyAll(); |
87 | 41.0k | |
88 | 41.0k | MCSubtargetAllocator.DestroyAll(); |
89 | 41.0k | UsedNames.clear(); |
90 | 41.0k | Symbols.clear(); |
91 | 41.0k | Allocator.Reset(); |
92 | 41.0k | Instances.clear(); |
93 | 41.0k | CompilationDir.clear(); |
94 | 41.0k | MainFileName.clear(); |
95 | 41.0k | MCDwarfLineTablesCUMap.clear(); |
96 | 41.0k | SectionsForRanges.clear(); |
97 | 41.0k | MCGenDwarfLabelEntries.clear(); |
98 | 41.0k | DwarfDebugFlags = StringRef(); |
99 | 41.0k | DwarfCompileUnitID = 0; |
100 | 41.0k | CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0); |
101 | 41.0k | |
102 | 41.0k | CVContext.reset(); |
103 | 41.0k | |
104 | 41.0k | MachOUniquingMap.clear(); |
105 | 41.0k | ELFUniquingMap.clear(); |
106 | 41.0k | COFFUniquingMap.clear(); |
107 | 41.0k | |
108 | 41.0k | NextID.clear(); |
109 | 41.0k | AllowTemporaryLabels = true; |
110 | 41.0k | DwarfLocSeen = false; |
111 | 41.0k | GenDwarfForAssembly = false; |
112 | 41.0k | GenDwarfFileNumber = 0; |
113 | 41.0k | |
114 | 41.0k | HadError = false; |
115 | 41.0k | } |
116 | | |
117 | | //===----------------------------------------------------------------------===// |
118 | | // Symbol Manipulation |
119 | | //===----------------------------------------------------------------------===// |
120 | | |
121 | 9.14M | MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) { |
122 | 9.14M | SmallString<128> NameSV; |
123 | 9.14M | StringRef NameRef = Name.toStringRef(NameSV); |
124 | 9.14M | |
125 | 9.14M | assert(!NameRef.empty() && "Normal symbols cannot be unnamed!"); |
126 | 9.14M | |
127 | 9.14M | MCSymbol *&Sym = Symbols[NameRef]; |
128 | 9.14M | if (!Sym) |
129 | 3.49M | Sym = createSymbol(NameRef, false, false); |
130 | 9.14M | |
131 | 9.14M | return Sym; |
132 | 9.14M | } |
133 | | |
134 | | MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName, |
135 | 28 | unsigned Idx) { |
136 | 28 | return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName + |
137 | 28 | "$frame_escape_" + Twine(Idx)); |
138 | 28 | } |
139 | | |
140 | 29 | MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName) { |
141 | 29 | return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName + |
142 | 29 | "$parent_frame_offset"); |
143 | 29 | } |
144 | | |
145 | 60 | MCSymbol *MCContext::getOrCreateLSDASymbol(StringRef FuncName) { |
146 | 60 | return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + "__ehtable$" + |
147 | 60 | FuncName); |
148 | 60 | } |
149 | | |
150 | | MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name, |
151 | 7.47M | bool IsTemporary) { |
152 | 7.47M | if (MOFI7.47M ) { |
153 | 7.47M | switch (MOFI->getObjectFileType()) { |
154 | 27.7k | case MCObjectFileInfo::IsCOFF: |
155 | 27.7k | return new (Name, *this) MCSymbolCOFF(Name, IsTemporary); |
156 | 353k | case MCObjectFileInfo::IsELF: |
157 | 353k | return new (Name, *this) MCSymbolELF(Name, IsTemporary); |
158 | 7.09M | case MCObjectFileInfo::IsMachO: |
159 | 7.09M | return new (Name, *this) MCSymbolMachO(Name, IsTemporary); |
160 | 0 | case MCObjectFileInfo::IsWasm: |
161 | 0 | return new (Name, *this) MCSymbolWasm(Name, IsTemporary); |
162 | 42 | } |
163 | 42 | } |
164 | 42 | return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name, |
165 | 42 | IsTemporary); |
166 | 42 | } |
167 | | |
168 | | MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix, |
169 | 7.47M | bool CanBeUnnamed) { |
170 | 7.47M | if (CanBeUnnamed && 7.47M !UseNamesOnTempLabels3.92M ) |
171 | 3.68M | return createSymbolImpl(nullptr, true); |
172 | 3.79M | |
173 | 3.79M | // Determine whether this is a user written assembler temporary or normal |
174 | 3.79M | // label, if used. |
175 | 3.79M | bool IsTemporary = CanBeUnnamed; |
176 | 3.79M | if (AllowTemporaryLabels && 3.79M !IsTemporary3.79M ) |
177 | 3.55M | IsTemporary = Name.startswith(MAI->getPrivateGlobalPrefix()); |
178 | 3.79M | |
179 | 3.79M | SmallString<128> NewName = Name; |
180 | 3.79M | bool AddSuffix = AlwaysAddSuffix; |
181 | 3.79M | unsigned &NextUniqueID = NextID[Name]; |
182 | 3.79M | while (true3.79M ) { |
183 | 3.79M | if (AddSuffix3.79M ) { |
184 | 235k | NewName.resize(Name.size()); |
185 | 235k | raw_svector_ostream(NewName) << NextUniqueID++; |
186 | 235k | } |
187 | 3.79M | auto NameEntry = UsedNames.insert(std::make_pair(NewName, true)); |
188 | 3.79M | if (NameEntry.second || 3.79M !NameEntry.first->second228 ) { |
189 | 3.79M | // Ok, we found a name. |
190 | 3.79M | // Mark it as used for a non-section symbol. |
191 | 3.79M | NameEntry.first->second = true; |
192 | 3.79M | // Have the MCSymbol object itself refer to the copy of the string that is |
193 | 3.79M | // embedded in the UsedNames entry. |
194 | 3.79M | return createSymbolImpl(&*NameEntry.first, IsTemporary); |
195 | 3.79M | } |
196 | 3.79M | assert(IsTemporary && "Cannot rename non-temporary symbols"); |
197 | 226 | AddSuffix = true; |
198 | 226 | } |
199 | 1 | llvm_unreachable1 ("Infinite loop"); |
200 | 0 | } |
201 | | |
202 | | MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix, |
203 | 3.92M | bool CanBeUnnamed) { |
204 | 3.92M | SmallString<128> NameSV; |
205 | 3.92M | raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name; |
206 | 3.92M | return createSymbol(NameSV, AlwaysAddSuffix, CanBeUnnamed); |
207 | 3.92M | } |
208 | | |
209 | 58.1k | MCSymbol *MCContext::createLinkerPrivateTempSymbol() { |
210 | 58.1k | SmallString<128> NameSV; |
211 | 58.1k | raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp"; |
212 | 58.1k | return createSymbol(NameSV, true, false); |
213 | 58.1k | } |
214 | | |
215 | 569k | MCSymbol *MCContext::createTempSymbol(bool CanBeUnnamed) { |
216 | 569k | return createTempSymbol("tmp", true, CanBeUnnamed); |
217 | 569k | } |
218 | | |
219 | 369 | unsigned MCContext::NextInstance(unsigned LocalLabelVal) { |
220 | 369 | MCLabel *&Label = Instances[LocalLabelVal]; |
221 | 369 | if (!Label) |
222 | 76 | Label = new (*this) MCLabel(0); |
223 | 369 | return Label->incInstance(); |
224 | 369 | } |
225 | | |
226 | 434 | unsigned MCContext::GetInstance(unsigned LocalLabelVal) { |
227 | 434 | MCLabel *&Label = Instances[LocalLabelVal]; |
228 | 434 | if (!Label) |
229 | 219 | Label = new (*this) MCLabel(0); |
230 | 434 | return Label->getInstance(); |
231 | 434 | } |
232 | | |
233 | | MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, |
234 | 803 | unsigned Instance) { |
235 | 803 | MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)]; |
236 | 803 | if (!Sym) |
237 | 379 | Sym = createTempSymbol(false); |
238 | 803 | return Sym; |
239 | 803 | } |
240 | | |
241 | 369 | MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) { |
242 | 369 | unsigned Instance = NextInstance(LocalLabelVal); |
243 | 369 | return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); |
244 | 369 | } |
245 | | |
246 | | MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal, |
247 | 434 | bool Before) { |
248 | 434 | unsigned Instance = GetInstance(LocalLabelVal); |
249 | 434 | if (!Before) |
250 | 306 | ++Instance; |
251 | 434 | return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance); |
252 | 434 | } |
253 | | |
254 | 1.64k | MCSymbol *MCContext::lookupSymbol(const Twine &Name) const { |
255 | 1.64k | SmallString<128> NameSV; |
256 | 1.64k | StringRef NameRef = Name.toStringRef(NameSV); |
257 | 1.64k | return Symbols.lookup(NameRef); |
258 | 1.64k | } |
259 | | |
260 | | void MCContext::setSymbolValue(MCStreamer &Streamer, |
261 | | StringRef Sym, |
262 | 2 | uint64_t Val) { |
263 | 2 | auto Symbol = getOrCreateSymbol(Sym); |
264 | 2 | Streamer.EmitAssignment(Symbol, MCConstantExpr::create(Val, *this)); |
265 | 2 | } |
266 | | |
267 | | //===----------------------------------------------------------------------===// |
268 | | // Section Management |
269 | | //===----------------------------------------------------------------------===// |
270 | | |
271 | | MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section, |
272 | | unsigned TypeAndAttributes, |
273 | | unsigned Reserved2, SectionKind Kind, |
274 | 974k | const char *BeginSymName) { |
275 | 974k | // We unique sections by their segment/section pair. The returned section |
276 | 974k | // may not have the same flags as the requested section, if so this should be |
277 | 974k | // diagnosed by the client as an error. |
278 | 974k | |
279 | 974k | // Form the name to look up. |
280 | 974k | SmallString<64> Name; |
281 | 974k | Name += Segment; |
282 | 974k | Name.push_back(','); |
283 | 974k | Name += Section; |
284 | 974k | |
285 | 974k | // Do the lookup, if we have a hit, return it. |
286 | 974k | MCSectionMachO *&Entry = MachOUniquingMap[Name]; |
287 | 974k | if (Entry) |
288 | 4.11k | return Entry; |
289 | 970k | |
290 | 970k | MCSymbol *Begin = nullptr; |
291 | 970k | if (BeginSymName) |
292 | 254k | Begin = createTempSymbol(BeginSymName, false); |
293 | 974k | |
294 | 974k | // Otherwise, return a new section. |
295 | 974k | return Entry = new (MachOAllocator.Allocate()) MCSectionMachO( |
296 | 974k | Segment, Section, TypeAndAttributes, Reserved2, Kind, Begin); |
297 | 974k | } |
298 | | |
299 | 5 | void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) { |
300 | 5 | StringRef GroupName; |
301 | 5 | if (const MCSymbol *Group = Section->getGroup()) |
302 | 0 | GroupName = Group->getName(); |
303 | 5 | |
304 | 5 | unsigned UniqueID = Section->getUniqueID(); |
305 | 5 | ELFUniquingMap.erase( |
306 | 5 | ELFSectionKey{Section->getSectionName(), GroupName, UniqueID}); |
307 | 5 | auto I = ELFUniquingMap.insert(std::make_pair( |
308 | 5 | ELFSectionKey{Name, GroupName, UniqueID}, |
309 | 5 | Section)) |
310 | 5 | .first; |
311 | 5 | StringRef CachedName = I->first.SectionName; |
312 | 5 | const_cast<MCSectionELF *>(Section)->setSectionName(CachedName); |
313 | 5 | } |
314 | | |
315 | | MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type, |
316 | | unsigned Flags, SectionKind K, |
317 | | unsigned EntrySize, |
318 | | const MCSymbolELF *Group, |
319 | | unsigned UniqueID, |
320 | 1.15M | const MCSymbolELF *Associated) { |
321 | 1.15M | MCSymbolELF *R; |
322 | 1.15M | MCSymbol *&Sym = Symbols[Section]; |
323 | 1.15M | // A section symbol can not redefine regular symbols. There may be multiple |
324 | 1.15M | // sections with the same name, in which case the first such section wins. |
325 | 1.15M | if (Sym && 1.15M Sym->isDefined()188 && |
326 | 177 | (!Sym->isInSection() || 177 Sym->getSection().getBeginSymbol() != Sym177 )) |
327 | 1 | reportError(SMLoc(), "invalid symbol redefinition"); |
328 | 1.15M | if (Sym && 1.15M Sym->isUndefined()188 ) { |
329 | 11 | R = cast<MCSymbolELF>(Sym); |
330 | 1.15M | } else { |
331 | 1.15M | auto NameIter = UsedNames.insert(std::make_pair(Section, false)).first; |
332 | 1.15M | R = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false); |
333 | 1.15M | if (!Sym) |
334 | 1.15M | Sym = R; |
335 | 1.15M | } |
336 | 1.15M | R->setBinding(ELF::STB_LOCAL); |
337 | 1.15M | R->setType(ELF::STT_SECTION); |
338 | 1.15M | |
339 | 1.15M | auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF( |
340 | 1.15M | Section, Type, Flags, K, EntrySize, Group, UniqueID, R, Associated); |
341 | 1.15M | |
342 | 1.15M | auto *F = new MCDataFragment(); |
343 | 1.15M | Ret->getFragmentList().insert(Ret->begin(), F); |
344 | 1.15M | F->setParent(Ret); |
345 | 1.15M | R->setFragment(F); |
346 | 1.15M | |
347 | 1.15M | return Ret; |
348 | 1.15M | } |
349 | | |
350 | | MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type, |
351 | | unsigned Flags, unsigned EntrySize, |
352 | | const MCSymbolELF *Group, |
353 | 2.56k | const MCSectionELF *RelInfoSection) { |
354 | 2.56k | StringMap<bool>::iterator I; |
355 | 2.56k | bool Inserted; |
356 | 2.56k | std::tie(I, Inserted) = |
357 | 2.56k | RelSecNames.insert(std::make_pair(Name.str(), true)); |
358 | 2.56k | |
359 | 2.56k | return createELFSectionImpl( |
360 | 2.56k | I->getKey(), Type, Flags, SectionKind::getReadOnly(), EntrySize, Group, |
361 | 2.56k | true, cast<MCSymbolELF>(RelInfoSection->getBeginSymbol())); |
362 | 2.56k | } |
363 | | |
364 | | MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix, |
365 | | const Twine &Suffix, unsigned Type, |
366 | | unsigned Flags, |
367 | 32 | unsigned EntrySize) { |
368 | 32 | return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix); |
369 | 32 | } |
370 | | |
371 | | MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, |
372 | | unsigned Flags, unsigned EntrySize, |
373 | | const Twine &Group, unsigned UniqueID, |
374 | 1.30M | const MCSymbolELF *Associated) { |
375 | 1.30M | MCSymbolELF *GroupSym = nullptr; |
376 | 1.30M | if (!Group.isTriviallyEmpty() && 1.30M !Group.str().empty()451k ) |
377 | 215 | GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group)); |
378 | 1.30M | |
379 | 1.30M | return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID, |
380 | 1.30M | Associated); |
381 | 1.30M | } |
382 | | |
383 | | MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type, |
384 | | unsigned Flags, unsigned EntrySize, |
385 | | const MCSymbolELF *GroupSym, |
386 | | unsigned UniqueID, |
387 | 1.30M | const MCSymbolELF *Associated) { |
388 | 1.30M | StringRef Group = ""; |
389 | 1.30M | if (GroupSym) |
390 | 221 | Group = GroupSym->getName(); |
391 | 1.30M | // Do the lookup, if we have a hit, return it. |
392 | 1.30M | auto IterBool = ELFUniquingMap.insert( |
393 | 1.30M | std::make_pair(ELFSectionKey{Section.str(), Group, UniqueID}, nullptr)); |
394 | 1.30M | auto &Entry = *IterBool.first; |
395 | 1.30M | if (!IterBool.second) |
396 | 157k | return Entry.second; |
397 | 1.15M | |
398 | 1.15M | StringRef CachedName = Entry.first.SectionName; |
399 | 1.15M | |
400 | 1.15M | SectionKind Kind; |
401 | 1.15M | if (Flags & ELF::SHF_ARM_PURECODE) |
402 | 436 | Kind = SectionKind::getExecuteOnly(); |
403 | 1.15M | else if (1.15M Flags & ELF::SHF_EXECINSTR1.15M ) |
404 | 19.1k | Kind = SectionKind::getText(); |
405 | 1.15M | else |
406 | 1.13M | Kind = SectionKind::getReadOnly(); |
407 | 1.30M | |
408 | 1.30M | MCSectionELF *Result = createELFSectionImpl( |
409 | 1.30M | CachedName, Type, Flags, Kind, EntrySize, GroupSym, UniqueID, Associated); |
410 | 1.30M | Entry.second = Result; |
411 | 1.30M | return Result; |
412 | 1.30M | } |
413 | | |
414 | 76 | MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) { |
415 | 76 | return createELFSectionImpl(".group", ELF::SHT_GROUP, 0, |
416 | 76 | SectionKind::getReadOnly(), 4, Group, ~0, |
417 | 76 | nullptr); |
418 | 76 | } |
419 | | |
420 | | MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, |
421 | | unsigned Characteristics, |
422 | | SectionKind Kind, |
423 | | StringRef COMDATSymName, int Selection, |
424 | | unsigned UniqueID, |
425 | 34.5k | const char *BeginSymName) { |
426 | 34.5k | MCSymbol *COMDATSymbol = nullptr; |
427 | 34.5k | if (!COMDATSymName.empty()34.5k ) { |
428 | 510 | COMDATSymbol = getOrCreateSymbol(COMDATSymName); |
429 | 510 | COMDATSymName = COMDATSymbol->getName(); |
430 | 510 | } |
431 | 34.5k | |
432 | 34.5k | |
433 | 34.5k | // Do the lookup, if we have a hit, return it. |
434 | 34.5k | COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID}; |
435 | 34.5k | auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr)); |
436 | 34.5k | auto Iter = IterBool.first; |
437 | 34.5k | if (!IterBool.second) |
438 | 381 | return Iter->second; |
439 | 34.1k | |
440 | 34.1k | MCSymbol *Begin = nullptr; |
441 | 34.1k | if (BeginSymName) |
442 | 14.8k | Begin = createTempSymbol(BeginSymName, false); |
443 | 34.5k | |
444 | 34.5k | StringRef CachedName = Iter->first.SectionName; |
445 | 34.5k | MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF( |
446 | 34.5k | CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin); |
447 | 34.5k | |
448 | 34.5k | Iter->second = Result; |
449 | 34.5k | return Result; |
450 | 34.5k | } |
451 | | |
452 | | MCSectionCOFF *MCContext::getCOFFSection(StringRef Section, |
453 | | unsigned Characteristics, |
454 | | SectionKind Kind, |
455 | 33.7k | const char *BeginSymName) { |
456 | 33.7k | return getCOFFSection(Section, Characteristics, Kind, "", 0, GenericSectionID, |
457 | 33.7k | BeginSymName); |
458 | 33.7k | } |
459 | | |
460 | 0 | MCSectionCOFF *MCContext::getCOFFSection(StringRef Section) { |
461 | 0 | COFFSectionKey T{Section, "", 0, GenericSectionID}; |
462 | 0 | auto Iter = COFFUniquingMap.find(T); |
463 | 0 | if (Iter == COFFUniquingMap.end()) |
464 | 0 | return nullptr; |
465 | 0 | return Iter->second; |
466 | 0 | } |
467 | | |
468 | | MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec, |
469 | | const MCSymbol *KeySym, |
470 | 507 | unsigned UniqueID) { |
471 | 507 | // Return the normal section if we don't have to be associative or unique. |
472 | 507 | if (!KeySym && 507 UniqueID == GenericSectionID422 ) |
473 | 401 | return Sec; |
474 | 106 | |
475 | 106 | // If we have a key symbol, make an associative section with the same name and |
476 | 106 | // kind as the normal section. |
477 | 106 | unsigned Characteristics = Sec->getCharacteristics(); |
478 | 106 | if (KeySym106 ) { |
479 | 85 | Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; |
480 | 85 | return getCOFFSection(Sec->getSectionName(), Characteristics, |
481 | 85 | Sec->getKind(), KeySym->getName(), |
482 | 85 | COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID); |
483 | 85 | } |
484 | 21 | |
485 | 21 | return getCOFFSection(Sec->getSectionName(), Characteristics, Sec->getKind(), |
486 | 21 | "", 0, UniqueID); |
487 | 21 | } |
488 | | |
489 | | MCSectionWasm *MCContext::getWasmSection(const Twine &Section, unsigned Type, |
490 | | const Twine &Group, unsigned UniqueID, |
491 | 0 | const char *BeginSymName) { |
492 | 0 | MCSymbolWasm *GroupSym = nullptr; |
493 | 0 | if (!Group.isTriviallyEmpty() && 0 !Group.str().empty()0 ) |
494 | 0 | GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group)); |
495 | 0 |
|
496 | 0 | return getWasmSection(Section, Type, GroupSym, UniqueID, BeginSymName); |
497 | 0 | } |
498 | | |
499 | | MCSectionWasm *MCContext::getWasmSection(const Twine &Section, unsigned Type, |
500 | | const MCSymbolWasm *GroupSym, |
501 | | unsigned UniqueID, |
502 | 0 | const char *BeginSymName) { |
503 | 0 | StringRef Group = ""; |
504 | 0 | if (GroupSym) |
505 | 0 | Group = GroupSym->getName(); |
506 | 0 | // Do the lookup, if we have a hit, return it. |
507 | 0 | auto IterBool = WasmUniquingMap.insert( |
508 | 0 | std::make_pair(WasmSectionKey{Section.str(), Group, UniqueID}, nullptr)); |
509 | 0 | auto &Entry = *IterBool.first; |
510 | 0 | if (!IterBool.second) |
511 | 0 | return Entry.second; |
512 | 0 |
|
513 | 0 | StringRef CachedName = Entry.first.SectionName; |
514 | 0 |
|
515 | 0 | SectionKind Kind = SectionKind::getText(); |
516 | 0 |
|
517 | 0 | MCSymbol *Begin = nullptr; |
518 | 0 | if (BeginSymName) |
519 | 0 | Begin = createTempSymbol(BeginSymName, false); |
520 | 0 |
|
521 | 0 | MCSectionWasm *Result = new (WasmAllocator.Allocate()) |
522 | 0 | MCSectionWasm(CachedName, Type, Kind, GroupSym, UniqueID, Begin); |
523 | 0 | Entry.second = Result; |
524 | 0 | return Result; |
525 | 0 | } |
526 | | |
527 | 1.34k | MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) { |
528 | 1.34k | return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI); |
529 | 1.34k | } |
530 | | |
531 | | //===----------------------------------------------------------------------===// |
532 | | // Dwarf Management |
533 | | //===----------------------------------------------------------------------===// |
534 | | |
535 | | /// getDwarfFile - takes a file name an number to place in the dwarf file and |
536 | | /// directory tables. If the file number has already been allocated it is an |
537 | | /// error and zero is returned and the client reports the error, else the |
538 | | /// allocated file number is returned. The file numbers may be in any order. |
539 | | unsigned MCContext::getDwarfFile(StringRef Directory, StringRef FileName, |
540 | 206k | unsigned FileNumber, unsigned CUID) { |
541 | 206k | MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID]; |
542 | 206k | return Table.getFile(Directory, FileName, FileNumber); |
543 | 206k | } |
544 | | |
545 | | /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it |
546 | | /// currently is assigned and false otherwise. |
547 | 133 | bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) { |
548 | 133 | const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles = getMCDwarfFiles(CUID); |
549 | 133 | if (FileNumber == 0 || 133 FileNumber >= MCDwarfFiles.size()133 ) |
550 | 0 | return false; |
551 | 133 | |
552 | 133 | return !MCDwarfFiles[FileNumber].Name.empty(); |
553 | 133 | } |
554 | | |
555 | | /// Remove empty sections from SectionStartEndSyms, to avoid generating |
556 | | /// useless debug info for them. |
557 | 29 | void MCContext::finalizeDwarfSections(MCStreamer &MCOS) { |
558 | 29 | SectionsForRanges.remove_if( |
559 | 36 | [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); }); |
560 | 29 | } |
561 | | |
562 | 29.2M | CodeViewContext &MCContext::getCVContext() { |
563 | 29.2M | if (!CVContext.get()) |
564 | 20.8k | CVContext.reset(new CodeViewContext); |
565 | 29.2M | return *CVContext.get(); |
566 | 29.2M | } |
567 | | |
568 | | //===----------------------------------------------------------------------===// |
569 | | // Error Reporting |
570 | | //===----------------------------------------------------------------------===// |
571 | | |
572 | 302 | void MCContext::reportError(SMLoc Loc, const Twine &Msg) { |
573 | 302 | HadError = true; |
574 | 302 | |
575 | 302 | // If we have a source manager use it. Otherwise, try using the inline source |
576 | 302 | // manager. |
577 | 302 | // If that fails, use the generic report_fatal_error(). |
578 | 302 | if (SrcMgr) |
579 | 297 | SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg); |
580 | 5 | else if (5 InlineSrcMgr5 ) |
581 | 4 | InlineSrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg); |
582 | 5 | else |
583 | 1 | report_fatal_error(Msg, false); |
584 | 301 | } |
585 | | |
586 | 4 | void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) { |
587 | 4 | reportError(Loc, Msg); |
588 | 4 | |
589 | 4 | // If we reached here, we are failing ungracefully. Run the interrupt handlers |
590 | 4 | // to make sure any special cleanups get done, in particular that we remove |
591 | 4 | // files registered with RemoveFileOnSignal. |
592 | 4 | sys::RunInterruptHandlers(); |
593 | 4 | exit(1); |
594 | 4 | } |