diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-06-17 00:14:54 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-06-17 00:14:54 +0000 |
commit | 4198293b2568c3fa287e7bde71162e9d442f4305 (patch) | |
tree | 8cfbc1a406237f68a9a68a544eb0b3129d6312ea /contrib/llvm | |
parent | 24d58133b7f7836aa02c66016f62b2a8d452ea18 (diff) | |
parent | f2eb97b2cded8209e6d0d35930507dcfcf5bc794 (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.cpp | 32 |
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 |