summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2019-12-17 21:35:02 -0800
committerFangrui Song <maskray@google.com>2019-12-20 11:32:02 -0800
commite8054f0933701a885a42e4a240f050402d7930e0 (patch)
treee6cb34e2d0bc9bd0f8e5456525e08b49f13a37c4 /llvm/lib/Target
parentde2378b4f3c4c88eae412a30a8bfaec82f54d1b7 (diff)
downloadbcm5719-llvm-e8054f0933701a885a42e4a240f050402d7930e0.tar.gz
bcm5719-llvm-e8054f0933701a885a42e4a240f050402d7930e0.zip
[PPC32] Emit R_PPC_PLTREL24 for calls to dso_local ifunc
static void *ifunc(void) __attribute__((ifunc("resolver"))); void foo() { ifunc(); } The relocation produced by the ifunc() call: 1. gcc -msecure-plt -fPIC => R_PPC_PLTREL24 r_addend=0x8000 2. gcc -msecure-plt -PIE => R_PPC_PLTREL24 r_addend=0x8000 3. clang -msecure-plt -fPIC => R_PPC_PLTREL24 r_addend=0x8000 4. clang -msecure-plt -fPIE => R_PPC_REL24 4 is incorrect. The R_PPC_REL24 needs a call stub due to ifunc. If this relocation is mixed with other R_PPC_PLTREL24(r_addend=0x8000) in a function, both GNU ld and lld (after D71621 fix) may produce a wrong result. This patch fixes 4 to use R_PPC_PLTREL24, which matches GCC. Both GNU ld and lld (after D71621) will be happy. Reviewed By: sfertile Differential Revision: https://reviews.llvm.org/D71649
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/PowerPC/PPCISelLowering.cpp5
1 files changed, 3 insertions, 2 deletions
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 3062dbb655f..ad7c9ea4e6c 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -5102,9 +5102,10 @@ static SDValue transformCallee(const SDValue &Callee, SelectionDAG &DAG,
auto isLocalCallee = [&]() {
const GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
const Module *Mod = DAG.getMachineFunction().getFunction().getParent();
+ const GlobalValue *GV = G ? G->getGlobal() : nullptr;
- return DAG.getTarget().shouldAssumeDSOLocal(*Mod,
- G ? G->getGlobal() : nullptr);
+ return DAG.getTarget().shouldAssumeDSOLocal(*Mod, GV) &&
+ !dyn_cast_or_null<GlobalIFunc>(GV);
};
// The PLT is only used in 32-bit ELF PIC mode. Attempting to use the PLT in
OpenPOWER on IntegriCloud