# /home/anton/tmp/robsd/src-llvm-ubsan.diff commit d3a6aff1880a334ddf75aa7e037dc00f054d9d75 Author: Anton Lindqvist Date: Tue Sep 30 20:36:43 2025 +0200 UBSan and execute-only are mutually exclusive -fsanitize=function implied by UBSan sanitizes indirect function calls in which a destination is only considered valid if preceded by a well known sequence (0xc105cafe). This of course requires being able to read the text segment, making it incompatible with execute-only. diff --git gnu/llvm/clang/lib/Driver/ToolChains/OpenBSD.cpp gnu/llvm/clang/lib/Driver/ToolChains/OpenBSD.cpp index 3770471bae7c..2a076df1905d 100644 --- gnu/llvm/clang/lib/Driver/ToolChains/OpenBSD.cpp +++ gnu/llvm/clang/lib/Driver/ToolChains/OpenBSD.cpp @@ -288,6 +288,19 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); } + auto hasNoExecuteOnly = [&Args]() { + for (const Arg *A : Args) { + if (A->getOption().matches(options::OPT_Wl_COMMA) && + A->containsValue("--no-execute-only")) + return true; + } + return false; + }; + if (ToolChain.getSanitizerArgs(Args).needsUbsanRt() && !hasNoExecuteOnly()) { + D.Diag(diag::err_drv_argument_only_allowed_with) + << "-fsanitize=undefined" << "-Wl,--no-execute-only"; + } + ToolChain.addProfileRTLibs(Args, CmdArgs); const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());