-
Notifications
You must be signed in to change notification settings - Fork 12.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[asan] Limit priority of ctor to kMax-1 #101772
[asan] Limit priority of ctor to kMax-1 #101772
Conversation
Created using spr 1.3.4 [skip ci]
Created using spr 1.3.4
@llvm/pr-subscribers-compiler-rt-sanitizer @llvm/pr-subscribers-llvm-transforms Author: Vitaly Buka (vitalybuka) ChangesReserve maximal availibe priority to Full diff: https://github.com/llvm/llvm-project/pull/101772.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 9fb1df7ab2b79..734cbd0515ea8 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -133,6 +133,7 @@ const char kAsanModuleDtorName[] = "asan.module_dtor";
static const uint64_t kAsanCtorAndDtorPriority = 1;
// On Emscripten, the system needs more than one priorities for constructors.
static const uint64_t kAsanEmscriptenCtorAndDtorPriority = 50;
+static const uint64_t kMaxCtorAndDtorPriority = 65535;
const char kAsanReportErrorTemplate[] = "__asan_report_";
const char kAsanRegisterGlobalsName[] = "__asan_register_globals";
const char kAsanUnregisterGlobalsName[] = "__asan_unregister_globals";
@@ -1993,6 +1994,29 @@ void ModuleAddressSanitizer::createInitializerPoisonCalls(
poisonOneInitializer(*F, ModuleName);
}
}
+ assert(ClInitializers);
+ updateGlobalCtors(M, [](Constant *C) -> Constant * {
+ ConstantStruct *CS = dyn_cast<ConstantStruct>(C);
+ if (!CS)
+ return C;
+ auto *Priority = cast<ConstantInt>(CS->getOperand(0));
+ if (Priority->getLimitedValue() != kMaxCtorAndDtorPriority)
+ return C;
+ // As optimization, runtime needs to execute callback just after all
+ // constructors. We going to set priority to the max allowed value. However,
+ // the default constructor priorily is already max, so as-is we will not be
+ // able to guaranty desired order. So reduce the priority by one to reserve
+ // max value for the constructor in runtime.
+ StructType *EltTy = cast<StructType>(CS->getType());
+ Constant *CSVals[3] = {
+ ConstantInt::getSigned(Priority->getType(),
+ kMaxCtorAndDtorPriority - 1),
+ CS->getOperand(1),
+ CS->getOperand(2),
+ };
+ return cast<ConstantStruct>(
+ ConstantStruct::get(EltTy, ArrayRef(CSVals, EltTy->getNumElements())));
+ });
}
const GlobalVariable *
diff --git a/llvm/test/Instrumentation/AddressSanitizer/instrument_late_initializer.ll b/llvm/test/Instrumentation/AddressSanitizer/instrument_late_initializer.ll
index 45d526a42c9f7..2225ccb217208 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/instrument_late_initializer.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/instrument_late_initializer.ll
@@ -9,7 +9,7 @@ target triple = "x86_64-unknown-linux-gnu"
@g = internal global i32 0, align 4, sanitize_address_dyninit ; With dynamic initializer.
;.
-; CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @__late_ctor, ptr null }, { i32, ptr, ptr } { i32 1, ptr @asan.module_ctor, ptr @asan.module_ctor }]
+; CHECK: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65534, ptr @__late_ctor, ptr null }, { i32, ptr, ptr } { i32 1, ptr @asan.module_ctor, ptr @asan.module_ctor }]
;.
; NOINIT: @llvm.global_ctors = appending global [2 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @__late_ctor, ptr null }, { i32, ptr, ptr } { i32 1, ptr @asan.module_ctor, ptr @asan.module_ctor }]
;.
|
asan changing the priority of a llvm.global_ctors element might be surprising. Is this change to work with some specific code or specific IR code generators that use 65535 (instrumentation cannot do anything with |
No. The goal to be able to call |
Is there more information about this decision? What would break if the order is different? So priority 65535 is unsuffixed If instrumentation changes IR 65535 elements in Execution order:
|
I see what you mean. :(
There is O(N^2) in init order checking, and it's heavy on our profiles, especial with dynamic linking: Now we for each TU:
With patches:
But at the end we need to unpoison all globals once, before we get to |
I see. The ODR indicator optimization might intrigue you to investigate the initialization order check performance:) I have some notes about the performance issue and I did not find a good way to improve the coverage ( (
Note, violations due to
|
Reserve maximal availibe priority to
runtime. We need to run code in sanitizer
runtime after all C++ constructors.
https://clang.llvm.org/docs/AttributeReference.html#constructor