diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-06-04 02:32:20 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-06-04 02:32:20 +0000 |
commit | d31203ae218637b8bb44824c9a7c63b1241fee8a (patch) | |
tree | 175660a504c8433606daa1781ed16d4baa9ecb32 /llvm/lib/MC/MCSymbolELF.cpp | |
parent | eb262ce4b63e76a70d95fef83ef55c9d222a3007 (diff) | |
download | bcm5719-llvm-d31203ae218637b8bb44824c9a7c63b1241fee8a.tar.gz bcm5719-llvm-d31203ae218637b8bb44824c9a7c63b1241fee8a.zip |
Pack the MCSymbolELF bit fields into MCSymbol's Flags.
This reduces MCSymolfELF from 64 bytes to 56 bytes on x86_64.
While at it, also make getOther/setOther easier to use by accepting unshifted
STO_* values.
llvm-svn: 239006
Diffstat (limited to 'llvm/lib/MC/MCSymbolELF.cpp')
-rw-r--r-- | llvm/lib/MC/MCSymbolELF.cpp | 173 |
1 files changed, 135 insertions, 38 deletions
diff --git a/llvm/lib/MC/MCSymbolELF.cpp b/llvm/lib/MC/MCSymbolELF.cpp index f4d3d176c3a..33542f99e1d 100644 --- a/llvm/lib/MC/MCSymbolELF.cpp +++ b/llvm/lib/MC/MCSymbolELF.cpp @@ -16,27 +16,71 @@ namespace llvm { namespace { enum { - ELF_STT_Shift = 0, // Shift value for STT_* flags - ELF_STB_Shift = 4, // Shift value for STB_* flags - ELF_STV_Shift = 8, // Shift value for STV_* flags - ELF_STO_Shift = 10 // Shift value for STO_* flags + // Shift value for STT_* flags. 7 possible values. 3 bits. + ELF_STT_Shift = 0, + + // Shift value for STB_* flags. 4 possible values, 2 bits. + ELF_STB_Shift = 3, + + // Shift value for STV_* flags. 4 possible values, 2 bits. + ELF_STV_Shift = 5, + + // Shift value for STO_* flags. 3 bits. All the values are between 0x20 and + // 0xe0, so we shift right by 5 before storing. + ELF_STO_Shift = 7, + + // One bit. + ELF_IsSignature_Shift = 10, + + // One bit. + ELF_WeakrefUsedInReloc_Shift = 11, + + // One bit. + ELF_UsedInReloc_Shift = 12, + + // One bit. + ELF_BindingSet_Shift = 13 }; } void MCSymbolELF::setBinding(unsigned Binding) const { - BindingSet = true; - assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || - Binding == ELF::STB_WEAK || Binding == ELF::STB_GNU_UNIQUE); - uint32_t OtherFlags = getFlags() & ~(0xf << ELF_STB_Shift); - setFlags(OtherFlags | (Binding << ELF_STB_Shift)); + setIsBindingSet(); + unsigned Val; + switch (Binding) { + default: + llvm_unreachable("Unsupported Binding"); + case ELF::STB_LOCAL: + Val = 0; + break; + case ELF::STB_GLOBAL: + Val = 1; + break; + case ELF::STB_WEAK: + Val = 2; + break; + case ELF::STB_GNU_UNIQUE: + Val = 3; + break; + } + uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STB_Shift); + setFlags(OtherFlags | (Val << ELF_STB_Shift)); } unsigned MCSymbolELF::getBinding() const { if (isBindingSet()) { - uint32_t Binding = (getFlags() & (0xf << ELF_STB_Shift)) >> ELF_STB_Shift; - assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || - Binding == ELF::STB_WEAK || Binding == ELF::STB_GNU_UNIQUE); - return Binding; + uint32_t Val = (getFlags() & (0x3 << ELF_STB_Shift)) >> ELF_STB_Shift; + switch (Val) { + default: + llvm_unreachable("Invalid value"); + case 0: + return ELF::STB_LOCAL; + case 1: + return ELF::STB_GLOBAL; + case 2: + return ELF::STB_WEAK; + case 3: + return ELF::STB_GNU_UNIQUE; + } } if (isDefined()) @@ -51,26 +95,58 @@ unsigned MCSymbolELF::getBinding() const { } void MCSymbolELF::setType(unsigned Type) const { - assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT || - Type == ELF::STT_FUNC || Type == ELF::STT_SECTION || - Type == ELF::STT_COMMON || Type == ELF::STT_TLS || - Type == ELF::STT_GNU_IFUNC); - - uint32_t OtherFlags = getFlags() & ~(0xf << ELF_STT_Shift); - setFlags(OtherFlags | (Type << ELF_STT_Shift)); + unsigned Val; + switch (Type) { + default: + llvm_unreachable("Unsupported Binding"); + case ELF::STT_NOTYPE: + Val = 0; + break; + case ELF::STT_OBJECT: + Val = 1; + break; + case ELF::STT_FUNC: + Val = 2; + break; + case ELF::STT_SECTION: + Val = 3; + break; + case ELF::STT_COMMON: + Val = 4; + break; + case ELF::STT_TLS: + Val = 5; + break; + case ELF::STT_GNU_IFUNC: + Val = 6; + break; + } + uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STT_Shift); + setFlags(OtherFlags | (Val << ELF_STT_Shift)); } unsigned MCSymbolELF::getType() const { - uint32_t Type = (getFlags() & (0xf << ELF_STT_Shift)) >> ELF_STT_Shift; - assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT || - Type == ELF::STT_FUNC || Type == ELF::STT_SECTION || - Type == ELF::STT_COMMON || Type == ELF::STT_TLS || - Type == ELF::STT_GNU_IFUNC); - return Type; + uint32_t Val = (getFlags() & (0x7 << ELF_STT_Shift)) >> ELF_STT_Shift; + switch (Val) { + default: + llvm_unreachable("Invalid value"); + case 0: + return ELF::STT_NOTYPE; + case 1: + return ELF::STT_OBJECT; + case 2: + return ELF::STT_FUNC; + case 3: + return ELF::STT_SECTION; + case 4: + return ELF::STT_COMMON; + case 5: + return ELF::STT_TLS; + case 6: + return ELF::STT_GNU_IFUNC; + } } -// Visibility is stored in the first two bits of st_other -// st_other values are stored in the second byte of get/setFlags void MCSymbolELF::setVisibility(unsigned Visibility) { assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); @@ -86,31 +162,52 @@ unsigned MCSymbolELF::getVisibility() const { return Visibility; } -// Other is stored in the last six bits of st_other -// st_other values are stored in the second byte of get/setFlags void MCSymbolELF::setOther(unsigned Other) { - uint32_t OtherFlags = getFlags() & ~(0x3f << ELF_STO_Shift); + assert((Other & 0x1f) == 0); + Other >>= 5; + assert(Other <= 0x7); + uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STO_Shift); setFlags(OtherFlags | (Other << ELF_STO_Shift)); } unsigned MCSymbolELF::getOther() const { unsigned Other = (getFlags() & (0x3f << ELF_STO_Shift)) >> ELF_STO_Shift; - return Other; + return Other << 5; } void MCSymbolELF::setUsedInReloc() const { - UsedInReloc = true; + uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_UsedInReloc_Shift); + setFlags(OtherFlags | (1 << ELF_UsedInReloc_Shift)); } bool MCSymbolELF::isUsedInReloc() const { - return UsedInReloc; + return getFlags() & (0x1 << ELF_UsedInReloc_Shift); } -void MCSymbolELF::setIsWeakrefUsedInReloc() const { WeakrefUsedInReloc = true; } +void MCSymbolELF::setIsWeakrefUsedInReloc() const { + uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_WeakrefUsedInReloc_Shift); + setFlags(OtherFlags | (1 << ELF_WeakrefUsedInReloc_Shift)); +} -bool MCSymbolELF::isWeakrefUsedInReloc() const { return WeakrefUsedInReloc; } +bool MCSymbolELF::isWeakrefUsedInReloc() const { + return getFlags() & (0x1 << ELF_WeakrefUsedInReloc_Shift); +} -void MCSymbolELF::setIsSignature() const { IsSignature = true; } +void MCSymbolELF::setIsSignature() const { + uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_IsSignature_Shift); + setFlags(OtherFlags | (1 << ELF_IsSignature_Shift)); +} -bool MCSymbolELF::isSignature() const { return IsSignature; } +bool MCSymbolELF::isSignature() const { + return getFlags() & (0x1 << ELF_IsSignature_Shift); +} + +void MCSymbolELF::setIsBindingSet() const { + uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_BindingSet_Shift); + setFlags(OtherFlags | (1 << ELF_BindingSet_Shift)); +} + +bool MCSymbolELF::isBindingSet() const { + return getFlags() & (0x1 << ELF_BindingSet_Shift); +} } |