[PATCH] D62598: [AArch64][ELF][llvm-objdump] Add support for PLT decoding with BTI instructions present

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 4 08:14:08 PDT 2019


peter.smith marked an inline comment as done.
peter.smith added a comment.

Thanks for the review.



================
Comment at: lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp:171
+      // Check for optional bti c that prefixes adrp in BTI enabled entries
+      if ((Insn & 0xd503245f) == 0xd503245f) {
+         Off = 4;
----------------
MaskRay wrote:
> peter.smith wrote:
> > MaskRay wrote:
> > > peter.smith wrote:
> > > > MaskRay wrote:
> > > > > I'm not familiar with the encoding.. but does this mean other bit patterns (e.g. 0xffffffff) should also be accepted?
> > > > Apologies I'm not sure I understand. I've put what I know in this comment. Please let me know if I've missed something?
> > > > 
> > > > At the moment I don't think any other bit-patterns are necessary. As I understand it the function will look for either:
> > > > 
> > > > ```
> > > > bti c
> > > > adrp 
> > > > ```
> > > > or
> > > > ```
> > > > adrp
> > > > ```
> > > > To denote the start of a PLT entry. If neither of those is found then we'll skip all instructions till we find one. All but one type of AArch64 PLT entry follows this form. There is one other "pseudo" PLT entry type that can be generated by ld.bfd (but not LLD) for the lazy resolver of TLSDESC variables. If it is present there is always only one entry at the end of the PLT. It can be generated by the following:
> > > > 
> > > > ```
> > > > extern __thread int val __attribute__((tls_model("global-dynamic")));
> > > > 
> > > > int func() {
> > > >     return val;
> > > > }
> > > > aarch64-linux-gnu-gcc  tls.c -O2 -fpic --shared -o tls.so
> > > > 
> > > > ```
> > > > It is of the form.
> > > > ```
> > > > _dl_tlsdesc_lazy_trampoline
> > > >   stp   x2, x3, [sp, #-16]!
> > > >   adrp  x2, DT_TLSDESC_GOT
> > > >   adrp  x3,  PLTGOT
> > > >   ldr   x2, [x2, :lo12:DT_TLSDESC_GOT]
> > > >   add   x3, x3, :lo12:PLTGOT
> > > >   br    x2
> > > > ``` 
> > > > Note that gnu objdump doesn't seem to disassemble it as part of the PLT, so I've not added any support for it. I guess that could come as a separate patch if we wanted to.
> > > > 
> > > > I'm looking to match exactly one instruction BTI with exactly one type of operand "c" so the encoding can be precise.
> > > > 
> > > > The encoding for BTI c (quoting from  DDI_0596_ARM_a64_instruction_set_architecture.pdf link in the description)
> > > > | 1 1 0 1 | 0 1 0 1 | 0 0 0 0 | 0 0 1 1 | 0 0 1 0 | 0 1 0 0 | x x 0 1 | 1 1 1 1 |
> > > > |     d       |      5      |      0     |      3      |       2     |       4     | x x 0 1 |      f       |
> > > > where xx is:
> > > > | 00 | (omitted) |
> > > > | 01 | c |
> > > > | 10 | j |
> > > > | 11 | jc |
> > > > For BTI c we'd want 0 1 0 1, which is 5.
> > > > 
> > > > Hope that answers the question?
> > > Thanks for the explanation! Then I think this should probably be: `(Inst | 0xc0) == 0xd50324df`
> > > 
> > > 
> > > `(Insn & 0xd503245f) == 0xd503245f` accepts many other irrelevant bit patterns like 0xffffffff.
> > I see what you mean now, apologies I should have spotted that! I think that as we are only interested in "BTI c" which matches a single bit-pattern then a simple (Inst == 0xd50324df) will do. Will post updated patch in a sec.
> As I understand it, BTI c can be the target of an indirect call (blr reg) or an indirect jump(tail call) (br x16/x17). Can it be used as a general indirect jump target (br xn where n is neither 16 nor 17)? e.g. reused as a jump table target. If it is possible, then `BTI jc` may make sense.
> 
> If `BTI jc` doesn't make sense, this LGTM.
FWIW I had to ask the same question to one of my colleagues. The J isn't required in this case for some non-obvious reasons. My best summary is:
- A program loader sets a Guard value on the executable pages of an ELF file that claims BTI support GNU_FEATURE_AARCH64_FEATURE_1_BTI. For a program made up of an executable and shared-libraries there can be a mixture of support in each ELF file.
- An indirect branch from a non-guarded page (no BTI support) will always succeed. So an indirect branch via another register is fine.
- An indirect branch from a guarded page must use x17, x16 in order to be compatible with "BTI C". As a guarded page can only result from a relocatable object with BTI support, we know the compiler can respect that.

There is some more information in the comment for LLVM support for BTI D52867 about the meaning of the flags. The J is meant for jump tables only.


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

https://reviews.llvm.org/D62598





More information about the llvm-commits mailing list