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>
Details
Diff Detail
- Repository
- rS FreeBSD src repository - subversion
- Lint
Lint Not Applicable - Unit
Tests Not Applicable
Event Timeline
LGTM
"emaste (Ed Maste)" <phabric-noreply@FreeBSD.org> writes:
emaste updated this revision to Diff 29605.
emaste added a comment.Add missing `;`s lost in a cut-and-paste accidentCHANGES SINCE LAST UPDATE
https://reviews.freebsd.org/D11191?vs=29590&id=29605REVISION DETAIL
https://reviews.freebsd.org/D11191AFFECTED FILES
contrib/llvm/tools/lld/ELF/InputSection.cppEMAIL PREFERENCES
https://reviews.freebsd.org/settings/panel/emailpreferences/To: emaste, dim, rafael.espindola_gmail.com
diff --git a/contrib/llvm/tools/lld/ELF/InputSection.cpp b/contrib/llvm/tools/lld/ELF/InputSection.cpp
- a/contrib/llvm/tools/lld/ELF/InputSection.cpp
+++ b/contrib/llvm/tools/lld/ELF/InputSection.cpp
@@ -255,20 +255,20 @@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: case R_ARM_PLT32: 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 @@
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 @@
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: