Skip to content

[asan] Limit priority of ctor to kMax-1 #101772

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -1993,6 +1994,31 @@ 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 priority 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.
// Note: It can break user-code that depends on the order between `max` and
// `max-1`, or `max-1` and `max-2`.
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 *
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 }]
;.
Expand Down
Loading