[ELF/AArch64] Factor out overflow checks into a separate function. NFC.

Differential revision: http://reviews.llvm.org/D14922

llvm-svn: 253884
This commit is contained in:
Igor Kudrin 2015-11-23 17:16:09 +00:00
parent 0ca5bd4a46
commit ee252ded15
1 changed files with 14 additions and 17 deletions

View File

@ -691,18 +691,23 @@ static uint64_t getAArch64Page(uint64_t Expr) {
return Expr & (~static_cast<uint64_t>(0xFFF)); return Expr & (~static_cast<uint64_t>(0xFFF));
} }
template <unsigned N>
static void checkAArch64OutOfRange(int64_t X, uint32_t Type) {
if (!isInt<N>(X))
error("Relocation " + getELFRelocationTypeName(EM_AARCH64, Type) +
" out of range");
}
void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd, void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
uint32_t Type, uint64_t P, uint32_t Type, uint64_t P,
uint64_t SA) const { uint64_t SA) const {
switch (Type) { switch (Type) {
case R_AARCH64_ABS16: case R_AARCH64_ABS16:
if (!isInt<16>(SA)) checkAArch64OutOfRange<16>(SA, Type);
error("Relocation R_AARCH64_ABS16 out of range");
write16le(Loc, SA); write16le(Loc, SA);
break; break;
case R_AARCH64_ABS32: case R_AARCH64_ABS32:
if (!isInt<32>(SA)) checkAArch64OutOfRange<32>(SA, Type);
error("Relocation R_AARCH64_ABS32 out of range");
write32le(Loc, SA); write32le(Loc, SA);
break; break;
case R_AARCH64_ABS64: case R_AARCH64_ABS64:
@ -719,26 +724,20 @@ void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
break; break;
case R_AARCH64_ADR_PREL_LO21: { case R_AARCH64_ADR_PREL_LO21: {
uint64_t X = SA - P; uint64_t X = SA - P;
if (!isInt<21>(X)) checkAArch64OutOfRange<21>(X, Type);
error("Relocation R_AARCH64_ADR_PREL_LO21 out of range");
updateAArch64Adr(Loc, X & 0x1FFFFF); updateAArch64Adr(Loc, X & 0x1FFFFF);
break; break;
} }
case R_AARCH64_ADR_PREL_PG_HI21: { case R_AARCH64_ADR_PREL_PG_HI21: {
uint64_t X = getAArch64Page(SA) - getAArch64Page(P); uint64_t X = getAArch64Page(SA) - getAArch64Page(P);
if (!isInt<33>(X)) checkAArch64OutOfRange<33>(X, Type);
error("Relocation R_AARCH64_ADR_PREL_PG_HI21 out of range");
updateAArch64Adr(Loc, (X >> 12) & 0x1FFFFF); // X[32:12] updateAArch64Adr(Loc, (X >> 12) & 0x1FFFFF); // X[32:12]
break; break;
} }
case R_AARCH64_JUMP26: case R_AARCH64_JUMP26:
case R_AARCH64_CALL26: { case R_AARCH64_CALL26: {
uint64_t X = SA - P; uint64_t X = SA - P;
if (!isInt<28>(X)) { checkAArch64OutOfRange<28>(X, Type);
if (Type == R_AARCH64_JUMP26)
error("Relocation R_AARCH64_JUMP26 out of range");
error("Relocation R_AARCH64_CALL26 out of range");
}
or32le(Loc, (X & 0x0FFFFFFC) >> 2); or32le(Loc, (X & 0x0FFFFFFC) >> 2);
break; break;
} }
@ -755,13 +754,11 @@ void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint8_t *BufEnd,
or32le(Loc, (SA & 0xFFF) << 10); or32le(Loc, (SA & 0xFFF) << 10);
break; break;
case R_AARCH64_PREL16: case R_AARCH64_PREL16:
if (!isInt<16>(SA - P)) checkAArch64OutOfRange<16>(SA - P, Type);
error("Relocation R_AARCH64_PREL16 out of range");
write16le(Loc, SA - P); write16le(Loc, SA - P);
break; break;
case R_AARCH64_PREL32: case R_AARCH64_PREL32:
if (!isInt<32>(SA - P)) checkAArch64OutOfRange<32>(SA - P, Type);
error("Relocation R_AARCH64_PREL32 out of range");
write32le(Loc, SA - P); write32le(Loc, SA - P);
break; break;
case R_AARCH64_PREL64: case R_AARCH64_PREL64: