diff options
| author | Peter Smith <peter.smith@linaro.org> | 2017-06-19 09:43:43 +0000 |
|---|---|---|
| committer | Peter Smith <peter.smith@linaro.org> | 2017-06-19 09:43:43 +0000 |
| commit | 9873c4b509a8fbf536e6b8c52eb8329a6d1d383c (patch) | |
| tree | e700f539c3714102bbc9e7d3d092853325896159 | |
| parent | 621894ac76c2ebfaf9c6a601c21550bdf3dc50d6 (diff) | |
| download | bcm5719-llvm-9873c4b509a8fbf536e6b8c52eb8329a6d1d383c.tar.gz bcm5719-llvm-9873c4b509a8fbf536e6b8c52eb8329a6d1d383c.zip | |
[ELF] make default for get{ARM,AArch64}UndefinedRelativeWeakVA unreachable
The get{ARM,AArch64}UndefinedRelativeWeakVA() functions should only be
called for PC-relative relocations. Complete the supported pc-relative
relocations in the switch statement and make the default case unreachable.
The R_ARM_TARGET relocation can be evaluated as R_ARM_REL32 but it is only
used in the context of exception tables, and is never output with respect
to a weak reference so it does not appear in the switch statement.
Differential Revision: https://reviews.llvm.org/D34138
llvm-svn: 305673
| -rw-r--r-- | lld/ELF/InputSection.cpp | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 9aae82bc299..b1d5e134946 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -399,9 +399,16 @@ void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) { } } +// The ARM and AArch64 ABI handle pc-relative relocations to undefined weak +// references specially. The general rule is that the value of the symbol in +// this context is the address of the place P. A further special case is that +// branch relocations to an undefined weak reference resolve to the next +// instruction. static uint32_t getARMUndefinedRelativeWeakVA(uint32_t Type, uint32_t A, uint32_t P) { switch (Type) { + // Unresolved branch relocations to weak references resolve to next + // instruction, this will be either 2 or 4 bytes on from P. case R_ARM_THM_JUMP11: return P + 2 + A; case R_ARM_CALL: @@ -415,22 +422,38 @@ static uint32_t getARMUndefinedRelativeWeakVA(uint32_t Type, uint32_t A, case R_ARM_THM_CALL: // We don't want an interworking BLX to ARM return P + 5 + A; - default: + // Unresolved non branch pc-relative relocations + // R_ARM_TARGET2 which can be resolved relatively is not present as it never + // targets a weak-reference. + case R_ARM_MOVW_PREL_NC: + case R_ARM_MOVT_PREL: + case R_ARM_REL32: + case R_ARM_THM_MOVW_PREL_NC: + case R_ARM_THM_MOVT_PREL: return P + A; } + llvm_unreachable("ARM pc-relative relocation expected\n"); } +// The comment above getARMUndefinedRelativeWeakVA applies to this function. static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A, uint64_t P) { switch (Type) { + // Unresolved branch relocations to weak references resolve to next + // instruction, this is 4 bytes on from P. case R_AARCH64_CALL26: case R_AARCH64_CONDBR19: case R_AARCH64_JUMP26: case R_AARCH64_TSTBR14: return P + 4 + A; - default: + // Unresolved non branch pc-relative relocations + case R_AARCH64_PREL16: + case R_AARCH64_PREL32: + case R_AARCH64_PREL64: + case R_AARCH64_ADR_PREL_LO21: return P + A; } + llvm_unreachable("AArch64 pc-relative relocation expected\n"); } // ARM SBREL relocations are of the form S + A - B where B is the static base |

