diff options
| author | Alex Richardson <Alexander.Richardson@cl.cam.ac.uk> | 2020-01-13 13:52:48 +0000 |
|---|---|---|
| committer | Alex Richardson <Alexander.Richardson@cl.cam.ac.uk> | 2020-01-13 14:14:03 +0000 |
| commit | 8e8ccf4712cf58562a91c197da3efd4f9963ce0d (patch) | |
| tree | 444388591ad6c533d6565e323c2f438d31114f75 /llvm/lib/Target/Mips | |
| parent | 894f742acb977a09285dcab024e50c2cf6bce578 (diff) | |
| download | bcm5719-llvm-8e8ccf4712cf58562a91c197da3efd4f9963ce0d.tar.gz bcm5719-llvm-8e8ccf4712cf58562a91c197da3efd4f9963ce0d.zip | |
[MIPS] Don't emit R_(MICRO)MIPS_JALR relocations against data symbols
The R_(MICRO)MIPS_JALR optimization only works when used against functions.
Using the relocation against a data symbol (e.g. function pointer) will
cause some linkers that don't ignore the hint in this case (e.g. LLD prior
to commit 5bab291b7b) to generate a relative branch to the data symbol
which crashes at run time. Before this patch, LLVM was erroneously emitting
these relocations against local-dynamic TLS function pointers and global
function pointers with internal visibility.
Reviewers: atanasyan, jrtc27, vstefanovic
Reviewed By: atanasyan
Differential Revision: https://reviews.llvm.org/D72571
Diffstat (limited to 'llvm/lib/Target/Mips')
| -rw-r--r-- | llvm/lib/Target/Mips/MipsISelLowering.cpp | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index ea242b4d46b..46b1f35a6fc 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -3111,6 +3111,14 @@ void MipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI, StringRef Sym; if (const GlobalAddressSDNode *G = dyn_cast_or_null<const GlobalAddressSDNode>(TargetAddr)) { + // We must not emit the R_MIPS_JALR relocation against data symbols + // since this will cause run-time crashes if the linker replaces the + // call instruction with a relative branch to the data symbol. + if (!isa<Function>(G->getGlobal())) { + LLVM_DEBUG(dbgs() << "Not adding R_MIPS_JALR against data symbol " + << G->getGlobal()->getName() << "\n"); + return; + } Sym = G->getGlobal()->getName(); } else if (const ExternalSymbolSDNode *ES = @@ -3123,6 +3131,7 @@ void MipsTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI, MachineFunction *MF = MI.getParent()->getParent(); MCSymbol *S = MF->getContext().getOrCreateSymbol(Sym); + LLVM_DEBUG(dbgs() << "Adding R_MIPS_JALR against " << Sym << "\n"); MI.addOperand(MachineOperand::CreateMCSymbol(S, MipsII::MO_JALR)); } } |

