summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorJoel Galenson <jgalenson@google.com>2018-07-13 15:19:33 +0000
committerJoel Galenson <jgalenson@google.com>2018-07-13 15:19:33 +0000
commit06e7e5798fa4efdcbc9598427fb8ccb6942d6cb0 (patch)
tree28217e428500e88e450e60f95ae2051a756e9f83 /llvm/lib/Target
parent02695fa8a7f2337bc4524dc877f618e0e2045e16 (diff)
downloadbcm5719-llvm-06e7e5798fa4efdcbc9598427fb8ccb6942d6cb0.tar.gz
bcm5719-llvm-06e7e5798fa4efdcbc9598427fb8ccb6942d6cb0.zip
[cfi-verify] Support AArch64.
This patch adds support for AArch64 to cfi-verify. This required three changes to cfi-verify. First, it generalizes checking if an instruction is a trap by adding a new isTrap flag to TableGen (and defining it for x86 and AArch64). Second, the code that ensures that the operand register is not clobbered between the CFI check and the indirect call needs to allow a single dereference (in x86 this happens as part of the jump instruction). Third, we needed to ensure that return instructions are not counted as indirect branches. Technically, returns are indirect branches and can be covered by CFI, but LLVM's forward-edge CFI does not protect them, and x86 does not consider them, so we keep that behavior. In addition, we had to improve AArch64's code to evaluate the branch target of a MCInst to handle calls where the destination is not the first operand (which it often is not). Differential Revision: https://reviews.llvm.org/D48836 llvm-svn: 337007
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r--llvm/lib/Target/AArch64/AArch64InstrInfo.td2
-rw-r--r--llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp20
-rw-r--r--llvm/lib/Target/X86/X86InstrSystem.td2
3 files changed, 15 insertions, 9 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 0d008beacd6..e5ab8044598 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -1442,7 +1442,9 @@ def : Pat<(AArch64call texternalsym:$func), (BL texternalsym:$func)>;
//===----------------------------------------------------------------------===//
// Exception generation instructions.
//===----------------------------------------------------------------------===//
+let isTrap = 1 in {
def BRK : ExceptionGeneration<0b001, 0b00, "brk">;
+}
def DCPS1 : ExceptionGeneration<0b101, 0b01, "dcps1">;
def DCPS2 : ExceptionGeneration<0b101, 0b10, "dcps2">;
def DCPS3 : ExceptionGeneration<0b101, 0b11, "dcps3">;
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
index 85402d7d411..4ceda7e122f 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCTargetDesc.cpp
@@ -140,14 +140,18 @@ public:
bool evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
uint64_t &Target) const override {
- if (Inst.getNumOperands() == 0 ||
- Info->get(Inst.getOpcode()).OpInfo[0].OperandType !=
- MCOI::OPERAND_PCREL)
- return false;
-
- int64_t Imm = Inst.getOperand(0).getImm() * 4;
- Target = Addr + Imm;
- return true;
+ // Search for a PC-relative argument.
+ // This will handle instructions like bcc (where the first argument is the
+ // condition code) and cbz (where it is a register).
+ const auto &Desc = Info->get(Inst.getOpcode());
+ for (unsigned i = 0, e = Inst.getNumOperands(); i != e; i++) {
+ if (Desc.OpInfo[i].OperandType == MCOI::OPERAND_PCREL) {
+ int64_t Imm = Inst.getOperand(i).getImm() * 4;
+ Target = Addr + Imm;
+ return true;
+ }
+ }
+ return false;
}
};
diff --git a/llvm/lib/Target/X86/X86InstrSystem.td b/llvm/lib/Target/X86/X86InstrSystem.td
index 2dfad13dbf7..35ee00b9e01 100644
--- a/llvm/lib/Target/X86/X86InstrSystem.td
+++ b/llvm/lib/Target/X86/X86InstrSystem.td
@@ -22,7 +22,7 @@ let Defs = [RAX, RCX, RDX] in
// CPU flow control instructions
-let mayLoad = 1, mayStore = 0, hasSideEffects = 1 in {
+let mayLoad = 1, mayStore = 0, hasSideEffects = 1, isTrap = 1 in {
def TRAP : I<0x0B, RawFrm, (outs), (ins), "ud2", [(trap)]>, TB;
def UD2B : I<0xB9, RawFrm, (outs), (ins), "ud2b", []>, TB;
}
OpenPOWER on IntegriCloud