[llvm] 8228749 - [CFGuard] Consider function aliases as indirect call targets (#188223)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 24 10:55:52 PDT 2026
Author: Hans Wennborg
Date: 2026-03-24T18:55:46+01:00
New Revision: 82287496072bef952bd400c335459f4fa4c750c7
URL: https://github.com/llvm/llvm-project/commit/82287496072bef952bd400c335459f4fa4c750c7
DIFF: https://github.com/llvm/llvm-project/commit/82287496072bef952bd400c335459f4fa4c750c7.diff
LOG: [CFGuard] Consider function aliases as indirect call targets (#188223)
With vector deleting destructors, it's common to include function
aliases in vftables.
After #185653 it's become more likely that the alias gets overridden in
a different TU. It's therefore important that it's the alias itself that
goes in the control-flow guard table.
Added:
llvm/test/CodeGen/WinCFGuard/cfguard-alias.ll
Modified:
llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp b/llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp
index d989659566355..4644a170d62a5 100644
--- a/llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/WinCFGuard.cpp
@@ -42,14 +42,14 @@ void WinCFGuard::endFunction(const MachineFunction *MF) {
/// it an indirect call target. Function::hasAddressTaken gives
diff erent
/// results when a function is called directly with a function prototype
/// mismatch, which requires a cast.
-static bool isPossibleIndirectCallTarget(const Function *F) {
- SmallVector<const Value *, 4> Users{F};
+static bool isPossibleIndirectCallTarget(const GlobalValue *GV) {
+ SmallVector<const Value *, 4> Users{GV};
while (!Users.empty()) {
const Value *FnOrCast = Users.pop_back_val();
for (const Use &U : FnOrCast->uses()) {
const User *FnUser = U.getUser();
if (const auto *Call = dyn_cast<CallBase>(FnUser)) {
- if ((!Call->isCallee(&U) || U.get() != F) &&
+ if ((!Call->isCallee(&U) || U.get() != GV) &&
!Call->getFunction()->getName().ends_with("$exit_thunk")) {
// Passing a function pointer to a call may lead to an indirect
// call. As an exception, ignore ARM64EC exit thunks.
@@ -60,6 +60,10 @@ static bool isPossibleIndirectCallTarget(const Function *F) {
// consequences like no-op intrinsics being an escape or a store *to* a
// function address being an escape.
return true;
+ } else if (isa<GlobalAlias>(FnUser)) {
+ // If the function is used via the alias, it's really the alias that's
+ // a possible call target. See "Consider aliases" in endModule().
+ continue;
} else if (const auto *G = dyn_cast<GlobalValue>(FnUser)) {
// Ignore llvm.arm64ec.symbolmap; it doesn't lower to an actual address.
if (G->getName() == "llvm.arm64ec.symbolmap")
@@ -104,6 +108,13 @@ void WinCFGuard::endModule() {
}
}
+ for (const GlobalAlias &GA : M->aliases()) {
+ // Consider aliases to functions as possible call targets.
+ const GlobalObject *Aliasee = GA.getAliaseeObject();
+ if (Aliasee && isa<Function>(Aliasee) && isPossibleIndirectCallTarget(&GA))
+ GFIDsEntries.push_back(Asm->getSymbol(&GA));
+ }
+
if (GFIDsEntries.empty() && GIATsEntries.empty() && LongjmpTargets.empty())
return;
diff --git a/llvm/test/CodeGen/WinCFGuard/cfguard-alias.ll b/llvm/test/CodeGen/WinCFGuard/cfguard-alias.ll
new file mode 100644
index 0000000000000..23d044800a44e
--- /dev/null
+++ b/llvm/test/CodeGen/WinCFGuard/cfguard-alias.ll
@@ -0,0 +1,28 @@
+; RUN: llc < %s -mtriple=x86_64-pc-windows-msvc | FileCheck %s
+
+; CHECK: .section .gfids$y
+; CHECK: .symidx alias
+; CHECK-NOT: .symidx calledalias
+; CHECK-NOT: .symidx func
+
+
+define void @func() {
+ ret void
+}
+
+ at alias = alias ptr, ptr @func
+
+; This makes @alias a potential indirect call target.
+; The aliasee (@func) is not considered as such.
+ at ptrs = global [1 x ptr] [ptr @alias]
+
+ at calledalias = alias ptr, ptr @func
+
+define void @caller() {
+ ; A direct call does not make the alias an indirect call target.
+ call void @calledalias()
+ ret void
+}
+
+!llvm.module.flags = !{!0}
+!0 = !{i32 2, !"cfguard", i32 2}
More information about the llvm-commits
mailing list