https://github.com/JDevlieghere created https://github.com/llvm/llvm-project/pull/204639
Evaluating any expression against a WebAssembly target aborted LLDB: (lldb) expr (int)sizeof(Point) LLVM ERROR: Objective-C support is unimplemented for object file format WebAssembly can't JIT expressions (RuntimeDyld doesn't support the Wasm object format, so ProcessWasm sets CanJIT to false), but it can handle simple expressions that can be IR interpreted. When setting up the expression's language options, LLDB speculatively enables Objective-C, which trips up the fatal error as Objective-C code generation only supports Mach-O, ELF, and COFF. Add ObjCLanguageRuntime::IsSupportedForArchitecture and disable Objective-C in the expression's language options when the target's object file format can't support it, parsing as C/C++ instead. The IR interpreter can then evaluate what it supports, and the rest fails cleanly instead of crashing. >From 7358c0b95c027d8afdb50b8f49e0c0d4124df052 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <[email protected]> Date: Thu, 18 Jun 2026 10:00:16 -0700 Subject: [PATCH] [lldb] Don't enable Objective-C in expressions on unsupported formats Evaluating any expression against a WebAssembly target aborted LLDB: (lldb) expr (int)sizeof(Point) LLVM ERROR: Objective-C support is unimplemented for object file format WebAssembly can't JIT expressions (RuntimeDyld doesn't support the Wasm object format, so ProcessWasm sets CanJIT to false), but it can handle simple expressions that can be IR interpreted. When setting up the expression's language options, LLDB speculatively enables Objective-C, which trips up the fatal error as Objective-C code generation only supports Mach-O, ELF, and COFF. Add ObjCLanguageRuntime::IsSupportedForArchitecture and disable Objective-C in the expression's language options when the target's object file format can't support it, parsing as C/C++ instead. The IR interpreter can then evaluate what it supports, and the rest fails cleanly instead of crashing. --- .../Clang/ClangExpressionParser.cpp | 8 ++++++++ .../ObjC/ObjCLanguageRuntime.cpp | 14 +++++++++++++ .../ObjC/ObjCLanguageRuntime.h | 9 +++++++++ .../test/Shell/Expr/wasm-no-objc-codegen.test | 20 +++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 lldb/test/Shell/Expr/wasm-no-objc-codegen.test diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index 861522623f68b..a6054dcf302b6 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -652,6 +652,14 @@ static void SetupLangOpts(CompilerInstance &compiler, break; } + // Clang aborts when generating Objective-C metadata for an object file + // format that doesn't support it (e.g. WebAssembly). Such targets have no + // Objective-C runtime anyway, so parse the expression as plain C/C++ instead + // of letting the compiler crash. + if (!ObjCLanguageRuntime::IsSupportedForArchitecture( + ArchSpec(compiler.getTargetOpts().Triple))) + lang_opts.ObjC = false; + diagnostic_manager.AddDiagnostic( llvm::formatv("{0}Ran expression as '{1}'.", language_fallback_reason, lldb_private::Language::GetDisplayNameForLanguageType( diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp index d0dc252199800..07c6e940c7ba9 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp @@ -19,6 +19,7 @@ #include "lldb/Symbol/Variable.h" #include "lldb/Target/ABI.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Timer.h" @@ -36,6 +37,19 @@ char ObjCLanguageRuntime::ID = 0; // Destructor ObjCLanguageRuntime::~ObjCLanguageRuntime() = default; +bool ObjCLanguageRuntime::IsSupportedForArchitecture(const ArchSpec &arch) { + // Mirror the object file formats clang can emit Objective-C metadata for; it + // aborts for any other format. + switch (arch.GetTriple().getObjectFormat()) { + case llvm::Triple::MachO: + case llvm::Triple::ELF: + case llvm::Triple::COFF: + return true; + default: + return false; + } +} + ObjCLanguageRuntime::ObjCLanguageRuntime(Process *process) : LanguageRuntime(process), m_impl_cache(), m_impl_str_cache(), m_has_new_literals_and_indexing(eLazyBoolCalculate), diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h index 8b5d6af54cbc3..7980f1d9e4bcf 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h @@ -226,6 +226,15 @@ class ObjCLanguageRuntime : public LanguageRuntime { process.GetLanguageRuntime(lldb::eLanguageTypeObjC)); } + /// Returns true if Objective-C is supported for the given architecture's + /// object file format. + /// + /// Clang only implements Objective-C code generation for the Mach-O, ELF, + /// and COFF formats and aborts for any other (e.g. WebAssembly), so callers + /// should avoid driving Objective-C code generation for targets that report + /// false here. + static bool IsSupportedForArchitecture(const ArchSpec &arch); + virtual TaggedPointerVendor *GetTaggedPointerVendor() { return nullptr; } typedef std::shared_ptr<EncodingToType> EncodingToTypeSP; diff --git a/lldb/test/Shell/Expr/wasm-no-objc-codegen.test b/lldb/test/Shell/Expr/wasm-no-objc-codegen.test new file mode 100644 index 0000000000000..56e3e150eb772 --- /dev/null +++ b/lldb/test/Shell/Expr/wasm-no-objc-codegen.test @@ -0,0 +1,20 @@ +# Evaluating an expression against a WebAssembly target used to abort the +# process: LLDB speculatively enabled Objective-C, and clang has no Objective-C +# codegen for the Wasm object file format, so it called report_fatal_error while +# finalizing the module. WebAssembly has no Objective-C runtime, so the +# expression should simply be evaluated as C/C++. + +# RUN: yaml2obj %s -o %t +# RUN: %lldb %t -b -o "expr 1 + 1" 2>&1 | FileCheck %s + +# CHECK: (int) $0 = 2 + +--- !WASM +FileHeader: + Version: 0x00000001 +Sections: + - Type: CODE + Functions: + - Index: 0 + Locals: [] + Body: 0B _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
