summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
diff options
context:
space:
mode:
authorJoel Galenson <jgalenson@google.com>2018-08-24 15:21:58 +0000
committerJoel Galenson <jgalenson@google.com>2018-08-24 15:21:58 +0000
commit6cc0e63e2f020961c8262b94ae30a23ef0f030af (patch)
tree859a0d7833960a43ceaaada8140b787bf0ab8dbe /llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
parent134cf47dcbe7ff4b58bc2001926b412b28138afc (diff)
downloadbcm5719-llvm-6cc0e63e2f020961c8262b94ae30a23ef0f030af.tar.gz
bcm5719-llvm-6cc0e63e2f020961c8262b94ae30a23ef0f030af.zip
[cfi-verify] Support cross-DSO
When used in cross-DSO mode, CFI will generate calls to special functions rather than trap instructions. For example, instead of generating if (!InlinedFastCheck(f)) abort(); call *f CFI generates if (!InlinedFastCheck(f)) __cfi_slowpath(CallSiteTypeId, f); call *f This patch teaches cfi-verify to recognize calls to __cfi_slowpath and abort and treat them as trap functions. In addition to normal symbols, we also parse the dynamic relocations to handle cross-DSO calls in libraries. We also extend cfi-verify to recognize other patterns that occur using cross-DSO. For example, some indirect calls are not guarded by a branch to a trap but instead follow a call to __cfi_slowpath. For example: if (!InlinedFastCheck(f)) call *f else { __cfi_slowpath(CallSiteTypeId, f); call *f } In this case, the second call to f is not marked as protected by the current code. We thus recognize if indirect calls directly follow a call to a function that will trap on CFI violations and treat them as protected. We also ignore indirect calls in the PLT, since on AArch64 each entry contains an indirect call that should not be protected by CFI, and these are labeled incorrectly when debug information is not present. Differential Revision: https://reviews.llvm.org/D49383 llvm-svn: 340612
Diffstat (limited to 'llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp')
-rw-r--r--llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp18
1 files changed, 18 insertions, 0 deletions
diff --git a/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp b/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
index 4153b5f6844..5b2bc6f0c3b 100644
--- a/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
+++ b/llvm/tools/llvm-cfi-verify/lib/GraphBuilder.cpp
@@ -311,6 +311,24 @@ void GraphBuilder::buildFlowGraphImpl(const FileAnalysis &Analysis,
Result.ConditionalBranchNodes.push_back(BranchNode);
}
+ // When using cross-DSO, some indirect calls are not guarded by a branch to a
+ // trap but instead follow a call to __cfi_slowpath. For example:
+ // if (!InlinedFastCheck(f))
+ // call *f
+ // else {
+ // __cfi_slowpath(CallSiteTypeId, f);
+ // call *f
+ // }
+ // To mark the second call as protected, we recognize indirect calls that
+ // directly follow calls to functions that will trap on CFI violations.
+ if (CFCrossRefs.empty()) {
+ const Instr *PrevInstr = Analysis.getPrevInstructionSequential(ChildMeta);
+ if (PrevInstr && Analysis.willTrapOnCFIViolation(*PrevInstr)) {
+ Result.IntermediateNodes[PrevInstr->VMAddress] = Address;
+ HasValidCrossRef = true;
+ }
+ }
+
if (!HasValidCrossRef)
Result.OrphanedNodes.push_back(Address);
OpenPOWER on IntegriCloud