svn commit: r319956 - head/contrib/llvm/tools/lld/ELF
Ed Maste
emaste at FreeBSD.org
Wed Jun 14 18:56:34 UTC 2017
Author: emaste
Date: Wed Jun 14 18:56:33 2017
New Revision: 319956
URL: https://svnweb.freebsd.org/changeset/base/319956
Log:
lld: Fix weak symbols on arm and aarch64
Given
.weak target
.global _start
_start:
b target
The intention is that the branch goes to the instruction after the
branch, effectively turning it on a nop. The branch adds the runtime
PC, but we were adding it statically too.
I noticed the oddity by inspection, but llvm-objdump seems to agree,
since it now prints things like:
b #-4 <_start+0x4>
Obtained from: LLD commit r305212
Differential Revision: https://reviews.freebsd.org/D11191
Reviewed by: dim, Rafael Espíndola
Obtained from: LLD r305212
MFC after: 3 days
Modified:
head/contrib/llvm/tools/lld/ELF/InputSection.cpp
Modified: head/contrib/llvm/tools/lld/ELF/InputSection.cpp
==============================================================================
--- head/contrib/llvm/tools/lld/ELF/InputSection.cpp Wed Jun 14 18:53:33 2017 (r319955)
+++ head/contrib/llvm/tools/lld/ELF/InputSection.cpp Wed Jun 14 18:56:33 2017 (r319956)
@@ -255,7 +255,7 @@ static uint32_t getARMUndefinedRelativeWeakVA(uint32_t
uint32_t P) {
switch (Type) {
case R_ARM_THM_JUMP11:
- return P + 2;
+ return P + 2 + A;
case R_ARM_CALL:
case R_ARM_JUMP24:
case R_ARM_PC24:
@@ -263,12 +263,12 @@ static uint32_t getARMUndefinedRelativeWeakVA(uint32_t
case R_ARM_PREL31:
case R_ARM_THM_JUMP19:
case R_ARM_THM_JUMP24:
- return P + 4;
+ return P + 4 + A;
case R_ARM_THM_CALL:
// We don't want an interworking BLX to ARM
- return P + 5;
+ return P + 5 + A;
default:
- return A;
+ return P + A;
}
}
@@ -279,9 +279,9 @@ static uint64_t getAArch64UndefinedRelativeWeakVA(uint
case R_AARCH64_CONDBR19:
case R_AARCH64_JUMP26:
case R_AARCH64_TSTBR14:
- return P + 4;
+ return P + 4 + A;
default:
- return A;
+ return P + A;
}
}
@@ -344,20 +344,30 @@ getRelocTargetVA(uint32_t Type, typename ELFT::uint A,
return In<ELFT>::MipsGot->getVA() + In<ELFT>::MipsGot->getTlsOffset() +
In<ELFT>::MipsGot->getTlsIndexOff() - In<ELFT>::MipsGot->getGp();
case R_PAGE_PC:
- case R_PLT_PAGE_PC:
+ case R_PLT_PAGE_PC: {
+ uint64_t Dest;
if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak())
- return getAArch64Page(A);
- return getAArch64Page(Body.getVA<ELFT>(A)) - getAArch64Page(P);
- case R_PC:
+ Dest = getAArch64Page(A);
+ else
+ Dest = getAArch64Page(Body.getVA<ELFT>(A));
+ return Dest - getAArch64Page(P);
+ }
+ case R_PC: {
+ uint64_t Dest;
if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) {
// On ARM and AArch64 a branch to an undefined weak resolves to the
// next instruction, otherwise the place.
if (Config->EMachine == EM_ARM)
- return getARMUndefinedRelativeWeakVA(Type, A, P);
- if (Config->EMachine == EM_AARCH64)
- return getAArch64UndefinedRelativeWeakVA(Type, A, P);
+ Dest = getARMUndefinedRelativeWeakVA(Type, A, P);
+ else if (Config->EMachine == EM_AARCH64)
+ Dest = getAArch64UndefinedRelativeWeakVA(Type, A, P);
+ else
+ Dest = Body.getVA<ELFT>(A);
+ } else {
+ Dest = Body.getVA<ELFT>(A);
}
- return Body.getVA<ELFT>(A) - P;
+ return Dest - P;
+ }
case R_PLT:
return Body.getPltVA<ELFT>() + A;
case R_PLT_PC:
More information about the svn-src-head
mailing list