[PATCH] D101156: [Clang] Support a user-defined __dso_handle
Andrew Savonichev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 23 05:19:24 PDT 2021
asavonic created this revision.
asavonic requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
This fixes PR49198: Wrong usage of __dso_handle in user code leads to a compiler
crash.
`__dso_handle` variable is now created with a prefix to avoid a conflict with
the user-defined one which can be emitted later. Once all globals are emitted,
it is renamed back or replaced with a user-defined `__dso_handle`.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D101156
Files:
clang/lib/CodeGen/ItaniumCXXABI.cpp
clang/test/CodeGenCXX/dso-handle-custom.cpp
Index: clang/test/CodeGenCXX/dso-handle-custom.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGenCXX/dso-handle-custom.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fexceptions %s -o - | FileCheck %s
+
+class A {
+public:
+ ~A();
+} a;
+
+// CHECK: @__dso_handle = hidden global i8* bitcast (i8** @__dso_handle to i8*), align 8
+// CHECK: define internal void @__cxx_global_var_init()
+// CHECK: call i32 @__cxa_atexit({{.*}}, {{.*}}, i8* bitcast (i8** @__dso_handle to i8*))
+
+void *__dso_handle = &__dso_handle;
+
+void use(void *);
+void use_dso_handle() {
+ use(__dso_handle);
+}
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2531,7 +2531,7 @@
// Create a variable that binds the atexit to this shared object.
llvm::Constant *handle =
- CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "__dso_handle");
+ CGF.CGM.CreateRuntimeVariable(CGF.Int8Ty, "$__dso_handle");
auto *GV = cast<llvm::GlobalValue>(handle->stripPointerCasts());
GV->setVisibility(llvm::GlobalValue::HiddenVisibility);
@@ -2685,6 +2685,26 @@
if (getCXXABI().useSinitAndSterm())
unregisterGlobalDtorsWithUnAtExit();
+
+ // Prefer user-defined __dso_handle over the compiler generated one
+ if (llvm::GlobalValue *GeneratedDSOHandle = GetGlobalValue("$__dso_handle")) {
+ llvm::GlobalValue *CustomDSOHandle = GetGlobalValue("__dso_handle");
+ if (!CustomDSOHandle) {
+ GeneratedDSOHandle->setName("__dso_handle");
+ } else {
+ if (!isa<llvm::GlobalVariable>(CustomDSOHandle))
+ llvm_unreachable("__dso_handle must be a global variable");
+
+ setDSOLocal(CustomDSOHandle);
+ CustomDSOHandle->setLinkage(llvm::GlobalValue::ExternalLinkage);
+ CustomDSOHandle->setVisibility(llvm::GlobalValue::HiddenVisibility);
+
+ llvm::Constant *DSOHandle = llvm::ConstantExpr::getBitCast(
+ CustomDSOHandle, GeneratedDSOHandle->getType());
+ GeneratedDSOHandle->replaceAllUsesWith(DSOHandle);
+ GeneratedDSOHandle->eraseFromParent();
+ }
+ }
}
/// Register a global destructor as best as we know how.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101156.339986.patch
Type: text/x-patch
Size: 2311 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210423/bc3cec98/attachment-0001.bin>
More information about the cfe-commits
mailing list