[PATCH] D59780: Support Intel Control-flow Enforcement Technology

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 28 22:53:08 PDT 2019


MaskRay added inline comments.


================
Comment at: lld/ELF/Arch/X86.cpp:413
+// If Intel CET (Control-Flow Enforcement Technology) is enabled,
+// we have to emit special PLT entries containing brend32 instructions.
+namespace {
----------------
`brend32` -> `endbr32`


================
Comment at: lld/ELF/Arch/X86.cpp:415
+namespace {
+class IntelCET : public X86 {
+  void writeGotPlt(uint8_t *Buf, const Symbol &S) const override;
----------------
`template <class ELFT> class IntelCET : public X86_64<ELFT> {`

`IBT-enabled PLT` can be used with the ILP32 programming model (x86-32 ABI). (If you don't like putting too much stuff in the initial commit, `class IntelCET : public X86_64<ELF64LE> {`.


================
Comment at: lld/ELF/Arch/X86_64.cpp:529
+// If Intel CET (Control-Flow Enforcement Technology) is enabled,
+// we have to emit special PLT entries containing brend32 instructions.
+namespace {
----------------
`brend32` -> `endbr64`


================
Comment at: lld/ELF/Arch/X86_64.cpp:546
+
+void IntelCET::writePltHeader(uint8_t *Buf) const {
+  // SPLT[0] is a blank slot. The ABI doesn't say anything about its contents.
----------------
If I understand it correctly, `IntelCET::writePlt` writes the contents of ld.bfd's `.plt.sec`, then it doesn't need a PLT header. Can `Symbol::getPltVA` (`Plt->getVA() + Plt->HeaderSize + PltIndex * Target->PltEntrySize;`) compute a wrong address because it thinks `HeaderSize` is actually 0?

```
Disassembly of section .plt:  // counterpart in lld: IntelCET::writeIBTPlt

0000000000001020 <.plt>:
    1020:       ff 35 e2 2f 00 00       pushq  0x2fe2(%rip)        # 4008 <_GLOBAL_OFFSET_TABLE_+0x8>
    1026:       f2 ff 25 e3 2f 00 00    bnd jmpq *0x2fe3(%rip)        # 4010 <_GLOBAL_OFFSET_TABLE_+0x10>
    102d:       0f 1f 00                nopl   (%rax)
    1030:       f3 0f 1e fa             endbr64 
    1034:       68 00 00 00 00          pushq  $0x0
    1039:       f2 e9 e1 ff ff ff       bnd jmpq 1020 <.plt>
    103f:       90                      nop
    1040:       f3 0f 1e fa             endbr64 
    1044:       68 01 00 00 00          pushq  $0x1
    1049:       f2 e9 d1 ff ff ff       bnd jmpq 1020 <.plt>
    104f:       90                      nop
...
Disassembly of section .plt.sec:  // counterpart in lld: IntelCET::writePlt

0000000000001060 <putchar at plt>:
    1060:       f3 0f 1e fa             endbr64 
    1064:       f2 ff 25 ad 2f 00 00    bnd jmp QWORD PTR [rip+0x2fad]        # 4018 <putchar at GLIBC_2.2.5>
    106b:       0f 1f 44 00 00          nop    DWORD PTR [rax+rax*1+0x0]

0000000000001070 <puts at plt>:
    1070:       f3 0f 1e fa             endbr64 
    1074:       f2 ff 25 a5 2f 00 00    bnd jmp QWORD PTR [rip+0x2fa5]        # 4020 <puts at GLIBC_2.2.5>
    107b:       0f 1f 44 00 00          nop    DWORD PTR [rax+rax*1+0x0]
```


================
Comment at: lld/ELF/InputFiles.cpp:594
 
+// If a source file is compiled with x86 hardware-assisted call flow control
+// enabled, the generated object file contains feature flags indicating that
----------------
call flow control -> Control-Flow Enforcement ?


================
Comment at: lld/ELF/InputFiles.cpp:608
+static uint32_t readX86Features(ObjFile<ELFT> *Obj, ArrayRef<uint8_t> Data) {
+  typedef typename ELFT::Nhdr Elf_Nhdr;
+  typedef typename ELFT::Note Elf_Note;
----------------
`using Elf_Nhdr = ...` is more common nowadays.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D59780





More information about the llvm-commits mailing list