[AMDGPU] prevent shrinking udiv/urem if either operand is in (SignedMax,UnsignedMax...
[llvm-project.git] / llvm / lib / MC / MCContext.cpp
blob46222fcaa5b152b372e3cfa977430e6c107f52e7
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 //===----------------------------------------------------------------------===//
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/Wasm.h"
18 #include "llvm/BinaryFormat/XCOFF.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCCodeView.h"
21 #include "llvm/MC/MCDwarf.h"
22 #include "llvm/MC/MCExpr.h"
23 #include "llvm/MC/MCFragment.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>
59 using namespace llvm;
61 static void defaultDiagHandler(const SMDiagnostic &SMD, bool, const SourceMgr &,
62 std::vector<const MDNode *> &) {
63 SMD.print(nullptr, errs());
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 SecureLogFile = TargetOptions ? TargetOptions->AsSecureLogFile : "";
79 if (SrcMgr && SrcMgr->getNumBuffers())
80 MainFileName = std::string(SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())
81 ->getBufferIdentifier());
83 switch (TheTriple.getObjectFormat()) {
84 case Triple::MachO:
85 Env = IsMachO;
86 break;
87 case Triple::COFF:
88 if (!TheTriple.isOSWindows() && !TheTriple.isUEFI())
89 report_fatal_error(
90 "Cannot initialize MC for non-Windows COFF object files.");
92 Env = IsCOFF;
93 break;
94 case Triple::ELF:
95 Env = IsELF;
96 break;
97 case Triple::Wasm:
98 Env = IsWasm;
99 break;
100 case Triple::XCOFF:
101 Env = IsXCOFF;
102 break;
103 case Triple::GOFF:
104 Env = IsGOFF;
105 break;
106 case Triple::DXContainer:
107 Env = IsDXContainer;
108 break;
109 case Triple::SPIRV:
110 Env = IsSPIRV;
111 break;
112 case Triple::UnknownObjectFormat:
113 report_fatal_error("Cannot initialize MC for unknown object file format.");
114 break;
118 MCContext::~MCContext() {
119 if (AutoReset)
120 reset();
122 // NOTE: The symbols are all allocated out of a bump pointer allocator,
123 // we don't need to free them here.
126 void MCContext::initInlineSourceManager() {
127 if (!InlineSrcMgr)
128 InlineSrcMgr.reset(new SourceMgr());
131 //===----------------------------------------------------------------------===//
132 // Module Lifetime Management
133 //===----------------------------------------------------------------------===//
135 void MCContext::reset() {
136 SrcMgr = nullptr;
137 InlineSrcMgr.reset();
138 LocInfos.clear();
139 DiagHandler = defaultDiagHandler;
141 // Call the destructors so the fragments are freed
142 COFFAllocator.DestroyAll();
143 DXCAllocator.DestroyAll();
144 ELFAllocator.DestroyAll();
145 GOFFAllocator.DestroyAll();
146 MachOAllocator.DestroyAll();
147 WasmAllocator.DestroyAll();
148 XCOFFAllocator.DestroyAll();
149 MCInstAllocator.DestroyAll();
150 SPIRVAllocator.DestroyAll();
151 WasmSignatureAllocator.DestroyAll();
153 // ~CodeViewContext may destroy a MCFragment outside of sections and need to
154 // be reset before FragmentAllocator.
155 CVContext.reset();
157 MCSubtargetAllocator.DestroyAll();
158 InlineAsmUsedLabelNames.clear();
159 Symbols.clear();
160 Allocator.Reset();
161 FragmentAllocator.Reset();
162 Instances.clear();
163 CompilationDir.clear();
164 MainFileName.clear();
165 MCDwarfLineTablesCUMap.clear();
166 SectionsForRanges.clear();
167 MCGenDwarfLabelEntries.clear();
168 DwarfDebugFlags = StringRef();
169 DwarfCompileUnitID = 0;
170 CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0);
172 MachOUniquingMap.clear();
173 ELFUniquingMap.clear();
174 GOFFUniquingMap.clear();
175 COFFUniquingMap.clear();
176 WasmUniquingMap.clear();
177 XCOFFUniquingMap.clear();
178 DXCUniquingMap.clear();
180 ELFEntrySizeMap.clear();
181 ELFSeenGenericMergeableSections.clear();
183 DwarfLocSeen = false;
184 GenDwarfForAssembly = false;
185 GenDwarfFileNumber = 0;
187 HadError = false;
190 //===----------------------------------------------------------------------===//
191 // MCInst Management
192 //===----------------------------------------------------------------------===//
194 MCInst *MCContext::createMCInst() {
195 return new (MCInstAllocator.Allocate()) MCInst;
198 // Allocate the initial MCDataFragment for the begin symbol.
199 MCDataFragment *MCContext::allocInitialFragment(MCSection &Sec) {
200 assert(!Sec.curFragList()->Head);
201 auto *F = allocFragment<MCDataFragment>();
202 F->setParent(&Sec);
203 Sec.curFragList()->Head = F;
204 Sec.curFragList()->Tail = F;
205 return F;
208 //===----------------------------------------------------------------------===//
209 // Symbol Manipulation
210 //===----------------------------------------------------------------------===//
212 MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) {
213 SmallString<128> NameSV;
214 StringRef NameRef = Name.toStringRef(NameSV);
216 assert(!NameRef.empty() && "Normal symbols cannot be unnamed!");
218 MCSymbolTableEntry &Entry = getSymbolTableEntry(NameRef);
219 if (!Entry.second.Symbol) {
220 bool IsRenamable = NameRef.starts_with(MAI->getPrivateGlobalPrefix());
221 bool IsTemporary = IsRenamable && !SaveTempLabels;
222 if (!Entry.second.Used) {
223 Entry.second.Used = true;
224 Entry.second.Symbol = createSymbolImpl(&Entry, IsTemporary);
225 } else {
226 assert(IsRenamable && "cannot rename non-private symbol");
227 // Slow path: we need to rename a temp symbol from the user.
228 Entry.second.Symbol = createRenamableSymbol(NameRef, false, IsTemporary);
232 return Entry.second.Symbol;
235 MCSymbol *MCContext::getOrCreateFrameAllocSymbol(const Twine &FuncName,
236 unsigned Idx) {
237 return getOrCreateSymbol(MAI->getPrivateGlobalPrefix() + FuncName +
238 "$frame_escape_" + Twine(Idx));
241 MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(const Twine &FuncName) {
242 return getOrCreateSymbol(MAI->getPrivateGlobalPrefix() + FuncName +
243 "$parent_frame_offset");
246 MCSymbol *MCContext::getOrCreateLSDASymbol(const Twine &FuncName) {
247 return getOrCreateSymbol(MAI->getPrivateGlobalPrefix() + "__ehtable$" +
248 FuncName);
251 MCSymbolTableEntry &MCContext::getSymbolTableEntry(StringRef Name) {
252 return *Symbols.try_emplace(Name, MCSymbolTableValue{}).first;
255 MCSymbol *MCContext::createSymbolImpl(const MCSymbolTableEntry *Name,
256 bool IsTemporary) {
257 static_assert(std::is_trivially_destructible<MCSymbolCOFF>(),
258 "MCSymbol classes must be trivially destructible");
259 static_assert(std::is_trivially_destructible<MCSymbolELF>(),
260 "MCSymbol classes must be trivially destructible");
261 static_assert(std::is_trivially_destructible<MCSymbolMachO>(),
262 "MCSymbol classes must be trivially destructible");
263 static_assert(std::is_trivially_destructible<MCSymbolWasm>(),
264 "MCSymbol classes must be trivially destructible");
265 static_assert(std::is_trivially_destructible<MCSymbolXCOFF>(),
266 "MCSymbol classes must be trivially destructible");
268 switch (getObjectFileType()) {
269 case MCContext::IsCOFF:
270 return new (Name, *this) MCSymbolCOFF(Name, IsTemporary);
271 case MCContext::IsELF:
272 return new (Name, *this) MCSymbolELF(Name, IsTemporary);
273 case MCContext::IsGOFF:
274 return new (Name, *this) MCSymbolGOFF(Name, IsTemporary);
275 case MCContext::IsMachO:
276 return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
277 case MCContext::IsWasm:
278 return new (Name, *this) MCSymbolWasm(Name, IsTemporary);
279 case MCContext::IsXCOFF:
280 return createXCOFFSymbolImpl(Name, IsTemporary);
281 case MCContext::IsDXContainer:
282 break;
283 case MCContext::IsSPIRV:
284 return new (Name, *this)
285 MCSymbol(MCSymbol::SymbolKindUnset, Name, IsTemporary);
287 return new (Name, *this)
288 MCSymbol(MCSymbol::SymbolKindUnset, Name, IsTemporary);
291 MCSymbol *MCContext::createRenamableSymbol(const Twine &Name,
292 bool AlwaysAddSuffix,
293 bool IsTemporary) {
294 SmallString<128> NewName;
295 Name.toVector(NewName);
296 size_t NameLen = NewName.size();
298 MCSymbolTableEntry &NameEntry = getSymbolTableEntry(NewName.str());
299 MCSymbolTableEntry *EntryPtr = &NameEntry;
300 while (AlwaysAddSuffix || EntryPtr->second.Used) {
301 AlwaysAddSuffix = false;
303 NewName.resize(NameLen);
304 raw_svector_ostream(NewName) << NameEntry.second.NextUniqueID++;
305 EntryPtr = &getSymbolTableEntry(NewName.str());
308 EntryPtr->second.Used = true;
309 return createSymbolImpl(EntryPtr, IsTemporary);
312 MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix) {
313 if (!UseNamesOnTempLabels)
314 return createSymbolImpl(nullptr, /*IsTemporary=*/true);
315 return createRenamableSymbol(MAI->getPrivateGlobalPrefix() + Name,
316 AlwaysAddSuffix, /*IsTemporary=*/true);
319 MCSymbol *MCContext::createNamedTempSymbol(const Twine &Name) {
320 return createRenamableSymbol(MAI->getPrivateGlobalPrefix() + Name, true,
321 /*IsTemporary=*/!SaveTempLabels);
324 MCSymbol *MCContext::createBlockSymbol(const Twine &Name, bool AlwaysEmit) {
325 if (AlwaysEmit)
326 return getOrCreateSymbol(MAI->getPrivateLabelPrefix() + Name);
328 bool IsTemporary = !SaveTempLabels;
329 if (IsTemporary && !UseNamesOnTempLabels)
330 return createSymbolImpl(nullptr, IsTemporary);
331 return createRenamableSymbol(MAI->getPrivateLabelPrefix() + Name,
332 /*AlwaysAddSuffix=*/false, IsTemporary);
335 MCSymbol *MCContext::createLinkerPrivateTempSymbol() {
336 return createLinkerPrivateSymbol("tmp");
339 MCSymbol *MCContext::createLinkerPrivateSymbol(const Twine &Name) {
340 return createRenamableSymbol(MAI->getLinkerPrivateGlobalPrefix() + Name,
341 /*AlwaysAddSuffix=*/true,
342 /*IsTemporary=*/false);
345 MCSymbol *MCContext::createTempSymbol() { return createTempSymbol("tmp"); }
347 MCSymbol *MCContext::createNamedTempSymbol() {
348 return createNamedTempSymbol("tmp");
351 MCSymbol *MCContext::createLocalSymbol(StringRef Name) {
352 MCSymbolTableEntry &NameEntry = getSymbolTableEntry(Name);
353 return createSymbolImpl(&NameEntry, /*IsTemporary=*/false);
356 unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
357 MCLabel *&Label = Instances[LocalLabelVal];
358 if (!Label)
359 Label = new (*this) MCLabel(0);
360 return Label->incInstance();
363 unsigned MCContext::GetInstance(unsigned LocalLabelVal) {
364 MCLabel *&Label = Instances[LocalLabelVal];
365 if (!Label)
366 Label = new (*this) MCLabel(0);
367 return Label->getInstance();
370 MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
371 unsigned Instance) {
372 MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)];
373 if (!Sym)
374 Sym = createNamedTempSymbol();
375 return Sym;
378 MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) {
379 unsigned Instance = NextInstance(LocalLabelVal);
380 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
383 MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal,
384 bool Before) {
385 unsigned Instance = GetInstance(LocalLabelVal);
386 if (!Before)
387 ++Instance;
388 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
391 template <typename Symbol>
392 Symbol *MCContext::getOrCreateSectionSymbol(StringRef Section) {
393 Symbol *R;
394 auto &SymEntry = getSymbolTableEntry(Section);
395 MCSymbol *Sym = SymEntry.second.Symbol;
396 // A section symbol can not redefine regular symbols. There may be multiple
397 // sections with the same name, in which case the first such section wins.
398 if (Sym && Sym->isDefined() &&
399 (!Sym->isInSection() || Sym->getSection().getBeginSymbol() != Sym))
400 reportError(SMLoc(), "invalid symbol redefinition");
401 if (Sym && Sym->isUndefined()) {
402 R = cast<Symbol>(Sym);
403 } else {
404 SymEntry.second.Used = true;
405 R = new (&SymEntry, *this) Symbol(&SymEntry, /*isTemporary=*/false);
406 if (!Sym)
407 SymEntry.second.Symbol = R;
409 return R;
412 MCSymbol *MCContext::lookupSymbol(const Twine &Name) const {
413 SmallString<128> NameSV;
414 StringRef NameRef = Name.toStringRef(NameSV);
415 return Symbols.lookup(NameRef).Symbol;
418 void MCContext::setSymbolValue(MCStreamer &Streamer, const Twine &Sym,
419 uint64_t Val) {
420 auto Symbol = getOrCreateSymbol(Sym);
421 Streamer.emitAssignment(Symbol, MCConstantExpr::create(Val, *this));
424 void MCContext::registerInlineAsmLabel(MCSymbol *Sym) {
425 InlineAsmUsedLabelNames[Sym->getName()] = Sym;
428 wasm::WasmSignature *MCContext::createWasmSignature() {
429 return new (WasmSignatureAllocator.Allocate()) wasm::WasmSignature;
432 MCSymbolXCOFF *MCContext::createXCOFFSymbolImpl(const MCSymbolTableEntry *Name,
433 bool IsTemporary) {
434 if (!Name)
435 return new (nullptr, *this) MCSymbolXCOFF(nullptr, IsTemporary);
437 StringRef OriginalName = Name->first();
438 if (OriginalName.starts_with("._Renamed..") ||
439 OriginalName.starts_with("_Renamed.."))
440 reportError(SMLoc(), "invalid symbol name from source");
442 if (MAI->isValidUnquotedName(OriginalName))
443 return new (Name, *this) MCSymbolXCOFF(Name, IsTemporary);
445 // Now we have a name that contains invalid character(s) for XCOFF symbol.
446 // Let's replace with something valid, but save the original name so that
447 // we could still use the original name in the symbol table.
448 SmallString<128> InvalidName(OriginalName);
450 // If it's an entry point symbol, we will keep the '.'
451 // in front for the convention purpose. Otherwise, add "_Renamed.."
452 // as prefix to signal this is an renamed symbol.
453 const bool IsEntryPoint = InvalidName.starts_with(".");
454 SmallString<128> ValidName =
455 StringRef(IsEntryPoint ? "._Renamed.." : "_Renamed..");
457 // Append the hex values of '_' and invalid characters with "_Renamed..";
458 // at the same time replace invalid characters with '_'.
459 for (size_t I = 0; I < InvalidName.size(); ++I) {
460 if (!MAI->isAcceptableChar(InvalidName[I]) || InvalidName[I] == '_') {
461 raw_svector_ostream(ValidName).write_hex(InvalidName[I]);
462 InvalidName[I] = '_';
466 // Skip entry point symbol's '.' as we already have a '.' in front of
467 // "_Renamed".
468 if (IsEntryPoint)
469 ValidName.append(InvalidName.substr(1, InvalidName.size() - 1));
470 else
471 ValidName.append(InvalidName);
473 MCSymbolTableEntry &NameEntry = getSymbolTableEntry(ValidName.str());
474 assert(!NameEntry.second.Used && "This name is used somewhere else.");
475 NameEntry.second.Used = true;
476 // Have the MCSymbol object itself refer to the copy of the string
477 // that is embedded in the symbol table entry.
478 MCSymbolXCOFF *XSym =
479 new (&NameEntry, *this) MCSymbolXCOFF(&NameEntry, IsTemporary);
480 XSym->setSymbolTableName(MCSymbolXCOFF::getUnqualifiedName(OriginalName));
481 return XSym;
484 //===----------------------------------------------------------------------===//
485 // Section Management
486 //===----------------------------------------------------------------------===//
488 MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
489 unsigned TypeAndAttributes,
490 unsigned Reserved2, SectionKind Kind,
491 const char *BeginSymName) {
492 // We unique sections by their segment/section pair. The returned section
493 // may not have the same flags as the requested section, if so this should be
494 // diagnosed by the client as an error.
496 // Form the name to look up.
497 assert(Section.size() <= 16 && "section name is too long");
498 assert(!memchr(Section.data(), '\0', Section.size()) &&
499 "section name cannot contain NUL");
501 // Do the lookup, if we have a hit, return it.
502 auto R = MachOUniquingMap.try_emplace((Segment + Twine(',') + Section).str());
503 if (!R.second)
504 return R.first->second;
506 MCSymbol *Begin = nullptr;
507 if (BeginSymName)
508 Begin = createTempSymbol(BeginSymName, false);
510 // Otherwise, return a new section.
511 StringRef Name = R.first->first();
512 auto *Ret = new (MachOAllocator.Allocate())
513 MCSectionMachO(Segment, Name.substr(Name.size() - Section.size()),
514 TypeAndAttributes, Reserved2, Kind, Begin);
515 R.first->second = Ret;
516 allocInitialFragment(*Ret);
517 return Ret;
520 MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
521 unsigned Flags,
522 unsigned EntrySize,
523 const MCSymbolELF *Group,
524 bool Comdat, unsigned UniqueID,
525 const MCSymbolELF *LinkedToSym) {
526 auto *R = getOrCreateSectionSymbol<MCSymbolELF>(Section);
527 R->setBinding(ELF::STB_LOCAL);
528 R->setType(ELF::STT_SECTION);
530 auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF(
531 Section, Type, Flags, EntrySize, Group, Comdat, UniqueID, R, LinkedToSym);
533 auto *F = allocInitialFragment(*Ret);
534 R->setFragment(F);
535 return Ret;
538 MCSectionELF *
539 MCContext::createELFRelSection(const Twine &Name, unsigned Type, unsigned Flags,
540 unsigned EntrySize, const MCSymbolELF *Group,
541 const MCSectionELF *RelInfoSection) {
542 StringMap<bool>::iterator I;
543 bool Inserted;
544 std::tie(I, Inserted) = RelSecNames.insert(std::make_pair(Name.str(), true));
546 return createELFSectionImpl(
547 I->getKey(), Type, Flags, EntrySize, Group, true, true,
548 cast<MCSymbolELF>(RelInfoSection->getBeginSymbol()));
551 MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
552 const Twine &Suffix, unsigned Type,
553 unsigned Flags,
554 unsigned EntrySize) {
555 return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix,
556 /*IsComdat=*/true);
559 MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
560 unsigned Flags, unsigned EntrySize,
561 const Twine &Group, bool IsComdat,
562 unsigned UniqueID,
563 const MCSymbolELF *LinkedToSym) {
564 MCSymbolELF *GroupSym = nullptr;
565 if (!Group.isTriviallyEmpty() && !Group.str().empty())
566 GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
568 return getELFSection(Section, Type, Flags, EntrySize, GroupSym, IsComdat,
569 UniqueID, LinkedToSym);
572 MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
573 unsigned Flags, unsigned EntrySize,
574 const MCSymbolELF *GroupSym,
575 bool IsComdat, unsigned UniqueID,
576 const MCSymbolELF *LinkedToSym) {
577 StringRef Group = "";
578 if (GroupSym)
579 Group = GroupSym->getName();
580 assert(!(LinkedToSym && LinkedToSym->getName().empty()));
582 // Sections are differentiated by the quadruple (section_name, group_name,
583 // unique_id, link_to_symbol_name). Sections sharing the same quadruple are
584 // combined into one section. As an optimization, non-unique sections without
585 // group or linked-to symbol have a shorter unique-ing key.
586 std::pair<StringMap<MCSectionELF *>::iterator, bool> EntryNewPair;
587 // Length of the section name, which are the first SectionLen bytes of the key
588 unsigned SectionLen;
589 if (GroupSym || LinkedToSym || UniqueID != MCSection::NonUniqueID) {
590 SmallString<128> Buffer;
591 Section.toVector(Buffer);
592 SectionLen = Buffer.size();
593 Buffer.push_back(0); // separator which cannot occur in the name
594 if (GroupSym)
595 Buffer.append(GroupSym->getName());
596 Buffer.push_back(0); // separator which cannot occur in the name
597 if (LinkedToSym)
598 Buffer.append(LinkedToSym->getName());
599 support::endian::write(Buffer, UniqueID, endianness::native);
600 StringRef UniqueMapKey = StringRef(Buffer);
601 EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));
602 } else if (!Section.isSingleStringRef()) {
603 SmallString<128> Buffer;
604 StringRef UniqueMapKey = Section.toStringRef(Buffer);
605 SectionLen = UniqueMapKey.size();
606 EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));
607 } else {
608 StringRef UniqueMapKey = Section.getSingleStringRef();
609 SectionLen = UniqueMapKey.size();
610 EntryNewPair = ELFUniquingMap.insert(std::make_pair(UniqueMapKey, nullptr));
613 if (!EntryNewPair.second)
614 return EntryNewPair.first->second;
616 StringRef CachedName = EntryNewPair.first->getKey().take_front(SectionLen);
618 MCSectionELF *Result =
619 createELFSectionImpl(CachedName, Type, Flags, EntrySize, GroupSym,
620 IsComdat, UniqueID, LinkedToSym);
621 EntryNewPair.first->second = Result;
623 recordELFMergeableSectionInfo(Result->getName(), Result->getFlags(),
624 Result->getUniqueID(), Result->getEntrySize());
626 return Result;
629 MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group,
630 bool IsComdat) {
631 return createELFSectionImpl(".group", ELF::SHT_GROUP, 0, 4, Group, IsComdat,
632 MCSection::NonUniqueID, nullptr);
635 void MCContext::recordELFMergeableSectionInfo(StringRef SectionName,
636 unsigned Flags, unsigned UniqueID,
637 unsigned EntrySize) {
638 bool IsMergeable = Flags & ELF::SHF_MERGE;
639 if (UniqueID == GenericSectionID) {
640 ELFSeenGenericMergeableSections.insert(SectionName);
641 // Minor performance optimization: avoid hash map lookup in
642 // isELFGenericMergeableSection, which will return true for SectionName.
643 IsMergeable = true;
646 // For mergeable sections or non-mergeable sections with a generic mergeable
647 // section name we enter their Unique ID into the ELFEntrySizeMap so that
648 // compatible globals can be assigned to the same section.
650 if (IsMergeable || isELFGenericMergeableSection(SectionName)) {
651 ELFEntrySizeMap.insert(std::make_pair(
652 std::make_tuple(SectionName, Flags, EntrySize), UniqueID));
656 bool MCContext::isELFImplicitMergeableSectionNamePrefix(StringRef SectionName) {
657 return SectionName.starts_with(".rodata.str") ||
658 SectionName.starts_with(".rodata.cst");
661 bool MCContext::isELFGenericMergeableSection(StringRef SectionName) {
662 return isELFImplicitMergeableSectionNamePrefix(SectionName) ||
663 ELFSeenGenericMergeableSections.count(SectionName);
666 std::optional<unsigned>
667 MCContext::getELFUniqueIDForEntsize(StringRef SectionName, unsigned Flags,
668 unsigned EntrySize) {
669 auto I = ELFEntrySizeMap.find(std::make_tuple(SectionName, Flags, EntrySize));
670 return (I != ELFEntrySizeMap.end()) ? std::optional<unsigned>(I->second)
671 : std::nullopt;
674 MCSectionGOFF *MCContext::getGOFFSection(StringRef Section, SectionKind Kind,
675 MCSection *Parent,
676 uint32_t Subsection) {
677 // Do the lookup. If we don't have a hit, return a new section.
678 auto IterBool =
679 GOFFUniquingMap.insert(std::make_pair(Section.str(), nullptr));
680 auto Iter = IterBool.first;
681 if (!IterBool.second)
682 return Iter->second;
684 StringRef CachedName = Iter->first;
685 MCSectionGOFF *GOFFSection = new (GOFFAllocator.Allocate())
686 MCSectionGOFF(CachedName, Kind, Parent, Subsection);
687 Iter->second = GOFFSection;
688 allocInitialFragment(*GOFFSection);
689 return GOFFSection;
692 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
693 unsigned Characteristics,
694 StringRef COMDATSymName, int Selection,
695 unsigned UniqueID) {
696 MCSymbol *COMDATSymbol = nullptr;
697 if (!COMDATSymName.empty()) {
698 COMDATSymbol = getOrCreateSymbol(COMDATSymName);
699 assert(COMDATSymbol && "COMDATSymbol is null");
700 COMDATSymName = COMDATSymbol->getName();
701 // A non-associative COMDAT is considered to define the COMDAT symbol. Check
702 // the redefinition error.
703 if (Selection != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE &&
704 COMDATSymbol->isDefined() &&
705 (!COMDATSymbol->isInSection() ||
706 cast<MCSectionCOFF>(COMDATSymbol->getSection()).getCOMDATSymbol() !=
707 COMDATSymbol))
708 reportError(SMLoc(), "invalid symbol redefinition");
711 // Do the lookup, if we have a hit, return it.
712 COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID};
713 auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));
714 auto Iter = IterBool.first;
715 if (!IterBool.second)
716 return Iter->second;
718 StringRef CachedName = Iter->first.SectionName;
719 MCSymbol *Begin = getOrCreateSectionSymbol<MCSymbolCOFF>(Section);
720 MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
721 CachedName, Characteristics, COMDATSymbol, Selection, Begin);
722 Iter->second = Result;
723 auto *F = allocInitialFragment(*Result);
724 Begin->setFragment(F);
725 return Result;
728 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
729 unsigned Characteristics) {
730 return getCOFFSection(Section, Characteristics, "", 0, GenericSectionID);
733 MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
734 const MCSymbol *KeySym,
735 unsigned UniqueID) {
736 // Return the normal section if we don't have to be associative or unique.
737 if (!KeySym && UniqueID == GenericSectionID)
738 return Sec;
740 // If we have a key symbol, make an associative section with the same name and
741 // kind as the normal section.
742 unsigned Characteristics = Sec->getCharacteristics();
743 if (KeySym) {
744 Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
745 return getCOFFSection(Sec->getName(), Characteristics, KeySym->getName(),
746 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
749 return getCOFFSection(Sec->getName(), Characteristics, "", 0, UniqueID);
752 MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind K,
753 unsigned Flags, const Twine &Group,
754 unsigned UniqueID) {
755 MCSymbolWasm *GroupSym = nullptr;
756 if (!Group.isTriviallyEmpty() && !Group.str().empty()) {
757 GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group));
758 GroupSym->setComdat(true);
759 if (K.isMetadata() && !GroupSym->getType().has_value()) {
760 // Comdat group symbol associated with a custom section is a section
761 // symbol (not a data symbol).
762 GroupSym->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
766 return getWasmSection(Section, K, Flags, GroupSym, UniqueID);
769 MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
770 unsigned Flags,
771 const MCSymbolWasm *GroupSym,
772 unsigned UniqueID) {
773 StringRef Group = "";
774 if (GroupSym)
775 Group = GroupSym->getName();
776 // Do the lookup, if we have a hit, return it.
777 auto IterBool = WasmUniquingMap.insert(
778 std::make_pair(WasmSectionKey{Section.str(), Group, UniqueID}, nullptr));
779 auto &Entry = *IterBool.first;
780 if (!IterBool.second)
781 return Entry.second;
783 StringRef CachedName = Entry.first.SectionName;
785 MCSymbol *Begin = createRenamableSymbol(CachedName, true, false);
786 // Begin always has a different name than CachedName... see #48596.
787 getSymbolTableEntry(Begin->getName()).second.Symbol = Begin;
788 cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
790 MCSectionWasm *Result = new (WasmAllocator.Allocate())
791 MCSectionWasm(CachedName, Kind, Flags, GroupSym, UniqueID, Begin);
792 Entry.second = Result;
794 auto *F = allocInitialFragment(*Result);
795 Begin->setFragment(F);
796 return Result;
799 bool MCContext::hasXCOFFSection(StringRef Section,
800 XCOFF::CsectProperties CsectProp) const {
801 return XCOFFUniquingMap.count(
802 XCOFFSectionKey(Section.str(), CsectProp.MappingClass)) != 0;
805 MCSectionXCOFF *MCContext::getXCOFFSection(
806 StringRef Section, SectionKind Kind,
807 std::optional<XCOFF::CsectProperties> CsectProp, bool MultiSymbolsAllowed,
808 std::optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSectionSubtypeFlags) {
809 bool IsDwarfSec = DwarfSectionSubtypeFlags.has_value();
810 assert((IsDwarfSec != CsectProp.has_value()) && "Invalid XCOFF section!");
812 // Do the lookup. If we have a hit, return it.
813 auto IterBool = XCOFFUniquingMap.insert(std::make_pair(
814 IsDwarfSec ? XCOFFSectionKey(Section.str(), *DwarfSectionSubtypeFlags)
815 : XCOFFSectionKey(Section.str(), CsectProp->MappingClass),
816 nullptr));
817 auto &Entry = *IterBool.first;
818 if (!IterBool.second) {
819 MCSectionXCOFF *ExistedEntry = Entry.second;
820 if (ExistedEntry->isMultiSymbolsAllowed() != MultiSymbolsAllowed)
821 report_fatal_error("section's multiply symbols policy does not match");
823 return ExistedEntry;
826 // Otherwise, return a new section.
827 StringRef CachedName = Entry.first.SectionName;
828 MCSymbolXCOFF *QualName = nullptr;
829 // Debug section don't have storage class attribute.
830 if (IsDwarfSec)
831 QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(CachedName));
832 else
833 QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(
834 CachedName + "[" +
835 XCOFF::getMappingClassString(CsectProp->MappingClass) + "]"));
837 // QualName->getUnqualifiedName() and CachedName are the same except when
838 // CachedName contains invalid character(s) such as '$' for an XCOFF symbol.
839 MCSectionXCOFF *Result = nullptr;
840 if (IsDwarfSec)
841 Result = new (XCOFFAllocator.Allocate()) MCSectionXCOFF(
842 QualName->getUnqualifiedName(), Kind, QualName,
843 *DwarfSectionSubtypeFlags, QualName, CachedName, MultiSymbolsAllowed);
844 else
845 Result = new (XCOFFAllocator.Allocate())
846 MCSectionXCOFF(QualName->getUnqualifiedName(), CsectProp->MappingClass,
847 CsectProp->Type, Kind, QualName, nullptr, CachedName,
848 MultiSymbolsAllowed);
850 Entry.second = Result;
852 auto *F = allocInitialFragment(*Result);
854 // We might miss calculating the symbols difference as absolute value before
855 // adding fixups when symbol_A without the fragment set is the csect itself
856 // and symbol_B is in it.
857 // TODO: Currently we only set the fragment for XMC_PR csects and DWARF
858 // sections because we don't have other cases that hit this problem yet.
859 if (IsDwarfSec || CsectProp->MappingClass == XCOFF::XMC_PR)
860 QualName->setFragment(F);
862 return Result;
865 MCSectionSPIRV *MCContext::getSPIRVSection() {
866 MCSectionSPIRV *Result = new (SPIRVAllocator.Allocate()) MCSectionSPIRV();
868 allocInitialFragment(*Result);
869 return Result;
872 MCSectionDXContainer *MCContext::getDXContainerSection(StringRef Section,
873 SectionKind K) {
874 // Do the lookup, if we have a hit, return it.
875 auto ItInsertedPair = DXCUniquingMap.try_emplace(Section);
876 if (!ItInsertedPair.second)
877 return ItInsertedPair.first->second;
879 auto MapIt = ItInsertedPair.first;
880 // Grab the name from the StringMap. Since the Section is going to keep a
881 // copy of this StringRef we need to make sure the underlying string stays
882 // alive as long as we need it.
883 StringRef Name = MapIt->first();
884 MapIt->second =
885 new (DXCAllocator.Allocate()) MCSectionDXContainer(Name, K, nullptr);
887 // The first fragment will store the header
888 allocInitialFragment(*MapIt->second);
889 return MapIt->second;
892 MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
893 return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
896 void MCContext::addDebugPrefixMapEntry(const std::string &From,
897 const std::string &To) {
898 DebugPrefixMap.emplace_back(From, To);
901 void MCContext::remapDebugPath(SmallVectorImpl<char> &Path) {
902 for (const auto &[From, To] : llvm::reverse(DebugPrefixMap))
903 if (llvm::sys::path::replace_path_prefix(Path, From, To))
904 break;
907 void MCContext::RemapDebugPaths() {
908 const auto &DebugPrefixMap = this->DebugPrefixMap;
909 if (DebugPrefixMap.empty())
910 return;
912 // Remap compilation directory.
913 remapDebugPath(CompilationDir);
915 // Remap MCDwarfDirs and RootFile.Name in all compilation units.
916 SmallString<256> P;
917 for (auto &CUIDTablePair : MCDwarfLineTablesCUMap) {
918 for (auto &Dir : CUIDTablePair.second.getMCDwarfDirs()) {
919 P = Dir;
920 remapDebugPath(P);
921 Dir = std::string(P);
924 // Used by DW_TAG_compile_unit's DT_AT_name and DW_TAG_label's
925 // DW_AT_decl_file for DWARF v5 generated for assembly source.
926 P = CUIDTablePair.second.getRootFile().Name;
927 remapDebugPath(P);
928 CUIDTablePair.second.getRootFile().Name = std::string(P);
932 //===----------------------------------------------------------------------===//
933 // Dwarf Management
934 //===----------------------------------------------------------------------===//
936 EmitDwarfUnwindType MCContext::emitDwarfUnwindInfo() const {
937 if (!TargetOptions)
938 return EmitDwarfUnwindType::Default;
939 return TargetOptions->EmitDwarfUnwind;
942 bool MCContext::emitCompactUnwindNonCanonical() const {
943 if (TargetOptions)
944 return TargetOptions->EmitCompactUnwindNonCanonical;
945 return false;
948 void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) {
949 // MCDwarf needs the root file as well as the compilation directory.
950 // If we find a '.file 0' directive that will supersede these values.
951 std::optional<MD5::MD5Result> Cksum;
952 if (getDwarfVersion() >= 5) {
953 MD5 Hash;
954 MD5::MD5Result Sum;
955 Hash.update(Buffer);
956 Hash.final(Sum);
957 Cksum = Sum;
959 // Canonicalize the root filename. It cannot be empty, and should not
960 // repeat the compilation dir.
961 // The MCContext ctor initializes MainFileName to the name associated with
962 // the SrcMgr's main file ID, which might be the same as InputFileName (and
963 // possibly include directory components).
964 // Or, MainFileName might have been overridden by a -main-file-name option,
965 // which is supposed to be just a base filename with no directory component.
966 // So, if the InputFileName and MainFileName are not equal, assume
967 // MainFileName is a substitute basename and replace the last component.
968 SmallString<1024> FileNameBuf = InputFileName;
969 if (FileNameBuf.empty() || FileNameBuf == "-")
970 FileNameBuf = "<stdin>";
971 if (!getMainFileName().empty() && FileNameBuf != getMainFileName()) {
972 llvm::sys::path::remove_filename(FileNameBuf);
973 llvm::sys::path::append(FileNameBuf, getMainFileName());
975 StringRef FileName = FileNameBuf;
976 if (FileName.consume_front(getCompilationDir()))
977 if (llvm::sys::path::is_separator(FileName.front()))
978 FileName = FileName.drop_front();
979 assert(!FileName.empty());
980 setMCLineTableRootFile(
981 /*CUID=*/0, getCompilationDir(), FileName, Cksum, std::nullopt);
984 /// getDwarfFile - takes a file name and number to place in the dwarf file and
985 /// directory tables. If the file number has already been allocated it is an
986 /// error and zero is returned and the client reports the error, else the
987 /// allocated file number is returned. The file numbers may be in any order.
988 Expected<unsigned>
989 MCContext::getDwarfFile(StringRef Directory, StringRef FileName,
990 unsigned FileNumber,
991 std::optional<MD5::MD5Result> Checksum,
992 std::optional<StringRef> Source, unsigned CUID) {
993 MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
994 return Table.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
995 FileNumber);
998 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
999 /// currently is assigned and false otherwise.
1000 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
1001 const MCDwarfLineTable &LineTable = getMCDwarfLineTable(CUID);
1002 if (FileNumber == 0)
1003 return getDwarfVersion() >= 5;
1004 if (FileNumber >= LineTable.getMCDwarfFiles().size())
1005 return false;
1007 return !LineTable.getMCDwarfFiles()[FileNumber].Name.empty();
1010 /// Remove empty sections from SectionsForRanges, to avoid generating
1011 /// useless debug info for them.
1012 void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
1013 SectionsForRanges.remove_if(
1014 [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); });
1017 CodeViewContext &MCContext::getCVContext() {
1018 if (!CVContext)
1019 CVContext.reset(new CodeViewContext(this));
1020 return *CVContext;
1023 //===----------------------------------------------------------------------===//
1024 // Error Reporting
1025 //===----------------------------------------------------------------------===//
1027 void MCContext::diagnose(const SMDiagnostic &SMD) {
1028 assert(DiagHandler && "MCContext::DiagHandler is not set");
1029 bool UseInlineSrcMgr = false;
1030 const SourceMgr *SMP = nullptr;
1031 if (SrcMgr) {
1032 SMP = SrcMgr;
1033 } else if (InlineSrcMgr) {
1034 SMP = InlineSrcMgr.get();
1035 UseInlineSrcMgr = true;
1036 } else
1037 llvm_unreachable("Either SourceMgr should be available");
1038 DiagHandler(SMD, UseInlineSrcMgr, *SMP, LocInfos);
1041 void MCContext::reportCommon(
1042 SMLoc Loc,
1043 std::function<void(SMDiagnostic &, const SourceMgr *)> GetMessage) {
1044 // * MCContext::SrcMgr is null when the MC layer emits machine code for input
1045 // other than assembly file, say, for .c/.cpp/.ll/.bc.
1046 // * MCContext::InlineSrcMgr is null when the inline asm is not used.
1047 // * A default SourceMgr is needed for diagnosing when both MCContext::SrcMgr
1048 // and MCContext::InlineSrcMgr are null.
1049 SourceMgr SM;
1050 const SourceMgr *SMP = &SM;
1051 bool UseInlineSrcMgr = false;
1053 // FIXME: Simplify these by combining InlineSrcMgr & SrcMgr.
1054 // For MC-only execution, only SrcMgr is used;
1055 // For non MC-only execution, InlineSrcMgr is only ctor'd if there is
1056 // inline asm in the IR.
1057 if (Loc.isValid()) {
1058 if (SrcMgr) {
1059 SMP = SrcMgr;
1060 } else if (InlineSrcMgr) {
1061 SMP = InlineSrcMgr.get();
1062 UseInlineSrcMgr = true;
1063 } else
1064 llvm_unreachable("Either SourceMgr should be available");
1067 SMDiagnostic D;
1068 GetMessage(D, SMP);
1069 DiagHandler(D, UseInlineSrcMgr, *SMP, LocInfos);
1072 void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
1073 HadError = true;
1074 reportCommon(Loc, [&](SMDiagnostic &D, const SourceMgr *SMP) {
1075 D = SMP->GetMessage(Loc, SourceMgr::DK_Error, Msg);
1079 void MCContext::reportWarning(SMLoc Loc, const Twine &Msg) {
1080 if (TargetOptions && TargetOptions->MCNoWarn)
1081 return;
1082 if (TargetOptions && TargetOptions->MCFatalWarnings) {
1083 reportError(Loc, Msg);
1084 } else {
1085 reportCommon(Loc, [&](SMDiagnostic &D, const SourceMgr *SMP) {
1086 D = SMP->GetMessage(Loc, SourceMgr::DK_Warning, Msg);