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