1 //===- lib/MC/MCContext.cpp - Machine Code Context ------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/MC/MCContext.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/ADT/StringMap.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/BinaryFormat/COFF.h"
16 #include "llvm/BinaryFormat/ELF.h"
17 #include "llvm/BinaryFormat/GOFF.h"
18 #include "llvm/BinaryFormat/Wasm.h"
19 #include "llvm/BinaryFormat/XCOFF.h"
20 #include "llvm/MC/MCAsmInfo.h"
21 #include "llvm/MC/MCCodeView.h"
22 #include "llvm/MC/MCDwarf.h"
23 #include "llvm/MC/MCExpr.h"
24 #include "llvm/MC/MCInst.h"
25 #include "llvm/MC/MCLabel.h"
26 #include "llvm/MC/MCSectionCOFF.h"
27 #include "llvm/MC/MCSectionDXContainer.h"
28 #include "llvm/MC/MCSectionELF.h"
29 #include "llvm/MC/MCSectionGOFF.h"
30 #include "llvm/MC/MCSectionMachO.h"
31 #include "llvm/MC/MCSectionSPIRV.h"
32 #include "llvm/MC/MCSectionWasm.h"
33 #include "llvm/MC/MCSectionXCOFF.h"
34 #include "llvm/MC/MCStreamer.h"
35 #include "llvm/MC/MCSubtargetInfo.h"
36 #include "llvm/MC/MCSymbol.h"
37 #include "llvm/MC/MCSymbolCOFF.h"
38 #include "llvm/MC/MCSymbolELF.h"
39 #include "llvm/MC/MCSymbolGOFF.h"
40 #include "llvm/MC/MCSymbolMachO.h"
41 #include "llvm/MC/MCSymbolWasm.h"
42 #include "llvm/MC/MCSymbolXCOFF.h"
43 #include "llvm/MC/MCTargetOptions.h"
44 #include "llvm/MC/SectionKind.h"
45 #include "llvm/Support/Casting.h"
46 #include "llvm/Support/EndianStream.h"
47 #include "llvm/Support/ErrorHandling.h"
48 #include "llvm/Support/MemoryBuffer.h"
49 #include "llvm/Support/Path.h"
50 #include "llvm/Support/SMLoc.h"
51 #include "llvm/Support/SourceMgr.h"
52 #include "llvm/Support/raw_ostream.h"
53 #include <cassert>
54 #include <cstdlib>
55 #include <optional>
56 #include <tuple>
57 #include <utility>
58
59 using namespace llvm;
60
defaultDiagHandler(const SMDiagnostic & SMD,bool,const SourceMgr &,std::vector<const MDNode * > &)61 static void defaultDiagHandler(const SMDiagnostic &SMD, bool, const SourceMgr &,
62 std::vector<const MDNode *> &) {
63 SMD.print(nullptr, errs());
64 }
65
MCContext(const Triple & TheTriple,const MCAsmInfo * mai,const MCRegisterInfo * mri,const MCSubtargetInfo * msti,const SourceMgr * mgr,MCTargetOptions const * TargetOpts,bool DoAutoReset,StringRef Swift5ReflSegmentName)66 MCContext::MCContext(const Triple &TheTriple, const MCAsmInfo *mai,
67 const MCRegisterInfo *mri, const MCSubtargetInfo *msti,
68 const SourceMgr *mgr, MCTargetOptions const *TargetOpts,
69 bool DoAutoReset, StringRef Swift5ReflSegmentName)
70 : Swift5ReflectionSegmentName(Swift5ReflSegmentName), TT(TheTriple),
71 SrcMgr(mgr), InlineSrcMgr(nullptr), DiagHandler(defaultDiagHandler),
72 MAI(mai), MRI(mri), MSTI(msti), Symbols(Allocator),
73 InlineAsmUsedLabelNames(Allocator),
74 CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0),
75 AutoReset(DoAutoReset), TargetOptions(TargetOpts) {
76 SaveTempLabels = TargetOptions && TargetOptions->MCSaveTempLabels;
77 if (SaveTempLabels)
78 setUseNamesOnTempLabels(true);
79 SecureLogFile = TargetOptions ? TargetOptions->AsSecureLogFile : "";
80
81 if (SrcMgr && SrcMgr->getNumBuffers())
82 MainFileName = std::string(SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())
83 ->getBufferIdentifier());
84
85 switch (TheTriple.getObjectFormat()) {
86 case Triple::MachO:
87 Env = IsMachO;
88 break;
89 case Triple::COFF:
90 if (!TheTriple.isOSWindows() && !TheTriple.isUEFI()) {
91 reportFatalUsageError(
92 "cannot initialize MC for non-Windows COFF object files");
93 }
94
95 Env = IsCOFF;
96 break;
97 case Triple::ELF:
98 Env = IsELF;
99 break;
100 case Triple::Wasm:
101 Env = IsWasm;
102 break;
103 case Triple::XCOFF:
104 Env = IsXCOFF;
105 break;
106 case Triple::GOFF:
107 Env = IsGOFF;
108 break;
109 case Triple::DXContainer:
110 Env = IsDXContainer;
111 break;
112 case Triple::SPIRV:
113 Env = IsSPIRV;
114 break;
115 case Triple::UnknownObjectFormat:
116 report_fatal_error("Cannot initialize MC for unknown object file format.");
117 break;
118 }
119 }
120
~MCContext()121 MCContext::~MCContext() {
122 if (AutoReset)
123 reset();
124
125 // NOTE: The symbols are all allocated out of a bump pointer allocator,
126 // we don't need to free them here.
127 }
128
initInlineSourceManager()129 void MCContext::initInlineSourceManager() {
130 if (!InlineSrcMgr)
131 InlineSrcMgr.reset(new SourceMgr());
132 }
133
134 //===----------------------------------------------------------------------===//
135 // Module Lifetime Management
136 //===----------------------------------------------------------------------===//
137
reset()138 void MCContext::reset() {
139 SrcMgr = nullptr;
140 InlineSrcMgr.reset();
141 LocInfos.clear();
142 DiagHandler = defaultDiagHandler;
143
144 // Call the destructors so the fragments are freed
145 COFFAllocator.DestroyAll();
146 DXCAllocator.DestroyAll();
147 ELFAllocator.DestroyAll();
148 GOFFAllocator.DestroyAll();
149 MachOAllocator.DestroyAll();
150 WasmAllocator.DestroyAll();
151 XCOFFAllocator.DestroyAll();
152 MCInstAllocator.DestroyAll();
153 SPIRVAllocator.DestroyAll();
154 WasmSignatureAllocator.DestroyAll();
155
156 // ~CodeViewContext may destroy a MCFragment outside of sections and need to
157 // be reset before FragmentAllocator.
158 CVContext.reset();
159
160 MCSubtargetAllocator.DestroyAll();
161 InlineAsmUsedLabelNames.clear();
162 Symbols.clear();
163 Allocator.Reset();
164 FragmentAllocator.Reset();
165 Instances.clear();
166 CompilationDir.clear();
167 MainFileName.clear();
168 MCDwarfLineTablesCUMap.clear();
169 SectionsForRanges.clear();
170 MCGenDwarfLabelEntries.clear();
171 DwarfDebugFlags = StringRef();
172 DwarfCompileUnitID = 0;
173 CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0);
174
175 MachOUniquingMap.clear();
176 ELFUniquingMap.clear();
177 GOFFUniquingMap.clear();
178 COFFUniquingMap.clear();
179 WasmUniquingMap.clear();
180 XCOFFUniquingMap.clear();
181 DXCUniquingMap.clear();
182
183 RelSecNames.clear();
184 MacroMap.clear();
185 ELFEntrySizeMap.clear();
186 ELFSeenGenericMergeableSections.clear();
187
188 DwarfLocSeen = false;
189 GenDwarfForAssembly = false;
190 GenDwarfFileNumber = 0;
191
192 HadError = false;
193 }
194
195 //===----------------------------------------------------------------------===//
196 // MCInst Management
197 //===----------------------------------------------------------------------===//
198
createMCInst()199 MCInst *MCContext::createMCInst() {
200 return new (MCInstAllocator.Allocate()) MCInst;
201 }
202
203 // Allocate the initial MCDataFragment for the begin symbol.
allocInitialFragment(MCSection & Sec)204 MCDataFragment *MCContext::allocInitialFragment(MCSection &Sec) {
205 assert(!Sec.curFragList()->Head);
206 auto *F = allocFragment<MCDataFragment>();
207 F->setParent(&Sec);
208 Sec.curFragList()->Head = F;
209 Sec.curFragList()->Tail = F;
210 return F;
211 }
212
213 //===----------------------------------------------------------------------===//
214 // Symbol Manipulation
215 //===----------------------------------------------------------------------===//
216
getOrCreateSymbol(const Twine & Name)217 MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) {
218 SmallString<128> NameSV;
219 StringRef NameRef = Name.toStringRef(NameSV);
220
221 assert(!NameRef.empty() && "Normal symbols cannot be unnamed!");
222
223 MCSymbolTableEntry &Entry = getSymbolTableEntry(NameRef);
224 if (!Entry.second.Symbol) {
225 bool IsRenamable = NameRef.starts_with(MAI->getPrivateGlobalPrefix());
226 bool IsTemporary = IsRenamable && !SaveTempLabels;
227 if (!Entry.second.Used) {
228 Entry.second.Used = true;
229 Entry.second.Symbol = createSymbolImpl(&Entry, IsTemporary);
230 } else {
231 assert(IsRenamable && "cannot rename non-private symbol");
232 // Slow path: we need to rename a temp symbol from the user.
233 Entry.second.Symbol = createRenamableSymbol(NameRef, false, IsTemporary);
234 }
235 }
236
237 return Entry.second.Symbol;
238 }
239
parseSymbol(const Twine & Name)240 MCSymbol *MCContext::parseSymbol(const Twine &Name) {
241 SmallString<128> SV;
242 StringRef NameRef = Name.toStringRef(SV);
243 if (NameRef.contains('\\')) {
244 SV = NameRef;
245 size_t S = 0;
246 // Support escaped \\ and \" as in GNU Assembler. GAS issues a warning for
247 // other characters following \\, which we do not implement due to code
248 // structure.
249 for (size_t I = 0, E = SV.size(); I != E; ++I) {
250 char C = SV[I];
251 if (C == '\\' && I + 1 != E) {
252 switch (SV[I + 1]) {
253 case '"':
254 case '\\':
255 C = SV[++I];
256 break;
257 }
258 }
259 SV[S++] = C;
260 }
261 SV.resize(S);
262 NameRef = SV;
263 }
264
265 return getOrCreateSymbol(NameRef);
266 }
267
getOrCreateFrameAllocSymbol(const Twine & FuncName,unsigned Idx)268 MCSymbol *MCContext::getOrCreateFrameAllocSymbol(const Twine &FuncName,
269 unsigned Idx) {
270 return getOrCreateSymbol(MAI->getPrivateGlobalPrefix() + FuncName +
271 "$frame_escape_" + Twine(Idx));
272 }
273
getOrCreateParentFrameOffsetSymbol(const Twine & FuncName)274 MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(const Twine &FuncName) {
275 return getOrCreateSymbol(MAI->getPrivateGlobalPrefix() + FuncName +
276 "$parent_frame_offset");
277 }
278
getOrCreateLSDASymbol(const Twine & FuncName)279 MCSymbol *MCContext::getOrCreateLSDASymbol(const Twine &FuncName) {
280 return getOrCreateSymbol(MAI->getPrivateGlobalPrefix() + "__ehtable$" +
281 FuncName);
282 }
283
getSymbolTableEntry(StringRef Name)284 MCSymbolTableEntry &MCContext::getSymbolTableEntry(StringRef Name) {
285 return *Symbols.try_emplace(Name, MCSymbolTableValue{}).first;
286 }
287
createSymbolImpl(const MCSymbolTableEntry * Name,bool IsTemporary)288 MCSymbol *MCContext::createSymbolImpl(const MCSymbolTableEntry *Name,
289 bool IsTemporary) {
290 static_assert(std::is_trivially_destructible<MCSymbolCOFF>(),
291 "MCSymbol classes must be trivially destructible");
292 static_assert(std::is_trivially_destructible<MCSymbolELF>(),
293 "MCSymbol classes must be trivially destructible");
294 static_assert(std::is_trivially_destructible<MCSymbolMachO>(),
295 "MCSymbol classes must be trivially destructible");
296 static_assert(std::is_trivially_destructible<MCSymbolWasm>(),
297 "MCSymbol classes must be trivially destructible");
298 static_assert(std::is_trivially_destructible<MCSymbolXCOFF>(),
299 "MCSymbol classes must be trivially destructible");
300
301 switch (getObjectFileType()) {
302 case MCContext::IsCOFF:
303 return new (Name, *this) MCSymbolCOFF(Name, IsTemporary);
304 case MCContext::IsELF:
305 return new (Name, *this) MCSymbolELF(Name, IsTemporary);
306 case MCContext::IsGOFF:
307 return new (Name, *this) MCSymbolGOFF(Name, IsTemporary);
308 case MCContext::IsMachO:
309 return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
310 case MCContext::IsWasm:
311 return new (Name, *this) MCSymbolWasm(Name, IsTemporary);
312 case MCContext::IsXCOFF:
313 return createXCOFFSymbolImpl(Name, IsTemporary);
314 case MCContext::IsDXContainer:
315 break;
316 case MCContext::IsSPIRV:
317 return new (Name, *this)
318 MCSymbol(MCSymbol::SymbolKindUnset, Name, IsTemporary);
319 }
320 return new (Name, *this)
321 MCSymbol(MCSymbol::SymbolKindUnset, Name, IsTemporary);
322 }
323
cloneSymbol(MCSymbol & Sym)324 MCSymbol *MCContext::cloneSymbol(MCSymbol &Sym) {
325 MCSymbol *NewSym = nullptr;
326 auto Name = Sym.getNameEntryPtr();
327 switch (getObjectFileType()) {
328 case MCContext::IsCOFF:
329 NewSym = new (Name, *this) MCSymbolCOFF(cast<MCSymbolCOFF>(Sym));
330 break;
331 case MCContext::IsELF:
332 NewSym = new (Name, *this) MCSymbolELF(cast<MCSymbolELF>(Sym));
333 break;
334 case MCContext::IsMachO:
335 NewSym = new (Name, *this) MCSymbolMachO(cast<MCSymbolMachO>(Sym));
336 break;
337 default:
338 reportFatalUsageError(".set redefinition is not supported");
339 break;
340 }
341 // Set the name and redirect the `Symbols` entry to `NewSym`.
342 NewSym->getNameEntryPtr() = Name;
343 const_cast<MCSymbolTableEntry *>(Name)->second.Symbol = NewSym;
344 // Ensure the next `registerSymbol` call will add the new symbol to `Symbols`.
345 NewSym->setIsRegistered(false);
346
347 // Ensure the original symbol is not emitted to the symbol table.
348 Sym.IsTemporary = true;
349 Sym.setExternal(false);
350 return NewSym;
351 }
352
createRenamableSymbol(const Twine & Name,bool AlwaysAddSuffix,bool IsTemporary)353 MCSymbol *MCContext::createRenamableSymbol(const Twine &Name,
354 bool AlwaysAddSuffix,
355 bool IsTemporary) {
356 SmallString<128> NewName;
357 Name.toVector(NewName);
358 size_t NameLen = NewName.size();
359
360 MCSymbolTableEntry &NameEntry = getSymbolTableEntry(NewName.str());
361 MCSymbolTableEntry *EntryPtr = &NameEntry;
362 while (AlwaysAddSuffix || EntryPtr->second.Used) {
363 AlwaysAddSuffix = false;
364
365 NewName.resize(NameLen);
366 raw_svector_ostream(NewName) << NameEntry.second.NextUniqueID++;
367 EntryPtr = &getSymbolTableEntry(NewName.str());
368 }
369
370 EntryPtr->second.Used = true;
371 return createSymbolImpl(EntryPtr, IsTemporary);
372 }
373
createTempSymbol(const Twine & Name,bool AlwaysAddSuffix)374 MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix) {
375 if (!UseNamesOnTempLabels)
376 return createSymbolImpl(nullptr, /*IsTemporary=*/true);
377 return createRenamableSymbol(MAI->getPrivateGlobalPrefix() + Name,
378 AlwaysAddSuffix, /*IsTemporary=*/true);
379 }
380
createNamedTempSymbol(const Twine & Name)381 MCSymbol *MCContext::createNamedTempSymbol(const Twine &Name) {
382 return createRenamableSymbol(MAI->getPrivateGlobalPrefix() + Name, true,
383 /*IsTemporary=*/!SaveTempLabels);
384 }
385
createBlockSymbol(const Twine & Name,bool AlwaysEmit)386 MCSymbol *MCContext::createBlockSymbol(const Twine &Name, bool AlwaysEmit) {
387 if (AlwaysEmit)
388 return getOrCreateSymbol(MAI->getPrivateLabelPrefix() + Name);
389
390 bool IsTemporary = !SaveTempLabels;
391 if (IsTemporary && !UseNamesOnTempLabels)
392 return createSymbolImpl(nullptr, IsTemporary);
393 return createRenamableSymbol(MAI->getPrivateLabelPrefix() + Name,
394 /*AlwaysAddSuffix=*/false, IsTemporary);
395 }
396
createLinkerPrivateTempSymbol()397 MCSymbol *MCContext::createLinkerPrivateTempSymbol() {
398 return createLinkerPrivateSymbol("tmp");
399 }
400
createLinkerPrivateSymbol(const Twine & Name)401 MCSymbol *MCContext::createLinkerPrivateSymbol(const Twine &Name) {
402 return createRenamableSymbol(MAI->getLinkerPrivateGlobalPrefix() + Name,
403 /*AlwaysAddSuffix=*/true,
404 /*IsTemporary=*/false);
405 }
406
createTempSymbol()407 MCSymbol *MCContext::createTempSymbol() { return createTempSymbol("tmp"); }
408
createNamedTempSymbol()409 MCSymbol *MCContext::createNamedTempSymbol() {
410 return createNamedTempSymbol("tmp");
411 }
412
createLocalSymbol(StringRef Name)413 MCSymbol *MCContext::createLocalSymbol(StringRef Name) {
414 MCSymbolTableEntry &NameEntry = getSymbolTableEntry(Name);
415 return createSymbolImpl(&NameEntry, /*IsTemporary=*/false);
416 }
417
NextInstance(unsigned LocalLabelVal)418 unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
419 MCLabel *&Label = Instances[LocalLabelVal];
420 if (!Label)
421 Label = new (*this) MCLabel(0);
422 return Label->incInstance();
423 }
424
GetInstance(unsigned LocalLabelVal)425 unsigned MCContext::GetInstance(unsigned LocalLabelVal) {
426 MCLabel *&Label = Instances[LocalLabelVal];
427 if (!Label)
428 Label = new (*this) MCLabel(0);
429 return Label->getInstance();
430 }
431
getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,unsigned Instance)432 MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
433 unsigned Instance) {
434 MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)];
435 if (!Sym)
436 Sym = createNamedTempSymbol();
437 return Sym;
438 }
439
createDirectionalLocalSymbol(unsigned LocalLabelVal)440 MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) {
441 unsigned Instance = NextInstance(LocalLabelVal);
442 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
443 }
444
getDirectionalLocalSymbol(unsigned LocalLabelVal,bool Before)445 MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal,
446 bool Before) {
447 unsigned Instance = GetInstance(LocalLabelVal);
448 if (!Before)
449 ++Instance;
450 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
451 }
452
453 template <typename Symbol>
getOrCreateSectionSymbol(StringRef Section)454 Symbol *MCContext::getOrCreateSectionSymbol(StringRef Section) {
455 Symbol *R;
456 auto &SymEntry = getSymbolTableEntry(Section);
457 MCSymbol *Sym = SymEntry.second.Symbol;
458 // A section symbol can not redefine regular symbols. There may be multiple
459 // sections with the same name, in which case the first such section wins.
460 if (Sym && Sym->isDefined() &&
461 (!Sym->isInSection() || Sym->getSection().getBeginSymbol() != Sym))
462 reportError(SMLoc(), "invalid symbol redefinition");
463 if (Sym && Sym->isUndefined()) {
464 R = cast<Symbol>(Sym);
465 } else {
466 SymEntry.second.Used = true;
467 R = new (&SymEntry, *this) Symbol(&SymEntry, /*isTemporary=*/false);
468 if (!Sym)
469 SymEntry.second.Symbol = R;
470 }
471 return R;
472 }
473
lookupSymbol(const Twine & Name) const474 MCSymbol *MCContext::lookupSymbol(const Twine &Name) const {
475 SmallString<128> NameSV;
476 StringRef NameRef = Name.toStringRef(NameSV);
477 return Symbols.lookup(NameRef).Symbol;
478 }
479
setSymbolValue(MCStreamer & Streamer,const Twine & Sym,uint64_t Val)480 void MCContext::setSymbolValue(MCStreamer &Streamer, const Twine &Sym,
481 uint64_t Val) {
482 auto Symbol = getOrCreateSymbol(Sym);
483 Streamer.emitAssignment(Symbol, MCConstantExpr::create(Val, *this));
484 }
485
registerInlineAsmLabel(MCSymbol * Sym)486 void MCContext::registerInlineAsmLabel(MCSymbol *Sym) {
487 InlineAsmUsedLabelNames[Sym->getName()] = Sym;
488 }
489
createWasmSignature()490 wasm::WasmSignature *MCContext::createWasmSignature() {
491 return new (WasmSignatureAllocator.Allocate()) wasm::WasmSignature;
492 }
493
createXCOFFSymbolImpl(const MCSymbolTableEntry * Name,bool IsTemporary)494 MCSymbolXCOFF *MCContext::createXCOFFSymbolImpl(const MCSymbolTableEntry *Name,
495 bool IsTemporary) {
496 if (!Name)
497 return new (nullptr, *this) MCSymbolXCOFF(nullptr, IsTemporary);
498
499 StringRef OriginalName = Name->first();
500 if (OriginalName.starts_with("._Renamed..") ||
501 OriginalName.starts_with("_Renamed.."))
502 reportError(SMLoc(), "invalid symbol name from source");
503
504 if (MAI->isValidUnquotedName(OriginalName))
505 return new (Name, *this) MCSymbolXCOFF(Name, IsTemporary);
506
507 // Now we have a name that contains invalid character(s) for XCOFF symbol.
508 // Let's replace with something valid, but save the original name so that
509 // we could still use the original name in the symbol table.
510 SmallString<128> InvalidName(OriginalName);
511
512 // If it's an entry point symbol, we will keep the '.'
513 // in front for the convention purpose. Otherwise, add "_Renamed.."
514 // as prefix to signal this is an renamed symbol.
515 const bool IsEntryPoint = InvalidName.starts_with(".");
516 SmallString<128> ValidName =
517 StringRef(IsEntryPoint ? "._Renamed.." : "_Renamed..");
518
519 // Append the hex values of '_' and invalid characters with "_Renamed..";
520 // at the same time replace invalid characters with '_'.
521 for (char &C : InvalidName) {
522 if (!MAI->isAcceptableChar(C) || C == '_') {
523 raw_svector_ostream(ValidName).write_hex(C);
524 C = '_';
525 }
526 }
527
528 // Skip entry point symbol's '.' as we already have a '.' in front of
529 // "_Renamed".
530 if (IsEntryPoint)
531 ValidName.append(InvalidName.substr(1, InvalidName.size() - 1));
532 else
533 ValidName.append(InvalidName);
534
535 MCSymbolTableEntry &NameEntry = getSymbolTableEntry(ValidName.str());
536 assert(!NameEntry.second.Used && "This name is used somewhere else.");
537 NameEntry.second.Used = true;
538 // Have the MCSymbol object itself refer to the copy of the string
539 // that is embedded in the symbol table entry.
540 MCSymbolXCOFF *XSym =
541 new (&NameEntry, *this) MCSymbolXCOFF(&NameEntry, IsTemporary);
542 XSym->setSymbolTableName(MCSymbolXCOFF::getUnqualifiedName(OriginalName));
543 return XSym;
544 }
545
546 //===----------------------------------------------------------------------===//
547 // Section Management
548 //===----------------------------------------------------------------------===//
549
getMachOSection(StringRef Segment,StringRef Section,unsigned TypeAndAttributes,unsigned Reserved2,SectionKind Kind,const char * BeginSymName)550 MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
551 unsigned TypeAndAttributes,
552 unsigned Reserved2, SectionKind Kind,
553 const char *BeginSymName) {
554 // We unique sections by their segment/section pair. The returned section
555 // may not have the same flags as the requested section, if so this should be
556 // diagnosed by the client as an error.
557
558 // Form the name to look up.
559 assert(Section.size() <= 16 && "section name is too long");
560 assert(!memchr(Section.data(), '\0', Section.size()) &&
561 "section name cannot contain NUL");
562
563 // Do the lookup, if we have a hit, return it.
564 auto R = MachOUniquingMap.try_emplace((Segment + Twine(',') + Section).str());
565 if (!R.second)
566 return R.first->second;
567
568 MCSymbol *Begin = nullptr;
569 if (BeginSymName)
570 Begin = createTempSymbol(BeginSymName, false);
571
572 // Otherwise, return a new section.
573 StringRef Name = R.first->first();
574 auto *Ret = new (MachOAllocator.Allocate())
575 MCSectionMachO(Segment, Name.substr(Name.size() - Section.size()),
576 TypeAndAttributes, Reserved2, Kind, Begin);
577 R.first->second = Ret;
578 allocInitialFragment(*Ret);
579 return Ret;
580 }
581
createELFSectionImpl(StringRef Section,unsigned Type,unsigned Flags,unsigned EntrySize,const MCSymbolELF * Group,bool Comdat,unsigned UniqueID,const MCSymbolELF * LinkedToSym)582 MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
583 unsigned Flags,
584 unsigned EntrySize,
585 const MCSymbolELF *Group,
586 bool Comdat, unsigned UniqueID,
587 const MCSymbolELF *LinkedToSym) {
588 auto *R = getOrCreateSectionSymbol<MCSymbolELF>(Section);
589 R->setBinding(ELF::STB_LOCAL);
590 R->setType(ELF::STT_SECTION);
591
592 auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF(
593 Section, Type, Flags, EntrySize, Group, Comdat, UniqueID, R, LinkedToSym);
594
595 auto *F = allocInitialFragment(*Ret);
596 R->setFragment(F);
597 return Ret;
598 }
599
600 MCSectionELF *
createELFRelSection(const Twine & Name,unsigned Type,unsigned Flags,unsigned EntrySize,const MCSymbolELF * Group,const MCSectionELF * RelInfoSection)601 MCContext::createELFRelSection(const Twine &Name, unsigned Type, unsigned Flags,
602 unsigned EntrySize, const MCSymbolELF *Group,
603 const MCSectionELF *RelInfoSection) {
604 StringMap<bool>::iterator I;
605 bool Inserted;
606 std::tie(I, Inserted) = RelSecNames.insert(std::make_pair(Name.str(), true));
607
608 return createELFSectionImpl(
609 I->getKey(), Type, Flags, EntrySize, Group, true, true,
610 cast<MCSymbolELF>(RelInfoSection->getBeginSymbol()));
611 }
612
getELFNamedSection(const Twine & Prefix,const Twine & Suffix,unsigned Type,unsigned Flags,unsigned EntrySize)613 MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
614 const Twine &Suffix, unsigned Type,
615 unsigned Flags,
616 unsigned EntrySize) {
617 return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix,
618 /*IsComdat=*/true);
619 }
620
getELFSection(const Twine & Section,unsigned Type,unsigned Flags,unsigned EntrySize,const Twine & Group,bool IsComdat,unsigned UniqueID,const MCSymbolELF * LinkedToSym)621 MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
622 unsigned Flags, unsigned EntrySize,
623 const Twine &Group, bool IsComdat,
624 unsigned UniqueID,
625 const MCSymbolELF *LinkedToSym) {
626 MCSymbolELF *GroupSym = nullptr;
627 if (!Group.isTriviallyEmpty() && !Group.str().empty())
628 GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
629
630 return getELFSection(Section, Type, Flags, EntrySize, GroupSym, IsComdat,
631 UniqueID, LinkedToSym);
632 }
633
getELFSection(const Twine & Section,unsigned Type,unsigned Flags,unsigned EntrySize,const MCSymbolELF * GroupSym,bool IsComdat,unsigned UniqueID,const MCSymbolELF * LinkedToSym)634 MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
635 unsigned Flags, unsigned EntrySize,
636 const MCSymbolELF *GroupSym,
637 bool IsComdat, unsigned UniqueID,
638 const MCSymbolELF *LinkedToSym) {
639 assert(!(LinkedToSym && LinkedToSym->getName().empty()));
640
641 // Sections are differentiated by the quadruple (section_name, group_name,
642 // unique_id, link_to_symbol_name). Sections sharing the same quadruple are
643 // combined into one section. As an optimization, non-unique sections without
644 // group or linked-to symbol have a shorter unique-ing key.
645 std::pair<StringMap<MCSectionELF *>::iterator, bool> EntryNewPair;
646 // Length of the section name, which are the first SectionLen bytes of the key
647 unsigned SectionLen;
648 if (GroupSym || LinkedToSym || UniqueID != MCSection::NonUniqueID) {
649 SmallString<128> Buffer;
650 Section.toVector(Buffer);
651 SectionLen = Buffer.size();
652 Buffer.push_back(0); // separator which cannot occur in the name
653 if (GroupSym)
654 Buffer.append(GroupSym->getName());
655 Buffer.push_back(0); // separator which cannot occur in the name
656 if (LinkedToSym)
657 Buffer.append(LinkedToSym->getName());
658 support::endian::write(Buffer, UniqueID, endianness::native);
659 StringRef UniqueMapKey = StringRef(Buffer);
660 EntryNewPair = ELFUniquingMap.try_emplace(UniqueMapKey);
661 } else if (!Section.isSingleStringRef()) {
662 SmallString<128> Buffer;
663 StringRef UniqueMapKey = Section.toStringRef(Buffer);
664 SectionLen = UniqueMapKey.size();
665 EntryNewPair = ELFUniquingMap.try_emplace(UniqueMapKey);
666 } else {
667 StringRef UniqueMapKey = Section.getSingleStringRef();
668 SectionLen = UniqueMapKey.size();
669 EntryNewPair = ELFUniquingMap.try_emplace(UniqueMapKey);
670 }
671
672 if (!EntryNewPair.second)
673 return EntryNewPair.first->second;
674
675 StringRef CachedName = EntryNewPair.first->getKey().take_front(SectionLen);
676
677 MCSectionELF *Result =
678 createELFSectionImpl(CachedName, Type, Flags, EntrySize, GroupSym,
679 IsComdat, UniqueID, LinkedToSym);
680 EntryNewPair.first->second = Result;
681
682 recordELFMergeableSectionInfo(Result->getName(), Result->getFlags(),
683 Result->getUniqueID(), Result->getEntrySize());
684
685 return Result;
686 }
687
createELFGroupSection(const MCSymbolELF * Group,bool IsComdat)688 MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group,
689 bool IsComdat) {
690 return createELFSectionImpl(".group", ELF::SHT_GROUP, 0, 4, Group, IsComdat,
691 MCSection::NonUniqueID, nullptr);
692 }
693
recordELFMergeableSectionInfo(StringRef SectionName,unsigned Flags,unsigned UniqueID,unsigned EntrySize)694 void MCContext::recordELFMergeableSectionInfo(StringRef SectionName,
695 unsigned Flags, unsigned UniqueID,
696 unsigned EntrySize) {
697 bool IsMergeable = Flags & ELF::SHF_MERGE;
698 if (UniqueID == MCSection::NonUniqueID) {
699 ELFSeenGenericMergeableSections.insert(SectionName);
700 // Minor performance optimization: avoid hash map lookup in
701 // isELFGenericMergeableSection, which will return true for SectionName.
702 IsMergeable = true;
703 }
704
705 // For mergeable sections or non-mergeable sections with a generic mergeable
706 // section name we enter their Unique ID into the ELFEntrySizeMap so that
707 // compatible globals can be assigned to the same section.
708
709 if (IsMergeable || isELFGenericMergeableSection(SectionName)) {
710 ELFEntrySizeMap.insert(std::make_pair(
711 std::make_tuple(SectionName, Flags, EntrySize), UniqueID));
712 }
713 }
714
isELFImplicitMergeableSectionNamePrefix(StringRef SectionName)715 bool MCContext::isELFImplicitMergeableSectionNamePrefix(StringRef SectionName) {
716 return SectionName.starts_with(".rodata.str") ||
717 SectionName.starts_with(".rodata.cst");
718 }
719
isELFGenericMergeableSection(StringRef SectionName)720 bool MCContext::isELFGenericMergeableSection(StringRef SectionName) {
721 return isELFImplicitMergeableSectionNamePrefix(SectionName) ||
722 ELFSeenGenericMergeableSections.count(SectionName);
723 }
724
725 std::optional<unsigned>
getELFUniqueIDForEntsize(StringRef SectionName,unsigned Flags,unsigned EntrySize)726 MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags,
727 unsigned EntrySize) {
728 auto I = ELFEntrySizeMap.find(std::make_tuple(SectionName, Flags, EntrySize));
729 return (I != ELFEntrySizeMap.end()) ? std::optional<unsigned>(I->second)
730 : std::nullopt;
731 }
732
733 template <typename TAttr>
getGOFFSection(SectionKind Kind,StringRef Name,TAttr Attributes,MCSection * Parent,bool IsVirtual)734 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
735 TAttr Attributes, MCSection *Parent,
736 bool IsVirtual) {
737 std::string UniqueName(Name);
738 if (Parent) {
739 UniqueName.append("/").append(Parent->getName());
740 if (auto *P = static_cast<MCSectionGOFF *>(Parent)->getParent())
741 UniqueName.append("/").append(P->getName());
742 }
743 // Do the lookup. If we don't have a hit, return a new section.
744 auto IterBool = GOFFUniquingMap.insert(std::make_pair(UniqueName, nullptr));
745 auto Iter = IterBool.first;
746 if (!IterBool.second)
747 return Iter->second;
748
749 StringRef CachedName = StringRef(Iter->first.c_str(), Name.size());
750 MCSectionGOFF *GOFFSection = new (GOFFAllocator.Allocate())
751 MCSectionGOFF(CachedName, Kind, IsVirtual, Attributes,
752 static_cast<MCSectionGOFF *>(Parent));
753 Iter->second = GOFFSection;
754 allocInitialFragment(*GOFFSection);
755 return GOFFSection;
756 }
757
getGOFFSection(SectionKind Kind,StringRef Name,GOFF::SDAttr SDAttributes)758 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
759 GOFF::SDAttr SDAttributes) {
760 return getGOFFSection<GOFF::SDAttr>(Kind, Name, SDAttributes, nullptr,
761 /*IsVirtual=*/true);
762 }
763
getGOFFSection(SectionKind Kind,StringRef Name,GOFF::EDAttr EDAttributes,MCSection * Parent)764 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
765 GOFF::EDAttr EDAttributes,
766 MCSection *Parent) {
767 return getGOFFSection<GOFF::EDAttr>(
768 Kind, Name, EDAttributes, Parent,
769 /*IsVirtual=*/EDAttributes.BindAlgorithm == GOFF::ESD_BA_Merge);
770 }
771
getGOFFSection(SectionKind Kind,StringRef Name,GOFF::PRAttr PRAttributes,MCSection * Parent)772 MCSectionGOFF *MCContext::getGOFFSection(SectionKind Kind, StringRef Name,
773 GOFF::PRAttr PRAttributes,
774 MCSection *Parent) {
775 return getGOFFSection<GOFF::PRAttr>(Kind, Name, PRAttributes, Parent,
776 /*IsVirtual=*/false);
777 }
778
getCOFFSection(StringRef Section,unsigned Characteristics,StringRef COMDATSymName,int Selection,unsigned UniqueID)779 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
780 unsigned Characteristics,
781 StringRef COMDATSymName, int Selection,
782 unsigned UniqueID) {
783 MCSymbol *COMDATSymbol = nullptr;
784 if (!COMDATSymName.empty()) {
785 COMDATSymbol = getOrCreateSymbol(COMDATSymName);
786 assert(COMDATSymbol && "COMDATSymbol is null");
787 COMDATSymName = COMDATSymbol->getName();
788 // A non-associative COMDAT is considered to define the COMDAT symbol. Check
789 // the redefinition error.
790 if (Selection != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE &&
791 COMDATSymbol->isDefined() &&
792 (!COMDATSymbol->isInSection() ||
793 cast<MCSectionCOFF>(COMDATSymbol->getSection()).getCOMDATSymbol() !=
794 COMDATSymbol))
795 reportError(SMLoc(), "invalid symbol redefinition");
796 }
797
798 // Do the lookup, if we have a hit, return it.
799 COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID};
800 auto [Iter, Inserted] = COFFUniquingMap.try_emplace(T);
801 if (!Inserted)
802 return Iter->second;
803
804 StringRef CachedName = Iter->first.SectionName;
805 MCSymbol *Begin = getOrCreateSectionSymbol<MCSymbolCOFF>(Section);
806 MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
807 CachedName, Characteristics, COMDATSymbol, Selection, UniqueID, Begin);
808 Iter->second = Result;
809 auto *F = allocInitialFragment(*Result);
810 Begin->setFragment(F);
811 return Result;
812 }
813
getCOFFSection(StringRef Section,unsigned Characteristics)814 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
815 unsigned Characteristics) {
816 return getCOFFSection(Section, Characteristics, "", 0,
817 MCSection::NonUniqueID);
818 }
819
getAssociativeCOFFSection(MCSectionCOFF * Sec,const MCSymbol * KeySym,unsigned UniqueID)820 MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
821 const MCSymbol *KeySym,
822 unsigned UniqueID) {
823 // Return the normal section if we don't have to be associative or unique.
824 if (!KeySym && UniqueID == MCSection::NonUniqueID)
825 return Sec;
826
827 // If we have a key symbol, make an associative section with the same name and
828 // kind as the normal section.
829 unsigned Characteristics = Sec->getCharacteristics();
830 if (KeySym) {
831 Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
832 return getCOFFSection(Sec->getName(), Characteristics, KeySym->getName(),
833 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
834 }
835
836 return getCOFFSection(Sec->getName(), Characteristics, "", 0, UniqueID);
837 }
838
getWasmSection(const Twine & Section,SectionKind K,unsigned Flags,const Twine & Group,unsigned UniqueID)839 MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind K,
840 unsigned Flags, const Twine &Group,
841 unsigned UniqueID) {
842 MCSymbolWasm *GroupSym = nullptr;
843 if (!Group.isTriviallyEmpty() && !Group.str().empty()) {
844 GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group));
845 GroupSym->setComdat(true);
846 if (K.isMetadata() && !GroupSym->getType().has_value()) {
847 // Comdat group symbol associated with a custom section is a section
848 // symbol (not a data symbol).
849 GroupSym->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
850 }
851 }
852
853 return getWasmSection(Section, K, Flags, GroupSym, UniqueID);
854 }
855
getWasmSection(const Twine & Section,SectionKind Kind,unsigned Flags,const MCSymbolWasm * GroupSym,unsigned UniqueID)856 MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
857 unsigned Flags,
858 const MCSymbolWasm *GroupSym,
859 unsigned UniqueID) {
860 StringRef Group = "";
861 if (GroupSym)
862 Group = GroupSym->getName();
863 // Do the lookup, if we have a hit, return it.
864 auto IterBool = WasmUniquingMap.insert(
865 std::make_pair(WasmSectionKey{Section.str(), Group, UniqueID}, nullptr));
866 auto &Entry = *IterBool.first;
867 if (!IterBool.second)
868 return Entry.second;
869
870 StringRef CachedName = Entry.first.SectionName;
871
872 MCSymbol *Begin = createRenamableSymbol(CachedName, true, false);
873 // Begin always has a different name than CachedName... see #48596.
874 getSymbolTableEntry(Begin->getName()).second.Symbol = Begin;
875 cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
876
877 MCSectionWasm *Result = new (WasmAllocator.Allocate())
878 MCSectionWasm(CachedName, Kind, Flags, GroupSym, UniqueID, Begin);
879 Entry.second = Result;
880
881 auto *F = allocInitialFragment(*Result);
882 Begin->setFragment(F);
883 return Result;
884 }
885
hasXCOFFSection(StringRef Section,XCOFF::CsectProperties CsectProp) const886 bool MCContext::hasXCOFFSection(StringRef Section,
887 XCOFF::CsectProperties CsectProp) const {
888 return XCOFFUniquingMap.count(
889 XCOFFSectionKey(Section.str(), CsectProp.MappingClass)) != 0;
890 }
891
getXCOFFSection(StringRef Section,SectionKind Kind,std::optional<XCOFF::CsectProperties> CsectProp,bool MultiSymbolsAllowed,std::optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSectionSubtypeFlags)892 MCSectionXCOFF *MCContext::getXCOFFSection(
893 StringRef Section, SectionKind Kind,
894 std::optional<XCOFF::CsectProperties> CsectProp, bool MultiSymbolsAllowed,
895 std::optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSectionSubtypeFlags) {
896 bool IsDwarfSec = DwarfSectionSubtypeFlags.has_value();
897 assert((IsDwarfSec != CsectProp.has_value()) && "Invalid XCOFF section!");
898
899 // Do the lookup. If we have a hit, return it.
900 auto IterBool = XCOFFUniquingMap.insert(std::make_pair(
901 IsDwarfSec ? XCOFFSectionKey(Section.str(), *DwarfSectionSubtypeFlags)
902 : XCOFFSectionKey(Section.str(), CsectProp->MappingClass),
903 nullptr));
904 auto &Entry = *IterBool.first;
905 if (!IterBool.second) {
906 MCSectionXCOFF *ExistedEntry = Entry.second;
907 if (ExistedEntry->isMultiSymbolsAllowed() != MultiSymbolsAllowed)
908 report_fatal_error("section's multiply symbols policy does not match");
909
910 return ExistedEntry;
911 }
912
913 // Otherwise, return a new section.
914 StringRef CachedName = Entry.first.SectionName;
915 MCSymbolXCOFF *QualName = nullptr;
916 // Debug section don't have storage class attribute.
917 if (IsDwarfSec)
918 QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(CachedName));
919 else
920 QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(
921 CachedName + "[" +
922 XCOFF::getMappingClassString(CsectProp->MappingClass) + "]"));
923
924 // QualName->getUnqualifiedName() and CachedName are the same except when
925 // CachedName contains invalid character(s) such as '$' for an XCOFF symbol.
926 MCSectionXCOFF *Result = nullptr;
927 if (IsDwarfSec)
928 Result = new (XCOFFAllocator.Allocate()) MCSectionXCOFF(
929 QualName->getUnqualifiedName(), Kind, QualName,
930 *DwarfSectionSubtypeFlags, QualName, CachedName, MultiSymbolsAllowed);
931 else
932 Result = new (XCOFFAllocator.Allocate())
933 MCSectionXCOFF(QualName->getUnqualifiedName(), CsectProp->MappingClass,
934 CsectProp->Type, Kind, QualName, nullptr, CachedName,
935 MultiSymbolsAllowed);
936
937 Entry.second = Result;
938
939 auto *F = allocInitialFragment(*Result);
940
941 // We might miss calculating the symbols difference as absolute value before
942 // adding fixups when symbol_A without the fragment set is the csect itself
943 // and symbol_B is in it.
944 // TODO: Currently we only set the fragment for XMC_PR csects and DWARF
945 // sections because we don't have other cases that hit this problem yet.
946 if (IsDwarfSec || CsectProp->MappingClass == XCOFF::XMC_PR)
947 QualName->setFragment(F);
948
949 return Result;
950 }
951
getSPIRVSection()952 MCSectionSPIRV *MCContext::getSPIRVSection() {
953 MCSectionSPIRV *Result = new (SPIRVAllocator.Allocate()) MCSectionSPIRV();
954
955 allocInitialFragment(*Result);
956 return Result;
957 }
958
getDXContainerSection(StringRef Section,SectionKind K)959 MCSectionDXContainer *MCContext::getDXContainerSection(StringRef Section,
960 SectionKind K) {
961 // Do the lookup, if we have a hit, return it.
962 auto ItInsertedPair = DXCUniquingMap.try_emplace(Section);
963 if (!ItInsertedPair.second)
964 return ItInsertedPair.first->second;
965
966 auto MapIt = ItInsertedPair.first;
967 // Grab the name from the StringMap. Since the Section is going to keep a
968 // copy of this StringRef we need to make sure the underlying string stays
969 // alive as long as we need it.
970 StringRef Name = MapIt->first();
971 MapIt->second =
972 new (DXCAllocator.Allocate()) MCSectionDXContainer(Name, K, nullptr);
973
974 // The first fragment will store the header
975 allocInitialFragment(*MapIt->second);
976 return MapIt->second;
977 }
978
getSubtargetCopy(const MCSubtargetInfo & STI)979 MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
980 return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
981 }
982
addDebugPrefixMapEntry(const std::string & From,const std::string & To)983 void MCContext::addDebugPrefixMapEntry(const std::string &From,
984 const std::string &To) {
985 DebugPrefixMap.emplace_back(From, To);
986 }
987
remapDebugPath(SmallVectorImpl<char> & Path)988 void MCContext::remapDebugPath(SmallVectorImpl<char> &Path) {
989 for (const auto &[From, To] : llvm::reverse(DebugPrefixMap))
990 if (llvm::sys::path::replace_path_prefix(Path, From, To))
991 break;
992 }
993
RemapDebugPaths()994 void MCContext::RemapDebugPaths() {
995 const auto &DebugPrefixMap = this->DebugPrefixMap;
996 if (DebugPrefixMap.empty())
997 return;
998
999 // Remap compilation directory.
1000 remapDebugPath(CompilationDir);
1001
1002 // Remap MCDwarfDirs and RootFile.Name in all compilation units.
1003 SmallString<256> P;
1004 for (auto &CUIDTablePair : MCDwarfLineTablesCUMap) {
1005 for (auto &Dir : CUIDTablePair.second.getMCDwarfDirs()) {
1006 P = Dir;
1007 remapDebugPath(P);
1008 Dir = std::string(P);
1009 }
1010
1011 // Used by DW_TAG_compile_unit's DT_AT_name and DW_TAG_label's
1012 // DW_AT_decl_file for DWARF v5 generated for assembly source.
1013 P = CUIDTablePair.second.getRootFile().Name;
1014 remapDebugPath(P);
1015 CUIDTablePair.second.getRootFile().Name = std::string(P);
1016 }
1017 }
1018
1019 //===----------------------------------------------------------------------===//
1020 // Dwarf Management
1021 //===----------------------------------------------------------------------===//
1022
emitDwarfUnwindInfo() const1023 EmitDwarfUnwindType MCContext::emitDwarfUnwindInfo() const {
1024 if (!TargetOptions)
1025 return EmitDwarfUnwindType::Default;
1026 return TargetOptions->EmitDwarfUnwind;
1027 }
1028
emitCompactUnwindNonCanonical() const1029 bool MCContext::emitCompactUnwindNonCanonical() const {
1030 if (TargetOptions)
1031 return TargetOptions->EmitCompactUnwindNonCanonical;
1032 return false;
1033 }
1034
setGenDwarfRootFile(StringRef InputFileName,StringRef Buffer)1035 void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) {
1036 // MCDwarf needs the root file as well as the compilation directory.
1037 // If we find a '.file 0' directive that will supersede these values.
1038 std::optional<MD5::MD5Result> Cksum;
1039 if (getDwarfVersion() >= 5) {
1040 MD5 Hash;
1041 MD5::MD5Result Sum;
1042 Hash.update(Buffer);
1043 Hash.final(Sum);
1044 Cksum = Sum;
1045 }
1046 // Canonicalize the root filename. It cannot be empty, and should not
1047 // repeat the compilation dir.
1048 // The MCContext ctor initializes MainFileName to the name associated with
1049 // the SrcMgr's main file ID, which might be the same as InputFileName (and
1050 // possibly include directory components).
1051 // Or, MainFileName might have been overridden by a -main-file-name option,
1052 // which is supposed to be just a base filename with no directory component.
1053 // So, if the InputFileName and MainFileName are not equal, assume
1054 // MainFileName is a substitute basename and replace the last component.
1055 SmallString<1024> FileNameBuf = InputFileName;
1056 if (FileNameBuf.empty() || FileNameBuf == "-")
1057 FileNameBuf = "<stdin>";
1058 if (!getMainFileName().empty() && FileNameBuf != getMainFileName()) {
1059 llvm::sys::path::remove_filename(FileNameBuf);
1060 llvm::sys::path::append(FileNameBuf, getMainFileName());
1061 }
1062 StringRef FileName = FileNameBuf;
1063 if (FileName.consume_front(getCompilationDir()))
1064 if (llvm::sys::path::is_separator(FileName.front()))
1065 FileName = FileName.drop_front();
1066 assert(!FileName.empty());
1067 setMCLineTableRootFile(
1068 /*CUID=*/0, getCompilationDir(), FileName, Cksum, std::nullopt);
1069 }
1070
1071 /// getDwarfFile - takes a file name and number to place in the dwarf file and
1072 /// directory tables. If the file number has already been allocated it is an
1073 /// error and zero is returned and the client reports the error, else the
1074 /// allocated file number is returned. The file numbers may be in any order.
1075 Expected<unsigned>
getDwarfFile(StringRef Directory,StringRef FileName,unsigned FileNumber,std::optional<MD5::MD5Result> Checksum,std::optional<StringRef> Source,unsigned CUID)1076 MCContext::getDwarfFile(StringRef Directory, StringRef FileName,
1077 unsigned FileNumber,
1078 std::optional<MD5::MD5Result> Checksum,
1079 std::optional<StringRef> Source, unsigned CUID) {
1080 MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
1081 return Table.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
1082 FileNumber);
1083 }
1084
1085 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
1086 /// currently is assigned and false otherwise.
isValidDwarfFileNumber(unsigned FileNumber,unsigned CUID)1087 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
1088 const MCDwarfLineTable &LineTable = getMCDwarfLineTable(CUID);
1089 if (FileNumber == 0)
1090 return getDwarfVersion() >= 5;
1091 if (FileNumber >= LineTable.getMCDwarfFiles().size())
1092 return false;
1093
1094 return !LineTable.getMCDwarfFiles()[FileNumber].Name.empty();
1095 }
1096
1097 /// Remove empty sections from SectionsForRanges, to avoid generating
1098 /// useless debug info for them.
finalizeDwarfSections(MCStreamer & MCOS)1099 void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
1100 SectionsForRanges.remove_if(
1101 [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); });
1102 }
1103
getCVContext()1104 CodeViewContext &MCContext::getCVContext() {
1105 if (!CVContext)
1106 CVContext.reset(new CodeViewContext(this));
1107 return *CVContext;
1108 }
1109
1110 //===----------------------------------------------------------------------===//
1111 // Error Reporting
1112 //===----------------------------------------------------------------------===//
1113
diagnose(const SMDiagnostic & SMD)1114 void MCContext::diagnose(const SMDiagnostic &SMD) {
1115 assert(DiagHandler && "MCContext::DiagHandler is not set");
1116 bool UseInlineSrcMgr = false;
1117 const SourceMgr *SMP = nullptr;
1118 if (SrcMgr) {
1119 SMP = SrcMgr;
1120 } else if (InlineSrcMgr) {
1121 SMP = InlineSrcMgr.get();
1122 UseInlineSrcMgr = true;
1123 } else
1124 llvm_unreachable("Either SourceMgr should be available");
1125 DiagHandler(SMD, UseInlineSrcMgr, *SMP, LocInfos);
1126 }
1127
reportCommon(SMLoc Loc,std::function<void (SMDiagnostic &,const SourceMgr *)> GetMessage)1128 void MCContext::reportCommon(
1129 SMLoc Loc,
1130 std::function<void(SMDiagnostic &, const SourceMgr *)> GetMessage) {
1131 // * MCContext::SrcMgr is null when the MC layer emits machine code for input
1132 // other than assembly file, say, for .c/.cpp/.ll/.bc.
1133 // * MCContext::InlineSrcMgr is null when the inline asm is not used.
1134 // * A default SourceMgr is needed for diagnosing when both MCContext::SrcMgr
1135 // and MCContext::InlineSrcMgr are null.
1136 SourceMgr SM;
1137 const SourceMgr *SMP = &SM;
1138 bool UseInlineSrcMgr = false;
1139
1140 // FIXME: Simplify these by combining InlineSrcMgr & SrcMgr.
1141 // For MC-only execution, only SrcMgr is used;
1142 // For non MC-only execution, InlineSrcMgr is only ctor'd if there is
1143 // inline asm in the IR.
1144 if (Loc.isValid()) {
1145 if (SrcMgr) {
1146 SMP = SrcMgr;
1147 } else if (InlineSrcMgr) {
1148 SMP = InlineSrcMgr.get();
1149 UseInlineSrcMgr = true;
1150 } else
1151 llvm_unreachable("Either SourceMgr should be available");
1152 }
1153
1154 SMDiagnostic D;
1155 GetMessage(D, SMP);
1156 DiagHandler(D, UseInlineSrcMgr, *SMP, LocInfos);
1157 }
1158
reportError(SMLoc Loc,const Twine & Msg)1159 void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
1160 HadError = true;
1161 reportCommon(Loc, [&](SMDiagnostic &D, const SourceMgr *SMP) {
1162 D = SMP->GetMessage(Loc, SourceMgr::DK_Error, Msg);
1163 });
1164 }
1165
reportWarning(SMLoc Loc,const Twine & Msg)1166 void MCContext::reportWarning(SMLoc Loc, const Twine &Msg) {
1167 if (TargetOptions && TargetOptions->MCNoWarn)
1168 return;
1169 if (TargetOptions && TargetOptions->MCFatalWarnings) {
1170 reportError(Loc, Msg);
1171 } else {
1172 reportCommon(Loc, [&](SMDiagnostic &D, const SourceMgr *SMP) {
1173 D = SMP->GetMessage(Loc, SourceMgr::DK_Warning, Msg);
1174 });
1175 }
1176 }
1177