xref: /aosp_15_r20/external/llvm/lib/MC/MCSymbolELF.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- lib/MC/MCSymbolELF.cpp ---------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAssembler.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbolELF.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCFixupKindInfo.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ELF.h"
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker namespace llvm {
16*9880d681SAndroid Build Coastguard Worker 
17*9880d681SAndroid Build Coastguard Worker namespace {
18*9880d681SAndroid Build Coastguard Worker enum {
19*9880d681SAndroid Build Coastguard Worker   // Shift value for STT_* flags. 7 possible values. 3 bits.
20*9880d681SAndroid Build Coastguard Worker   ELF_STT_Shift = 0,
21*9880d681SAndroid Build Coastguard Worker 
22*9880d681SAndroid Build Coastguard Worker   // Shift value for STB_* flags. 4 possible values, 2 bits.
23*9880d681SAndroid Build Coastguard Worker   ELF_STB_Shift = 3,
24*9880d681SAndroid Build Coastguard Worker 
25*9880d681SAndroid Build Coastguard Worker   // Shift value for STV_* flags. 4 possible values, 2 bits.
26*9880d681SAndroid Build Coastguard Worker   ELF_STV_Shift = 5,
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker   // Shift value for STO_* flags. 3 bits. All the values are between 0x20 and
29*9880d681SAndroid Build Coastguard Worker   // 0xe0, so we shift right by 5 before storing.
30*9880d681SAndroid Build Coastguard Worker   ELF_STO_Shift = 7,
31*9880d681SAndroid Build Coastguard Worker 
32*9880d681SAndroid Build Coastguard Worker   // One bit.
33*9880d681SAndroid Build Coastguard Worker   ELF_IsSignature_Shift = 10,
34*9880d681SAndroid Build Coastguard Worker 
35*9880d681SAndroid Build Coastguard Worker   // One bit.
36*9880d681SAndroid Build Coastguard Worker   ELF_WeakrefUsedInReloc_Shift = 11,
37*9880d681SAndroid Build Coastguard Worker 
38*9880d681SAndroid Build Coastguard Worker   // One bit.
39*9880d681SAndroid Build Coastguard Worker   ELF_BindingSet_Shift = 12
40*9880d681SAndroid Build Coastguard Worker };
41*9880d681SAndroid Build Coastguard Worker }
42*9880d681SAndroid Build Coastguard Worker 
setBinding(unsigned Binding) const43*9880d681SAndroid Build Coastguard Worker void MCSymbolELF::setBinding(unsigned Binding) const {
44*9880d681SAndroid Build Coastguard Worker   setIsBindingSet();
45*9880d681SAndroid Build Coastguard Worker   unsigned Val;
46*9880d681SAndroid Build Coastguard Worker   switch (Binding) {
47*9880d681SAndroid Build Coastguard Worker   default:
48*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unsupported Binding");
49*9880d681SAndroid Build Coastguard Worker   case ELF::STB_LOCAL:
50*9880d681SAndroid Build Coastguard Worker     Val = 0;
51*9880d681SAndroid Build Coastguard Worker     break;
52*9880d681SAndroid Build Coastguard Worker   case ELF::STB_GLOBAL:
53*9880d681SAndroid Build Coastguard Worker     Val = 1;
54*9880d681SAndroid Build Coastguard Worker     break;
55*9880d681SAndroid Build Coastguard Worker   case ELF::STB_WEAK:
56*9880d681SAndroid Build Coastguard Worker     Val = 2;
57*9880d681SAndroid Build Coastguard Worker     break;
58*9880d681SAndroid Build Coastguard Worker   case ELF::STB_GNU_UNIQUE:
59*9880d681SAndroid Build Coastguard Worker     Val = 3;
60*9880d681SAndroid Build Coastguard Worker     break;
61*9880d681SAndroid Build Coastguard Worker   }
62*9880d681SAndroid Build Coastguard Worker   uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STB_Shift);
63*9880d681SAndroid Build Coastguard Worker   setFlags(OtherFlags | (Val << ELF_STB_Shift));
64*9880d681SAndroid Build Coastguard Worker }
65*9880d681SAndroid Build Coastguard Worker 
getBinding() const66*9880d681SAndroid Build Coastguard Worker unsigned MCSymbolELF::getBinding() const {
67*9880d681SAndroid Build Coastguard Worker   if (isBindingSet()) {
68*9880d681SAndroid Build Coastguard Worker     uint32_t Val = (getFlags() & (0x3 << ELF_STB_Shift)) >> ELF_STB_Shift;
69*9880d681SAndroid Build Coastguard Worker     switch (Val) {
70*9880d681SAndroid Build Coastguard Worker     default:
71*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Invalid value");
72*9880d681SAndroid Build Coastguard Worker     case 0:
73*9880d681SAndroid Build Coastguard Worker       return ELF::STB_LOCAL;
74*9880d681SAndroid Build Coastguard Worker     case 1:
75*9880d681SAndroid Build Coastguard Worker       return ELF::STB_GLOBAL;
76*9880d681SAndroid Build Coastguard Worker     case 2:
77*9880d681SAndroid Build Coastguard Worker       return ELF::STB_WEAK;
78*9880d681SAndroid Build Coastguard Worker     case 3:
79*9880d681SAndroid Build Coastguard Worker       return ELF::STB_GNU_UNIQUE;
80*9880d681SAndroid Build Coastguard Worker     }
81*9880d681SAndroid Build Coastguard Worker   }
82*9880d681SAndroid Build Coastguard Worker 
83*9880d681SAndroid Build Coastguard Worker   if (isDefined())
84*9880d681SAndroid Build Coastguard Worker     return ELF::STB_LOCAL;
85*9880d681SAndroid Build Coastguard Worker   if (isUsedInReloc())
86*9880d681SAndroid Build Coastguard Worker     return ELF::STB_GLOBAL;
87*9880d681SAndroid Build Coastguard Worker   if (isWeakrefUsedInReloc())
88*9880d681SAndroid Build Coastguard Worker     return ELF::STB_WEAK;
89*9880d681SAndroid Build Coastguard Worker   if (isSignature())
90*9880d681SAndroid Build Coastguard Worker     return ELF::STB_LOCAL;
91*9880d681SAndroid Build Coastguard Worker   return ELF::STB_GLOBAL;
92*9880d681SAndroid Build Coastguard Worker }
93*9880d681SAndroid Build Coastguard Worker 
setType(unsigned Type) const94*9880d681SAndroid Build Coastguard Worker void MCSymbolELF::setType(unsigned Type) const {
95*9880d681SAndroid Build Coastguard Worker   unsigned Val;
96*9880d681SAndroid Build Coastguard Worker   switch (Type) {
97*9880d681SAndroid Build Coastguard Worker   default:
98*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unsupported Binding");
99*9880d681SAndroid Build Coastguard Worker   case ELF::STT_NOTYPE:
100*9880d681SAndroid Build Coastguard Worker     Val = 0;
101*9880d681SAndroid Build Coastguard Worker     break;
102*9880d681SAndroid Build Coastguard Worker   case ELF::STT_OBJECT:
103*9880d681SAndroid Build Coastguard Worker     Val = 1;
104*9880d681SAndroid Build Coastguard Worker     break;
105*9880d681SAndroid Build Coastguard Worker   case ELF::STT_FUNC:
106*9880d681SAndroid Build Coastguard Worker     Val = 2;
107*9880d681SAndroid Build Coastguard Worker     break;
108*9880d681SAndroid Build Coastguard Worker   case ELF::STT_SECTION:
109*9880d681SAndroid Build Coastguard Worker     Val = 3;
110*9880d681SAndroid Build Coastguard Worker     break;
111*9880d681SAndroid Build Coastguard Worker   case ELF::STT_COMMON:
112*9880d681SAndroid Build Coastguard Worker     Val = 4;
113*9880d681SAndroid Build Coastguard Worker     break;
114*9880d681SAndroid Build Coastguard Worker   case ELF::STT_TLS:
115*9880d681SAndroid Build Coastguard Worker     Val = 5;
116*9880d681SAndroid Build Coastguard Worker     break;
117*9880d681SAndroid Build Coastguard Worker   case ELF::STT_GNU_IFUNC:
118*9880d681SAndroid Build Coastguard Worker     Val = 6;
119*9880d681SAndroid Build Coastguard Worker     break;
120*9880d681SAndroid Build Coastguard Worker   }
121*9880d681SAndroid Build Coastguard Worker   uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STT_Shift);
122*9880d681SAndroid Build Coastguard Worker   setFlags(OtherFlags | (Val << ELF_STT_Shift));
123*9880d681SAndroid Build Coastguard Worker }
124*9880d681SAndroid Build Coastguard Worker 
getType() const125*9880d681SAndroid Build Coastguard Worker unsigned MCSymbolELF::getType() const {
126*9880d681SAndroid Build Coastguard Worker   uint32_t Val = (getFlags() & (0x7 << ELF_STT_Shift)) >> ELF_STT_Shift;
127*9880d681SAndroid Build Coastguard Worker   switch (Val) {
128*9880d681SAndroid Build Coastguard Worker   default:
129*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Invalid value");
130*9880d681SAndroid Build Coastguard Worker   case 0:
131*9880d681SAndroid Build Coastguard Worker     return ELF::STT_NOTYPE;
132*9880d681SAndroid Build Coastguard Worker   case 1:
133*9880d681SAndroid Build Coastguard Worker     return ELF::STT_OBJECT;
134*9880d681SAndroid Build Coastguard Worker   case 2:
135*9880d681SAndroid Build Coastguard Worker     return ELF::STT_FUNC;
136*9880d681SAndroid Build Coastguard Worker   case 3:
137*9880d681SAndroid Build Coastguard Worker     return ELF::STT_SECTION;
138*9880d681SAndroid Build Coastguard Worker   case 4:
139*9880d681SAndroid Build Coastguard Worker     return ELF::STT_COMMON;
140*9880d681SAndroid Build Coastguard Worker   case 5:
141*9880d681SAndroid Build Coastguard Worker     return ELF::STT_TLS;
142*9880d681SAndroid Build Coastguard Worker   case 6:
143*9880d681SAndroid Build Coastguard Worker     return ELF::STT_GNU_IFUNC;
144*9880d681SAndroid Build Coastguard Worker   }
145*9880d681SAndroid Build Coastguard Worker }
146*9880d681SAndroid Build Coastguard Worker 
setVisibility(unsigned Visibility)147*9880d681SAndroid Build Coastguard Worker void MCSymbolELF::setVisibility(unsigned Visibility) {
148*9880d681SAndroid Build Coastguard Worker   assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
149*9880d681SAndroid Build Coastguard Worker          Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
150*9880d681SAndroid Build Coastguard Worker 
151*9880d681SAndroid Build Coastguard Worker   uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STV_Shift);
152*9880d681SAndroid Build Coastguard Worker   setFlags(OtherFlags | (Visibility << ELF_STV_Shift));
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker 
getVisibility() const155*9880d681SAndroid Build Coastguard Worker unsigned MCSymbolELF::getVisibility() const {
156*9880d681SAndroid Build Coastguard Worker   unsigned Visibility = (getFlags() & (0x3 << ELF_STV_Shift)) >> ELF_STV_Shift;
157*9880d681SAndroid Build Coastguard Worker   assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
158*9880d681SAndroid Build Coastguard Worker          Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
159*9880d681SAndroid Build Coastguard Worker   return Visibility;
160*9880d681SAndroid Build Coastguard Worker }
161*9880d681SAndroid Build Coastguard Worker 
setOther(unsigned Other)162*9880d681SAndroid Build Coastguard Worker void MCSymbolELF::setOther(unsigned Other) {
163*9880d681SAndroid Build Coastguard Worker   assert((Other & 0x1f) == 0);
164*9880d681SAndroid Build Coastguard Worker   Other >>= 5;
165*9880d681SAndroid Build Coastguard Worker   assert(Other <= 0x7);
166*9880d681SAndroid Build Coastguard Worker   uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STO_Shift);
167*9880d681SAndroid Build Coastguard Worker   setFlags(OtherFlags | (Other << ELF_STO_Shift));
168*9880d681SAndroid Build Coastguard Worker }
169*9880d681SAndroid Build Coastguard Worker 
getOther() const170*9880d681SAndroid Build Coastguard Worker unsigned MCSymbolELF::getOther() const {
171*9880d681SAndroid Build Coastguard Worker   unsigned Other = (getFlags() & (0x7 << ELF_STO_Shift)) >> ELF_STO_Shift;
172*9880d681SAndroid Build Coastguard Worker   return Other << 5;
173*9880d681SAndroid Build Coastguard Worker }
174*9880d681SAndroid Build Coastguard Worker 
setIsWeakrefUsedInReloc() const175*9880d681SAndroid Build Coastguard Worker void MCSymbolELF::setIsWeakrefUsedInReloc() const {
176*9880d681SAndroid Build Coastguard Worker   uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_WeakrefUsedInReloc_Shift);
177*9880d681SAndroid Build Coastguard Worker   setFlags(OtherFlags | (1 << ELF_WeakrefUsedInReloc_Shift));
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker 
isWeakrefUsedInReloc() const180*9880d681SAndroid Build Coastguard Worker bool MCSymbolELF::isWeakrefUsedInReloc() const {
181*9880d681SAndroid Build Coastguard Worker   return getFlags() & (0x1 << ELF_WeakrefUsedInReloc_Shift);
182*9880d681SAndroid Build Coastguard Worker }
183*9880d681SAndroid Build Coastguard Worker 
setIsSignature() const184*9880d681SAndroid Build Coastguard Worker void MCSymbolELF::setIsSignature() const {
185*9880d681SAndroid Build Coastguard Worker   uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_IsSignature_Shift);
186*9880d681SAndroid Build Coastguard Worker   setFlags(OtherFlags | (1 << ELF_IsSignature_Shift));
187*9880d681SAndroid Build Coastguard Worker }
188*9880d681SAndroid Build Coastguard Worker 
isSignature() const189*9880d681SAndroid Build Coastguard Worker bool MCSymbolELF::isSignature() const {
190*9880d681SAndroid Build Coastguard Worker   return getFlags() & (0x1 << ELF_IsSignature_Shift);
191*9880d681SAndroid Build Coastguard Worker }
192*9880d681SAndroid Build Coastguard Worker 
setIsBindingSet() const193*9880d681SAndroid Build Coastguard Worker void MCSymbolELF::setIsBindingSet() const {
194*9880d681SAndroid Build Coastguard Worker   uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_BindingSet_Shift);
195*9880d681SAndroid Build Coastguard Worker   setFlags(OtherFlags | (1 << ELF_BindingSet_Shift));
196*9880d681SAndroid Build Coastguard Worker }
197*9880d681SAndroid Build Coastguard Worker 
isBindingSet() const198*9880d681SAndroid Build Coastguard Worker bool MCSymbolELF::isBindingSet() const {
199*9880d681SAndroid Build Coastguard Worker   return getFlags() & (0x1 << ELF_BindingSet_Shift);
200*9880d681SAndroid Build Coastguard Worker }
201*9880d681SAndroid Build Coastguard Worker }
202