diff options
author | Fangrui Song <maskray@google.com> | 2019-09-07 14:58:47 +0000 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2019-09-07 14:58:47 +0000 |
commit | 72e99e63a2f9b51853cf74eddae37d7eaf106ca5 (patch) | |
tree | 75ef84b3ee3162fc67b0162d61cb16cb54d7aaa7 /llvm/lib/MC/ELFObjectWriter.cpp | |
parent | 4e76f880723a4a1a25a94f556aea72f63da8f17a (diff) | |
download | bcm5719-llvm-72e99e63a2f9b51853cf74eddae37d7eaf106ca5.tar.gz bcm5719-llvm-72e99e63a2f9b51853cf74eddae37d7eaf106ca5.zip |
[ELF][MC] Set types of aliases of IFunc to STT_GNU_IFUNC
```
.type foo,@gnu_indirect_function
.set foo,foo_resolver
.set foo2,foo
.set foo3,foo2
```
The types of foo2 and foo3 should be STT_GNU_IFUNC, but we currently
resolve them to the type of foo_resolver. This patch fixes it.
Differential Revision: https://reviews.llvm.org/D67206
Patch by Senran Zhang
llvm-svn: 371312
Diffstat (limited to 'llvm/lib/MC/ELFObjectWriter.cpp')
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 014eafed588..9f66e31a902 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -511,6 +511,19 @@ static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) { return Type; } +static bool isIFunc(const MCSymbolELF *Symbol) { + while (Symbol->getType() != ELF::STT_GNU_IFUNC) { + const MCSymbolRefExpr *Value; + if (!Symbol->isVariable() || + !(Value = dyn_cast<MCSymbolRefExpr>(Symbol->getVariableValue())) || + Value->getKind() != MCSymbolRefExpr::VK_None || + mergeTypeForSet(Symbol->getType(), ELF::STT_GNU_IFUNC) != ELF::STT_GNU_IFUNC) + return false; + Symbol = &cast<MCSymbolELF>(Value->getSymbol()); + } + return true; +} + void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex, ELFSymbolData &MSD, const MCAsmLayout &Layout) { const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol); @@ -524,6 +537,8 @@ void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex, // Binding and Type share the same byte as upper and lower nibbles uint8_t Binding = Symbol.getBinding(); uint8_t Type = Symbol.getType(); + if (isIFunc(&Symbol)) + Type = ELF::STT_GNU_IFUNC; if (Base) { Type = mergeTypeForSet(Type, Base->getType()); } |