From 4af106a677eca0c2ee979d01d2874998f5273492 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 18 Mar 2014 20:40:38 +0000 Subject: Add back r203962, r204028 and r204059. This reverts commit r204137. This includes a fix for handling aliases of aliases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204178 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/ELFObjectWriter.cpp | 97 +++++++++++++++++++++++++++------------------- 1 file changed, 58 insertions(+), 39 deletions(-) (limited to 'lib/MC/ELFObjectWriter.cpp') diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 909ea80083..dd06304b71 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -271,6 +271,7 @@ class ELFObjectWriter : public MCObjectWriter { /// \param RevGroupMap - Maps a signature symbol to the group section. /// \param NumRegularSections - Number of non-relocation sections. void ComputeSymbolTable(MCAssembler &Asm, + const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap, RevGroupMapTy RevGroupMap, unsigned NumRegularSections); @@ -462,33 +463,47 @@ void ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF, } } -uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, +uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &OrigData, const MCAsmLayout &Layout) { - if (Data.isCommon() && Data.isExternal()) - return Data.getCommonAlignment(); - - const MCSymbol &Symbol = Data.getSymbol(); - - if (Symbol.isAbsolute() && Symbol.isVariable()) { - if (const MCExpr *Value = Symbol.getVariableValue()) { - int64_t IntValue; - if (Value->EvaluateAsAbsolute(IntValue, Layout)) - return (uint64_t)IntValue; - } + MCSymbolData *Data = &OrigData; + if (Data->isCommon() && Data->isExternal()) + return Data->getCommonAlignment(); + + const MCSymbol *Symbol = &Data->getSymbol(); + const bool IsThumbFunc = OrigData.getFlags() & ELF_Other_ThumbFunc; + + uint64_t Res = 0; + if (Symbol->isVariable()) { + const MCExpr *Expr = Symbol->getVariableValue(); + MCValue Value; + if (!Expr->EvaluateAsRelocatable(Value, &Layout)) + return 0; + if (Value.getSymB()) + return 0; + + Res = Value.getConstant(); + if (IsThumbFunc) + Res |= 1; + + const MCSymbolRefExpr *A = Value.getSymA(); + if (!A) + return Res; + + Symbol = &A->getSymbol(); + Data = &Layout.getAssembler().getSymbolData(*Symbol); } - if (!Symbol.isInSection()) + if (!Symbol->isInSection()) return 0; + if (!Data->getFragment()) + return 0; - if (Data.getFragment()) { - if (Data.getFlags() & ELF_Other_ThumbFunc) - return Layout.getSymbolOffset(&Data)+1; - else - return Layout.getSymbolOffset(&Data); - } + Res += Layout.getSymbolOffset(Data); + if (IsThumbFunc || Data->getFlags() & ELF_Other_ThumbFunc) + Res |= 1; - return 0; + return Res; } void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, @@ -569,8 +584,9 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, ELFSymbolData &MSD, const MCAsmLayout &Layout) { MCSymbolData &OrigData = *MSD.SymbolData; - MCSymbolData &Data = - Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol()); + const MCSymbol *Base = OrigData.getSymbol().getBaseSymbol(Layout); + const MCSymbolData &Data = + Base ? Layout.getAssembler().getSymbolData(*Base) : OrigData; bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || Data.getSymbol().isVariable(); @@ -578,6 +594,8 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, // Binding and Type share the same byte as upper and lower nibbles uint8_t Binding = MCELF::GetBinding(OrigData); uint8_t Type = mergeTypeForSet(MCELF::GetType(OrigData), MCELF::GetType(Data)); + if (OrigData.getFlags() & ELF_Other_ThumbFunc) + Type = ELF::STT_FUNC; uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); // Other and Visibility share the same byte with Visibility using the lower @@ -586,7 +604,7 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, uint8_t Other = MCELF::getOther(OrigData) << (ELF_STO_Shift - ELF_STV_Shift); Other |= Visibility; - uint64_t Value = SymbolValue(Data, Layout); + uint64_t Value = SymbolValue(OrigData, Layout); uint64_t Size = 0; assert(!(Data.isCommon() && !Data.isExternal())); @@ -897,10 +915,11 @@ void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, } } -void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, - const SectionIndexMapTy &SectionIndexMap, - RevGroupMapTy RevGroupMap, - unsigned NumRegularSections) { +void +ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, + const SectionIndexMapTy &SectionIndexMap, + RevGroupMapTy RevGroupMap, + unsigned NumRegularSections) { // FIXME: Is this the correct place to do this? // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? if (NeedsGOT) { @@ -948,33 +967,33 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, ELFSymbolData MSD; MSD.SymbolData = it; - const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); + const MCSymbol *BaseSymbol = Symbol.getBaseSymbol(Layout); // Undefined symbols are global, but this is the first place we // are able to set it. bool Local = isLocal(*it, isSignature, Used); if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) { - MCSymbolData &SD = Asm.getSymbolData(RefSymbol); + assert(BaseSymbol); + MCSymbolData &SD = Asm.getSymbolData(*BaseSymbol); MCELF::SetBinding(*it, ELF::STB_GLOBAL); MCELF::SetBinding(SD, ELF::STB_GLOBAL); } - if (RefSymbol.isUndefined() && !Used && WeakrefUsed) - MCELF::SetBinding(*it, ELF::STB_WEAK); - - if (it->isCommon()) { + if (!BaseSymbol) { + MSD.SectionIndex = ELF::SHN_ABS; + } else if (it->isCommon()) { assert(!Local); MSD.SectionIndex = ELF::SHN_COMMON; - } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) { - MSD.SectionIndex = ELF::SHN_ABS; - } else if (RefSymbol.isUndefined()) { + } else if (BaseSymbol->isUndefined()) { if (isSignature && !Used) MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]); else MSD.SectionIndex = ELF::SHN_UNDEF; + if (!Used && WeakrefUsed) + MCELF::SetBinding(*it, ELF::STB_WEAK); } else { const MCSectionELF &Section = - static_cast(RefSymbol.getSection()); + static_cast(BaseSymbol->getSection()); MSD.SectionIndex = SectionIndexMap.lookup(&Section); if (MSD.SectionIndex >= ELF::SHN_LORESERVE) NeedsSymtabShndx = true; @@ -1560,8 +1579,8 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, unsigned NumRegularSections = NumUserSections + NumIndexedSections; // Compute symbol table information. - ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections); - + ComputeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap, + NumRegularSections); WriteRelocations(Asm, const_cast(Layout), RelMap); -- cgit v1.2.3