summaryrefslogtreecommitdiff
path: root/ELF/Arch/Mips.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ELF/Arch/Mips.cpp')
-rw-r--r--ELF/Arch/Mips.cpp8
1 files changed, 6 insertions, 2 deletions
diff --git a/ELF/Arch/Mips.cpp b/ELF/Arch/Mips.cpp
index 495e2567006f5..e8af36e6d11e3 100644
--- a/ELF/Arch/Mips.cpp
+++ b/ELF/Arch/Mips.cpp
@@ -296,7 +296,8 @@ template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2
}
- write32<E>(Buf + 24, 0x0320f809); // jalr $25
+ uint32_t JalrInst = Config->ZHazardplt ? 0x0320fc09 : 0x0320f809;
+ write32<E>(Buf + 24, JalrInst); // jalr.hb $25 or jalr $25
write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2
uint64_t GotPlt = InX::GotPlt->getVA();
@@ -330,9 +331,12 @@ void MIPS<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
return;
}
+ uint32_t JrInst = isMipsR6() ? (Config->ZHazardplt ? 0x03200409 : 0x03200009)
+ : (Config->ZHazardplt ? 0x03200408 : 0x03200008);
+
write32<E>(Buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry)
write32<E>(Buf + 4, 0x8df90000); // l[wd] $25, %lo(.got.plt entry)($15)
- write32<E>(Buf + 8, isMipsR6() ? 0x03200009 : 0x03200008); // jr $25
+ write32<E>(Buf + 8, JrInst); // jr $25 / jr.hb $25
write32<E>(Buf + 12, 0x25f80000); // addiu $24, $15, %lo(.got.plt entry)
writeRelocation<E>(Buf, GotPltEntryAddr + 0x8000, 16, 16);
writeRelocation<E>(Buf + 4, GotPltEntryAddr, 16, 0);