diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2014-03-21 22:00:29 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2014-03-21 22:00:29 +0000 |
commit | 66f96fe0cbcae5837f233090321d10a87a316ee8 (patch) | |
tree | bab9f35fa9e8ab2cf55a1174be9ff6de1eaa1be3 /llvm/lib/MC/ELFObjectWriter.cpp | |
parent | c97727a49268408ae2ead1b00705000adf2fd9f6 (diff) | |
download | bcm5719-llvm-66f96fe0cbcae5837f233090321d10a87a316ee8.tar.gz bcm5719-llvm-66f96fe0cbcae5837f233090321d10a87a316ee8.zip |
Fix the value computation in
sym_a:
sym_d = sym_a + 1
This is the smallest fix I was able to extract from what got reverted in
r204203.
llvm-svn: 204527
Diffstat (limited to 'llvm/lib/MC/ELFObjectWriter.cpp')
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 54 |
1 files changed, 31 insertions, 23 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 9168fea53bd..dc77e0361c5 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -462,36 +462,44 @@ 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(); + MCSymbolData *Data = &OrigData; + if (Data->isCommon() && Data->isExternal()) + return Data->getCommonAlignment(); - const MCSymbol &Symbol = Data.getSymbol(); + const MCSymbol *Symbol = &Data->getSymbol(); + bool IsThumbFunc = OrigData.getFlags() & ELF_Other_ThumbFunc; - if (Symbol.isAbsolute() && Symbol.isVariable()) { - if (const MCExpr *Value = Symbol.getVariableValue()) { - int64_t IntValue; - if (Value->EvaluateAsAbsolute(IntValue, Layout)) { - if (Data.getFlags() & ELF_Other_ThumbFunc) - return static_cast<uint64_t>(IntValue | 1); - else - return static_cast<uint64_t>(IntValue); - } + uint64_t Res = 0; + if (Symbol->isVariable()) { + const MCExpr *Expr = Symbol->getVariableValue(); + MCValue Value; + if (!Expr->EvaluateAsRelocatable(Value, &Layout)) + llvm_unreachable("Invalid expression"); + + assert(!Value.getSymB()); + + Res = Value.getConstant(); + + if (const MCSymbolRefExpr *A = Value.getSymA()) { + Symbol = &A->getSymbol(); + Data = &Layout.getAssembler().getSymbolData(*Symbol); + } else { + Symbol = 0; + Data = 0; } } - if (!Symbol.isInSection()) - return 0; + if (IsThumbFunc) + Res |= 1; - if (Data.getFragment()) { - if (Data.getFlags() & ELF_Other_ThumbFunc) - return Layout.getSymbolOffset(&Data) | 1; - else - return Layout.getSymbolOffset(&Data); - } + if (!Symbol || !Symbol->isInSection()) + return Res; + + Res += Layout.getSymbolOffset(Data); - return 0; + return Res; } void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, @@ -591,7 +599,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); if (OrigData.getFlags() & ELF_Other_ThumbFunc) Value |= 1; uint64_t Size = 0; |