1 //===- lib/MC/MCSymbolELF.cpp ---------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/MC/MCSymbolELF.h"
11 #include "llvm/BinaryFormat/ELF.h"
12 #include "llvm/MC/MCFixupKindInfo.h"
18 // Shift value for STT_* flags. 7 possible values. 3 bits.
21 // Shift value for STB_* flags. 4 possible values, 2 bits.
24 // Shift value for STV_* flags. 4 possible values, 2 bits.
27 // Shift value for STO_* flags. 3 bits. All the values are between 0x20 and
28 // 0xe0, so we shift right by 5 before storing.
32 ELF_IsSignature_Shift
= 10,
35 ELF_WeakrefUsedInReloc_Shift
= 11,
38 ELF_BindingSet_Shift
= 12
42 void MCSymbolELF::setBinding(unsigned Binding
) const {
44 if (getType() == ELF::STT_SECTION
&& Binding
!= ELF::STB_LOCAL
)
45 setType(ELF::STT_NOTYPE
);
49 llvm_unreachable("Unsupported Binding");
59 case ELF::STB_GNU_UNIQUE
:
63 uint32_t OtherFlags
= getFlags() & ~(0x3 << ELF_STB_Shift
);
64 setFlags(OtherFlags
| (Val
<< ELF_STB_Shift
));
67 unsigned MCSymbolELF::getBinding() const {
69 uint32_t Val
= (getFlags() & (0x3 << ELF_STB_Shift
)) >> ELF_STB_Shift
;
72 llvm_unreachable("Invalid value");
74 return ELF::STB_LOCAL
;
76 return ELF::STB_GLOBAL
;
80 return ELF::STB_GNU_UNIQUE
;
85 return ELF::STB_LOCAL
;
87 return ELF::STB_GLOBAL
;
88 if (isWeakrefUsedInReloc())
91 return ELF::STB_LOCAL
;
92 return ELF::STB_GLOBAL
;
95 void MCSymbolELF::setType(unsigned Type
) const {
97 if (Type
== ELF::STT_SECTION
&& getBinding() != ELF::STB_LOCAL
)
101 llvm_unreachable("Unsupported Binding");
102 case ELF::STT_NOTYPE
:
105 case ELF::STT_OBJECT
:
111 case ELF::STT_SECTION
:
114 case ELF::STT_COMMON
:
120 case ELF::STT_GNU_IFUNC
:
124 uint32_t OtherFlags
= getFlags() & ~(0x7 << ELF_STT_Shift
);
125 setFlags(OtherFlags
| (Val
<< ELF_STT_Shift
));
128 unsigned MCSymbolELF::getType() const {
129 uint32_t Val
= (getFlags() & (0x7 << ELF_STT_Shift
)) >> ELF_STT_Shift
;
132 llvm_unreachable("Invalid value");
134 return ELF::STT_NOTYPE
;
136 return ELF::STT_OBJECT
;
138 return ELF::STT_FUNC
;
140 return ELF::STT_SECTION
;
142 return ELF::STT_COMMON
;
146 return ELF::STT_GNU_IFUNC
;
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
);
154 uint32_t OtherFlags
= getFlags() & ~(0x3 << ELF_STV_Shift
);
155 setFlags(OtherFlags
| (Visibility
<< ELF_STV_Shift
));
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
);
165 void MCSymbolELF::setOther(unsigned Other
) {
166 assert((Other
& 0x1f) == 0);
168 assert(Other
<= 0x7);
169 uint32_t OtherFlags
= getFlags() & ~(0x7 << ELF_STO_Shift
);
170 setFlags(OtherFlags
| (Other
<< ELF_STO_Shift
));
173 unsigned MCSymbolELF::getOther() const {
174 unsigned Other
= (getFlags() & (0x7 << ELF_STO_Shift
)) >> ELF_STO_Shift
;
178 void MCSymbolELF::setIsWeakrefUsedInReloc() const {
179 uint32_t OtherFlags
= getFlags() & ~(0x1 << ELF_WeakrefUsedInReloc_Shift
);
180 setFlags(OtherFlags
| (1 << ELF_WeakrefUsedInReloc_Shift
));
183 bool MCSymbolELF::isWeakrefUsedInReloc() const {
184 return getFlags() & (0x1 << ELF_WeakrefUsedInReloc_Shift
);
187 void MCSymbolELF::setIsSignature() const {
188 uint32_t OtherFlags
= getFlags() & ~(0x1 << ELF_IsSignature_Shift
);
189 setFlags(OtherFlags
| (1 << ELF_IsSignature_Shift
));
192 bool MCSymbolELF::isSignature() const {
193 return getFlags() & (0x1 << ELF_IsSignature_Shift
);
196 void MCSymbolELF::setIsBindingSet() const {
197 uint32_t OtherFlags
= getFlags() & ~(0x1 << ELF_BindingSet_Shift
);
198 setFlags(OtherFlags
| (1 << ELF_BindingSet_Shift
));
201 bool MCSymbolELF::isBindingSet() const {
202 return getFlags() & (0x1 << ELF_BindingSet_Shift
);