LLVM  9.0.0svn
MCSymbol.h
Go to the documentation of this file.
1 //===- MCSymbol.h - Machine Code Symbols ------------------------*- 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 // This file contains the declaration of the MCSymbol class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_MC_MCSYMBOL_H
14 #define LLVM_MC_MCSYMBOL_H
15 
17 #include "llvm/ADT/StringMap.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/MC/MCFragment.h"
22 #include <cassert>
23 #include <cstddef>
24 #include <cstdint>
25 
26 namespace llvm {
27 
28 class MCAsmInfo;
29 class MCContext;
30 class MCExpr;
31 class MCSection;
32 class raw_ostream;
33 
34 /// MCSymbol - Instances of this class represent a symbol name in the MC file,
35 /// and MCSymbols are created and uniqued by the MCContext class. MCSymbols
36 /// should only be constructed with valid names for the object file.
37 ///
38 /// If the symbol is defined/emitted into the current translation unit, the
39 /// Section member is set to indicate what section it lives in. Otherwise, if
40 /// it is a reference to an external entity, it has a null section.
41 class MCSymbol {
42 protected:
43  /// The kind of the symbol. If it is any value other than unset then this
44  /// class is actually one of the appropriate subclasses of MCSymbol.
45  enum SymbolKind {
51  };
52 
53  /// A symbol can contain an Offset, or Value, or be Common, but never more
54  /// than one of these.
55  enum Contents : uint8_t {
60  };
61 
62  // Special sentinal value for the absolute pseudo fragment.
64 
65  /// If a symbol has a Fragment, the section is implied, so we only need
66  /// one pointer.
67  /// The special AbsolutePseudoFragment value is for absolute symbols.
68  /// If this is a variable symbol, this caches the variable value's fragment.
69  /// FIXME: We might be able to simplify this by having the asm streamer create
70  /// dummy fragments.
71  /// If this is a section, then it gives the symbol is defined in. This is null
72  /// for undefined symbols.
73  ///
74  /// If this is a fragment, then it gives the fragment this symbol's value is
75  /// relative to, if any.
76  ///
77  /// For the 'HasName' integer, this is true if this symbol is named.
78  /// A named symbol will have a pointer to the name allocated in the bytes
79  /// immediately prior to the MCSymbol.
81 
82  /// IsTemporary - True if this is an assembler temporary label, which
83  /// typically does not survive in the .o file's symbol table. Usually
84  /// "Lfoo" or ".foo".
85  unsigned IsTemporary : 1;
86 
87  /// True if this symbol can be redefined.
88  unsigned IsRedefinable : 1;
89 
90  /// IsUsed - True if this symbol has been used.
91  mutable unsigned IsUsed : 1;
92 
93  mutable unsigned IsRegistered : 1;
94 
95  /// This symbol is visible outside this translation unit.
96  mutable unsigned IsExternal : 1;
97 
98  /// This symbol is private extern.
99  mutable unsigned IsPrivateExtern : 1;
100 
101  /// LLVM RTTI discriminator. This is actually a SymbolKind enumerator, but is
102  /// unsigned to avoid sign extension and achieve better bitpacking with MSVC.
103  unsigned Kind : 3;
104 
105  /// True if we have created a relocation that uses this symbol.
106  mutable unsigned IsUsedInReloc : 1;
107 
108  /// This is actually a Contents enumerator, but is unsigned to avoid sign
109  /// extension and achieve better bitpacking with MSVC.
110  unsigned SymbolContents : 2;
111 
112  /// The alignment of the symbol, if it is 'common', or -1.
113  ///
114  /// The alignment is stored as log2(align) + 1. This allows all values from
115  /// 0 to 2^31 to be stored which is every power of 2 representable by an
116  /// unsigned.
117  enum : unsigned { NumCommonAlignmentBits = 5 };
119 
120  /// The Flags field is used by object file implementations to store
121  /// additional per symbol information which is not easily classified.
122  enum : unsigned { NumFlagsBits = 16 };
124 
125  /// Index field, for use by the object file implementation.
126  mutable uint32_t Index = 0;
127 
128  union {
129  /// The offset to apply to the fragment address to form this symbol's value.
130  uint64_t Offset;
131 
132  /// The size of the symbol, if it is 'common'.
133  uint64_t CommonSize;
134 
135  /// If non-null, the value for a variable symbol.
136  const MCExpr *Value;
137  };
138 
139  // MCContext creates and uniques these.
140  friend class MCExpr;
141  friend class MCContext;
142 
143  /// The name for a symbol.
144  /// MCSymbol contains a uint64_t so is probably aligned to 8. On a 32-bit
145  /// system, the name is a pointer so isn't going to satisfy the 8 byte
146  /// alignment of uint64_t. Account for that here.
147  using NameEntryStorageTy = union {
148  const StringMapEntry<bool> *NameEntry;
150  };
151 
153  : IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false),
156  CommonAlignLog2(0), Flags(0) {
157  Offset = 0;
158  FragmentAndHasName.setInt(!!Name);
159  if (Name)
160  getNameEntryPtr() = Name;
161  }
162 
163  // Provide custom new/delete as we will only allocate space for a name
164  // if we need one.
165  void *operator new(size_t s, const StringMapEntry<bool> *Name,
166  MCContext &Ctx);
167 
168 private:
169  void operator delete(void *);
170  /// Placement delete - required by std, but never called.
171  void operator delete(void*, unsigned) {
172  llvm_unreachable("Constructor throws?");
173  }
174  /// Placement delete - required by std, but never called.
175  void operator delete(void*, unsigned, bool) {
176  llvm_unreachable("Constructor throws?");
177  }
178 
179  MCSection *getSectionPtr() const {
180  if (MCFragment *F = getFragment()) {
181  assert(F != AbsolutePseudoFragment);
182  return F->getParent();
183  }
184  return nullptr;
185  }
186 
187  /// Get a reference to the name field. Requires that we have a name
188  const StringMapEntry<bool> *&getNameEntryPtr() {
189  assert(FragmentAndHasName.getInt() && "Name is required");
190  NameEntryStorageTy *Name = reinterpret_cast<NameEntryStorageTy *>(this);
191  return (*(Name - 1)).NameEntry;
192  }
193  const StringMapEntry<bool> *&getNameEntryPtr() const {
194  return const_cast<MCSymbol*>(this)->getNameEntryPtr();
195  }
196 
197 public:
198  MCSymbol(const MCSymbol &) = delete;
199  MCSymbol &operator=(const MCSymbol &) = delete;
200 
201  /// getName - Get the symbol name.
202  StringRef getName() const {
203  if (!FragmentAndHasName.getInt())
204  return StringRef();
205 
206  return getNameEntryPtr()->first();
207  }
208 
209  bool isRegistered() const { return IsRegistered; }
210  void setIsRegistered(bool Value) const { IsRegistered = Value; }
211 
212  void setUsedInReloc() const { IsUsedInReloc = true; }
213  bool isUsedInReloc() const { return IsUsedInReloc; }
214 
215  /// \name Accessors
216  /// @{
217 
218  /// isTemporary - Check if this is an assembler temporary symbol.
219  bool isTemporary() const { return IsTemporary; }
220 
221  /// isUsed - Check if this is used.
222  bool isUsed() const { return IsUsed; }
223 
224  /// Check if this symbol is redefinable.
225  bool isRedefinable() const { return IsRedefinable; }
226  /// Mark this symbol as redefinable.
228  /// Prepare this symbol to be redefined.
230  if (IsRedefinable) {
232  Value = nullptr;
234  }
235  setUndefined();
236  IsRedefinable = false;
237  }
238  }
239 
240  /// @}
241  /// \name Associated Sections
242  /// @{
243 
244  /// isDefined - Check if this symbol is defined (i.e., it has an address).
245  ///
246  /// Defined symbols are either absolute or in some section.
247  bool isDefined() const { return !isUndefined(); }
248 
249  /// isInSection - Check if this symbol is defined in some section (i.e., it
250  /// is defined but not absolute).
251  bool isInSection() const {
252  return isDefined() && !isAbsolute();
253  }
254 
255  /// isUndefined - Check if this symbol undefined (i.e., implicitly defined).
256  bool isUndefined(bool SetUsed = true) const {
257  return getFragment(SetUsed) == nullptr;
258  }
259 
260  /// isAbsolute - Check if this is an absolute symbol.
261  bool isAbsolute() const {
263  }
264 
265  /// Get the section associated with a defined, non-absolute symbol.
267  assert(isInSection() && "Invalid accessor!");
268  return *getSectionPtr();
269  }
270 
271  /// Mark the symbol as defined in the fragment \p F.
272  void setFragment(MCFragment *F) const {
273  assert(!isVariable() && "Cannot set fragment of variable");
274  FragmentAndHasName.setPointer(F);
275  }
276 
277  /// Mark the symbol as undefined.
278  void setUndefined() { FragmentAndHasName.setPointer(nullptr); }
279 
280  bool isELF() const { return Kind == SymbolKindELF; }
281 
282  bool isCOFF() const { return Kind == SymbolKindCOFF; }
283 
284  bool isMachO() const { return Kind == SymbolKindMachO; }
285 
286  bool isWasm() const { return Kind == SymbolKindWasm; }
287 
288  /// @}
289  /// \name Variable Symbols
290  /// @{
291 
292  /// isVariable - Check if this is a variable symbol.
293  bool isVariable() const {
295  }
296 
297  /// getVariableValue - Get the value for variable symbols.
298  const MCExpr *getVariableValue(bool SetUsed = true) const {
299  assert(isVariable() && "Invalid accessor!");
300  IsUsed |= SetUsed;
301  return Value;
302  }
303 
304  void setVariableValue(const MCExpr *Value);
305 
306  /// @}
307 
308  /// Get the (implementation defined) index.
309  uint32_t getIndex() const {
310  return Index;
311  }
312 
313  /// Set the (implementation defined) index.
314  void setIndex(uint32_t Value) const {
315  Index = Value;
316  }
317 
318  bool isUnset() const { return SymbolContents == SymContentsUnset; }
319 
320  uint64_t getOffset() const {
323  "Cannot get offset for a common/variable symbol");
324  return Offset;
325  }
326  void setOffset(uint64_t Value) {
329  "Cannot set offset for a common/variable symbol");
330  Offset = Value;
332  }
333 
334  /// Return the size of a 'common' symbol.
335  uint64_t getCommonSize() const {
336  assert(isCommon() && "Not a 'common' symbol!");
337  return CommonSize;
338  }
339 
340  /// Mark this symbol as being 'common'.
341  ///
342  /// \param Size - The size of the symbol.
343  /// \param Align - The alignment of the symbol.
344  void setCommon(uint64_t Size, unsigned Align) {
345  assert(getOffset() == 0);
346  CommonSize = Size;
348 
349  assert((!Align || isPowerOf2_32(Align)) &&
350  "Alignment must be a power of 2");
351  unsigned Log2Align = Log2_32(Align) + 1;
352  assert(Log2Align < (1U << NumCommonAlignmentBits) &&
353  "Out of range alignment");
354  CommonAlignLog2 = Log2Align;
355  }
356 
357  /// Return the alignment of a 'common' symbol.
358  unsigned getCommonAlignment() const {
359  assert(isCommon() && "Not a 'common' symbol!");
360  return CommonAlignLog2 ? (1U << (CommonAlignLog2 - 1)) : 0;
361  }
362 
363  /// Declare this symbol as being 'common'.
364  ///
365  /// \param Size - The size of the symbol.
366  /// \param Align - The alignment of the symbol.
367  /// \return True if symbol was already declared as a different type
368  bool declareCommon(uint64_t Size, unsigned Align) {
369  assert(isCommon() || getOffset() == 0);
370  if(isCommon()) {
371  if(CommonSize != Size || getCommonAlignment() != Align)
372  return true;
373  } else
374  setCommon(Size, Align);
375  return false;
376  }
377 
378  /// Is this a 'common' symbol.
379  bool isCommon() const {
381  }
382 
383  MCFragment *getFragment(bool SetUsed = true) const {
384  MCFragment *Fragment = FragmentAndHasName.getPointer();
385  if (Fragment || !isVariable())
386  return Fragment;
387  Fragment = getVariableValue(SetUsed)->findAssociatedFragment();
388  FragmentAndHasName.setPointer(Fragment);
389  return Fragment;
390  }
391 
392  bool isExternal() const { return IsExternal; }
393  void setExternal(bool Value) const { IsExternal = Value; }
394 
395  bool isPrivateExtern() const { return IsPrivateExtern; }
396  void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
397 
398  /// print - Print the value to the stream \p OS.
399  void print(raw_ostream &OS, const MCAsmInfo *MAI) const;
400 
401  /// dump - Print the value to stderr.
402  void dump() const;
403 
404 protected:
405  /// Get the (implementation defined) symbol flags.
406  uint32_t getFlags() const { return Flags; }
407 
408  /// Set the (implementation defined) symbol flags.
409  void setFlags(uint32_t Value) const {
410  assert(Value < (1U << NumFlagsBits) && "Out of range flags");
411  Flags = Value;
412  }
413 
414  /// Modify the flags via a mask
415  void modifyFlags(uint32_t Value, uint32_t Mask) const {
416  assert(Value < (1U << NumFlagsBits) && "Out of range flags");
417  Flags = (Flags & ~Mask) | Value;
418  }
419 };
420 
421 inline raw_ostream &operator<<(raw_ostream &OS, const MCSymbol &Sym) {
422  Sym.print(OS, nullptr);
423  return OS;
424 }
425 
426 } // end namespace llvm
427 
428 #endif // LLVM_MC_MCSYMBOL_H
bool isCOFF() const
Definition: MCSymbol.h:282
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:38
union { const StringMapEntry< bool > *NameEntry NameEntryStorageTy
The name for a symbol.
Definition: MCSymbol.h:148
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
void setInt(IntType IntVal)
void setPrivateExtern(bool Value)
Definition: MCSymbol.h:396
uint32_t getIndex() const
Get the (implementation defined) index.
Definition: MCSymbol.h:309
void setUsedInReloc() const
Definition: MCSymbol.h:212
unsigned IsRegistered
Definition: MCSymbol.h:93
This class represents lattice values for constants.
Definition: AllocatorList.h:23
PointerTy getPointer() const
bool isVariable() const
isVariable - Check if this is a variable symbol.
Definition: MCSymbol.h:293
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
Definition: StringMap.h:125
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
void redefineIfPossible()
Prepare this symbol to be redefined.
Definition: MCSymbol.h:229
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
bool isWasm() const
Definition: MCSymbol.h:286
unsigned getCommonAlignment() const
Return the alignment of a &#39;common&#39; symbol.
Definition: MCSymbol.h:358
SymbolKind
The kind of the symbol.
Definition: MCSymbol.h:45
F(f)
uint64_t CommonSize
The size of the symbol, if it is &#39;common&#39;.
Definition: MCSymbol.h:133
bool isCommon() const
Is this a &#39;common&#39; symbol.
Definition: MCSymbol.h:379
unsigned IsPrivateExtern
This symbol is private extern.
Definition: MCSymbol.h:99
bool isRedefinable() const
Check if this symbol is redefinable.
Definition: MCSymbol.h:225
void setPointer(PointerTy PtrVal)
void setExternal(bool Value) const
Definition: MCSymbol.h:393
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
Definition: MCSymbol.h:251
void setFragment(MCFragment *F) const
Mark the symbol as defined in the fragment F.
Definition: MCSymbol.h:272
void setCommon(uint64_t Size, unsigned Align)
Mark this symbol as being &#39;common&#39;.
Definition: MCSymbol.h:344
Context object for machine code objects.
Definition: MCContext.h:62
unsigned IsUsedInReloc
True if we have created a relocation that uses this symbol.
Definition: MCSymbol.h:106
IntType getInt() const
uint64_t Offset
The offset to apply to the fragment address to form this symbol&#39;s value.
Definition: MCSymbol.h:130
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:55
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:428
PointerIntPair - This class implements a pair of a pointer and small integer.
void setRedefinable(bool Value)
Mark this symbol as redefinable.
Definition: MCSymbol.h:227
uint32_t Index
Index field, for use by the object file implementation.
Definition: MCSymbol.h:126
unsigned Kind
LLVM RTTI discriminator.
Definition: MCSymbol.h:103
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
Definition: MCSymbol.h:219
uint64_t getCommonSize() const
Return the size of a &#39;common&#39; symbol.
Definition: MCSymbol.h:335
uint64_t getOffset() const
Definition: MCSymbol.h:320
void setOffset(uint64_t Value)
Definition: MCSymbol.h:326
bool isExternal() const
Definition: MCSymbol.h:392
void setFlags(uint32_t Value) const
Set the (implementation defined) symbol flags.
Definition: MCSymbol.h:409
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static MCFragment * AbsolutePseudoFragment
Definition: MCSymbol.h:63
void setUndefined()
Mark the symbol as undefined.
Definition: MCSymbol.h:278
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition: MCSymbol.h:256
MCFragment * getFragment(bool SetUsed=true) const
Definition: MCSymbol.h:383
bool isRegistered() const
Definition: MCSymbol.h:209
unsigned IsUsed
IsUsed - True if this symbol has been used.
Definition: MCSymbol.h:91
uint32_t Flags
Definition: MCSymbol.h:123
unsigned IsExternal
This symbol is visible outside this translation unit.
Definition: MCSymbol.h:96
bool isUsed() const
isUsed - Check if this is used.
Definition: MCSymbol.h:222
unsigned SymbolContents
This is actually a Contents enumerator, but is unsigned to avoid sign extension and achieve better bi...
Definition: MCSymbol.h:110
void setVariableValue(const MCExpr *Value)
Definition: MCSymbol.cpp:48
void dump() const
dump - Print the value to stderr.
Definition: MCSymbol.cpp:85
MCFragment * findAssociatedFragment() const
Find the "associated section" for this expression, which is currently defined as the absolute section...
Definition: MCExpr.cpp:864
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:538
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
Definition: MCSymbol.h:247
bool isMachO() const
Definition: MCSymbol.h:284
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:266
bool isAbsolute() const
isAbsolute - Check if this is an absolute symbol.
Definition: MCSymbol.h:261
void setIsRegistered(bool Value) const
Definition: MCSymbol.h:210
bool isUsedInReloc() const
Definition: MCSymbol.h:213
bool isUnset() const
Definition: MCSymbol.h:318
unsigned CommonAlignLog2
Definition: MCSymbol.h:118
unsigned IsRedefinable
True if this symbol can be redefined.
Definition: MCSymbol.h:88
uint32_t Size
Definition: Profile.cpp:46
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
Definition: APInt.h:2038
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:202
uint64_t AlignmentPadding
Definition: MCSymbol.h:149
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
Definition: MCSymbol.h:298
MCSymbol & operator=(const MCSymbol &)=delete
LLVM Value Representation.
Definition: Value.h:72
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:80
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
const MCExpr * Value
If non-null, the value for a variable symbol.
Definition: MCSymbol.h:136
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
MCSymbol(SymbolKind Kind, const StringMapEntry< bool > *Name, bool isTemporary)
Definition: MCSymbol.h:152
bool isELF() const
Definition: MCSymbol.h:280
PointerIntPair< MCFragment *, 1 > FragmentAndHasName
If a symbol has a Fragment, the section is implied, so we only need one pointer.
Definition: MCSymbol.h:80
Contents
A symbol can contain an Offset, or Value, or be Common, but never more than one of these...
Definition: MCSymbol.h:55
bool declareCommon(uint64_t Size, unsigned Align)
Declare this symbol as being &#39;common&#39;.
Definition: MCSymbol.h:368
bool isPrivateExtern() const
Definition: MCSymbol.h:395
void setIndex(uint32_t Value) const
Set the (implementation defined) index.
Definition: MCSymbol.h:314
void modifyFlags(uint32_t Value, uint32_t Mask) const
Modify the flags via a mask.
Definition: MCSymbol.h:415
uint32_t getFlags() const
Get the (implementation defined) symbol flags.
Definition: MCSymbol.h:406
unsigned IsTemporary
IsTemporary - True if this is an assembler temporary label, which typically does not survive in the ...
Definition: MCSymbol.h:85
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:59