xref: /freebsd/contrib/llvm-project/llvm/include/llvm/MC/MCSymbolMachO.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===- MCSymbolMachO.h -  ---------------------------------------*- 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 #ifndef LLVM_MC_MCSYMBOLMACHO_H
9 #define LLVM_MC_MCSYMBOLMACHO_H
10 
11 #include "llvm/ADT/Twine.h"
12 #include "llvm/MC/MCSymbol.h"
13 #include "llvm/MC/MCSymbolTableEntry.h"
14 
15 namespace llvm {
16 class MCSymbolMachO : public MCSymbol {
17   /// We store the value for the 'desc' symbol field in the
18   /// lowest 16 bits of the implementation defined flags.
19   enum MachOSymbolFlags : uint16_t { // See <mach-o/nlist.h>.
20     SF_DescFlagsMask                        = 0xFFFF,
21 
22     // Reference type flags.
23     SF_ReferenceTypeMask                    = 0x0007,
24     SF_ReferenceTypeUndefinedNonLazy        = 0x0000,
25     SF_ReferenceTypeUndefinedLazy           = 0x0001,
26     SF_ReferenceTypeDefined                 = 0x0002,
27     SF_ReferenceTypePrivateDefined          = 0x0003,
28     SF_ReferenceTypePrivateUndefinedNonLazy = 0x0004,
29     SF_ReferenceTypePrivateUndefinedLazy    = 0x0005,
30 
31     // Other 'desc' flags.
32     SF_ThumbFunc                            = 0x0008,
33     SF_NoDeadStrip                          = 0x0020,
34     SF_WeakReference                        = 0x0040,
35     SF_WeakDefinition                       = 0x0080,
36     SF_SymbolResolver                       = 0x0100,
37     SF_AltEntry                             = 0x0200,
38     SF_Cold                                 = 0x0400,
39 
40     // Common alignment
41     SF_CommonAlignmentMask                  = 0xF0FF,
42     SF_CommonAlignmentShift                 = 8
43   };
44 
45 public:
MCSymbolMachO(const MCSymbolTableEntry * Name,bool isTemporary)46   MCSymbolMachO(const MCSymbolTableEntry *Name, bool isTemporary)
47       : MCSymbol(SymbolKindMachO, Name, isTemporary) {}
48 
isPrivateExtern()49   bool isPrivateExtern() const { return IsPrivateExtern; }
setPrivateExtern(bool Value)50   void setPrivateExtern(bool Value) { IsPrivateExtern = Value; }
51 
52   // Reference type methods.
53 
clearReferenceType()54   void clearReferenceType() const {
55     modifyFlags(0, SF_ReferenceTypeMask);
56   }
57 
setReferenceTypeUndefinedLazy(bool Value)58   void setReferenceTypeUndefinedLazy(bool Value) const {
59     modifyFlags(Value ? SF_ReferenceTypeUndefinedLazy : 0,
60                 SF_ReferenceTypeUndefinedLazy);
61   }
62 
63   // Other 'desc' methods.
64 
setThumbFunc()65   void setThumbFunc() const {
66     modifyFlags(SF_ThumbFunc, SF_ThumbFunc);
67   }
68 
isNoDeadStrip()69   bool isNoDeadStrip() const {
70     return getFlags() & SF_NoDeadStrip;
71   }
setNoDeadStrip()72   void setNoDeadStrip() const {
73     modifyFlags(SF_NoDeadStrip, SF_NoDeadStrip);
74   }
75 
isWeakReference()76   bool isWeakReference() const {
77     return getFlags() & SF_WeakReference;
78   }
setWeakReference()79   void setWeakReference() const {
80     modifyFlags(SF_WeakReference, SF_WeakReference);
81   }
82 
isWeakDefinition()83   bool isWeakDefinition() const {
84     return getFlags() & SF_WeakDefinition;
85   }
setWeakDefinition()86   void setWeakDefinition() const {
87     modifyFlags(SF_WeakDefinition, SF_WeakDefinition);
88   }
89 
isSymbolResolver()90   bool isSymbolResolver() const {
91     return getFlags() & SF_SymbolResolver;
92   }
setSymbolResolver()93   void setSymbolResolver() const {
94     modifyFlags(SF_SymbolResolver, SF_SymbolResolver);
95   }
96 
setAltEntry()97   void setAltEntry() const {
98     modifyFlags(SF_AltEntry, SF_AltEntry);
99   }
100 
isAltEntry()101   bool isAltEntry() const {
102     return getFlags() & SF_AltEntry;
103   }
104 
setCold()105   void setCold() const { modifyFlags(SF_Cold, SF_Cold); }
106 
isCold()107   bool isCold() const { return getFlags() & SF_Cold; }
108 
setDesc(unsigned Value)109   void setDesc(unsigned Value) const {
110     assert(Value == (Value & SF_DescFlagsMask) &&
111            "Invalid .desc value!");
112     setFlags(Value & SF_DescFlagsMask);
113   }
114 
115   // Check whether a particular symbol is visible to the linker and is required
116   // in the symbol table, or whether it can be discarded by the assembler. This
117   // also effects whether the assembler treats the label as potentially defining
118   // a separate atom.
isSymbolLinkerVisible()119   bool isSymbolLinkerVisible() const {
120     // Non-temporary labels should always be visible to the linker.
121     if (!isTemporary())
122       return true;
123 
124     return isUsedInReloc();
125   }
126 
127   /// Get the encoded value of the flags as they will be emitted in to
128   /// the MachO binary
getEncodedFlags(bool EncodeAsAltEntry)129   uint16_t getEncodedFlags(bool EncodeAsAltEntry) const {
130     uint16_t Flags = getFlags();
131 
132     // Common alignment is packed into the 'desc' bits.
133     if (isCommon()) {
134       if (MaybeAlign MaybeAlignment = getCommonAlignment()) {
135         Align Alignment = *MaybeAlignment;
136         unsigned Log2Size = Log2(Alignment);
137         if (Log2Size > 15)
138           report_fatal_error("invalid 'common' alignment '" +
139                                  Twine(Alignment.value()) + "' for '" +
140                                  getName() + "'",
141                              false);
142         Flags = (Flags & SF_CommonAlignmentMask) |
143                 (Log2Size << SF_CommonAlignmentShift);
144       }
145     }
146 
147     if (EncodeAsAltEntry)
148       Flags |= SF_AltEntry;
149 
150     return Flags;
151   }
152 
classof(const MCSymbol * S)153   static bool classof(const MCSymbol *S) { return S->isMachO(); }
154 };
155 }
156 
157 #endif
158