From a86ecee52ba011fc16a4cac338bf2a7015becb2a Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 4 Jun 2015 05:00:12 +0000 Subject: [PATCH] Revert "Pack the MCSymbolELF bit fields into MCSymbol's Flags." This reverts commit r239006. I am debugging the powerpc failures. llvm-svn: 239010 --- llvm/include/llvm/MC/MCSymbolELF.h | 13 +- llvm/lib/MC/ELFObjectWriter.cpp | 3 +- llvm/lib/MC/MCSymbolELF.cpp | 173 +++++---------------- .../Mips/MCTargetDesc/MipsELFObjectWriter.cpp | 2 +- .../Target/Mips/MCTargetDesc/MipsELFStreamer.cpp | 5 +- .../Mips/MCTargetDesc/MipsTargetStreamer.cpp | 12 +- .../PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp | 16 +- 7 files changed, 73 insertions(+), 151 deletions(-) diff --git a/llvm/include/llvm/MC/MCSymbolELF.h b/llvm/include/llvm/MC/MCSymbolELF.h index c943054..374e6b8 100644 --- a/llvm/include/llvm/MC/MCSymbolELF.h +++ b/llvm/include/llvm/MC/MCSymbolELF.h @@ -17,9 +17,15 @@ class MCSymbolELF : public MCSymbol { /// symbol has no size this field will be NULL. const MCExpr *SymbolSize = nullptr; + mutable unsigned BindingSet : 1; + mutable unsigned UsedInReloc : 1; + mutable unsigned WeakrefUsedInReloc : 1; + mutable unsigned IsSignature : 1; + public: MCSymbolELF(const StringMapEntry *Name, bool isTemporary) - : MCSymbol(true, Name, isTemporary) {} + : MCSymbol(true, Name, isTemporary), BindingSet(false), + UsedInReloc(false), WeakrefUsedInReloc(false), IsSignature(false) {} void setSize(const MCExpr *SS) { SymbolSize = SS; } const MCExpr *getSize() const { return SymbolSize; } @@ -36,7 +42,7 @@ public: void setBinding(unsigned Binding) const; unsigned getBinding() const; - bool isBindingSet() const; + bool isBindingSet() const { return BindingSet; } void setUsedInReloc() const; bool isUsedInReloc() const; @@ -48,9 +54,6 @@ public: bool isSignature() const; static bool classof(const MCSymbol *S) { return S->isELF(); } - -private: - void setIsBindingSet() const; }; } diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index f8cf7d2..d811cfe 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -463,7 +463,8 @@ void ELFObjectWriter::writeSymbol(SymbolTableWriter &Writer, // Other and Visibility share the same byte with Visibility using the lower // 2 bits uint8_t Visibility = Symbol.getVisibility(); - uint8_t Other = Symbol.getOther() | Visibility; + uint8_t Other = Symbol.getOther() << 2; + Other |= Visibility; uint64_t Value = SymbolValue(*MSD.Symbol, Layout); uint64_t Size = 0; diff --git a/llvm/lib/MC/MCSymbolELF.cpp b/llvm/lib/MC/MCSymbolELF.cpp index 33542f9..f4d3d17 100644 --- a/llvm/lib/MC/MCSymbolELF.cpp +++ b/llvm/lib/MC/MCSymbolELF.cpp @@ -16,71 +16,27 @@ namespace llvm { namespace { enum { - // 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 + 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 }; } void MCSymbolELF::setBinding(unsigned Binding) const { - 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)); + 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)); } unsigned MCSymbolELF::getBinding() const { if (isBindingSet()) { - 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; - } + 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; } if (isDefined()) @@ -95,58 +51,26 @@ unsigned MCSymbolELF::getBinding() const { } void MCSymbolELF::setType(unsigned Type) const { - 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)); + 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 MCSymbolELF::getType() const { - 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; - } + 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; } +// 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); @@ -162,52 +86,31 @@ 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) { - assert((Other & 0x1f) == 0); - Other >>= 5; - assert(Other <= 0x7); - uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STO_Shift); + uint32_t OtherFlags = getFlags() & ~(0x3f << 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 << 5; + return Other; } void MCSymbolELF::setUsedInReloc() const { - uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_UsedInReloc_Shift); - setFlags(OtherFlags | (1 << ELF_UsedInReloc_Shift)); + UsedInReloc = true; } bool MCSymbolELF::isUsedInReloc() const { - return getFlags() & (0x1 << ELF_UsedInReloc_Shift); + return UsedInReloc; } -void MCSymbolELF::setIsWeakrefUsedInReloc() const { - uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_WeakrefUsedInReloc_Shift); - setFlags(OtherFlags | (1 << ELF_WeakrefUsedInReloc_Shift)); -} +void MCSymbolELF::setIsWeakrefUsedInReloc() const { WeakrefUsedInReloc = true; } -bool MCSymbolELF::isWeakrefUsedInReloc() const { - return getFlags() & (0x1 << ELF_WeakrefUsedInReloc_Shift); -} +bool MCSymbolELF::isWeakrefUsedInReloc() const { return WeakrefUsedInReloc; } -void MCSymbolELF::setIsSignature() const { - uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_IsSignature_Shift); - setFlags(OtherFlags | (1 << ELF_IsSignature_Shift)); -} +void MCSymbolELF::setIsSignature() const { IsSignature = true; } -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); -} +bool MCSymbolELF::isSignature() const { return IsSignature; } } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index 982a7f5..82ae413 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -384,7 +384,7 @@ bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, return true; case ELF::R_MIPS_32: - if (cast(Sym).getOther() & ELF::STO_MIPS_MICROMIPS) + if (cast(Sym).getOther() & (ELF::STO_MIPS_MICROMIPS >> 2)) return true; // falltrough case ELF::R_MIPS_26: diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp index b45d9cf..d1e3a47 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp @@ -44,7 +44,10 @@ void MipsELFStreamer::createPendingLabelRelocs() { for (auto *L : Labels) { auto *Label = cast(L); getAssembler().registerSymbol(*Label); - Label->setOther(ELF::STO_MIPS_MICROMIPS); + // The "other" values are stored in the last 6 bits of the second byte. + // The traditional defines for STO values assume the full byte and thus + // the shift to pack it. + Label->setOther(ELF::STO_MIPS_MICROMIPS >> 2); } } diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index a051f4c..787d9a7 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -462,7 +462,10 @@ void MipsTargetELFStreamer::emitLabel(MCSymbol *S) { if (Type != ELF::STT_FUNC) return; - Symbol->setOther(ELF::STO_MIPS_MICROMIPS); + // The "other" values are stored in the last 6 bits of the second byte + // The traditional defines for STO values assume the full byte and thus + // the shift to pack it. + Symbol->setOther(ELF::STO_MIPS_MICROMIPS >> 2); } void MipsTargetELFStreamer::finish() { @@ -524,10 +527,13 @@ void MipsTargetELFStreamer::emitAssignment(MCSymbol *S, const MCExpr *Value) { const auto &RhsSym = cast( static_cast(Value)->getSymbol()); - if (!(RhsSym.getOther() & ELF::STO_MIPS_MICROMIPS)) + if (!(RhsSym.getOther() & (ELF::STO_MIPS_MICROMIPS >> 2))) return; - Symbol->setOther(ELF::STO_MIPS_MICROMIPS); + // The "other" values are stored in the last 6 bits of the second byte. + // The traditional defines for STO values assume the full byte and thus + // the shift to pack it. + Symbol->setOther(ELF::STO_MIPS_MICROMIPS >> 2); } MCELFStreamer &MipsTargetELFStreamer::getStreamer() { diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp index aba262c..0f9697b 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp @@ -169,10 +169,13 @@ public: if (Res != ELF::decodePPC64LocalEntryOffset(Encoded)) report_fatal_error(".localentry expression cannot be encoded."); - unsigned Other = S->getOther(); + // The "other" values are stored in the last 6 bits of the second byte. + // The traditional defines for STO values assume the full byte and thus + // the shift to pack it. + unsigned Other = S->getOther() << 2; Other &= ~ELF::STO_PPC64_LOCAL_MASK; Other |= Encoded; - S->setOther(Other); + S->setOther(Other >> 2); // For GAS compatibility, unless we already saw a .abiversion directive, // set e_flags to indicate ELFv2 ABI. @@ -188,10 +191,13 @@ public: return; const auto &RhsSym = cast( static_cast(Value)->getSymbol()); - unsigned Other = Symbol->getOther(); + // The "other" values are stored in the last 6 bits of the second byte. + // The traditional defines for STO values assume the full byte and thus + // the shift to pack it. + unsigned Other = Symbol->getOther() << 2; Other &= ~ELF::STO_PPC64_LOCAL_MASK; - Other |= RhsSym.getOther() & ELF::STO_PPC64_LOCAL_MASK; - Symbol->setOther(Other); + Other |= (RhsSym.getOther() << 2) & ELF::STO_PPC64_LOCAL_MASK; + Symbol->setOther(Other >> 2); } }; -- 2.7.4