From 82fdcc0e7f6f329404bc4195f98ed0ca92988194 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 29 May 2015 17:48:04 +0000 Subject: [PATCH] Move common symbol related information from MCSectionData to MCSymbol. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238583 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCSymbol.h | 100 +++++++++++++++++---------------- lib/MC/ELFObjectWriter.cpp | 8 +-- lib/MC/MCAssembler.cpp | 10 +--- lib/MC/MCELFStreamer.cpp | 2 +- lib/MC/MCExpr.cpp | 2 +- lib/MC/MCMachOStreamer.cpp | 5 +- lib/MC/MCObjectStreamer.cpp | 8 +-- lib/MC/MachObjectWriter.cpp | 6 +- lib/MC/WinCOFFObjectWriter.cpp | 6 +- lib/MC/WinCOFFStreamer.cpp | 2 +- 10 files changed, 73 insertions(+), 76 deletions(-) diff --git a/include/llvm/MC/MCSymbol.h b/include/llvm/MC/MCSymbol.h index d9b3b8486d2..15ca057e82c 100644 --- a/include/llvm/MC/MCSymbol.h +++ b/include/llvm/MC/MCSymbol.h @@ -34,39 +34,17 @@ class MCSymbolData { /// if it is private extern (bit 1). PointerIntPair Fragment; - union { - /// Offset - The offset to apply to the fragment address to form this - /// symbol's value. - uint64_t Offset; - - /// CommonSize - The size of the symbol, if it is 'common'. - uint64_t CommonSize; - }; - - /// CommonAlign - The alignment of the symbol, if it is 'common', or -1. - // - // FIXME: Pack this in with other fields? - unsigned CommonAlign = -1U; /// Flags - The Flags field is used by object file implementations to store /// additional per symbol information which is not easily classified. uint32_t Flags = 0; public: - MCSymbolData() { Offset = 0; } + MCSymbolData() {} MCFragment *getFragment() const { return Fragment.getPointer(); } void setFragment(MCFragment *Value) { Fragment.setPointer(Value); } - uint64_t getOffset() const { - assert(!isCommon()); - return Offset; - } - void setOffset(uint64_t Value) { - assert(!isCommon()); - Offset = Value; - } - /// @} /// \name Symbol Attributes /// @{ @@ -81,31 +59,6 @@ public: Fragment.setInt((Fragment.getInt() & ~2) | (unsigned(Value) << 1)); } - /// isCommon - Is this a 'common' symbol. - bool isCommon() const { return CommonAlign != -1U; } - - /// setCommon - Mark this symbol as being 'common'. - /// - /// \param Size - The size of the symbol. - /// \param Align - The alignment of the symbol. - void setCommon(uint64_t Size, unsigned Align) { - assert(getOffset() == 0); - CommonSize = Size; - CommonAlign = Align; - } - - /// getCommonSize - Return the size of a 'common' symbol. - uint64_t getCommonSize() const { - assert(isCommon() && "Not a 'common' symbol!"); - return CommonSize; - } - - /// getCommonAlignment - Return the alignment of a 'common' symbol. - unsigned getCommonAlignment() const { - assert(isCommon() && "Not a 'common' symbol!"); - return CommonAlign; - } - /// getFlags - Get the (implementation defined) symbol flags. uint32_t getFlags() const { return Flags; } @@ -167,6 +120,19 @@ class MCSymbol { /// symbol has no size this field will be NULL. const MCExpr *SymbolSize = nullptr; + /// The alignment of the symbol, if it is 'common', or -1. + // + // FIXME: Pack this in with other fields? + unsigned CommonAlign = -1U; + + union { + /// The offset to apply to the fragment address to form this symbol's value. + uint64_t Offset; + + /// The size of the symbol, if it is 'common'. + uint64_t CommonSize; + }; + mutable MCSymbolData Data; private: // MCContext creates and uniques these. @@ -174,7 +140,9 @@ private: // MCContext creates and uniques these. friend class MCContext; MCSymbol(const StringMapEntry *Name, bool isTemporary) : Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary), - IsRedefinable(false), IsUsed(false), HasData(false), Index(0) {} + IsRedefinable(false), IsUsed(false), HasData(false), Index(0) { + Offset = 0; + } MCSymbol(const MCSymbol &) = delete; void operator=(const MCSymbol &) = delete; @@ -295,6 +263,40 @@ public: const MCExpr *getSize() const { return SymbolSize; } + uint64_t getOffset() const { + assert(!isCommon()); + return Offset; + } + void setOffset(uint64_t Value) { + assert(!isCommon()); + Offset = Value; + } + + /// Return the size of a 'common' symbol. + uint64_t getCommonSize() const { + assert(isCommon() && "Not a 'common' symbol!"); + return CommonSize; + } + + /// Mark this symbol as being 'common'. + /// + /// \param Size - The size of the symbol. + /// \param Align - The alignment of the symbol. + void setCommon(uint64_t Size, unsigned Align) { + assert(getOffset() == 0); + CommonSize = Size; + CommonAlign = Align; + } + + /// Return the alignment of a 'common' symbol. + unsigned getCommonAlignment() const { + assert(isCommon() && "Not a 'common' symbol!"); + return CommonAlign; + } + + /// Is this a 'common' symbol. + bool isCommon() const { return CommonAlign != -1U; } + /// print - Print the value to the stream \p OS. void print(raw_ostream &OS) const; diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 97c0bcb4af7..7041902ef5b 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -360,8 +360,8 @@ void ELFObjectWriter::writeHeader(const MCAssembler &Asm) { uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout) { MCSymbolData &Data = Sym.getData(); - if (Data.isCommon() && Data.isExternal()) - return Data.getCommonAlignment(); + if (Sym.isCommon() && Data.isExternal()) + return Sym.getCommonAlignment(); uint64_t Res; if (!Layout.getSymbolOffset(Sym, Res)) @@ -459,7 +459,7 @@ void ELFObjectWriter::writeSymbol(SymbolTableWriter &Writer, // This has to be in sync with when computeSymbolTable uses SHN_ABS or // SHN_COMMON. - bool IsReserved = !Base || OrigData.isCommon(); + bool IsReserved = !Base || MSD.Symbol->isCommon(); // Binding and Type share the same byte as upper and lower nibbles uint8_t Binding = MCELF::GetBinding(OrigData); @@ -832,7 +832,7 @@ void ELFObjectWriter::computeSymbolTable( if (Symbol.isAbsolute()) { MSD.SectionIndex = ELF::SHN_ABS; - } else if (SD.isCommon()) { + } else if (Symbol.isCommon()) { assert(!Local); MSD.SectionIndex = ELF::SHN_COMMON; } else if (Symbol.isUndefined()) { diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index ab54c37624e..02619121a02 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -127,7 +127,7 @@ static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S, S.getName() + "'"); return false; } - Val = Layout.getFragmentOffset(SD.getFragment()) + SD.getOffset(); + Val = Layout.getFragmentOffset(SD.getFragment()) + S.getOffset(); return true; } @@ -195,8 +195,7 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const { const MCSymbol &ASym = A->getSymbol(); const MCAssembler &Asm = getAssembler(); - const MCSymbolData &ASD = ASym.getData(); - if (ASD.isCommon()) { + if (ASym.isCommon()) { // FIXME: we should probably add a SMLoc to MCExpr. Asm.getContext().reportFatalError(SMLoc(), "Common symbol " + ASym.getName() + @@ -1189,12 +1188,7 @@ void MCSymbolData::dump() const { OS << "setCommon(Size, ByteAlignment); } Symbol->setSize(MCConstantExpr::Create(Size, getContext())); diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp index 1b328ac436f..35d084d08e9 100644 --- a/lib/MC/MCExpr.cpp +++ b/lib/MC/MCExpr.cpp @@ -475,7 +475,7 @@ static void AttemptToFoldSymbolOffsetDifference( const MCSymbolData &BD = SB.getData(); if (AD.getFragment() == BD.getFragment()) { - Addend += (AD.getOffset() - BD.getOffset()); + Addend += (SA.getOffset() - SB.getOffset()); // Pointers to Thumb symbols need to have their low-bit set to allow // for interworking. diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index eac6d02d6d6..dfefd947c8b 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -392,7 +392,7 @@ void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); SD.setExternal(true); - SD.setCommon(Size, ByteAlignment); + Symbol->setCommon(Size, ByteAlignment); } void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, @@ -470,7 +470,8 @@ void MCMachOStreamer::FinishImpl() { MCSymbolData &SD = Symbol.getData(); if (getAssembler().isSymbolLinkerVisible(Symbol) && SD.getFragment()) { // An atom defining symbol should never be internal to a fragment. - assert(SD.getOffset() == 0 && "Invalid offset in atom defining symbol!"); + assert(Symbol.getOffset() == 0 && + "Invalid offset in atom defining symbol!"); DefiningSymbolMap[SD.getFragment()] = &Symbol; } } diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index 88cced6c2f5..e608fe73f37 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -49,7 +49,7 @@ void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) { for (MCSymbol *Sym : PendingLabels) { MCSymbolData *SD = &Sym->getData(); SD->setFragment(F); - SD->setOffset(FOffset); + Sym->setOffset(FOffset); } PendingLabels.clear(); } @@ -72,9 +72,9 @@ bool MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, if (!isa(HiD.getFragment())) return false; - assert(HiD.getOffset() >= LoD.getOffset() && + assert(Hi->getOffset() >= Lo->getOffset() && "Expected Hi to be greater than Lo"); - EmitIntValue(HiD.getOffset() - LoD.getOffset(), Size); + EmitIntValue(Hi->getOffset() - Lo->getOffset(), Size); return true; } @@ -173,7 +173,7 @@ void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { if (F && !(getAssembler().isBundlingEnabled() && getAssembler().getRelaxAll())) { SD.setFragment(F); - SD.setOffset(F->getContents().size()); + Symbol->setOffset(F->getContents().size()); } else { PendingLabels.push_back(Symbol); } diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp index bbdb8ea0b6c..6d8e7ae147f 100644 --- a/lib/MC/MachObjectWriter.cpp +++ b/lib/MC/MachObjectWriter.cpp @@ -373,13 +373,13 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD, Address = AliaseeInfo->StringIndex; else if (Symbol->isDefined()) Address = getSymbolAddress(OrigSymbol, Layout); - else if (Data.isCommon()) { + else if (Symbol->isCommon()) { // Common symbols are encoded with the size in the address // field, and their alignment in the flags. - Address = Data.getCommonSize(); + Address = Symbol->getCommonSize(); // Common alignment is packed into the 'desc' bits. - if (unsigned Align = Data.getCommonAlignment()) { + if (unsigned Align = Symbol->getCommonAlignment()) { unsigned Log2Size = Log2_32(Align); assert((1U << Log2Size) == Align && "Invalid 'common' alignment!"); if (Log2Size > 15) diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp index 86cf7ad782c..72a92204f1a 100644 --- a/lib/MC/WinCOFFObjectWriter.cpp +++ b/lib/MC/WinCOFFObjectWriter.cpp @@ -365,8 +365,8 @@ void WinCOFFObjectWriter::defineSection(MCSectionCOFF const &Sec) { static uint64_t getSymbolValue(const MCSymbol &Symbol, const MCAsmLayout &Layout) { const MCSymbolData &Data = Symbol.getData(); - if (Data.isCommon() && Data.isExternal()) - return Data.getCommonSize(); + if (Symbol.isCommon() && Data.isExternal()) + return Symbol.getCommonSize(); uint64_t Res; if (!Layout.getSymbolOffset(Symbol, Res)) @@ -765,7 +765,7 @@ void WinCOFFObjectWriter::RecordRelocation( Reloc.Symb = coff_symbol->Section->Symbol; FixedValue += Layout.getFragmentOffset(coff_symbol->MC->getData().getFragment()) + - coff_symbol->MC->getData().getOffset(); + coff_symbol->MC->getOffset(); } else Reloc.Symb = coff_symbol; diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp index 752c9722cc7..262e375abc3 100644 --- a/lib/MC/WinCOFFStreamer.cpp +++ b/lib/MC/WinCOFFStreamer.cpp @@ -196,7 +196,7 @@ void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); SD.setExternal(true); - SD.setCommon(Size, ByteAlignment); + Symbol->setCommon(Size, ByteAlignment); if (!T.isKnownWindowsMSVCEnvironment() && ByteAlignment > 1) { SmallString<128> Directive; -- 2.34.1