aboutsummaryrefslogtreecommitdiff
path: root/ELF
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-06-27 19:15:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-06-27 19:15:02 +0000
commit384e0a667a03156faed5fb21210af8a9288a9122 (patch)
treed6ca6b097f252b802977b508309796c533b94cc5 /ELF
parentf0d24653c11c321b090f5fce1fef226689eb7930 (diff)
Vendor import of lld 6.0.1 release r335540:vendor/lld/lld-release_601-r335540vendor/lld-60
Notes
Notes: svn path=/vendor/lld/dist-release_60/; revision=335728 svn path=/vendor/lld/lld-release_601-r335540/; revision=335729; tag=vendor/lld/lld-release_601-r335540
Diffstat (limited to 'ELF')
-rw-r--r--ELF/Arch/Mips.cpp8
-rw-r--r--ELF/Config.h1
-rw-r--r--ELF/Driver.cpp1
3 files changed, 8 insertions, 2 deletions
diff --git a/ELF/Arch/Mips.cpp b/ELF/Arch/Mips.cpp
index 495e2567006f..e8af36e6d11e 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);
diff --git a/ELF/Config.h b/ELF/Config.h
index ed425720965e..1f244df4d652 100644
--- a/ELF/Config.h
+++ b/ELF/Config.h
@@ -151,6 +151,7 @@ struct Configuration {
bool WarnMissingEntry;
bool ZCombreloc;
bool ZExecstack;
+ bool ZHazardplt;
bool ZNocopyreloc;
bool ZNodelete;
bool ZNodlopen;
diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
index 714976ae9c4b..44cfa56c94ce 100644
--- a/ELF/Driver.cpp
+++ b/ELF/Driver.cpp
@@ -668,6 +668,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->WarnCommon = Args.hasArg(OPT_warn_common);
Config->ZCombreloc = !hasZOption(Args, "nocombreloc");
Config->ZExecstack = hasZOption(Args, "execstack");
+ Config->ZHazardplt = hasZOption(Args, "hazardplt");
Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc");
Config->ZNodelete = hasZOption(Args, "nodelete");
Config->ZNodlopen = hasZOption(Args, "nodlopen");