diff options
Diffstat (limited to 'llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp')
-rw-r--r-- | llvm/tools/llvm-cfi-verify/lib/FileAnalysis.cpp | 42 |
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 = |