Commit 3d9b1128 authored by Fangrui Song's avatar Fangrui Song
Browse files

[ELF][ARM] Add getPCBias()

ThunkCreator::getThunk and ThunkCreator::normalizeExistingThunk
currently assume that the implicit addends are -8 for ARM and -4 for
Thumb. In D70637, ThunkCreator::getThunk will need to take care of the
relocation addend explicitly.

Add the utility function getPCBias() as a prerequisite so that the getThunk change in D70637
can be more general.

Reviewed By: peter.smith

Differential Revision: https://reviews.llvm.org/D70690
parent a048bf87
Loading
Loading
Loading
Loading
+18 −2
Original line number Diff line number Diff line
@@ -1763,6 +1763,19 @@ static bool isThunkSectionCompatible(InputSection *source,
  return true;
}

static int64_t getPCBias(RelType type) {
  if (config->emachine != EM_ARM)
    return 0;
  switch (type) {
  case R_ARM_THM_JUMP19:
  case R_ARM_THM_JUMP24:
  case R_ARM_THM_CALL:
    return 4;
  default:
    return 8;
  }
}

std::pair<Thunk *, bool> ThunkCreator::getThunk(InputSection *isec,
                                                Relocation &rel, uint64_t src) {
  std::vector<Thunk *> *thunkVec = nullptr;
@@ -1779,7 +1792,9 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(InputSection *isec,
  for (Thunk *t : *thunkVec)
    if (isThunkSectionCompatible(isec, t->getThunkTargetSym()->section) &&
        t->isCompatibleWith(*isec, rel) &&
        target->inBranchRange(rel.type, src, t->getThunkTargetSym()->getVA()))
        target->inBranchRange(rel.type, src,
                              t->getThunkTargetSym()->getVA(rel.addend) +
                                  getPCBias(rel.type)))
      return std::make_pair(t, false);

  // No existing compatible Thunk in range, create a new one
@@ -1794,7 +1809,8 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(InputSection *isec,
// relocation back to its original non-Thunk target.
bool ThunkCreator::normalizeExistingThunk(Relocation &rel, uint64_t src) {
  if (Thunk *t = thunks.lookup(rel.sym)) {
    if (target->inBranchRange(rel.type, src, rel.sym->getVA()))
    if (target->inBranchRange(rel.type, src,
                              rel.sym->getVA(rel.addend) + getPCBias(rel.type)))
      return true;
    rel.sym = &t->destination;
    if (rel.sym->isInPlt())