Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -399,6 +399,11 @@ } } +// 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) { @@ -411,15 +416,28 @@ case R_ARM_PREL31: case R_ARM_THM_JUMP19: case R_ARM_THM_JUMP24: + // Unresolved branch relocations to weak references resolve to next + // instruction, this will be either: + // 2 bytes on from P for a 16-bit instruction + // 4 bytes on from P for a 32-bit instruction return P + 4 + A; case R_ARM_THM_CALL: - // We don't want an interworking BLX to ARM + // As above but we need to add Thumb bit to avoid a blx return P + 5 + A; - default: + 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: + // Unresolved non branch pc-relative relocations + // R_ARM_TARGET2 which can be resolved relatively is not present as it never + // targets a weak-reference. 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) { @@ -427,10 +445,17 @@ case R_AARCH64_CONDBR19: case R_AARCH64_JUMP26: case R_AARCH64_TSTBR14: + // Unresolved branch relocations to weak references resolve to next + // instruction, this is 4 bytes on from P. return P + 4 + A; - default: + case R_AARCH64_PREL16: + case R_AARCH64_PREL32: + case R_AARCH64_PREL64: + case R_AARCH64_ADR_PREL_LO21: + // Unresolved non branch pc-relative relocations 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