Re-unique_ptrify LoadedObjectInfo::clone after it was reverted due to some other...
[oota-llvm.git] / lib / MC / MCSymbolELF.cpp
1 //===- lib/MC/MCSymbolELF.cpp ---------------------------------------------===//
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 #include "llvm/MC/MCAssembler.h"
11 #include "llvm/MC/MCSymbolELF.h"
12 #include "llvm/MC/MCFixupKindInfo.h"
13 #include "llvm/Support/ELF.h"
14
15 namespace llvm {
16
17 namespace {
18 enum {
19   // Shift value for STT_* flags. 7 possible values. 3 bits.
20   ELF_STT_Shift = 0,
21
22   // Shift value for STB_* flags. 4 possible values, 2 bits.
23   ELF_STB_Shift = 3,
24
25   // Shift value for STV_* flags. 4 possible values, 2 bits.
26   ELF_STV_Shift = 5,
27
28   // Shift value for STO_* flags. 3 bits. All the values are between 0x20 and
29   // 0xe0, so we shift right by 5 before storing.
30   ELF_STO_Shift = 7,
31
32   // One bit.
33   ELF_IsSignature_Shift = 10,
34
35   // One bit.
36   ELF_WeakrefUsedInReloc_Shift = 11,
37
38   // One bit.
39   ELF_UsedInReloc_Shift = 12,
40
41   // One bit.
42   ELF_BindingSet_Shift = 13
43 };
44 }
45
46 void MCSymbolELF::setBinding(unsigned Binding) const {
47   setIsBindingSet();
48   unsigned Val;
49   switch (Binding) {
50   default:
51     llvm_unreachable("Unsupported Binding");
52   case ELF::STB_LOCAL:
53     Val = 0;
54     break;
55   case ELF::STB_GLOBAL:
56     Val = 1;
57     break;
58   case ELF::STB_WEAK:
59     Val = 2;
60     break;
61   case ELF::STB_GNU_UNIQUE:
62     Val = 3;
63     break;
64   }
65   uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STB_Shift);
66   setFlags(OtherFlags | (Val << ELF_STB_Shift));
67 }
68
69 unsigned MCSymbolELF::getBinding() const {
70   if (isBindingSet()) {
71     uint32_t Val = (getFlags() & (0x3 << ELF_STB_Shift)) >> ELF_STB_Shift;
72     switch (Val) {
73     default:
74       llvm_unreachable("Invalid value");
75     case 0:
76       return ELF::STB_LOCAL;
77     case 1:
78       return ELF::STB_GLOBAL;
79     case 2:
80       return ELF::STB_WEAK;
81     case 3:
82       return ELF::STB_GNU_UNIQUE;
83     }
84   }
85
86   if (isDefined())
87     return ELF::STB_LOCAL;
88   if (isUsedInReloc())
89     return ELF::STB_GLOBAL;
90   if (isWeakrefUsedInReloc())
91     return ELF::STB_WEAK;
92   if (isSignature())
93     return ELF::STB_LOCAL;
94   return ELF::STB_GLOBAL;
95 }
96
97 void MCSymbolELF::setType(unsigned Type) const {
98   unsigned Val;
99   switch (Type) {
100   default:
101     llvm_unreachable("Unsupported Binding");
102   case ELF::STT_NOTYPE:
103     Val = 0;
104     break;
105   case ELF::STT_OBJECT:
106     Val = 1;
107     break;
108   case ELF::STT_FUNC:
109     Val = 2;
110     break;
111   case ELF::STT_SECTION:
112     Val = 3;
113     break;
114   case ELF::STT_COMMON:
115     Val = 4;
116     break;
117   case ELF::STT_TLS:
118     Val = 5;
119     break;
120   case ELF::STT_GNU_IFUNC:
121     Val = 6;
122     break;
123   }
124   uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STT_Shift);
125   setFlags(OtherFlags | (Val << ELF_STT_Shift));
126 }
127
128 unsigned MCSymbolELF::getType() const {
129   uint32_t Val = (getFlags() & (0x7 << ELF_STT_Shift)) >> ELF_STT_Shift;
130   switch (Val) {
131   default:
132     llvm_unreachable("Invalid value");
133   case 0:
134     return ELF::STT_NOTYPE;
135   case 1:
136     return ELF::STT_OBJECT;
137   case 2:
138     return ELF::STT_FUNC;
139   case 3:
140     return ELF::STT_SECTION;
141   case 4:
142     return ELF::STT_COMMON;
143   case 5:
144     return ELF::STT_TLS;
145   case 6:
146     return ELF::STT_GNU_IFUNC;
147   }
148 }
149
150 void MCSymbolELF::setVisibility(unsigned Visibility) {
151   assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
152          Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
153
154   uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STV_Shift);
155   setFlags(OtherFlags | (Visibility << ELF_STV_Shift));
156 }
157
158 unsigned MCSymbolELF::getVisibility() const {
159   unsigned Visibility = (getFlags() & (0x3 << ELF_STV_Shift)) >> ELF_STV_Shift;
160   assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
161          Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
162   return Visibility;
163 }
164
165 void MCSymbolELF::setOther(unsigned Other) {
166   assert((Other & 0x1f) == 0);
167   Other >>= 5;
168   assert(Other <= 0x7);
169   uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STO_Shift);
170   setFlags(OtherFlags | (Other << ELF_STO_Shift));
171 }
172
173 unsigned MCSymbolELF::getOther() const {
174   unsigned Other = (getFlags() & (0x7 << ELF_STO_Shift)) >> ELF_STO_Shift;
175   return Other << 5;
176 }
177
178 void MCSymbolELF::setUsedInReloc() const {
179   uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_UsedInReloc_Shift);
180   setFlags(OtherFlags | (1 << ELF_UsedInReloc_Shift));
181 }
182
183 bool MCSymbolELF::isUsedInReloc() const {
184   return getFlags() & (0x1 << ELF_UsedInReloc_Shift);
185 }
186
187 void MCSymbolELF::setIsWeakrefUsedInReloc() const {
188   uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_WeakrefUsedInReloc_Shift);
189   setFlags(OtherFlags | (1 << ELF_WeakrefUsedInReloc_Shift));
190 }
191
192 bool MCSymbolELF::isWeakrefUsedInReloc() const {
193   return getFlags() & (0x1 << ELF_WeakrefUsedInReloc_Shift);
194 }
195
196 void MCSymbolELF::setIsSignature() const {
197   uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_IsSignature_Shift);
198   setFlags(OtherFlags | (1 << ELF_IsSignature_Shift));
199 }
200
201 bool MCSymbolELF::isSignature() const {
202   return getFlags() & (0x1 << ELF_IsSignature_Shift);
203 }
204
205 void MCSymbolELF::setIsBindingSet() const {
206   uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_BindingSet_Shift);
207   setFlags(OtherFlags | (1 << ELF_BindingSet_Shift));
208 }
209
210 bool MCSymbolELF::isBindingSet() const {
211   return getFlags() & (0x1 << ELF_BindingSet_Shift);
212 }
213 }