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/Optional.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/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/MCLabel.h"
25 #include "llvm/MC/MCObjectFileInfo.h"
26 #include "llvm/MC/MCSectionCOFF.h"
27 #include "llvm/MC/MCSectionELF.h"
28 #include "llvm/MC/MCSectionMachO.h"
29 #include "llvm/MC/MCSectionWasm.h"
30 #include "llvm/MC/MCSectionXCOFF.h"
31 #include "llvm/MC/MCStreamer.h"
32 #include "llvm/MC/MCSymbol.h"
33 #include "llvm/MC/MCSymbolCOFF.h"
34 #include "llvm/MC/MCSymbolELF.h"
35 #include "llvm/MC/MCSymbolMachO.h"
36 #include "llvm/MC/MCSymbolWasm.h"
37 #include "llvm/MC/MCSymbolXCOFF.h"
38 #include "llvm/MC/SectionKind.h"
39 #include "llvm/Support/Casting.h"
40 #include "llvm/Support/CommandLine.h"
41 #include "llvm/Support/ErrorHandling.h"
42 #include "llvm/Support/MemoryBuffer.h"
43 #include "llvm/Support/Path.h"
44 #include "llvm/Support/Signals.h"
45 #include "llvm/Support/SourceMgr.h"
46 #include "llvm/Support/raw_ostream.h"
47 #include <cassert>
48 #include <cstdlib>
49 #include <tuple>
50 #include <utility>
51
52 using namespace llvm;
53
54 static cl::opt<char*>
55 AsSecureLogFileName("as-secure-log-file-name",
56 cl::desc("As secure log file name (initialized from "
57 "AS_SECURE_LOG_FILE env variable)"),
58 cl::init(getenv("AS_SECURE_LOG_FILE")), cl::Hidden);
59
MCContext(const MCAsmInfo * mai,const MCRegisterInfo * mri,const MCObjectFileInfo * mofi,const SourceMgr * mgr,MCTargetOptions const * TargetOpts,bool DoAutoReset)60 MCContext::MCContext(const MCAsmInfo *mai, const MCRegisterInfo *mri,
61 const MCObjectFileInfo *mofi, const SourceMgr *mgr,
62 MCTargetOptions const *TargetOpts, bool DoAutoReset)
63 : SrcMgr(mgr), InlineSrcMgr(nullptr), MAI(mai), MRI(mri), MOFI(mofi),
64 Symbols(Allocator), UsedNames(Allocator),
65 InlineAsmUsedLabelNames(Allocator),
66 CurrentDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0),
67 AutoReset(DoAutoReset), TargetOptions(TargetOpts) {
68 SecureLogFile = AsSecureLogFileName;
69
70 if (SrcMgr && SrcMgr->getNumBuffers())
71 MainFileName = std::string(SrcMgr->getMemoryBuffer(SrcMgr->getMainFileID())
72 ->getBufferIdentifier());
73 }
74
~MCContext()75 MCContext::~MCContext() {
76 if (AutoReset)
77 reset();
78
79 // NOTE: The symbols are all allocated out of a bump pointer allocator,
80 // we don't need to free them here.
81 }
82
83 //===----------------------------------------------------------------------===//
84 // Module Lifetime Management
85 //===----------------------------------------------------------------------===//
86
reset()87 void MCContext::reset() {
88 // Call the destructors so the fragments are freed
89 COFFAllocator.DestroyAll();
90 ELFAllocator.DestroyAll();
91 MachOAllocator.DestroyAll();
92 XCOFFAllocator.DestroyAll();
93 MCInstAllocator.DestroyAll();
94
95 MCSubtargetAllocator.DestroyAll();
96 InlineAsmUsedLabelNames.clear();
97 UsedNames.clear();
98 Symbols.clear();
99 Allocator.Reset();
100 Instances.clear();
101 CompilationDir.clear();
102 MainFileName.clear();
103 MCDwarfLineTablesCUMap.clear();
104 SectionsForRanges.clear();
105 MCGenDwarfLabelEntries.clear();
106 DwarfDebugFlags = StringRef();
107 DwarfCompileUnitID = 0;
108 CurrentDwarfLoc = MCDwarfLoc(0, 0, 0, DWARF2_FLAG_IS_STMT, 0, 0);
109
110 CVContext.reset();
111
112 MachOUniquingMap.clear();
113 ELFUniquingMap.clear();
114 COFFUniquingMap.clear();
115 WasmUniquingMap.clear();
116 XCOFFUniquingMap.clear();
117
118 ELFEntrySizeMap.clear();
119 ELFSeenGenericMergeableSections.clear();
120
121 NextID.clear();
122 AllowTemporaryLabels = true;
123 DwarfLocSeen = false;
124 GenDwarfForAssembly = false;
125 GenDwarfFileNumber = 0;
126
127 HadError = false;
128 }
129
130 //===----------------------------------------------------------------------===//
131 // MCInst Management
132 //===----------------------------------------------------------------------===//
133
createMCInst()134 MCInst *MCContext::createMCInst() {
135 return new (MCInstAllocator.Allocate()) MCInst;
136 }
137
138 //===----------------------------------------------------------------------===//
139 // Symbol Manipulation
140 //===----------------------------------------------------------------------===//
141
getOrCreateSymbol(const Twine & Name)142 MCSymbol *MCContext::getOrCreateSymbol(const Twine &Name) {
143 SmallString<128> NameSV;
144 StringRef NameRef = Name.toStringRef(NameSV);
145
146 assert(!NameRef.empty() && "Normal symbols cannot be unnamed!");
147
148 MCSymbol *&Sym = Symbols[NameRef];
149 if (!Sym)
150 Sym = createSymbol(NameRef, false, false);
151
152 return Sym;
153 }
154
getOrCreateFrameAllocSymbol(StringRef FuncName,unsigned Idx)155 MCSymbol *MCContext::getOrCreateFrameAllocSymbol(StringRef FuncName,
156 unsigned Idx) {
157 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
158 "$frame_escape_" + Twine(Idx));
159 }
160
getOrCreateParentFrameOffsetSymbol(StringRef FuncName)161 MCSymbol *MCContext::getOrCreateParentFrameOffsetSymbol(StringRef FuncName) {
162 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + FuncName +
163 "$parent_frame_offset");
164 }
165
getOrCreateLSDASymbol(StringRef FuncName)166 MCSymbol *MCContext::getOrCreateLSDASymbol(StringRef FuncName) {
167 return getOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) + "__ehtable$" +
168 FuncName);
169 }
170
createSymbolImpl(const StringMapEntry<bool> * Name,bool IsTemporary)171 MCSymbol *MCContext::createSymbolImpl(const StringMapEntry<bool> *Name,
172 bool IsTemporary) {
173 static_assert(std::is_trivially_destructible<MCSymbolCOFF>(),
174 "MCSymbol classes must be trivially destructible");
175 static_assert(std::is_trivially_destructible<MCSymbolELF>(),
176 "MCSymbol classes must be trivially destructible");
177 static_assert(std::is_trivially_destructible<MCSymbolMachO>(),
178 "MCSymbol classes must be trivially destructible");
179 static_assert(std::is_trivially_destructible<MCSymbolWasm>(),
180 "MCSymbol classes must be trivially destructible");
181 static_assert(std::is_trivially_destructible<MCSymbolXCOFF>(),
182 "MCSymbol classes must be trivially destructible");
183 if (MOFI) {
184 switch (MOFI->getObjectFileType()) {
185 case MCObjectFileInfo::IsCOFF:
186 return new (Name, *this) MCSymbolCOFF(Name, IsTemporary);
187 case MCObjectFileInfo::IsELF:
188 return new (Name, *this) MCSymbolELF(Name, IsTemporary);
189 case MCObjectFileInfo::IsMachO:
190 return new (Name, *this) MCSymbolMachO(Name, IsTemporary);
191 case MCObjectFileInfo::IsWasm:
192 return new (Name, *this) MCSymbolWasm(Name, IsTemporary);
193 case MCObjectFileInfo::IsXCOFF:
194 return createXCOFFSymbolImpl(Name, IsTemporary);
195 }
196 }
197 return new (Name, *this) MCSymbol(MCSymbol::SymbolKindUnset, Name,
198 IsTemporary);
199 }
200
createSymbol(StringRef Name,bool AlwaysAddSuffix,bool CanBeUnnamed)201 MCSymbol *MCContext::createSymbol(StringRef Name, bool AlwaysAddSuffix,
202 bool CanBeUnnamed) {
203 if (CanBeUnnamed && !UseNamesOnTempLabels)
204 return createSymbolImpl(nullptr, true);
205
206 // Determine whether this is a user written assembler temporary or normal
207 // label, if used.
208 bool IsTemporary = CanBeUnnamed;
209 if (AllowTemporaryLabels && !IsTemporary)
210 IsTemporary = Name.startswith(MAI->getPrivateGlobalPrefix());
211
212 SmallString<128> NewName = Name;
213 bool AddSuffix = AlwaysAddSuffix;
214 unsigned &NextUniqueID = NextID[Name];
215 while (true) {
216 if (AddSuffix) {
217 NewName.resize(Name.size());
218 raw_svector_ostream(NewName) << NextUniqueID++;
219 }
220 auto NameEntry = UsedNames.insert(std::make_pair(NewName, true));
221 if (NameEntry.second || !NameEntry.first->second) {
222 // Ok, we found a name.
223 // Mark it as used for a non-section symbol.
224 NameEntry.first->second = true;
225 // Have the MCSymbol object itself refer to the copy of the string that is
226 // embedded in the UsedNames entry.
227 return createSymbolImpl(&*NameEntry.first, IsTemporary);
228 }
229 assert(IsTemporary && "Cannot rename non-temporary symbols");
230 AddSuffix = true;
231 }
232 llvm_unreachable("Infinite loop");
233 }
234
createTempSymbol(const Twine & Name,bool AlwaysAddSuffix)235 MCSymbol *MCContext::createTempSymbol(const Twine &Name, bool AlwaysAddSuffix) {
236 SmallString<128> NameSV;
237 raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name;
238 return createSymbol(NameSV, AlwaysAddSuffix, true);
239 }
240
createNamedTempSymbol(const Twine & Name)241 MCSymbol *MCContext::createNamedTempSymbol(const Twine &Name) {
242 SmallString<128> NameSV;
243 raw_svector_ostream(NameSV) << MAI->getPrivateGlobalPrefix() << Name;
244 return createSymbol(NameSV, true, false);
245 }
246
createLinkerPrivateTempSymbol()247 MCSymbol *MCContext::createLinkerPrivateTempSymbol() {
248 SmallString<128> NameSV;
249 raw_svector_ostream(NameSV) << MAI->getLinkerPrivateGlobalPrefix() << "tmp";
250 return createSymbol(NameSV, true, false);
251 }
252
createTempSymbol()253 MCSymbol *MCContext::createTempSymbol() { return createTempSymbol("tmp"); }
254
createNamedTempSymbol()255 MCSymbol *MCContext::createNamedTempSymbol() {
256 return createNamedTempSymbol("tmp");
257 }
258
NextInstance(unsigned LocalLabelVal)259 unsigned MCContext::NextInstance(unsigned LocalLabelVal) {
260 MCLabel *&Label = Instances[LocalLabelVal];
261 if (!Label)
262 Label = new (*this) MCLabel(0);
263 return Label->incInstance();
264 }
265
GetInstance(unsigned LocalLabelVal)266 unsigned MCContext::GetInstance(unsigned LocalLabelVal) {
267 MCLabel *&Label = Instances[LocalLabelVal];
268 if (!Label)
269 Label = new (*this) MCLabel(0);
270 return Label->getInstance();
271 }
272
getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,unsigned Instance)273 MCSymbol *MCContext::getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
274 unsigned Instance) {
275 MCSymbol *&Sym = LocalSymbols[std::make_pair(LocalLabelVal, Instance)];
276 if (!Sym)
277 Sym = createNamedTempSymbol();
278 return Sym;
279 }
280
createDirectionalLocalSymbol(unsigned LocalLabelVal)281 MCSymbol *MCContext::createDirectionalLocalSymbol(unsigned LocalLabelVal) {
282 unsigned Instance = NextInstance(LocalLabelVal);
283 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
284 }
285
getDirectionalLocalSymbol(unsigned LocalLabelVal,bool Before)286 MCSymbol *MCContext::getDirectionalLocalSymbol(unsigned LocalLabelVal,
287 bool Before) {
288 unsigned Instance = GetInstance(LocalLabelVal);
289 if (!Before)
290 ++Instance;
291 return getOrCreateDirectionalLocalSymbol(LocalLabelVal, Instance);
292 }
293
lookupSymbol(const Twine & Name) const294 MCSymbol *MCContext::lookupSymbol(const Twine &Name) const {
295 SmallString<128> NameSV;
296 StringRef NameRef = Name.toStringRef(NameSV);
297 return Symbols.lookup(NameRef);
298 }
299
setSymbolValue(MCStreamer & Streamer,StringRef Sym,uint64_t Val)300 void MCContext::setSymbolValue(MCStreamer &Streamer,
301 StringRef Sym,
302 uint64_t Val) {
303 auto Symbol = getOrCreateSymbol(Sym);
304 Streamer.emitAssignment(Symbol, MCConstantExpr::create(Val, *this));
305 }
306
registerInlineAsmLabel(MCSymbol * Sym)307 void MCContext::registerInlineAsmLabel(MCSymbol *Sym) {
308 InlineAsmUsedLabelNames[Sym->getName()] = Sym;
309 }
310
311 MCSymbolXCOFF *
createXCOFFSymbolImpl(const StringMapEntry<bool> * Name,bool IsTemporary)312 MCContext::createXCOFFSymbolImpl(const StringMapEntry<bool> *Name,
313 bool IsTemporary) {
314 if (!Name)
315 return new (nullptr, *this) MCSymbolXCOFF(nullptr, IsTemporary);
316
317 StringRef OriginalName = Name->first();
318 if (OriginalName.startswith("._Renamed..") ||
319 OriginalName.startswith("_Renamed.."))
320 reportError(SMLoc(), "invalid symbol name from source");
321
322 if (MAI->isValidUnquotedName(OriginalName))
323 return new (Name, *this) MCSymbolXCOFF(Name, IsTemporary);
324
325 // Now we have a name that contains invalid character(s) for XCOFF symbol.
326 // Let's replace with something valid, but save the original name so that
327 // we could still use the original name in the symbol table.
328 SmallString<128> InvalidName(OriginalName);
329
330 // If it's an entry point symbol, we will keep the '.'
331 // in front for the convention purpose. Otherwise, add "_Renamed.."
332 // as prefix to signal this is an renamed symbol.
333 const bool IsEntryPoint = !InvalidName.empty() && InvalidName[0] == '.';
334 SmallString<128> ValidName =
335 StringRef(IsEntryPoint ? "._Renamed.." : "_Renamed..");
336
337 // Append the hex values of '_' and invalid characters with "_Renamed..";
338 // at the same time replace invalid characters with '_'.
339 for (size_t I = 0; I < InvalidName.size(); ++I) {
340 if (!MAI->isAcceptableChar(InvalidName[I]) || InvalidName[I] == '_') {
341 raw_svector_ostream(ValidName).write_hex(InvalidName[I]);
342 InvalidName[I] = '_';
343 }
344 }
345
346 // Skip entry point symbol's '.' as we already have a '.' in front of
347 // "_Renamed".
348 if (IsEntryPoint)
349 ValidName.append(InvalidName.substr(1, InvalidName.size() - 1));
350 else
351 ValidName.append(InvalidName);
352
353 auto NameEntry = UsedNames.insert(std::make_pair(ValidName, true));
354 assert((NameEntry.second || !NameEntry.first->second) &&
355 "This name is used somewhere else.");
356 // Mark the name as used for a non-section symbol.
357 NameEntry.first->second = true;
358 // Have the MCSymbol object itself refer to the copy of the string
359 // that is embedded in the UsedNames entry.
360 MCSymbolXCOFF *XSym = new (&*NameEntry.first, *this)
361 MCSymbolXCOFF(&*NameEntry.first, IsTemporary);
362 XSym->setSymbolTableName(MCSymbolXCOFF::getUnqualifiedName(OriginalName));
363 return XSym;
364 }
365
366 //===----------------------------------------------------------------------===//
367 // Section Management
368 //===----------------------------------------------------------------------===//
369
getMachOSection(StringRef Segment,StringRef Section,unsigned TypeAndAttributes,unsigned Reserved2,SectionKind Kind,const char * BeginSymName)370 MCSectionMachO *MCContext::getMachOSection(StringRef Segment, StringRef Section,
371 unsigned TypeAndAttributes,
372 unsigned Reserved2, SectionKind Kind,
373 const char *BeginSymName) {
374 // We unique sections by their segment/section pair. The returned section
375 // may not have the same flags as the requested section, if so this should be
376 // diagnosed by the client as an error.
377
378 // Form the name to look up.
379 assert(Section.size() <= 16 && "section name is too long");
380 assert(!memchr(Section.data(), '\0', Section.size()) &&
381 "section name cannot contain NUL");
382
383 // Do the lookup, if we have a hit, return it.
384 auto R = MachOUniquingMap.try_emplace((Segment + Twine(',') + Section).str());
385 if (!R.second)
386 return R.first->second;
387
388 MCSymbol *Begin = nullptr;
389 if (BeginSymName)
390 Begin = createTempSymbol(BeginSymName, false);
391
392 // Otherwise, return a new section.
393 StringRef Name = R.first->first();
394 R.first->second = new (MachOAllocator.Allocate())
395 MCSectionMachO(Segment, Name.substr(Name.size() - Section.size()),
396 TypeAndAttributes, Reserved2, Kind, Begin);
397 return R.first->second;
398 }
399
renameELFSection(MCSectionELF * Section,StringRef Name)400 void MCContext::renameELFSection(MCSectionELF *Section, StringRef Name) {
401 StringRef GroupName;
402 if (const MCSymbol *Group = Section->getGroup())
403 GroupName = Group->getName();
404
405 // This function is only used by .debug*, which should not have the
406 // SHF_LINK_ORDER flag.
407 unsigned UniqueID = Section->getUniqueID();
408 ELFUniquingMap.erase(
409 ELFSectionKey{Section->getName(), GroupName, "", UniqueID});
410 auto I = ELFUniquingMap
411 .insert(std::make_pair(
412 ELFSectionKey{Name, GroupName, "", UniqueID}, Section))
413 .first;
414 StringRef CachedName = I->first.SectionName;
415 const_cast<MCSectionELF *>(Section)->setSectionName(CachedName);
416 }
417
createELFSectionImpl(StringRef Section,unsigned Type,unsigned Flags,SectionKind K,unsigned EntrySize,const MCSymbolELF * Group,unsigned UniqueID,const MCSymbolELF * LinkedToSym)418 MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type,
419 unsigned Flags, SectionKind K,
420 unsigned EntrySize,
421 const MCSymbolELF *Group,
422 unsigned UniqueID,
423 const MCSymbolELF *LinkedToSym) {
424 MCSymbolELF *R;
425 MCSymbol *&Sym = Symbols[Section];
426 // A section symbol can not redefine regular symbols. There may be multiple
427 // sections with the same name, in which case the first such section wins.
428 if (Sym && Sym->isDefined() &&
429 (!Sym->isInSection() || Sym->getSection().getBeginSymbol() != Sym))
430 reportError(SMLoc(), "invalid symbol redefinition");
431 if (Sym && Sym->isUndefined()) {
432 R = cast<MCSymbolELF>(Sym);
433 } else {
434 auto NameIter = UsedNames.insert(std::make_pair(Section, false)).first;
435 R = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false);
436 if (!Sym)
437 Sym = R;
438 }
439 R->setBinding(ELF::STB_LOCAL);
440 R->setType(ELF::STT_SECTION);
441
442 auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF(
443 Section, Type, Flags, K, EntrySize, Group, UniqueID, R, LinkedToSym);
444
445 auto *F = new MCDataFragment();
446 Ret->getFragmentList().insert(Ret->begin(), F);
447 F->setParent(Ret);
448 R->setFragment(F);
449
450 return Ret;
451 }
452
createELFRelSection(const Twine & Name,unsigned Type,unsigned Flags,unsigned EntrySize,const MCSymbolELF * Group,const MCSectionELF * RelInfoSection)453 MCSectionELF *MCContext::createELFRelSection(const Twine &Name, unsigned Type,
454 unsigned Flags, unsigned EntrySize,
455 const MCSymbolELF *Group,
456 const MCSectionELF *RelInfoSection) {
457 StringMap<bool>::iterator I;
458 bool Inserted;
459 std::tie(I, Inserted) =
460 RelSecNames.insert(std::make_pair(Name.str(), true));
461
462 return createELFSectionImpl(
463 I->getKey(), Type, Flags, SectionKind::getReadOnly(), EntrySize, Group,
464 true, cast<MCSymbolELF>(RelInfoSection->getBeginSymbol()));
465 }
466
getELFNamedSection(const Twine & Prefix,const Twine & Suffix,unsigned Type,unsigned Flags,unsigned EntrySize)467 MCSectionELF *MCContext::getELFNamedSection(const Twine &Prefix,
468 const Twine &Suffix, unsigned Type,
469 unsigned Flags,
470 unsigned EntrySize) {
471 return getELFSection(Prefix + "." + Suffix, Type, Flags, EntrySize, Suffix);
472 }
473
getELFSection(const Twine & Section,unsigned Type,unsigned Flags,unsigned EntrySize,const Twine & Group,unsigned UniqueID,const MCSymbolELF * LinkedToSym)474 MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
475 unsigned Flags, unsigned EntrySize,
476 const Twine &Group, unsigned UniqueID,
477 const MCSymbolELF *LinkedToSym) {
478 MCSymbolELF *GroupSym = nullptr;
479 if (!Group.isTriviallyEmpty() && !Group.str().empty())
480 GroupSym = cast<MCSymbolELF>(getOrCreateSymbol(Group));
481
482 return getELFSection(Section, Type, Flags, EntrySize, GroupSym, UniqueID,
483 LinkedToSym);
484 }
485
getELFSection(const Twine & Section,unsigned Type,unsigned Flags,unsigned EntrySize,const MCSymbolELF * GroupSym,unsigned UniqueID,const MCSymbolELF * LinkedToSym)486 MCSectionELF *MCContext::getELFSection(const Twine &Section, unsigned Type,
487 unsigned Flags, unsigned EntrySize,
488 const MCSymbolELF *GroupSym,
489 unsigned UniqueID,
490 const MCSymbolELF *LinkedToSym) {
491 StringRef Group = "";
492 if (GroupSym)
493 Group = GroupSym->getName();
494 assert(!(LinkedToSym && LinkedToSym->getName().empty()));
495 // Do the lookup, if we have a hit, return it.
496 auto IterBool = ELFUniquingMap.insert(std::make_pair(
497 ELFSectionKey{Section.str(), Group,
498 LinkedToSym ? LinkedToSym->getName() : "", UniqueID},
499 nullptr));
500 auto &Entry = *IterBool.first;
501 if (!IterBool.second)
502 return Entry.second;
503
504 StringRef CachedName = Entry.first.SectionName;
505
506 SectionKind Kind;
507 if (Flags & ELF::SHF_ARM_PURECODE)
508 Kind = SectionKind::getExecuteOnly();
509 else if (Flags & ELF::SHF_EXECINSTR)
510 Kind = SectionKind::getText();
511 else
512 Kind = SectionKind::getReadOnly();
513
514 MCSectionELF *Result =
515 createELFSectionImpl(CachedName, Type, Flags, Kind, EntrySize, GroupSym,
516 UniqueID, LinkedToSym);
517 Entry.second = Result;
518
519 recordELFMergeableSectionInfo(Result->getName(), Result->getFlags(),
520 Result->getUniqueID(), Result->getEntrySize());
521
522 return Result;
523 }
524
createELFGroupSection(const MCSymbolELF * Group)525 MCSectionELF *MCContext::createELFGroupSection(const MCSymbolELF *Group) {
526 return createELFSectionImpl(".group", ELF::SHT_GROUP, 0,
527 SectionKind::getReadOnly(), 4, Group,
528 MCSection::NonUniqueID, nullptr);
529 }
530
recordELFMergeableSectionInfo(StringRef SectionName,unsigned Flags,unsigned UniqueID,unsigned EntrySize)531 void MCContext::recordELFMergeableSectionInfo(StringRef SectionName,
532 unsigned Flags, unsigned UniqueID,
533 unsigned EntrySize) {
534 bool IsMergeable = Flags & ELF::SHF_MERGE;
535 if (IsMergeable && (UniqueID == GenericSectionID))
536 ELFSeenGenericMergeableSections.insert(SectionName);
537
538 // For mergeable sections or non-mergeable sections with a generic mergeable
539 // section name we enter their Unique ID into the ELFEntrySizeMap so that
540 // compatible globals can be assigned to the same section.
541 if (IsMergeable || isELFGenericMergeableSection(SectionName)) {
542 ELFEntrySizeMap.insert(std::make_pair(
543 ELFEntrySizeKey{SectionName, Flags, EntrySize}, UniqueID));
544 }
545 }
546
isELFImplicitMergeableSectionNamePrefix(StringRef SectionName)547 bool MCContext::isELFImplicitMergeableSectionNamePrefix(StringRef SectionName) {
548 return SectionName.startswith(".rodata.str") ||
549 SectionName.startswith(".rodata.cst");
550 }
551
isELFGenericMergeableSection(StringRef SectionName)552 bool MCContext::isELFGenericMergeableSection(StringRef SectionName) {
553 return isELFImplicitMergeableSectionNamePrefix(SectionName) ||
554 ELFSeenGenericMergeableSections.count(SectionName);
555 }
556
getELFUniqueIDForEntsize(StringRef SectionName,unsigned Flags,unsigned EntrySize)557 Optional<unsigned> MCContext::getELFUniqueIDForEntsize(StringRef SectionName,
558 unsigned Flags,
559 unsigned EntrySize) {
560 auto I = ELFEntrySizeMap.find(
561 MCContext::ELFEntrySizeKey{SectionName, Flags, EntrySize});
562 return (I != ELFEntrySizeMap.end()) ? Optional<unsigned>(I->second) : None;
563 }
564
getCOFFSection(StringRef Section,unsigned Characteristics,SectionKind Kind,StringRef COMDATSymName,int Selection,unsigned UniqueID,const char * BeginSymName)565 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
566 unsigned Characteristics,
567 SectionKind Kind,
568 StringRef COMDATSymName, int Selection,
569 unsigned UniqueID,
570 const char *BeginSymName) {
571 MCSymbol *COMDATSymbol = nullptr;
572 if (!COMDATSymName.empty()) {
573 COMDATSymbol = getOrCreateSymbol(COMDATSymName);
574 COMDATSymName = COMDATSymbol->getName();
575 }
576
577
578 // Do the lookup, if we have a hit, return it.
579 COFFSectionKey T{Section, COMDATSymName, Selection, UniqueID};
580 auto IterBool = COFFUniquingMap.insert(std::make_pair(T, nullptr));
581 auto Iter = IterBool.first;
582 if (!IterBool.second)
583 return Iter->second;
584
585 MCSymbol *Begin = nullptr;
586 if (BeginSymName)
587 Begin = createTempSymbol(BeginSymName, false);
588
589 StringRef CachedName = Iter->first.SectionName;
590 MCSectionCOFF *Result = new (COFFAllocator.Allocate()) MCSectionCOFF(
591 CachedName, Characteristics, COMDATSymbol, Selection, Kind, Begin);
592
593 Iter->second = Result;
594 return Result;
595 }
596
getCOFFSection(StringRef Section,unsigned Characteristics,SectionKind Kind,const char * BeginSymName)597 MCSectionCOFF *MCContext::getCOFFSection(StringRef Section,
598 unsigned Characteristics,
599 SectionKind Kind,
600 const char *BeginSymName) {
601 return getCOFFSection(Section, Characteristics, Kind, "", 0, GenericSectionID,
602 BeginSymName);
603 }
604
getAssociativeCOFFSection(MCSectionCOFF * Sec,const MCSymbol * KeySym,unsigned UniqueID)605 MCSectionCOFF *MCContext::getAssociativeCOFFSection(MCSectionCOFF *Sec,
606 const MCSymbol *KeySym,
607 unsigned UniqueID) {
608 // Return the normal section if we don't have to be associative or unique.
609 if (!KeySym && UniqueID == GenericSectionID)
610 return Sec;
611
612 // If we have a key symbol, make an associative section with the same name and
613 // kind as the normal section.
614 unsigned Characteristics = Sec->getCharacteristics();
615 if (KeySym) {
616 Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT;
617 return getCOFFSection(Sec->getName(), Characteristics, Sec->getKind(),
618 KeySym->getName(),
619 COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE, UniqueID);
620 }
621
622 return getCOFFSection(Sec->getName(), Characteristics, Sec->getKind(), "", 0,
623 UniqueID);
624 }
625
getWasmSection(const Twine & Section,SectionKind K,const Twine & Group,unsigned UniqueID,const char * BeginSymName)626 MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind K,
627 const Twine &Group, unsigned UniqueID,
628 const char *BeginSymName) {
629 MCSymbolWasm *GroupSym = nullptr;
630 if (!Group.isTriviallyEmpty() && !Group.str().empty()) {
631 GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group));
632 GroupSym->setComdat(true);
633 }
634
635 return getWasmSection(Section, K, GroupSym, UniqueID, BeginSymName);
636 }
637
getWasmSection(const Twine & Section,SectionKind Kind,const MCSymbolWasm * GroupSym,unsigned UniqueID,const char * BeginSymName)638 MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind Kind,
639 const MCSymbolWasm *GroupSym,
640 unsigned UniqueID,
641 const char *BeginSymName) {
642 StringRef Group = "";
643 if (GroupSym)
644 Group = GroupSym->getName();
645 // Do the lookup, if we have a hit, return it.
646 auto IterBool = WasmUniquingMap.insert(
647 std::make_pair(WasmSectionKey{Section.str(), Group, UniqueID}, nullptr));
648 auto &Entry = *IterBool.first;
649 if (!IterBool.second)
650 return Entry.second;
651
652 StringRef CachedName = Entry.first.SectionName;
653
654 MCSymbol *Begin = createSymbol(CachedName, true, false);
655 cast<MCSymbolWasm>(Begin)->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
656
657 MCSectionWasm *Result = new (WasmAllocator.Allocate())
658 MCSectionWasm(CachedName, Kind, GroupSym, UniqueID, Begin);
659 Entry.second = Result;
660
661 auto *F = new MCDataFragment();
662 Result->getFragmentList().insert(Result->begin(), F);
663 F->setParent(Result);
664 Begin->setFragment(F);
665
666 return Result;
667 }
668
669 MCSectionXCOFF *
getXCOFFSection(StringRef Section,XCOFF::StorageMappingClass SMC,XCOFF::SymbolType Type,SectionKind Kind,bool MultiSymbolsAllowed,const char * BeginSymName)670 MCContext::getXCOFFSection(StringRef Section, XCOFF::StorageMappingClass SMC,
671 XCOFF::SymbolType Type, SectionKind Kind,
672 bool MultiSymbolsAllowed, const char *BeginSymName) {
673 // Do the lookup. If we have a hit, return it.
674 auto IterBool = XCOFFUniquingMap.insert(
675 std::make_pair(XCOFFSectionKey{Section.str(), SMC}, nullptr));
676 auto &Entry = *IterBool.first;
677 if (!IterBool.second) {
678 MCSectionXCOFF *ExistedEntry = Entry.second;
679 if (ExistedEntry->isMultiSymbolsAllowed() != MultiSymbolsAllowed)
680 report_fatal_error("section's multiply symbols policy does not match");
681
682 return ExistedEntry;
683 }
684
685 // Otherwise, return a new section.
686 StringRef CachedName = Entry.first.SectionName;
687 MCSymbolXCOFF *QualName = cast<MCSymbolXCOFF>(getOrCreateSymbol(
688 CachedName + "[" + XCOFF::getMappingClassString(SMC) + "]"));
689
690 MCSymbol *Begin = nullptr;
691 if (BeginSymName)
692 Begin = createTempSymbol(BeginSymName, false);
693
694 // QualName->getUnqualifiedName() and CachedName are the same except when
695 // CachedName contains invalid character(s) such as '$' for an XCOFF symbol.
696 MCSectionXCOFF *Result = new (XCOFFAllocator.Allocate())
697 MCSectionXCOFF(QualName->getUnqualifiedName(), SMC, Type, Kind, QualName,
698 Begin, CachedName, MultiSymbolsAllowed);
699 Entry.second = Result;
700
701 auto *F = new MCDataFragment();
702 Result->getFragmentList().insert(Result->begin(), F);
703 F->setParent(Result);
704
705 if (Begin)
706 Begin->setFragment(F);
707
708 return Result;
709 }
710
getSubtargetCopy(const MCSubtargetInfo & STI)711 MCSubtargetInfo &MCContext::getSubtargetCopy(const MCSubtargetInfo &STI) {
712 return *new (MCSubtargetAllocator.Allocate()) MCSubtargetInfo(STI);
713 }
714
addDebugPrefixMapEntry(const std::string & From,const std::string & To)715 void MCContext::addDebugPrefixMapEntry(const std::string &From,
716 const std::string &To) {
717 DebugPrefixMap.insert(std::make_pair(From, To));
718 }
719
RemapDebugPaths()720 void MCContext::RemapDebugPaths() {
721 const auto &DebugPrefixMap = this->DebugPrefixMap;
722 if (DebugPrefixMap.empty())
723 return;
724
725 const auto RemapDebugPath = [&DebugPrefixMap](std::string &Path) {
726 SmallString<256> P(Path);
727 for (const auto &Entry : DebugPrefixMap) {
728 if (llvm::sys::path::replace_path_prefix(P, Entry.first, Entry.second)) {
729 Path = P.str().str();
730 break;
731 }
732 }
733 };
734
735 // Remap compilation directory.
736 std::string CompDir = std::string(CompilationDir.str());
737 RemapDebugPath(CompDir);
738 CompilationDir = CompDir;
739
740 // Remap MCDwarfDirs in all compilation units.
741 for (auto &CUIDTablePair : MCDwarfLineTablesCUMap)
742 for (auto &Dir : CUIDTablePair.second.getMCDwarfDirs())
743 RemapDebugPath(Dir);
744 }
745
746 //===----------------------------------------------------------------------===//
747 // Dwarf Management
748 //===----------------------------------------------------------------------===//
749
setGenDwarfRootFile(StringRef InputFileName,StringRef Buffer)750 void MCContext::setGenDwarfRootFile(StringRef InputFileName, StringRef Buffer) {
751 // MCDwarf needs the root file as well as the compilation directory.
752 // If we find a '.file 0' directive that will supersede these values.
753 Optional<MD5::MD5Result> Cksum;
754 if (getDwarfVersion() >= 5) {
755 MD5 Hash;
756 MD5::MD5Result Sum;
757 Hash.update(Buffer);
758 Hash.final(Sum);
759 Cksum = Sum;
760 }
761 // Canonicalize the root filename. It cannot be empty, and should not
762 // repeat the compilation dir.
763 // The MCContext ctor initializes MainFileName to the name associated with
764 // the SrcMgr's main file ID, which might be the same as InputFileName (and
765 // possibly include directory components).
766 // Or, MainFileName might have been overridden by a -main-file-name option,
767 // which is supposed to be just a base filename with no directory component.
768 // So, if the InputFileName and MainFileName are not equal, assume
769 // MainFileName is a substitute basename and replace the last component.
770 SmallString<1024> FileNameBuf = InputFileName;
771 if (FileNameBuf.empty() || FileNameBuf == "-")
772 FileNameBuf = "<stdin>";
773 if (!getMainFileName().empty() && FileNameBuf != getMainFileName()) {
774 llvm::sys::path::remove_filename(FileNameBuf);
775 llvm::sys::path::append(FileNameBuf, getMainFileName());
776 }
777 StringRef FileName = FileNameBuf;
778 if (FileName.consume_front(getCompilationDir()))
779 if (llvm::sys::path::is_separator(FileName.front()))
780 FileName = FileName.drop_front();
781 assert(!FileName.empty());
782 setMCLineTableRootFile(
783 /*CUID=*/0, getCompilationDir(), FileName, Cksum, None);
784 }
785
786 /// getDwarfFile - takes a file name and number to place in the dwarf file and
787 /// directory tables. If the file number has already been allocated it is an
788 /// error and zero is returned and the client reports the error, else the
789 /// allocated file number is returned. The file numbers may be in any order.
getDwarfFile(StringRef Directory,StringRef FileName,unsigned FileNumber,Optional<MD5::MD5Result> Checksum,Optional<StringRef> Source,unsigned CUID)790 Expected<unsigned> MCContext::getDwarfFile(StringRef Directory,
791 StringRef FileName,
792 unsigned FileNumber,
793 Optional<MD5::MD5Result> Checksum,
794 Optional<StringRef> Source,
795 unsigned CUID) {
796 MCDwarfLineTable &Table = MCDwarfLineTablesCUMap[CUID];
797 return Table.tryGetFile(Directory, FileName, Checksum, Source, DwarfVersion,
798 FileNumber);
799 }
800
801 /// isValidDwarfFileNumber - takes a dwarf file number and returns true if it
802 /// currently is assigned and false otherwise.
isValidDwarfFileNumber(unsigned FileNumber,unsigned CUID)803 bool MCContext::isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID) {
804 const MCDwarfLineTable &LineTable = getMCDwarfLineTable(CUID);
805 if (FileNumber == 0)
806 return getDwarfVersion() >= 5;
807 if (FileNumber >= LineTable.getMCDwarfFiles().size())
808 return false;
809
810 return !LineTable.getMCDwarfFiles()[FileNumber].Name.empty();
811 }
812
813 /// Remove empty sections from SectionsForRanges, to avoid generating
814 /// useless debug info for them.
finalizeDwarfSections(MCStreamer & MCOS)815 void MCContext::finalizeDwarfSections(MCStreamer &MCOS) {
816 SectionsForRanges.remove_if(
817 [&](MCSection *Sec) { return !MCOS.mayHaveInstructions(*Sec); });
818 }
819
getCVContext()820 CodeViewContext &MCContext::getCVContext() {
821 if (!CVContext.get())
822 CVContext.reset(new CodeViewContext);
823 return *CVContext.get();
824 }
825
826 //===----------------------------------------------------------------------===//
827 // Error Reporting
828 //===----------------------------------------------------------------------===//
829
reportError(SMLoc Loc,const Twine & Msg)830 void MCContext::reportError(SMLoc Loc, const Twine &Msg) {
831 HadError = true;
832
833 // If we have a source manager use it. Otherwise, try using the inline source
834 // manager.
835 // If that fails, construct a temporary SourceMgr.
836 if (SrcMgr)
837 SrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
838 else if (InlineSrcMgr)
839 InlineSrcMgr->PrintMessage(Loc, SourceMgr::DK_Error, Msg);
840 else
841 SourceMgr().PrintMessage(Loc, SourceMgr::DK_Error, Msg);
842 }
843
reportWarning(SMLoc Loc,const Twine & Msg)844 void MCContext::reportWarning(SMLoc Loc, const Twine &Msg) {
845 if (TargetOptions && TargetOptions->MCNoWarn)
846 return;
847 if (TargetOptions && TargetOptions->MCFatalWarnings)
848 reportError(Loc, Msg);
849 else {
850 // If we have a source manager use it. Otherwise, try using the inline
851 // source manager.
852 if (SrcMgr)
853 SrcMgr->PrintMessage(Loc, SourceMgr::DK_Warning, Msg);
854 else if (InlineSrcMgr)
855 InlineSrcMgr->PrintMessage(Loc, SourceMgr::DK_Warning, Msg);
856 }
857 }
858
reportFatalError(SMLoc Loc,const Twine & Msg)859 void MCContext::reportFatalError(SMLoc Loc, const Twine &Msg) {
860 reportError(Loc, Msg);
861
862 // If we reached here, we are failing ungracefully. Run the interrupt handlers
863 // to make sure any special cleanups get done, in particular that we remove
864 // files registered with RemoveFileOnSignal.
865 sys::RunInterruptHandlers();
866 exit(1);
867 }
868