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