summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC/ELFObjectWriter.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2014-03-23 03:33:20 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2014-03-23 03:33:20 +0000
commita6e3a599d150361abc655122258ee21331ef4618 (patch)
tree711f74ab843c51ae4a0a80e80f6d9f97401f79e8 /llvm/lib/MC/ELFObjectWriter.cpp
parentc264d35adcddd2fdafb5d002eb8bc639879078e1 (diff)
downloadbcm5719-llvm-a6e3a599d150361abc655122258ee21331ef4618.tar.gz
bcm5719-llvm-a6e3a599d150361abc655122258ee21331ef4618.zip
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
Diffstat (limited to 'llvm/lib/MC/ELFObjectWriter.cpp')
-rw-r--r--llvm/lib/MC/ELFObjectWriter.cpp23
1 files changed, 22 insertions, 1 deletions
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);
OpenPOWER on IntegriCloud