1 | //===- MCContext.h - Machine Code Context -----------------------*- C++ -*-===// |
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 | #ifndef LLVM_MC_MCCONTEXT_H |
10 | #define LLVM_MC_MCCONTEXT_H |
11 | |
12 | #include "llvm/ADT/DenseMap.h" |
13 | #include "llvm/ADT/SetVector.h" |
14 | #include "llvm/ADT/SmallString.h" |
15 | #include "llvm/ADT/StringMap.h" |
16 | #include "llvm/ADT/StringRef.h" |
17 | #include "llvm/ADT/Twine.h" |
18 | #include "llvm/BinaryFormat/Dwarf.h" |
19 | #include "llvm/BinaryFormat/XCOFF.h" |
20 | #include "llvm/MC/MCAsmMacro.h" |
21 | #include "llvm/MC/MCDwarf.h" |
22 | #include "llvm/MC/MCPseudoProbe.h" |
23 | #include "llvm/MC/MCSection.h" |
24 | #include "llvm/MC/SectionKind.h" |
25 | #include "llvm/Support/Allocator.h" |
26 | #include "llvm/Support/Compiler.h" |
27 | #include "llvm/Support/Error.h" |
28 | #include "llvm/Support/MD5.h" |
29 | #include "llvm/Support/raw_ostream.h" |
30 | #include <algorithm> |
31 | #include <cassert> |
32 | #include <cstddef> |
33 | #include <cstdint> |
34 | #include <functional> |
35 | #include <map> |
36 | #include <memory> |
37 | #include <optional> |
38 | #include <string> |
39 | #include <utility> |
40 | #include <vector> |
41 | |
42 | namespace llvm { |
43 | |
44 | class CodeViewContext; |
45 | class MCAsmInfo; |
46 | class MCInst; |
47 | class MCLabel; |
48 | class MCObjectFileInfo; |
49 | class MCRegisterInfo; |
50 | class MCSection; |
51 | class MCSectionCOFF; |
52 | class MCSectionDXContainer; |
53 | class MCSectionELF; |
54 | class MCSectionGOFF; |
55 | class MCSectionMachO; |
56 | class MCSectionSPIRV; |
57 | class MCSectionWasm; |
58 | class MCSectionXCOFF; |
59 | class MCStreamer; |
60 | class MCSubtargetInfo; |
61 | class MCSymbol; |
62 | class MCSymbolELF; |
63 | class MCSymbolWasm; |
64 | class MCSymbolXCOFF; |
65 | class MCTargetOptions; |
66 | class MDNode; |
67 | template <typename T> class SmallVectorImpl; |
68 | class SMDiagnostic; |
69 | class SMLoc; |
70 | class SourceMgr; |
71 | enum class EmitDwarfUnwindType; |
72 | |
73 | /// Context object for machine code objects. This class owns all of the |
74 | /// sections that it creates. |
75 | /// |
76 | class MCContext { |
77 | public: |
78 | using SymbolTable = StringMap<MCSymbol *, BumpPtrAllocator &>; |
79 | using DiagHandlerTy = |
80 | std::function<void(const SMDiagnostic &, bool, const SourceMgr &, |
81 | std::vector<const MDNode *> &)>; |
82 | enum Environment { |
83 | IsMachO, |
84 | IsELF, |
85 | IsGOFF, |
86 | IsCOFF, |
87 | IsSPIRV, |
88 | IsWasm, |
89 | IsXCOFF, |
90 | IsDXContainer |
91 | }; |
92 | |
93 | private: |
94 | Environment Env; |
95 | |
96 | /// The name of the Segment where Swift5 Reflection Section data will be |
97 | /// outputted |
98 | StringRef Swift5ReflectionSegmentName; |
99 | |
100 | /// The triple for this object. |
101 | Triple TT; |
102 | |
103 | /// The SourceMgr for this object, if any. |
104 | const SourceMgr *SrcMgr = nullptr; |
105 | |
106 | /// The SourceMgr for inline assembly, if any. |
107 | std::unique_ptr<SourceMgr> InlineSrcMgr; |
108 | std::vector<const MDNode *> LocInfos; |
109 | |
110 | DiagHandlerTy DiagHandler; |
111 | |
112 | /// The MCAsmInfo for this target. |
113 | const MCAsmInfo *MAI = nullptr; |
114 | |
115 | /// The MCRegisterInfo for this target. |
116 | const MCRegisterInfo *MRI = nullptr; |
117 | |
118 | /// The MCObjectFileInfo for this target. |
119 | const MCObjectFileInfo *MOFI = nullptr; |
120 | |
121 | /// The MCSubtargetInfo for this target. |
122 | const MCSubtargetInfo *MSTI = nullptr; |
123 | |
124 | std::unique_ptr<CodeViewContext> CVContext; |
125 | |
126 | /// Allocator object used for creating machine code objects. |
127 | /// |
128 | /// We use a bump pointer allocator to avoid the need to track all allocated |
129 | /// objects. |
130 | BumpPtrAllocator Allocator; |
131 | |
132 | SpecificBumpPtrAllocator<MCSectionCOFF> COFFAllocator; |
133 | SpecificBumpPtrAllocator<MCSectionDXContainer> DXCAllocator; |
134 | SpecificBumpPtrAllocator<MCSectionELF> ELFAllocator; |
135 | SpecificBumpPtrAllocator<MCSectionMachO> MachOAllocator; |
136 | SpecificBumpPtrAllocator<MCSectionGOFF> GOFFAllocator; |
137 | SpecificBumpPtrAllocator<MCSectionSPIRV> SPIRVAllocator; |
138 | SpecificBumpPtrAllocator<MCSectionWasm> WasmAllocator; |
139 | SpecificBumpPtrAllocator<MCSectionXCOFF> XCOFFAllocator; |
140 | SpecificBumpPtrAllocator<MCInst> MCInstAllocator; |
141 | |
142 | /// Bindings of names to symbols. |
143 | SymbolTable Symbols; |
144 | |
145 | /// A mapping from a local label number and an instance count to a symbol. |
146 | /// For example, in the assembly |
147 | /// 1: |
148 | /// 2: |
149 | /// 1: |
150 | /// We have three labels represented by the pairs (1, 0), (2, 0) and (1, 1) |
151 | DenseMap<std::pair<unsigned, unsigned>, MCSymbol *> LocalSymbols; |
152 | |
153 | /// Keeps tracks of names that were used both for used declared and |
154 | /// artificial symbols. The value is "true" if the name has been used for a |
155 | /// non-section symbol (there can be at most one of those, plus an unlimited |
156 | /// number of section symbols with the same name). |
157 | StringMap<bool, BumpPtrAllocator &> UsedNames; |
158 | |
159 | /// Keeps track of labels that are used in inline assembly. |
160 | SymbolTable InlineAsmUsedLabelNames; |
161 | |
162 | /// The next ID to dole out to an unnamed assembler temporary symbol with |
163 | /// a given prefix. |
164 | StringMap<unsigned> NextID; |
165 | |
166 | /// Instances of directional local labels. |
167 | DenseMap<unsigned, MCLabel *> Instances; |
168 | /// NextInstance() creates the next instance of the directional local label |
169 | /// for the LocalLabelVal and adds it to the map if needed. |
170 | unsigned NextInstance(unsigned LocalLabelVal); |
171 | /// GetInstance() gets the current instance of the directional local label |
172 | /// for the LocalLabelVal and adds it to the map if needed. |
173 | unsigned GetInstance(unsigned LocalLabelVal); |
174 | |
175 | /// LLVM_BB_ADDR_MAP version to emit. |
176 | uint8_t BBAddrMapVersion = 2; |
177 | |
178 | /// The file name of the log file from the environment variable |
179 | /// AS_SECURE_LOG_FILE. Which must be set before the .secure_log_unique |
180 | /// directive is used or it is an error. |
181 | std::string SecureLogFile; |
182 | /// The stream that gets written to for the .secure_log_unique directive. |
183 | std::unique_ptr<raw_fd_ostream> SecureLog; |
184 | /// Boolean toggled when .secure_log_unique / .secure_log_reset is seen to |
185 | /// catch errors if .secure_log_unique appears twice without |
186 | /// .secure_log_reset appearing between them. |
187 | bool SecureLogUsed = false; |
188 | |
189 | /// The compilation directory to use for DW_AT_comp_dir. |
190 | SmallString<128> CompilationDir; |
191 | |
192 | /// Prefix replacement map for source file information. |
193 | SmallVector<std::pair<std::string, std::string>, 0> DebugPrefixMap; |
194 | |
195 | /// The main file name if passed in explicitly. |
196 | std::string MainFileName; |
197 | |
198 | /// The dwarf file and directory tables from the dwarf .file directive. |
199 | /// We now emit a line table for each compile unit. To reduce the prologue |
200 | /// size of each line table, the files and directories used by each compile |
201 | /// unit are separated. |
202 | std::map<unsigned, MCDwarfLineTable> MCDwarfLineTablesCUMap; |
203 | |
204 | /// The current dwarf line information from the last dwarf .loc directive. |
205 | MCDwarfLoc CurrentDwarfLoc; |
206 | bool DwarfLocSeen = false; |
207 | |
208 | /// Generate dwarf debugging info for assembly source files. |
209 | bool GenDwarfForAssembly = false; |
210 | |
211 | /// The current dwarf file number when generate dwarf debugging info for |
212 | /// assembly source files. |
213 | unsigned GenDwarfFileNumber = 0; |
214 | |
215 | /// Sections for generating the .debug_ranges and .debug_aranges sections. |
216 | SetVector<MCSection *> SectionsForRanges; |
217 | |
218 | /// The information gathered from labels that will have dwarf label |
219 | /// entries when generating dwarf assembly source files. |
220 | std::vector<MCGenDwarfLabelEntry> MCGenDwarfLabelEntries; |
221 | |
222 | /// The string to embed in the debug information for the compile unit, if |
223 | /// non-empty. |
224 | StringRef DwarfDebugFlags; |
225 | |
226 | /// The string to embed in as the dwarf AT_producer for the compile unit, if |
227 | /// non-empty. |
228 | StringRef DwarfDebugProducer; |
229 | |
230 | /// The maximum version of dwarf that we should emit. |
231 | uint16_t DwarfVersion = 4; |
232 | |
233 | /// The format of dwarf that we emit. |
234 | dwarf::DwarfFormat DwarfFormat = dwarf::DWARF32; |
235 | |
236 | /// Honor temporary labels, this is useful for debugging semantic |
237 | /// differences between temporary and non-temporary labels (primarily on |
238 | /// Darwin). |
239 | bool AllowTemporaryLabels = true; |
240 | bool UseNamesOnTempLabels = false; |
241 | |
242 | /// The Compile Unit ID that we are currently processing. |
243 | unsigned DwarfCompileUnitID = 0; |
244 | |
245 | /// A collection of MCPseudoProbe in the current module |
246 | MCPseudoProbeTable PseudoProbeTable; |
247 | |
248 | // Sections are differentiated by the quadruple (section_name, group_name, |
249 | // unique_id, link_to_symbol_name). Sections sharing the same quadruple are |
250 | // combined into one section. |
251 | struct ELFSectionKey { |
252 | std::string SectionName; |
253 | StringRef GroupName; |
254 | StringRef LinkedToName; |
255 | unsigned UniqueID; |
256 | |
257 | ELFSectionKey(StringRef SectionName, StringRef GroupName, |
258 | StringRef LinkedToName, unsigned UniqueID) |
259 | : SectionName(SectionName), GroupName(GroupName), |
260 | LinkedToName(LinkedToName), UniqueID(UniqueID) {} |
261 | |
262 | bool operator<(const ELFSectionKey &Other) const { |
263 | if (SectionName != Other.SectionName) |
264 | return SectionName < Other.SectionName; |
265 | if (GroupName != Other.GroupName) |
266 | return GroupName < Other.GroupName; |
267 | if (int O = LinkedToName.compare(RHS: Other.LinkedToName)) |
268 | return O < 0; |
269 | return UniqueID < Other.UniqueID; |
270 | } |
271 | }; |
272 | |
273 | struct COFFSectionKey { |
274 | std::string SectionName; |
275 | StringRef GroupName; |
276 | int SelectionKey; |
277 | unsigned UniqueID; |
278 | |
279 | COFFSectionKey(StringRef SectionName, StringRef GroupName, int SelectionKey, |
280 | unsigned UniqueID) |
281 | : SectionName(SectionName), GroupName(GroupName), |
282 | SelectionKey(SelectionKey), UniqueID(UniqueID) {} |
283 | |
284 | bool operator<(const COFFSectionKey &Other) const { |
285 | if (SectionName != Other.SectionName) |
286 | return SectionName < Other.SectionName; |
287 | if (GroupName != Other.GroupName) |
288 | return GroupName < Other.GroupName; |
289 | if (SelectionKey != Other.SelectionKey) |
290 | return SelectionKey < Other.SelectionKey; |
291 | return UniqueID < Other.UniqueID; |
292 | } |
293 | }; |
294 | |
295 | struct WasmSectionKey { |
296 | std::string SectionName; |
297 | StringRef GroupName; |
298 | unsigned UniqueID; |
299 | |
300 | WasmSectionKey(StringRef SectionName, StringRef GroupName, |
301 | unsigned UniqueID) |
302 | : SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) {} |
303 | |
304 | bool operator<(const WasmSectionKey &Other) const { |
305 | if (SectionName != Other.SectionName) |
306 | return SectionName < Other.SectionName; |
307 | if (GroupName != Other.GroupName) |
308 | return GroupName < Other.GroupName; |
309 | return UniqueID < Other.UniqueID; |
310 | } |
311 | }; |
312 | |
313 | struct XCOFFSectionKey { |
314 | // Section name. |
315 | std::string SectionName; |
316 | // Section property. |
317 | // For csect section, it is storage mapping class. |
318 | // For debug section, it is section type flags. |
319 | union { |
320 | XCOFF::StorageMappingClass MappingClass; |
321 | XCOFF::DwarfSectionSubtypeFlags DwarfSubtypeFlags; |
322 | }; |
323 | bool IsCsect; |
324 | |
325 | XCOFFSectionKey(StringRef SectionName, |
326 | XCOFF::StorageMappingClass MappingClass) |
327 | : SectionName(SectionName), MappingClass(MappingClass), IsCsect(true) {} |
328 | |
329 | XCOFFSectionKey(StringRef SectionName, |
330 | XCOFF::DwarfSectionSubtypeFlags DwarfSubtypeFlags) |
331 | : SectionName(SectionName), DwarfSubtypeFlags(DwarfSubtypeFlags), |
332 | IsCsect(false) {} |
333 | |
334 | bool operator<(const XCOFFSectionKey &Other) const { |
335 | if (IsCsect && Other.IsCsect) |
336 | return std::tie(args: SectionName, args: MappingClass) < |
337 | std::tie(args: Other.SectionName, args: Other.MappingClass); |
338 | if (IsCsect != Other.IsCsect) |
339 | return IsCsect; |
340 | return std::tie(args: SectionName, args: DwarfSubtypeFlags) < |
341 | std::tie(args: Other.SectionName, args: Other.DwarfSubtypeFlags); |
342 | } |
343 | }; |
344 | |
345 | StringMap<MCSectionMachO *> MachOUniquingMap; |
346 | std::map<ELFSectionKey, MCSectionELF *> ELFUniquingMap; |
347 | std::map<COFFSectionKey, MCSectionCOFF *> COFFUniquingMap; |
348 | std::map<std::string, MCSectionGOFF *> GOFFUniquingMap; |
349 | std::map<WasmSectionKey, MCSectionWasm *> WasmUniquingMap; |
350 | std::map<XCOFFSectionKey, MCSectionXCOFF *> XCOFFUniquingMap; |
351 | StringMap<MCSectionDXContainer *> DXCUniquingMap; |
352 | StringMap<bool> RelSecNames; |
353 | |
354 | SpecificBumpPtrAllocator<MCSubtargetInfo> MCSubtargetAllocator; |
355 | |
356 | /// Do automatic reset in destructor |
357 | bool AutoReset; |
358 | |
359 | MCTargetOptions const *TargetOptions; |
360 | |
361 | bool HadError = false; |
362 | |
363 | void reportCommon(SMLoc Loc, |
364 | std::function<void(SMDiagnostic &, const SourceMgr *)>); |
365 | |
366 | MCSymbol *createSymbolImpl(const StringMapEntry<bool> *Name, |
367 | bool CanBeUnnamed); |
368 | MCSymbol *createSymbol(StringRef Name, bool AlwaysAddSuffix, |
369 | bool IsTemporary); |
370 | |
371 | MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal, |
372 | unsigned Instance); |
373 | |
374 | MCSectionELF *createELFSectionImpl(StringRef Section, unsigned Type, |
375 | unsigned Flags, SectionKind K, |
376 | unsigned EntrySize, |
377 | const MCSymbolELF *Group, bool IsComdat, |
378 | unsigned UniqueID, |
379 | const MCSymbolELF *LinkedToSym); |
380 | |
381 | MCSymbolXCOFF *createXCOFFSymbolImpl(const StringMapEntry<bool> *Name, |
382 | bool IsTemporary); |
383 | |
384 | /// Map of currently defined macros. |
385 | StringMap<MCAsmMacro> MacroMap; |
386 | |
387 | struct ELFEntrySizeKey { |
388 | std::string SectionName; |
389 | unsigned Flags; |
390 | unsigned EntrySize; |
391 | |
392 | ELFEntrySizeKey(StringRef SectionName, unsigned Flags, unsigned EntrySize) |
393 | : SectionName(SectionName), Flags(Flags), EntrySize(EntrySize) {} |
394 | |
395 | bool operator<(const ELFEntrySizeKey &Other) const { |
396 | if (SectionName != Other.SectionName) |
397 | return SectionName < Other.SectionName; |
398 | if (Flags != Other.Flags) |
399 | return Flags < Other.Flags; |
400 | return EntrySize < Other.EntrySize; |
401 | } |
402 | }; |
403 | |
404 | // Symbols must be assigned to a section with a compatible entry size and |
405 | // flags. This map is used to assign unique IDs to sections to distinguish |
406 | // between sections with identical names but incompatible entry sizes and/or |
407 | // flags. This can occur when a symbol is explicitly assigned to a section, |
408 | // e.g. via __attribute__((section("myname"))). |
409 | std::map<ELFEntrySizeKey, unsigned> ELFEntrySizeMap; |
410 | |
411 | // This set is used to record the generic mergeable section names seen. |
412 | // These are sections that are created as mergeable e.g. .debug_str. We need |
413 | // to avoid assigning non-mergeable symbols to these sections. It is used |
414 | // to prevent non-mergeable symbols being explicitly assigned to mergeable |
415 | // sections (e.g. via _attribute_((section("myname")))). |
416 | DenseSet<StringRef> ELFSeenGenericMergeableSections; |
417 | |
418 | public: |
419 | explicit MCContext(const Triple &TheTriple, const MCAsmInfo *MAI, |
420 | const MCRegisterInfo *MRI, const MCSubtargetInfo *MSTI, |
421 | const SourceMgr *Mgr = nullptr, |
422 | MCTargetOptions const *TargetOpts = nullptr, |
423 | bool DoAutoReset = true, |
424 | StringRef Swift5ReflSegmentName = {}); |
425 | MCContext(const MCContext &) = delete; |
426 | MCContext &operator=(const MCContext &) = delete; |
427 | ~MCContext(); |
428 | |
429 | Environment getObjectFileType() const { return Env; } |
430 | |
431 | const StringRef &getSwift5ReflectionSegmentName() const { |
432 | return Swift5ReflectionSegmentName; |
433 | } |
434 | const Triple &getTargetTriple() const { return TT; } |
435 | const SourceMgr *getSourceManager() const { return SrcMgr; } |
436 | |
437 | void initInlineSourceManager(); |
438 | SourceMgr *getInlineSourceManager() { return InlineSrcMgr.get(); } |
439 | std::vector<const MDNode *> &getLocInfos() { return LocInfos; } |
440 | void setDiagnosticHandler(DiagHandlerTy DiagHandler) { |
441 | this->DiagHandler = DiagHandler; |
442 | } |
443 | |
444 | void setObjectFileInfo(const MCObjectFileInfo *Mofi) { MOFI = Mofi; } |
445 | |
446 | const MCAsmInfo *getAsmInfo() const { return MAI; } |
447 | |
448 | const MCRegisterInfo *getRegisterInfo() const { return MRI; } |
449 | |
450 | const MCObjectFileInfo *getObjectFileInfo() const { return MOFI; } |
451 | |
452 | const MCSubtargetInfo *getSubtargetInfo() const { return MSTI; } |
453 | |
454 | CodeViewContext &getCVContext(); |
455 | |
456 | void setAllowTemporaryLabels(bool Value) { AllowTemporaryLabels = Value; } |
457 | void setUseNamesOnTempLabels(bool Value) { UseNamesOnTempLabels = Value; } |
458 | |
459 | /// \name Module Lifetime Management |
460 | /// @{ |
461 | |
462 | /// reset - return object to right after construction state to prepare |
463 | /// to process a new module |
464 | void reset(); |
465 | |
466 | /// @} |
467 | |
468 | /// \name McInst Management |
469 | |
470 | /// Create and return a new MC instruction. |
471 | MCInst *createMCInst(); |
472 | |
473 | /// \name Symbol Management |
474 | /// @{ |
475 | |
476 | /// Create a new linker temporary symbol with the specified prefix (Name) or |
477 | /// "tmp". This creates a "l"-prefixed symbol for Mach-O and is identical to |
478 | /// createNamedTempSymbol for other object file formats. |
479 | MCSymbol *createLinkerPrivateTempSymbol(); |
480 | MCSymbol *createLinkerPrivateSymbol(const Twine &Name); |
481 | |
482 | /// Create a temporary symbol with a unique name. The name will be omitted |
483 | /// in the symbol table if UseNamesOnTempLabels is false (default except |
484 | /// MCAsmStreamer). The overload without Name uses an unspecified name. |
485 | MCSymbol *createTempSymbol(); |
486 | MCSymbol *createTempSymbol(const Twine &Name, bool AlwaysAddSuffix = true); |
487 | |
488 | /// Create a temporary symbol with a unique name whose name cannot be |
489 | /// omitted in the symbol table. This is rarely used. |
490 | MCSymbol *createNamedTempSymbol(); |
491 | MCSymbol *createNamedTempSymbol(const Twine &Name); |
492 | |
493 | /// Create the definition of a directional local symbol for numbered label |
494 | /// (used for "1:" definitions). |
495 | MCSymbol *createDirectionalLocalSymbol(unsigned LocalLabelVal); |
496 | |
497 | /// Create and return a directional local symbol for numbered label (used |
498 | /// for "1b" or 1f" references). |
499 | MCSymbol *getDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before); |
500 | |
501 | /// Lookup the symbol inside with the specified \p Name. If it exists, |
502 | /// return it. If not, create a forward reference and return it. |
503 | /// |
504 | /// \param Name - The symbol name, which must be unique across all symbols. |
505 | MCSymbol *getOrCreateSymbol(const Twine &Name); |
506 | |
507 | /// Gets a symbol that will be defined to the final stack offset of a local |
508 | /// variable after codegen. |
509 | /// |
510 | /// \param Idx - The index of a local variable passed to \@llvm.localescape. |
511 | MCSymbol *getOrCreateFrameAllocSymbol(const Twine &FuncName, unsigned Idx); |
512 | |
513 | MCSymbol *getOrCreateParentFrameOffsetSymbol(const Twine &FuncName); |
514 | |
515 | MCSymbol *getOrCreateLSDASymbol(const Twine &FuncName); |
516 | |
517 | /// Get the symbol for \p Name, or null. |
518 | MCSymbol *lookupSymbol(const Twine &Name) const; |
519 | |
520 | /// Set value for a symbol. |
521 | void setSymbolValue(MCStreamer &Streamer, const Twine &Sym, uint64_t Val); |
522 | |
523 | /// getSymbols - Get a reference for the symbol table for clients that |
524 | /// want to, for example, iterate over all symbols. 'const' because we |
525 | /// still want any modifications to the table itself to use the MCContext |
526 | /// APIs. |
527 | const SymbolTable &getSymbols() const { return Symbols; } |
528 | |
529 | /// isInlineAsmLabel - Return true if the name is a label referenced in |
530 | /// inline assembly. |
531 | MCSymbol *getInlineAsmLabel(StringRef Name) const { |
532 | return InlineAsmUsedLabelNames.lookup(Key: Name); |
533 | } |
534 | |
535 | /// registerInlineAsmLabel - Records that the name is a label referenced in |
536 | /// inline assembly. |
537 | void registerInlineAsmLabel(MCSymbol *Sym); |
538 | |
539 | /// @} |
540 | |
541 | /// \name Section Management |
542 | /// @{ |
543 | |
544 | enum : unsigned { |
545 | /// Pass this value as the UniqueID during section creation to get the |
546 | /// generic section with the given name and characteristics. The usual |
547 | /// sections such as .text use this ID. |
548 | GenericSectionID = ~0U |
549 | }; |
550 | |
551 | /// Return the MCSection for the specified mach-o section. This requires |
552 | /// the operands to be valid. |
553 | MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section, |
554 | unsigned TypeAndAttributes, |
555 | unsigned Reserved2, SectionKind K, |
556 | const char *BeginSymName = nullptr); |
557 | |
558 | MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section, |
559 | unsigned TypeAndAttributes, SectionKind K, |
560 | const char *BeginSymName = nullptr) { |
561 | return getMachOSection(Segment, Section, TypeAndAttributes, Reserved2: 0, K, |
562 | BeginSymName); |
563 | } |
564 | |
565 | MCSectionELF *getELFSection(const Twine &Section, unsigned Type, |
566 | unsigned Flags) { |
567 | return getELFSection(Section, Type, Flags, EntrySize: 0, Group: "" , IsComdat: false); |
568 | } |
569 | |
570 | MCSectionELF *getELFSection(const Twine &Section, unsigned Type, |
571 | unsigned Flags, unsigned EntrySize) { |
572 | return getELFSection(Section, Type, Flags, EntrySize, Group: "" , IsComdat: false, |
573 | UniqueID: MCSection::NonUniqueID, LinkedToSym: nullptr); |
574 | } |
575 | |
576 | MCSectionELF *getELFSection(const Twine &Section, unsigned Type, |
577 | unsigned Flags, unsigned EntrySize, |
578 | const Twine &Group, bool IsComdat) { |
579 | return getELFSection(Section, Type, Flags, EntrySize, Group, IsComdat, |
580 | UniqueID: MCSection::NonUniqueID, LinkedToSym: nullptr); |
581 | } |
582 | |
583 | MCSectionELF *getELFSection(const Twine &Section, unsigned Type, |
584 | unsigned Flags, unsigned EntrySize, |
585 | const Twine &Group, bool IsComdat, |
586 | unsigned UniqueID, |
587 | const MCSymbolELF *LinkedToSym); |
588 | |
589 | MCSectionELF *getELFSection(const Twine &Section, unsigned Type, |
590 | unsigned Flags, unsigned EntrySize, |
591 | const MCSymbolELF *Group, bool IsComdat, |
592 | unsigned UniqueID, |
593 | const MCSymbolELF *LinkedToSym); |
594 | |
595 | /// Get a section with the provided group identifier. This section is |
596 | /// named by concatenating \p Prefix with '.' then \p Suffix. The \p Type |
597 | /// describes the type of the section and \p Flags are used to further |
598 | /// configure this named section. |
599 | MCSectionELF *getELFNamedSection(const Twine &Prefix, const Twine &Suffix, |
600 | unsigned Type, unsigned Flags, |
601 | unsigned EntrySize = 0); |
602 | |
603 | MCSectionELF *createELFRelSection(const Twine &Name, unsigned Type, |
604 | unsigned Flags, unsigned EntrySize, |
605 | const MCSymbolELF *Group, |
606 | const MCSectionELF *RelInfoSection); |
607 | |
608 | MCSectionELF *createELFGroupSection(const MCSymbolELF *Group, bool IsComdat); |
609 | |
610 | void recordELFMergeableSectionInfo(StringRef SectionName, unsigned Flags, |
611 | unsigned UniqueID, unsigned EntrySize); |
612 | |
613 | bool isELFImplicitMergeableSectionNamePrefix(StringRef Name); |
614 | |
615 | bool isELFGenericMergeableSection(StringRef Name); |
616 | |
617 | /// Return the unique ID of the section with the given name, flags and entry |
618 | /// size, if it exists. |
619 | std::optional<unsigned> getELFUniqueIDForEntsize(StringRef SectionName, |
620 | unsigned Flags, |
621 | unsigned EntrySize); |
622 | |
623 | MCSectionGOFF *getGOFFSection(StringRef Section, SectionKind Kind, |
624 | MCSection *Parent, const MCExpr *SubsectionId); |
625 | |
626 | MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, |
627 | SectionKind Kind, StringRef COMDATSymName, |
628 | int Selection, |
629 | unsigned UniqueID = GenericSectionID, |
630 | const char *BeginSymName = nullptr); |
631 | |
632 | MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics, |
633 | SectionKind Kind, |
634 | const char *BeginSymName = nullptr); |
635 | |
636 | /// Gets or creates a section equivalent to Sec that is associated with the |
637 | /// section containing KeySym. For example, to create a debug info section |
638 | /// associated with an inline function, pass the normal debug info section |
639 | /// as Sec and the function symbol as KeySym. |
640 | MCSectionCOFF * |
641 | getAssociativeCOFFSection(MCSectionCOFF *Sec, const MCSymbol *KeySym, |
642 | unsigned UniqueID = GenericSectionID); |
643 | |
644 | MCSectionSPIRV *getSPIRVSection(); |
645 | |
646 | MCSectionWasm *getWasmSection(const Twine &Section, SectionKind K, |
647 | unsigned Flags = 0) { |
648 | return getWasmSection(Section, K, Flags, BeginSymName: nullptr); |
649 | } |
650 | |
651 | MCSectionWasm *getWasmSection(const Twine &Section, SectionKind K, |
652 | unsigned Flags, const char *BeginSymName) { |
653 | return getWasmSection(Section, K, Flags, Group: "" , UniqueID: ~0, BeginSymName); |
654 | } |
655 | |
656 | MCSectionWasm *getWasmSection(const Twine &Section, SectionKind K, |
657 | unsigned Flags, const Twine &Group, |
658 | unsigned UniqueID) { |
659 | return getWasmSection(Section, K, Flags, Group, UniqueID, BeginSymName: nullptr); |
660 | } |
661 | |
662 | MCSectionWasm *getWasmSection(const Twine &Section, SectionKind K, |
663 | unsigned Flags, const Twine &Group, |
664 | unsigned UniqueID, const char *BeginSymName); |
665 | |
666 | MCSectionWasm *getWasmSection(const Twine &Section, SectionKind K, |
667 | unsigned Flags, const MCSymbolWasm *Group, |
668 | unsigned UniqueID, const char *BeginSymName); |
669 | |
670 | /// Get the section for the provided Section name |
671 | MCSectionDXContainer *getDXContainerSection(StringRef Section, SectionKind K); |
672 | |
673 | bool hasXCOFFSection(StringRef Section, |
674 | XCOFF::CsectProperties CsectProp) const; |
675 | |
676 | MCSectionXCOFF *getXCOFFSection( |
677 | StringRef Section, SectionKind K, |
678 | std::optional<XCOFF::CsectProperties> CsectProp = std::nullopt, |
679 | bool MultiSymbolsAllowed = false, const char *BeginSymName = nullptr, |
680 | std::optional<XCOFF::DwarfSectionSubtypeFlags> DwarfSubtypeFlags = |
681 | std::nullopt); |
682 | |
683 | // Create and save a copy of STI and return a reference to the copy. |
684 | MCSubtargetInfo &getSubtargetCopy(const MCSubtargetInfo &STI); |
685 | |
686 | uint8_t getBBAddrMapVersion() const { return BBAddrMapVersion; } |
687 | |
688 | /// @} |
689 | |
690 | /// \name Dwarf Management |
691 | /// @{ |
692 | |
693 | /// Get the compilation directory for DW_AT_comp_dir |
694 | /// The compilation directory should be set with \c setCompilationDir before |
695 | /// calling this function. If it is unset, an empty string will be returned. |
696 | StringRef getCompilationDir() const { return CompilationDir; } |
697 | |
698 | /// Set the compilation directory for DW_AT_comp_dir |
699 | void setCompilationDir(StringRef S) { CompilationDir = S.str(); } |
700 | |
701 | /// Add an entry to the debug prefix map. |
702 | void addDebugPrefixMapEntry(const std::string &From, const std::string &To); |
703 | |
704 | /// Remap one path in-place as per the debug prefix map. |
705 | void remapDebugPath(SmallVectorImpl<char> &Path); |
706 | |
707 | // Remaps all debug directory paths in-place as per the debug prefix map. |
708 | void RemapDebugPaths(); |
709 | |
710 | /// Get the main file name for use in error messages and debug |
711 | /// info. This can be set to ensure we've got the correct file name |
712 | /// after preprocessing or for -save-temps. |
713 | const std::string &getMainFileName() const { return MainFileName; } |
714 | |
715 | /// Set the main file name and override the default. |
716 | void setMainFileName(StringRef S) { MainFileName = std::string(S); } |
717 | |
718 | /// Creates an entry in the dwarf file and directory tables. |
719 | Expected<unsigned> getDwarfFile(StringRef Directory, StringRef FileName, |
720 | unsigned FileNumber, |
721 | std::optional<MD5::MD5Result> Checksum, |
722 | std::optional<StringRef> Source, |
723 | unsigned CUID); |
724 | |
725 | bool isValidDwarfFileNumber(unsigned FileNumber, unsigned CUID = 0); |
726 | |
727 | const std::map<unsigned, MCDwarfLineTable> &getMCDwarfLineTables() const { |
728 | return MCDwarfLineTablesCUMap; |
729 | } |
730 | |
731 | MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) { |
732 | return MCDwarfLineTablesCUMap[CUID]; |
733 | } |
734 | |
735 | const MCDwarfLineTable &getMCDwarfLineTable(unsigned CUID) const { |
736 | auto I = MCDwarfLineTablesCUMap.find(x: CUID); |
737 | assert(I != MCDwarfLineTablesCUMap.end()); |
738 | return I->second; |
739 | } |
740 | |
741 | const SmallVectorImpl<MCDwarfFile> &getMCDwarfFiles(unsigned CUID = 0) { |
742 | return getMCDwarfLineTable(CUID).getMCDwarfFiles(); |
743 | } |
744 | |
745 | const SmallVectorImpl<std::string> &getMCDwarfDirs(unsigned CUID = 0) { |
746 | return getMCDwarfLineTable(CUID).getMCDwarfDirs(); |
747 | } |
748 | |
749 | unsigned getDwarfCompileUnitID() { return DwarfCompileUnitID; } |
750 | |
751 | void setDwarfCompileUnitID(unsigned CUIndex) { DwarfCompileUnitID = CUIndex; } |
752 | |
753 | /// Specifies the "root" file and directory of the compilation unit. |
754 | /// These are "file 0" and "directory 0" in DWARF v5. |
755 | void setMCLineTableRootFile(unsigned CUID, StringRef CompilationDir, |
756 | StringRef Filename, |
757 | std::optional<MD5::MD5Result> Checksum, |
758 | std::optional<StringRef> Source) { |
759 | getMCDwarfLineTable(CUID).setRootFile(Directory: CompilationDir, FileName: Filename, Checksum, |
760 | Source); |
761 | } |
762 | |
763 | /// Reports whether MD5 checksum usage is consistent (all-or-none). |
764 | bool isDwarfMD5UsageConsistent(unsigned CUID) const { |
765 | return getMCDwarfLineTable(CUID).isMD5UsageConsistent(); |
766 | } |
767 | |
768 | /// Saves the information from the currently parsed dwarf .loc directive |
769 | /// and sets DwarfLocSeen. When the next instruction is assembled an entry |
770 | /// in the line number table with this information and the address of the |
771 | /// instruction will be created. |
772 | void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column, |
773 | unsigned Flags, unsigned Isa, |
774 | unsigned Discriminator) { |
775 | CurrentDwarfLoc.setFileNum(FileNum); |
776 | CurrentDwarfLoc.setLine(Line); |
777 | CurrentDwarfLoc.setColumn(Column); |
778 | CurrentDwarfLoc.setFlags(Flags); |
779 | CurrentDwarfLoc.setIsa(Isa); |
780 | CurrentDwarfLoc.setDiscriminator(Discriminator); |
781 | DwarfLocSeen = true; |
782 | } |
783 | |
784 | void clearDwarfLocSeen() { DwarfLocSeen = false; } |
785 | |
786 | bool getDwarfLocSeen() { return DwarfLocSeen; } |
787 | const MCDwarfLoc &getCurrentDwarfLoc() { return CurrentDwarfLoc; } |
788 | |
789 | bool getGenDwarfForAssembly() { return GenDwarfForAssembly; } |
790 | void setGenDwarfForAssembly(bool Value) { GenDwarfForAssembly = Value; } |
791 | unsigned getGenDwarfFileNumber() { return GenDwarfFileNumber; } |
792 | EmitDwarfUnwindType emitDwarfUnwindInfo() const; |
793 | bool emitCompactUnwindNonCanonical() const; |
794 | |
795 | void setGenDwarfFileNumber(unsigned FileNumber) { |
796 | GenDwarfFileNumber = FileNumber; |
797 | } |
798 | |
799 | /// Specifies information about the "root file" for assembler clients |
800 | /// (e.g., llvm-mc). Assumes compilation dir etc. have been set up. |
801 | void setGenDwarfRootFile(StringRef FileName, StringRef Buffer); |
802 | |
803 | const SetVector<MCSection *> &getGenDwarfSectionSyms() { |
804 | return SectionsForRanges; |
805 | } |
806 | |
807 | bool addGenDwarfSection(MCSection *Sec) { |
808 | return SectionsForRanges.insert(X: Sec); |
809 | } |
810 | |
811 | void finalizeDwarfSections(MCStreamer &MCOS); |
812 | |
813 | const std::vector<MCGenDwarfLabelEntry> &getMCGenDwarfLabelEntries() const { |
814 | return MCGenDwarfLabelEntries; |
815 | } |
816 | |
817 | void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E) { |
818 | MCGenDwarfLabelEntries.push_back(x: E); |
819 | } |
820 | |
821 | void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; } |
822 | StringRef getDwarfDebugFlags() { return DwarfDebugFlags; } |
823 | |
824 | void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; } |
825 | StringRef getDwarfDebugProducer() { return DwarfDebugProducer; } |
826 | |
827 | void setDwarfFormat(dwarf::DwarfFormat f) { DwarfFormat = f; } |
828 | dwarf::DwarfFormat getDwarfFormat() const { return DwarfFormat; } |
829 | |
830 | void setDwarfVersion(uint16_t v) { DwarfVersion = v; } |
831 | uint16_t getDwarfVersion() const { return DwarfVersion; } |
832 | |
833 | /// @} |
834 | |
835 | StringRef getSecureLogFile() { return SecureLogFile; } |
836 | raw_fd_ostream *getSecureLog() { return SecureLog.get(); } |
837 | |
838 | void setSecureLog(std::unique_ptr<raw_fd_ostream> Value) { |
839 | SecureLog = std::move(Value); |
840 | } |
841 | |
842 | bool getSecureLogUsed() { return SecureLogUsed; } |
843 | void setSecureLogUsed(bool Value) { SecureLogUsed = Value; } |
844 | |
845 | void *allocate(unsigned Size, unsigned Align = 8) { |
846 | return Allocator.Allocate(Size, Alignment: Align); |
847 | } |
848 | |
849 | void deallocate(void *Ptr) {} |
850 | |
851 | bool hadError() { return HadError; } |
852 | void diagnose(const SMDiagnostic &SMD); |
853 | void reportError(SMLoc L, const Twine &Msg); |
854 | void reportWarning(SMLoc L, const Twine &Msg); |
855 | |
856 | const MCAsmMacro *lookupMacro(StringRef Name) { |
857 | StringMap<MCAsmMacro>::iterator I = MacroMap.find(Key: Name); |
858 | return (I == MacroMap.end()) ? nullptr : &I->getValue(); |
859 | } |
860 | |
861 | void defineMacro(StringRef Name, MCAsmMacro Macro) { |
862 | MacroMap.insert(KV: std::make_pair(x&: Name, y: std::move(Macro))); |
863 | } |
864 | |
865 | void undefineMacro(StringRef Name) { MacroMap.erase(Key: Name); } |
866 | |
867 | MCPseudoProbeTable &getMCPseudoProbeTable() { return PseudoProbeTable; } |
868 | }; |
869 | |
870 | } // end namespace llvm |
871 | |
872 | // operator new and delete aren't allowed inside namespaces. |
873 | // The throw specifications are mandated by the standard. |
874 | /// Placement new for using the MCContext's allocator. |
875 | /// |
876 | /// This placement form of operator new uses the MCContext's allocator for |
877 | /// obtaining memory. It is a non-throwing new, which means that it returns |
878 | /// null on error. (If that is what the allocator does. The current does, so if |
879 | /// this ever changes, this operator will have to be changed, too.) |
880 | /// Usage looks like this (assuming there's an MCContext 'Context' in scope): |
881 | /// \code |
882 | /// // Default alignment (8) |
883 | /// IntegerLiteral *Ex = new (Context) IntegerLiteral(arguments); |
884 | /// // Specific alignment |
885 | /// IntegerLiteral *Ex2 = new (Context, 4) IntegerLiteral(arguments); |
886 | /// \endcode |
887 | /// Please note that you cannot use delete on the pointer; it must be |
888 | /// deallocated using an explicit destructor call followed by |
889 | /// \c Context.Deallocate(Ptr). |
890 | /// |
891 | /// \param Bytes The number of bytes to allocate. Calculated by the compiler. |
892 | /// \param C The MCContext that provides the allocator. |
893 | /// \param Alignment The alignment of the allocated memory (if the underlying |
894 | /// allocator supports it). |
895 | /// \return The allocated memory. Could be NULL. |
896 | inline void *operator new(size_t Bytes, llvm::MCContext &C, |
897 | size_t Alignment = 8) noexcept { |
898 | return C.allocate(Size: Bytes, Align: Alignment); |
899 | } |
900 | /// Placement delete companion to the new above. |
901 | /// |
902 | /// This operator is just a companion to the new above. There is no way of |
903 | /// invoking it directly; see the new operator for more details. This operator |
904 | /// is called implicitly by the compiler if a placement new expression using |
905 | /// the MCContext throws in the object constructor. |
906 | inline void operator delete(void *Ptr, llvm::MCContext &C, size_t) noexcept { |
907 | C.deallocate(Ptr); |
908 | } |
909 | |
910 | /// This placement form of operator new[] uses the MCContext's allocator for |
911 | /// obtaining memory. It is a non-throwing new[], which means that it returns |
912 | /// null on error. |
913 | /// Usage looks like this (assuming there's an MCContext 'Context' in scope): |
914 | /// \code |
915 | /// // Default alignment (8) |
916 | /// char *data = new (Context) char[10]; |
917 | /// // Specific alignment |
918 | /// char *data = new (Context, 4) char[10]; |
919 | /// \endcode |
920 | /// Please note that you cannot use delete on the pointer; it must be |
921 | /// deallocated using an explicit destructor call followed by |
922 | /// \c Context.Deallocate(Ptr). |
923 | /// |
924 | /// \param Bytes The number of bytes to allocate. Calculated by the compiler. |
925 | /// \param C The MCContext that provides the allocator. |
926 | /// \param Alignment The alignment of the allocated memory (if the underlying |
927 | /// allocator supports it). |
928 | /// \return The allocated memory. Could be NULL. |
929 | inline void *operator new[](size_t Bytes, llvm::MCContext &C, |
930 | size_t Alignment = 8) noexcept { |
931 | return C.allocate(Size: Bytes, Align: Alignment); |
932 | } |
933 | |
934 | /// Placement delete[] companion to the new[] above. |
935 | /// |
936 | /// This operator is just a companion to the new[] above. There is no way of |
937 | /// invoking it directly; see the new[] operator for more details. This operator |
938 | /// is called implicitly by the compiler if a placement new[] expression using |
939 | /// the MCContext throws in the object constructor. |
940 | inline void operator delete[](void *Ptr, llvm::MCContext &C) noexcept { |
941 | C.deallocate(Ptr); |
942 | } |
943 | |
944 | #endif // LLVM_MC_MCCONTEXT_H |
945 | |