From a6e3a599d150361abc655122258ee21331ef4618 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 23 Mar 2014 03:33:20 +0000 Subject: Propagate types from symbol to aliases. This is similar, but not identical to what gas does. The logic in MC is to just compute the symbol table after parsing the entire file. GAS is mixed, given .type b, @object a = b b: .type b, @function It will propagate the change and make 'a' a function. Given .type b, @object b: a = b .type b, @function the type of 'a' is still object. Since we do the computation in the end, we produce a function in both cases. llvm-svn: 204555 --- llvm/lib/MC/ELFObjectWriter.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'llvm/lib') diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index dc77e0361c5..076b9993077 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -575,6 +575,22 @@ static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) { return Type; } +static const MCSymbol *getBaseSymbol(const MCAsmLayout &Layout, + const MCSymbol &Symbol) { + if (!Symbol.isVariable()) + return &Symbol; + + const MCExpr *Expr = Symbol.getVariableValue(); + MCValue Value; + if (!Expr->EvaluateAsRelocatable(Value, &Layout)) + llvm_unreachable("Invalid Expression"); + assert(!Value.getSymB()); + const MCSymbolRefExpr *A = Value.getSymA(); + if (!A) + return nullptr; + return getBaseSymbol(Layout, A->getSymbol()); +} + void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF, ELFSymbolData &MSD, @@ -588,7 +604,12 @@ 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)); + uint8_t Type = MCELF::GetType(OrigData); + const MCSymbol *Base = getBaseSymbol(Layout, OrigData.getSymbol()); + if (Base) { + MCSymbolData BaseSD = Layout.getAssembler().getSymbolData(*Base); + Type = mergeTypeForSet(Type, MCELF::GetType(BaseSD)); + } if (OrigData.getFlags() & ELF_Other_ThumbFunc) Type = ELF::STT_FUNC; uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); -- cgit v1.2.3