summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp')
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp42
1 files changed, 32 insertions, 10 deletions
diff --git a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
index 75482544718..15bf20f091d 100644
--- a/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
+++ b/llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp
@@ -154,7 +154,8 @@ const Instr &FileAnalysis::getInstructionOrDie(uint64_t Address) const {
}
bool FileAnalysis::isCFITrap(const Instr &InstrMeta) const {
- return MII->getName(InstrMeta.Instruction.getOpcode()) == "TRAP";
+ const auto &InstrDesc = MII->get(InstrMeta.Instruction.getOpcode());
+ return InstrDesc.isTrap();
}
bool FileAnalysis::canFallThrough(const Instr &InstrMeta) const {
@@ -296,20 +297,38 @@ uint64_t FileAnalysis::indirectCFOperandClobber(const GraphResult &Graph) const
else
Node = Branch.Fallthrough;
- while (Node != Graph.BaseAddress) {
+ // Some architectures (e.g., AArch64) cannot load in an indirect branch, so
+ // we allow them one load.
+ bool canLoad = !MII->get(IndirectCF.Instruction.getOpcode()).mayLoad();
+
+ // We walk backwards from the indirect CF. It is the last node returned by
+ // Graph.flattenAddress, so we skip it since we already handled it.
+ DenseSet<unsigned> CurRegisterNumbers = RegisterNumbers;
+ std::vector<uint64_t> Nodes = Graph.flattenAddress(Node);
+ for (auto I = Nodes.rbegin() + 1, E = Nodes.rend(); I != E; ++I) {
+ Node = *I;
const Instr &NodeInstr = getInstructionOrDie(Node);
const auto &InstrDesc = MII->get(NodeInstr.Instruction.getOpcode());
- for (unsigned RegNum : RegisterNumbers) {
+ for (auto RI = CurRegisterNumbers.begin(), RE = CurRegisterNumbers.end();
+ RI != RE; ++RI) {
+ unsigned RegNum = *RI;
if (InstrDesc.hasDefOfPhysReg(NodeInstr.Instruction, RegNum,
- *RegisterInfo))
- return Node;
+ *RegisterInfo)) {
+ if (!canLoad || !InstrDesc.mayLoad())
+ return Node;
+ canLoad = false;
+ CurRegisterNumbers.erase(RI);
+ // Add the registers this load reads to those we check for clobbers.
+ for (unsigned i = InstrDesc.getNumDefs(),
+ e = InstrDesc.getNumOperands(); i != e; i++) {
+ const auto Operand = NodeInstr.Instruction.getOperand(i);
+ if (Operand.isReg())
+ CurRegisterNumbers.insert(Operand.getReg());
+ }
+ break;
+ }
}
-
- const auto &KV = Graph.IntermediateNodes.find(Node);
- assert((KV != Graph.IntermediateNodes.end()) &&
- "Could not get next node.");
- Node = KV->second;
}
}
@@ -456,6 +475,9 @@ void FileAnalysis::parseSectionContents(ArrayRef<uint8_t> SectionBytes,
if (!usesRegisterOperand(InstrMeta))
continue;
+ if (InstrDesc.isReturn())
+ continue;
+
// Check if this instruction exists in the range of the DWARF metadata.
if (!IgnoreDWARFFlag) {
auto LineInfo =
OpenPOWER on IntegriCloud