/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/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/MCSymbolELF.h" |
11 | | #include "llvm/BinaryFormat/ELF.h" |
12 | | #include "llvm/MC/MCAssembler.h" |
13 | | #include "llvm/MC/MCFixupKindInfo.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_BindingSet_Shift = 12 |
40 | | }; |
41 | | } |
42 | | |
43 | 1.15M | void MCSymbolELF::setBinding(unsigned Binding) const { |
44 | 1.15M | setIsBindingSet(); |
45 | 1.15M | if (getType() == ELF::STT_SECTION && 1.15M Binding != ELF::STB_LOCAL0 ) |
46 | 0 | setType(ELF::STT_NOTYPE); |
47 | 1.15M | unsigned Val; |
48 | 1.15M | switch (Binding) { |
49 | 0 | default: |
50 | 0 | llvm_unreachable("Unsupported Binding"); |
51 | 1.15M | case ELF::STB_LOCAL: |
52 | 1.15M | Val = 0; |
53 | 1.15M | break; |
54 | 3.67k | case ELF::STB_GLOBAL: |
55 | 3.67k | Val = 1; |
56 | 3.67k | break; |
57 | 181 | case ELF::STB_WEAK: |
58 | 181 | Val = 2; |
59 | 181 | break; |
60 | 2 | case ELF::STB_GNU_UNIQUE: |
61 | 2 | Val = 3; |
62 | 2 | break; |
63 | 1.15M | } |
64 | 1.15M | uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STB_Shift); |
65 | 1.15M | setFlags(OtherFlags | (Val << ELF_STB_Shift)); |
66 | 1.15M | } |
67 | | |
68 | 1.18M | unsigned MCSymbolELF::getBinding() const { |
69 | 1.18M | if (isBindingSet()1.18M ) { |
70 | 1.16M | uint32_t Val = (getFlags() & (0x3 << ELF_STB_Shift)) >> ELF_STB_Shift; |
71 | 1.16M | switch (Val) { |
72 | 0 | default: |
73 | 0 | llvm_unreachable("Invalid value"); |
74 | 1.16M | case 0: |
75 | 1.16M | return ELF::STB_LOCAL; |
76 | 8.38k | case 1: |
77 | 8.38k | return ELF::STB_GLOBAL; |
78 | 458 | case 2: |
79 | 458 | return ELF::STB_WEAK; |
80 | 4 | case 3: |
81 | 4 | return ELF::STB_GNU_UNIQUE; |
82 | 13.1k | } |
83 | 13.1k | } |
84 | 13.1k | |
85 | 13.1k | if (13.1k isDefined()13.1k ) |
86 | 10.2k | return ELF::STB_LOCAL; |
87 | 2.91k | if (2.91k isUsedInReloc()2.91k ) |
88 | 2.78k | return ELF::STB_GLOBAL; |
89 | 133 | if (133 isWeakrefUsedInReloc()133 ) |
90 | 12 | return ELF::STB_WEAK; |
91 | 121 | if (121 isSignature()121 ) |
92 | 90 | return ELF::STB_LOCAL; |
93 | 31 | return ELF::STB_GLOBAL; |
94 | 31 | } |
95 | | |
96 | 1.16M | void MCSymbolELF::setType(unsigned Type) const { |
97 | 1.16M | unsigned Val; |
98 | 1.16M | if (Type == ELF::STT_SECTION && 1.16M getBinding() != ELF::STB_LOCAL1.15M ) |
99 | 0 | return; |
100 | 1.16M | switch (Type) { |
101 | 0 | default: |
102 | 0 | llvm_unreachable("Unsupported Binding"); |
103 | 853 | case ELF::STT_NOTYPE: |
104 | 853 | Val = 0; |
105 | 853 | break; |
106 | 687 | case ELF::STT_OBJECT: |
107 | 687 | Val = 1; |
108 | 687 | break; |
109 | 2.76k | case ELF::STT_FUNC: |
110 | 2.76k | Val = 2; |
111 | 2.76k | break; |
112 | 1.15M | case ELF::STT_SECTION: |
113 | 1.15M | Val = 3; |
114 | 1.15M | break; |
115 | 0 | case ELF::STT_COMMON: |
116 | 0 | Val = 4; |
117 | 0 | break; |
118 | 1.01k | case ELF::STT_TLS: |
119 | 1.01k | Val = 5; |
120 | 1.01k | break; |
121 | 261 | case ELF::STT_GNU_IFUNC: |
122 | 261 | Val = 6; |
123 | 261 | break; |
124 | 1.16M | } |
125 | 1.16M | uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STT_Shift); |
126 | 1.16M | setFlags(OtherFlags | (Val << ELF_STT_Shift)); |
127 | 1.16M | } |
128 | | |
129 | 1.59M | unsigned MCSymbolELF::getType() const { |
130 | 1.59M | uint32_t Val = (getFlags() & (0x7 << ELF_STT_Shift)) >> ELF_STT_Shift; |
131 | 1.59M | switch (Val) { |
132 | 0 | default: |
133 | 0 | llvm_unreachable("Invalid value"); |
134 | 1.22M | case 0: |
135 | 1.22M | return ELF::STT_NOTYPE; |
136 | 5.06k | case 1: |
137 | 5.06k | return ELF::STT_OBJECT; |
138 | 20.3k | case 2: |
139 | 20.3k | return ELF::STT_FUNC; |
140 | 346k | case 3: |
141 | 346k | return ELF::STT_SECTION; |
142 | 0 | case 4: |
143 | 0 | return ELF::STT_COMMON; |
144 | 1.74k | case 5: |
145 | 1.74k | return ELF::STT_TLS; |
146 | 3.89k | case 6: |
147 | 3.89k | return ELF::STT_GNU_IFUNC; |
148 | 0 | } |
149 | 0 | } |
150 | | |
151 | 165 | void MCSymbolELF::setVisibility(unsigned Visibility) { |
152 | 165 | assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || |
153 | 165 | Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); |
154 | 165 | |
155 | 165 | uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STV_Shift); |
156 | 165 | setFlags(OtherFlags | (Visibility << ELF_STV_Shift)); |
157 | 165 | } |
158 | | |
159 | 9.71k | unsigned MCSymbolELF::getVisibility() const { |
160 | 9.71k | unsigned Visibility = (getFlags() & (0x3 << ELF_STV_Shift)) >> ELF_STV_Shift; |
161 | 9.71k | assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || |
162 | 9.71k | Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); |
163 | 9.71k | return Visibility; |
164 | 9.71k | } |
165 | | |
166 | 79 | void MCSymbolELF::setOther(unsigned Other) { |
167 | 79 | assert((Other & 0x1f) == 0); |
168 | 79 | Other >>= 5; |
169 | 79 | assert(Other <= 0x7); |
170 | 79 | uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STO_Shift); |
171 | 79 | setFlags(OtherFlags | (Other << ELF_STO_Shift)); |
172 | 79 | } |
173 | | |
174 | 10.1k | unsigned MCSymbolELF::getOther() const { |
175 | 10.1k | unsigned Other = (getFlags() & (0x7 << ELF_STO_Shift)) >> ELF_STO_Shift; |
176 | 10.1k | return Other << 5; |
177 | 10.1k | } |
178 | | |
179 | 12 | void MCSymbolELF::setIsWeakrefUsedInReloc() const { |
180 | 12 | uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_WeakrefUsedInReloc_Shift); |
181 | 12 | setFlags(OtherFlags | (1 << ELF_WeakrefUsedInReloc_Shift)); |
182 | 12 | } |
183 | | |
184 | 356k | bool MCSymbolELF::isWeakrefUsedInReloc() const { |
185 | 356k | return getFlags() & (0x1 << ELF_WeakrefUsedInReloc_Shift); |
186 | 356k | } |
187 | | |
188 | 340 | void MCSymbolELF::setIsSignature() const { |
189 | 340 | uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_IsSignature_Shift); |
190 | 340 | setFlags(OtherFlags | (1 << ELF_IsSignature_Shift)); |
191 | 340 | } |
192 | | |
193 | 356k | bool MCSymbolELF::isSignature() const { |
194 | 356k | return getFlags() & (0x1 << ELF_IsSignature_Shift); |
195 | 356k | } |
196 | | |
197 | 1.15M | void MCSymbolELF::setIsBindingSet() const { |
198 | 1.15M | uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_BindingSet_Shift); |
199 | 1.15M | setFlags(OtherFlags | (1 << ELF_BindingSet_Shift)); |
200 | 1.15M | } |
201 | | |
202 | 1.18M | bool MCSymbolELF::isBindingSet() const { |
203 | 1.18M | return getFlags() & (0x1 << ELF_BindingSet_Shift); |
204 | 1.18M | } |
205 | | } |