[PATCH] D49383: [cfi-verify] Support cross-DSO by treating certain calls as traps.

Peter Collingbourne via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 25 15:27:02 PDT 2018


pcc added a comment.

In https://reviews.llvm.org/D49383#1175843, @jgalenson wrote:

> In https://reviews.llvm.org/D49383#1175738, @pcc wrote:
>
> > I agree with eugenis that the PLT symbolization should live in lib/Object. That would also help us implement PLT symbolization in llvm-objdump. I was imagining that there would be a function that would take an object file and return a list of (PLT entry address, symbol) pairs. That would seem to be sufficient for llvm-objdump as well as for this code.
> >
> > I was discussing PLT symbolization offline with eugenis and did a little more investigation. It turns out that it shouldn't be that hard to symbolize the PLT, at least not on aarch64. All of bfd/gold/lld start their PLT entries with a straightforward ADRP/LDR sequence, which you can pretty straighforwardly map onto a GOT entry and then onto a symbol.
>
>
> As I said initially, I did think putting this logic in core LLVM was the best way, but I still don't understand how to do it (other than the way I did).  Do you have more details or a sample patch?


There are three parts: disassembling the .plt section, finding the PLT entry points with corresponding virtual addresses for GOT entries and mapping them onto the dynamic relocations for the GOT. The first two parts are architecture specific and the third is mostly architecture independent (except for the relocation type for GOT entries). I was imagining that you would add a virtual function to MCInstrAnalysis:

  std::vector<std::pair</*PLT VA*/uint64_t, /*GOT entry VA*/uint64_t>> findPltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents);

whose implementations would basically do something like this function:

http://llvm-cs.pcc.me.uk/tools/llvm-cfi-verify/lib/FileAnalysis.cpp#417

except that they would look for instructions that appear in PLT entries (i.e. ADRP/LDR instructions in the AArch64 implementation).

Then you'd add a function to ELFObjectFileBase

  std::vector<std::pair</* symbol */DataRefImpl, /* PLT VA */uint64_t>> getPltAddresses()

that would

1. find the `.plt` section by enumerating sections using `section_iterator`
2. use `getSectionContents` to get the contents and then pass them to `findPltEntries`
3. find `.rela.plt` or `.rel.plt` in the same way (or just in the same loop during step 1) and once you've found it use SectionRef::relocations to enumerate relocations
4. from there you'll be able to get the "offset" (actually a VA in executables and DSOs), type and symbol. Check that the type is correct (correct meaning has the correct relocation type -- this could just be determined with a switch statement like

  switch (something) {
  case aarch64:
    return R_AARCH64_JUMP_SLOT;
  ....
  }

) and if the offset/VA matches one of the GOT entry VAs that you previously got from `findPltEntries` then add the (symbol, PLT VA) pair to the vector that you're going to return.


https://reviews.llvm.org/D49383





More information about the llvm-commits mailing list