[PATCH] D86706: [LLD][PowerPC] Add pc-rel based long branch thunks

Sean Fertile via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 27 14:15:44 PDT 2020


sfertile added inline comments.


================
Comment at: lld/ELF/Thunks.cpp:966
+void PPC64PCRelLongBranchThunk::writeTo(uint8_t *buf) {
+  int64_t offset = destination.getVA(addend) - getThunkTargetSym()->getVA();
+  if (!isInt<34>(offset))
----------------
I don't believe we have accounted for the addend in the other PPC64 thunks (both toc-based and pc-rel based). If we do take into account the addend then we have to account for that in 'isCompatableWith' as well.  I don't believe the compilers emit calls instructions using both symbol and addends (or we likely would have realized this earlier). I suggest to keep it simple we follow the example of the other thinks and omit the addend, or potentially error on a non-zero addend. We can then revisit this in a subsequent patch where we fix all the thunks that will need to account for the addend. 


================
Comment at: lld/ELF/Thunks.cpp:993
+
+void PPC64PCRelLongBranchThunk::writeTo(uint8_t *buf) {
+  int64_t offset = in.ppc64LongBranchTarget->getEntryVA(&destination, addend) -
----------------
NeHuang wrote:
> nemanjai wrote:
> > NeHuang wrote:
> > > sfertile wrote:
> > > > The R12Setup stub calculates the address of the callee relative to the program counter.
> > > > 
> > > > ```
> > > >   writePrefixedInstruction(buf + 0, paddi); // paddi r12, 0, func at pcrel, 1
> > > >   write32(buf + 8, MTCTR_R12);              // mtctr r12
> > > >   write32(buf + 12, BCTR);                  // bctr
> > > > ```
> > > > 
> > > > The toc-based long branch thunks have to use a table in the data segment because of limited address-ability. The pc-rel instructions and ABI doesn't have the same limitation, so why use the branch linkage table intead of doing the same thing the R12Setup stubs do?
> > > Good point! Will update the patch without using branch_lt table. 
> > Is it not possible to need a long branch to a destination that isn't available yet? I thought that something like the following would require a long branch to a PLT stub:
> > 
> > ```
> > #include <stdio.h>
> > int main(int argc, const char **argv) {
> >   int a = argc;
> >   printf("a = %d\n", a);
> >   asm (".space 134217728");
> >   printf("a = %d\n", a);
> > }
> > ```
> > But that seems to create two PLT stubs. Is this something that always happens? Namely, is it always the case that the linker will never create a thunk that goes to another thunk? If so, I think a comment explaining that might be useful.
> IIUC we only create a long branch thunk between a caller and callee and we check if there is a valid RelType (R_PPC64_REL14, R_PPC64_REL24, R_PPC64_REL24_NOTOC) in `PPC64::needsThunk` 
> is it always the case that the linker will never create a thunk that goes to another thunk.
[[ https://github.com/llvm/llvm-project/blob/a1bc37c9e54e0163bc6ccb7a438a68047310ccff/lld/ELF/Relocations.cpp#L1880 | getThunk]] looks at the symbol referenced by the relocation and sees if an existing compatible thunk can be reused, but if none fit the cirteria it creates a new thunk targeting the symbol rather then creating a thunk that targets another thunk. 

> Is it not possible to need a long branch to a destination that isn't available yet?
No: all the address sensitive content has been laid out and finalized by the time the thinks `writeTo` member function is called. 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D86706



More information about the llvm-commits mailing list