Skip to content

Commit

Permalink
[MachO] Disable atexit()-based lowering when LTO'ing kernel/kext code
Browse files Browse the repository at this point in the history
The kernel and kext environments do not provide the `__cxa_atexit()`
function, so we can't use it for lowering global module destructors.

Unfortunately, just querying for "compiling for kernel/kext?" in the LTO
pipeline isn't possible (kernel/kext identifier isn't part of the triple
yet) so we need to pass down a CodeGen flag.

rdar://93536111

Differential Revision: https://reviews.llvm.org/D148967
  • Loading branch information
Julian Lettner committed Apr 25, 2023
1 parent 09d879d commit c3f0153
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 2 deletions.
7 changes: 7 additions & 0 deletions clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,13 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
}
}

if (Args.hasArg(options::OPT_mkernel) ||
Args.hasArg(options::OPT_fapple_kext) ||
Args.hasArg(options::OPT_ffreestanding)) {
CmdArgs.push_back("-mllvm");
CmdArgs.push_back("-disable-atexit-based-global-dtor-lowering");
}

Args.AddLastArg(CmdArgs, options::OPT_prebind);
Args.AddLastArg(CmdArgs, options::OPT_noprebind);
Args.AddLastArg(CmdArgs, options::OPT_nofixprebinding);
Expand Down
8 changes: 8 additions & 0 deletions clang/test/Driver/darwin-ld-lto.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,11 @@
// GISEL: {{ld(.exe)?"}}
// GISEL: "-mllvm" "-global-isel"
// GISEL: "-mllvm" "-global-isel-abort=0"


// Check that we disable atexit()-based global destructor lowering when
// compiling/linking for kernel/kext/freestanding.
// RUN: %clang -target arm64-apple-darwin %s -flto -fapple-kext -### 2>&1 | \
// RUN: FileCheck --check-prefix=KEXT %s
// KEXT: {{ld(.exe)?"}}
// KEXT: "-mllvm" "-disable-atexit-based-global-dtor-lowering"
7 changes: 6 additions & 1 deletion llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1202,7 +1202,12 @@ void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx,

MCSection *TargetLoweringObjectFileMachO::getStaticDtorSection(
unsigned Priority, const MCSymbol *KeySym) const {
report_fatal_error("@llvm.global_dtors should have been lowered already");
return StaticDtorSection;
// In userspace, we lower global destructors via atexit(), but kernel/kext
// environments do not provide this function so we still need to support the
// legacy way here.
// See the -disable-atexit-based-global-dtor-lowering CodeGen flag for more
// context.
}

void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer,
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/CodeGen/TargetPassConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ static cl::opt<bool> DisableCopyProp("disable-copyprop", cl::Hidden,
cl::desc("Disable Copy Propagation pass"));
static cl::opt<bool> DisablePartialLibcallInlining("disable-partial-libcall-inlining",
cl::Hidden, cl::desc("Disable Partial Libcall Inlining"));
static cl::opt<bool> DisableAtExitBasedGlobalDtorLowering(
"disable-atexit-based-global-dtor-lowering", cl::Hidden,
cl::desc("For MachO, disable atexit()-based global destructor lowering"));
static cl::opt<bool> EnableImplicitNullChecks(
"enable-implicit-null-checks",
cl::desc("Fold null checks into faulting memory operations"),
Expand Down Expand Up @@ -878,7 +881,8 @@ void TargetPassConfig::addIRPasses() {

// For MachO, lower @llvm.global_dtors into @llvm.global_ctors with
// __cxa_atexit() calls to avoid emitting the deprecated __mod_term_func.
if (TM->getTargetTriple().isOSBinFormatMachO())
if (TM->getTargetTriple().isOSBinFormatMachO() &&
!DisableAtExitBasedGlobalDtorLowering)
addPass(createLowerGlobalDtorsLegacyPass());

// Make sure that no unreachable blocks are instruction selected.
Expand Down
5 changes: 5 additions & 0 deletions llvm/test/CodeGen/ARM/ctors_dtors.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; RUN: llc < %s -mtriple=arm-apple-darwin | FileCheck %s -check-prefix=DARWIN
; RUN: llc < %s -mtriple=arm-apple-darwin -disable-atexit-based-global-dtor-lowering | FileCheck %s -check-prefix=DARWIN-LEGACY
; RUN: llc < %s -mtriple=arm-linux-gnu -target-abi=apcs | FileCheck %s -check-prefix=ELF
; RUN: llc < %s -mtriple=arm-linux-gnueabi | FileCheck %s -check-prefix=GNUEABI

Expand All @@ -7,6 +8,10 @@
; DARWIN: .section __DATA,__mod_init_func,mod_init_funcs
; DARWIN-NOT: __mod_term_func

; DARWIN-LEGACY-NOT: atexit
; DARWIN-LEGACY: .section __DATA,__mod_init_func,mod_init_funcs
; DARWIN-LEGACY: .section __DATA,__mod_term_func,mod_term_funcs

; ELF: .section .ctors,"aw",%progbits
; ELF: .section .dtors,"aw",%progbits

Expand Down

0 comments on commit c3f0153

Please sign in to comment.