aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-06-17 00:14:54 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-06-17 00:14:54 +0000
commit4198293b2568c3fa287e7bde71162e9d442f4305 (patch)
tree8cfbc1a406237f68a9a68a544eb0b3129d6312ea /contrib/llvm
parent24d58133b7f7836aa02c66016f62b2a8d452ea18 (diff)
parentf2eb97b2cded8209e6d0d35930507dcfcf5bc794 (diff)
Merge ^/head r319801 through r320041.
Notes
Notes: svn path=/projects/clang500-import/; revision=320042
Diffstat (limited to 'contrib/llvm')
-rw-r--r--contrib/llvm/tools/lld/ELF/InputSection.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/contrib/llvm/tools/lld/ELF/InputSection.cpp b/contrib/llvm/tools/lld/ELF/InputSection.cpp
index 9aae82bc2992..eb084f18daaf 100644
--- a/contrib/llvm/tools/lld/ELF/InputSection.cpp
+++ b/contrib/llvm/tools/lld/ELF/InputSection.cpp
@@ -467,6 +467,7 @@ static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P,
case R_GOTREL_FROM_END:
return Body.getVA(A) - InX::Got->getVA() - InX::Got->getSize();
case R_GOT_FROM_END:
+ case R_GOT_FROM_END:
case R_RELAX_TLS_GD_TO_IE_END:
return Body.getGotOffset() + A - InX::Got->getSize();
case R_GOT_OFF:
@@ -475,6 +476,7 @@ static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P,
case R_RELAX_TLS_GD_TO_IE_PAGE_PC:
return getAArch64Page(Body.getGotVA() + A) - getAArch64Page(P);
case R_GOT_PC:
+ case R_GOT_PC:
case R_RELAX_TLS_GD_TO_IE:
return Body.getGotVA() + A - P;
case R_HINT:
@@ -544,6 +546,36 @@ static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P,
case R_PLT_PC:
case R_PPC_PLT_OPD:
return Body.getPltVA() + A - P;
+ case R_PAGE_PC:
+ case R_PLT_PAGE_PC: {
+ uint64_t Dest;
+ if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak())
+ 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)
+ 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 Dest - P;
+ }
+ case R_PLT:
+ return Body.getPltVA<ELFT>() + A;
+ case R_PLT_PC:
+ case R_PPC_PLT_OPD:
+ return Body.getPltVA<ELFT>() + A - P;
case R_PPC_OPD: {
uint64_t SymVA = Body.getVA(A);
// If we have an undefined weak symbol, we might get here with a symbol