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