[PATCH] D70637: [ELF][AArch64] Support R_AARCH64_{CALL26,JUMP26} range extension thunks with addends

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 26 02:34:27 PST 2019


peter.smith added a comment.

In D70637#1759352 <https://reviews.llvm.org/D70637#1759352>, @MaskRay wrote:

> > Can you elaborate? My understanding is that needsThunk() and inBranchRange() assume all Arm branches to have an immediate (which becomes the relocation addend) of -8 and Thumb branches to have -4. This cancels the PC-bias of 8-bytes in Arm and 4-bytes in Thumb.
> > 
> > This is my current thinking. If the addend from the branch immediate, whether read from the instruction, or assumed to be -8 for an Arm branch or -4 for a Thumb branch, is passed in to needsThunk() I think that we could do:
> > 
> > src = branchAddr +  (Is Thumb branch then + 4, else +8) 
> >  dst = (expr == R_PLT_PC) ? s.getPltVA(addend) : s.getVA(addend);
>
> Created D70690 <https://reviews.llvm.org/D70690> as a prerequisite change to make this patch affect ARM even less.
>
> The update in `test/ELF/arm-thumb-mix-range-thunk-os.s` is related to the following diff:
>
>   if (auto *d = dyn_cast<Defined>(rel.sym))
>     if (!d->isInPlt() && d->section)
>       thunkVec = &thunkedSymbolsBySectionAndAddend[{
>           {d->section->repl, d->value}, rel.addend}];  // If I use 0 instead of rel.addend,
>   if (!thunkVec)
>     thunkVec = &thunkedSymbols[{rel.sym, rel.addend}]; // If I use 0 instead of rel.addend,  test/ELF/arm-thumb-mix-range-thunk-os.s will not need an update.
>   
>
> The R_ARM_THM_CALL in tfunc33 causes creation of a Thumb thunk. The R_ARM_CALL in tfunc34 have different implicit addends, so making `rel.addend` part of the key will create an ARM thunk, rather than reuse the existing Thumb thunk. If reusing the thunk is the intended behavior, I'll change it to
>
>   // This ternary expression makes the code less general.
>   int64_t addend = config->emachine == EM_ARM ? 0 : rel.addend;
>   
>   if (auto *d = dyn_cast<Defined>(rel.sym))
>     if (!d->isInPlt() && d->section)
>       thunkVec = &thunkedSymbolsBySectionAndAddend[{
>           {d->section->repl, d->value}, addend}];
>   if (!thunkVec)
>     thunkVec = &thunkedSymbols[{rel.sym, addend}];
>   
>
> can keep the test unchanged.


Yes it is intentional, an Arm or Thumb BL instruction can be changed into a BLX instruction that changes state, so it is possible for both an Arm and Thumb relocation to share the same Thunk.

Instead of

  // This ternary expression makes the code less general.
  int64_t addend = config->emachine == EM_ARM ? 0 : rel.addend;

May I suggest

  int64_t addend = rel.addend + getPCBias(type, rel.addend);

This could be virtual function for Target, but could just be static function that in effect cancels -4 or -8 to 0 on Arm, but still accounts for non -4 or -8 addends. The body would be something like:

    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;
    }
  }

This is more code, but it is a bit more general.

>> I would like to fix this but it will mean adding Symbol, or at least the result of S.isFunc() as a parameter to relocateOne(). If that doesn't sound too objectionable I'd be happy to work on it.
> 
> I support that we add Symbol to the parameter list of relocateOne. This can improve `reportRangeError` messages as well. Right now we don't report which symbol has the problem. With the Symbol information the message can be more specific.




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D70637/new/

https://reviews.llvm.org/D70637





More information about the llvm-commits mailing list