[PATCH] D67206: [ELF][MC] Fix IFunc alias resolving issue
Sr.Zhang via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 4 18:29:19 PDT 2019
zsrkmyn created this revision.
zsrkmyn added reviewers: grosbach, craig.topper, annita.zhang, LuoYuanke, MaskRay.
Herald added subscribers: llvm-commits, hiraditya, arichardson, emaste.
Herald added a reviewer: espindola.
Herald added a project: LLVM.
If we use '.set' directive to set a symbol as an alias of an IFunc, then the
symbol should also be IFunc. But it's evaluated to be the IFunc resolver at
this time. This patch tries to fix it.
Repository:
rL LLVM
https://reviews.llvm.org/D67206
Files:
llvm/lib/MC/ELFObjectWriter.cpp
llvm/test/MC/ELF/ifunc-alias.s
Index: llvm/test/MC/ELF/ifunc-alias.s
===================================================================
--- /dev/null
+++ llvm/test/MC/ELF/ifunc-alias.s
@@ -0,0 +1,58 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj --symbols | FileCheck %s
+.text
+
+.globl foo_impl
+.type foo_impl, at function
+foo_impl:
+ ret
+
+.globl foo_resolver
+.type foo_resolver, at function
+foo_resolver:
+ mov $foo_impl, %rax
+ ret
+
+.globl foo
+.type foo, at gnu_indirect_function
+.set foo,foo_resolver
+
+// 'foo2' should be an IFunc identical to 'foo'
+.globl foo2
+.set foo2,foo
+
+// CHECK: Symbol {
+// CHECK: Name: foo (25)
+// CHECK-NEXT: Value: 0x1
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global (0x1)
+// CHECK-NEXT: Type: GNU_IFunc (0xA)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text (0x2)
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: foo2 (54)
+// CHECK-NEXT: Value: 0x1
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global (0x1)
+// CHECK-NEXT: Type: GNU_IFunc (0xA)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text (0x2)
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: foo_impl (29)
+// CHECK-NEXT: Value: 0x0
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global (0x1)
+// CHECK-NEXT: Type: Function (0x2)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text (0x2)
+// CHECK-NEXT: }
+// CHECK-NEXT: Symbol {
+// CHECK-NEXT: Name: foo_resolver (12)
+// CHECK-NEXT: Value: 0x1
+// CHECK-NEXT: Size: 0
+// CHECK-NEXT: Binding: Global (0x1)
+// CHECK-NEXT: Type: Function (0x2)
+// CHECK-NEXT: Other: 0
+// CHECK-NEXT: Section: .text (0x2)
+// CHECK-NEXT: }
Index: llvm/lib/MC/ELFObjectWriter.cpp
===================================================================
--- llvm/lib/MC/ELFObjectWriter.cpp
+++ llvm/lib/MC/ELFObjectWriter.cpp
@@ -511,6 +511,18 @@
return Type;
}
+static bool isIFunc(const MCSymbolELF &Symbol) {
+ if (Symbol.getType() == ELF::STT_GNU_IFUNC)
+ return true;
+
+ const MCSymbolRefExpr *Value;
+ if (!Symbol.isVariable() ||
+ !(Value = dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue())) ||
+ Value->getKind() != MCSymbolRefExpr::VK_None)
+ return false;
+ return isIFunc(cast<MCSymbolELF>(Value->getSymbol()));
+}
+
void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
ELFSymbolData &MSD, const MCAsmLayout &Layout) {
const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
@@ -524,6 +536,8 @@
// Binding and Type share the same byte as upper and lower nibbles
uint8_t Binding = Symbol.getBinding();
uint8_t Type = Symbol.getType();
+ if (Type == ELF::STT_NOTYPE && isIFunc(Symbol))
+ Type = ELF::STT_GNU_IFUNC;
if (Base) {
Type = mergeTypeForSet(Type, Base->getType());
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D67206.218822.patch
Type: text/x-patch
Size: 2910 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190905/48dce291/attachment-0001.bin>
More information about the llvm-commits
mailing list