/src/keystone/llvm/lib/MC/MCSymbolELF.cpp
Line | Count | Source (jump to first uncovered line) |
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_ks { |
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_BindingSet_Shift = 12 |
40 | | }; |
41 | | } |
42 | | |
43 | 6.15k | void MCSymbolELF::setBinding(unsigned Binding) const { |
44 | 6.15k | setIsBindingSet(); |
45 | 6.15k | unsigned Val; |
46 | 6.15k | switch (Binding) { |
47 | 0 | default: |
48 | 0 | llvm_unreachable("Unsupported Binding"); |
49 | 2.32k | case ELF::STB_LOCAL: |
50 | 2.32k | Val = 0; |
51 | 2.32k | break; |
52 | 3.83k | case ELF::STB_GLOBAL: |
53 | 3.83k | Val = 1; |
54 | 3.83k | break; |
55 | 0 | case ELF::STB_WEAK: |
56 | 0 | Val = 2; |
57 | 0 | break; |
58 | 0 | case ELF::STB_GNU_UNIQUE: |
59 | 0 | Val = 3; |
60 | 0 | break; |
61 | 6.15k | } |
62 | 6.15k | uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STB_Shift); |
63 | 6.15k | setFlags(OtherFlags | (Val << ELF_STB_Shift)); |
64 | 6.15k | } |
65 | | |
66 | 127k | unsigned MCSymbolELF::getBinding() const { |
67 | 127k | if (isBindingSet()) { |
68 | 8.95k | uint32_t Val = (getFlags() & (0x3 << ELF_STB_Shift)) >> ELF_STB_Shift; |
69 | 8.95k | switch (Val) { |
70 | 0 | default: |
71 | 0 | llvm_unreachable("Invalid value"); |
72 | 437 | case 0: |
73 | 437 | return ELF::STB_LOCAL; |
74 | 8.52k | case 1: |
75 | 8.52k | return ELF::STB_GLOBAL; |
76 | 0 | case 2: |
77 | 0 | return ELF::STB_WEAK; |
78 | 0 | case 3: |
79 | 0 | return ELF::STB_GNU_UNIQUE; |
80 | 8.95k | } |
81 | 8.95k | } |
82 | | |
83 | 118k | if (isDefined()) |
84 | 116k | return ELF::STB_LOCAL; |
85 | 2.07k | if (isUsedInReloc()) |
86 | 0 | return ELF::STB_GLOBAL; |
87 | 2.07k | if (isWeakrefUsedInReloc()) |
88 | 0 | return ELF::STB_WEAK; |
89 | 2.07k | if (isSignature()) |
90 | 0 | return ELF::STB_LOCAL; |
91 | 2.07k | return ELF::STB_GLOBAL; |
92 | 2.07k | } |
93 | | |
94 | 175k | void MCSymbolELF::setType(unsigned Type) const { |
95 | 175k | unsigned Val; |
96 | 175k | switch (Type) { |
97 | 0 | default: |
98 | 0 | llvm_unreachable("Unsupported Binding"); |
99 | 0 | case ELF::STT_NOTYPE: |
100 | 0 | Val = 0; |
101 | 0 | break; |
102 | 8.95k | case ELF::STT_OBJECT: |
103 | 8.95k | Val = 1; |
104 | 8.95k | break; |
105 | 0 | case ELF::STT_FUNC: |
106 | 0 | Val = 2; |
107 | 0 | break; |
108 | 134k | case ELF::STT_SECTION: |
109 | 134k | Val = 3; |
110 | 134k | break; |
111 | 0 | case ELF::STT_COMMON: |
112 | 0 | Val = 4; |
113 | 0 | break; |
114 | 32.2k | case ELF::STT_TLS: |
115 | 32.2k | Val = 5; |
116 | 32.2k | break; |
117 | 0 | case ELF::STT_GNU_IFUNC: |
118 | 0 | Val = 6; |
119 | 0 | break; |
120 | 175k | } |
121 | 175k | uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STT_Shift); |
122 | 175k | setFlags(OtherFlags | (Val << ELF_STT_Shift)); |
123 | 175k | } |
124 | | |
125 | 25.4k | unsigned MCSymbolELF::getType() const { |
126 | 25.4k | uint32_t Val = (getFlags() & (0x7 << ELF_STT_Shift)) >> ELF_STT_Shift; |
127 | 25.4k | switch (Val) { |
128 | 0 | default: |
129 | 0 | llvm_unreachable("Invalid value"); |
130 | 25.3k | case 0: |
131 | 25.3k | return ELF::STT_NOTYPE; |
132 | 0 | case 1: |
133 | 0 | return ELF::STT_OBJECT; |
134 | 0 | case 2: |
135 | 0 | return ELF::STT_FUNC; |
136 | 0 | case 3: |
137 | 0 | return ELF::STT_SECTION; |
138 | 0 | case 4: |
139 | 0 | return ELF::STT_COMMON; |
140 | 92 | case 5: |
141 | 92 | return ELF::STT_TLS; |
142 | 0 | case 6: |
143 | 0 | return ELF::STT_GNU_IFUNC; |
144 | 25.4k | } |
145 | 25.4k | } |
146 | | |
147 | 0 | void MCSymbolELF::setVisibility(unsigned Visibility) { |
148 | 0 | assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || |
149 | 0 | Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); |
150 | | |
151 | 0 | uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STV_Shift); |
152 | 0 | setFlags(OtherFlags | (Visibility << ELF_STV_Shift)); |
153 | 0 | } |
154 | | |
155 | 0 | unsigned MCSymbolELF::getVisibility() const { |
156 | 0 | unsigned Visibility = (getFlags() & (0x3 << ELF_STV_Shift)) >> ELF_STV_Shift; |
157 | 0 | assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || |
158 | 0 | Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); |
159 | 0 | return Visibility; |
160 | 0 | } |
161 | | |
162 | 0 | void MCSymbolELF::setOther(unsigned Other) { |
163 | 0 | assert((Other & 0x1f) == 0); |
164 | 0 | Other >>= 5; |
165 | 0 | assert(Other <= 0x7); |
166 | 0 | uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STO_Shift); |
167 | 0 | setFlags(OtherFlags | (Other << ELF_STO_Shift)); |
168 | 0 | } |
169 | | |
170 | 7.65k | unsigned MCSymbolELF::getOther() const { |
171 | 7.65k | unsigned Other = (getFlags() & (0x7 << ELF_STO_Shift)) >> ELF_STO_Shift; |
172 | 7.65k | return Other << 5; |
173 | 7.65k | } |
174 | | |
175 | 0 | void MCSymbolELF::setIsWeakrefUsedInReloc() const { |
176 | 0 | uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_WeakrefUsedInReloc_Shift); |
177 | 0 | setFlags(OtherFlags | (1 << ELF_WeakrefUsedInReloc_Shift)); |
178 | 0 | } |
179 | | |
180 | 2.07k | bool MCSymbolELF::isWeakrefUsedInReloc() const { |
181 | 2.07k | return getFlags() & (0x1 << ELF_WeakrefUsedInReloc_Shift); |
182 | 2.07k | } |
183 | | |
184 | 0 | void MCSymbolELF::setIsSignature() const { |
185 | 0 | uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_IsSignature_Shift); |
186 | 0 | setFlags(OtherFlags | (1 << ELF_IsSignature_Shift)); |
187 | 0 | } |
188 | | |
189 | 2.07k | bool MCSymbolELF::isSignature() const { |
190 | 2.07k | return getFlags() & (0x1 << ELF_IsSignature_Shift); |
191 | 2.07k | } |
192 | | |
193 | 6.15k | void MCSymbolELF::setIsBindingSet() const { |
194 | 6.15k | uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_BindingSet_Shift); |
195 | 6.15k | setFlags(OtherFlags | (1 << ELF_BindingSet_Shift)); |
196 | 6.15k | } |
197 | | |
198 | 136k | bool MCSymbolELF::isBindingSet() const { |
199 | 136k | return getFlags() & (0x1 << ELF_BindingSet_Shift); |
200 | 136k | } |
201 | | } |