aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
authorSami Tolvanen <samitolvanen@google.com>2021-08-10 10:02:17 -0700
committerSami Tolvanen <samitolvanen@google.com>2021-12-20 12:55:32 -0800
commit5dc8aaac39c53c8e91842a9233921759544759bc (patch)
tree3e984846bc4ff9321e15efe94762100218a859d6 /llvm/lib/Bitcode/Reader/BitcodeReader.cpp
parent02b6fb218e44490f3ea1597e35df1b1b66c6b869 (diff)
downloadllvm-5dc8aaac39c53c8e91842a9233921759544759bc.zip
llvm-5dc8aaac39c53c8e91842a9233921759544759bc.tar.gz
llvm-5dc8aaac39c53c8e91842a9233921759544759bc.tar.bz2
[llvm][IR] Add no_cfi constant
With Control-Flow Integrity (CFI), the LowerTypeTests pass replaces function references with CFI jump table references, which is a problem for low-level code that needs the address of the actual function body. For example, in the Linux kernel, the code that sets up interrupt handlers needs to take the address of the interrupt handler function instead of the CFI jump table, as the jump table may not even be mapped into memory when an interrupt is triggered. This change adds the no_cfi constant type, which wraps function references in a value that LowerTypeTestsModule::replaceCfiUses does not replace. Link: https://github.com/ClangBuiltLinux/linux/issues/1353 Reviewed By: nickdesaulniers, pcc Differential Revision: https://reviews.llvm.org/D108478
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index d914152..f5a878f 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2938,6 +2938,19 @@ Error BitcodeReader::parseConstants() {
V = DSOLocalEquivalent::get(GV);
break;
}
+ case bitc::CST_CODE_NO_CFI_VALUE: {
+ if (Record.size() < 2)
+ return error("Invalid record");
+ Type *GVTy = getTypeByID(Record[0]);
+ if (!GVTy)
+ return error("Invalid record");
+ GlobalValue *GV = dyn_cast_or_null<GlobalValue>(
+ ValueList.getConstantFwdRef(Record[1], GVTy));
+ if (!GV)
+ return error("Invalid record");
+ V = NoCFIValue::get(GV);
+ break;
+ }
}
ValueList.assignValue(V, NextCstNo);