[Lldb-commits] [lldb] [lldb][MachO][NFC] Extract ObjC metadata symbol parsing into helper function (PR #161536)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Wed Oct 1 08:21:39 PDT 2025
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/161536
Just a simple de-duplication of the same code. We saw a bug here
recently (https://github.com/llvm/llvm-project/pull/161521). Might as well isolate this all in one place.
rdar://158159242
>From f4e7b75aebadbb3f135f2cfd45fd80aba42598c9 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 1 Oct 2025 14:25:34 +0100
Subject: [PATCH 1/3] [lldb][test] Allow '.c' files to be used as shell tests
---
lldb/test/Shell/lit.cfg.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/test/Shell/lit.cfg.py b/lldb/test/Shell/lit.cfg.py
index 505847fb763e0..cdc0cfe51f7c6 100644
--- a/lldb/test/Shell/lit.cfg.py
+++ b/lldb/test/Shell/lit.cfg.py
@@ -33,7 +33,7 @@
# suffixes: A list of file extensions to treat as test files. This is overriden
# by individual lit.local.cfg files in the test subdirectories.
-config.suffixes = [".test", ".cpp", ".s", ".m", ".ll"]
+config.suffixes = [".test", ".cpp", ".s", ".m", ".ll", ".c"]
# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
>From 24007eee1dec91fc6252dff59e49d3a8fc0b5e75 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 1 Oct 2025 14:23:26 +0100
Subject: [PATCH 2/3] [lldb][MachO] Fix inspection of global variables that
start with 'O'
---
.../ObjectFile/Mach-O/ObjectFileMachO.cpp | 90 +++++++++----------
.../Shell/Expr/TestGlobalSymbolObjCConflict.c | 33 +++++++
2 files changed, 75 insertions(+), 48 deletions(-)
create mode 100644 lldb/test/Shell/Expr/TestGlobalSymbolObjCConflict.c
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index fada1fda2b4bc..91c93be1b8cfd 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -2805,32 +2805,29 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
is_gsym = true;
sym[sym_idx].SetExternal(true);
- if (symbol_name && symbol_name[0] == '_' &&
- symbol_name[1] == 'O') {
- llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.starts_with(
- g_objc_v2_prefix_class)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
-
- } else if (symbol_name_ref.starts_with(
- g_objc_v2_prefix_metaclass)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- } else if (symbol_name_ref.starts_with(
- g_objc_v2_prefix_ivar)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
- }
+ llvm::StringRef symbol_name_ref(symbol_name);
+ if (symbol_name_ref.starts_with(
+ g_objc_v2_prefix_class)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name =
+ symbol_name + g_objc_v2_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
+
+ } else if (symbol_name_ref.starts_with(
+ g_objc_v2_prefix_metaclass)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name =
+ symbol_name + g_objc_v2_prefix_metaclass.size();
+ type = eSymbolTypeObjCMetaClass;
+ demangled_is_synthesized = true;
+ } else if (symbol_name_ref.starts_with(
+ g_objc_v2_prefix_ivar)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name =
+ symbol_name + g_objc_v2_prefix_ivar.size();
+ type = eSymbolTypeObjCIVar;
+ demangled_is_synthesized = true;
} else {
if (nlist.n_value != 0)
symbol_section = section_info.GetSection(
@@ -3652,7 +3649,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
if (is_debug) {
switch (nlist.n_type) {
- case N_GSYM:
+ case N_GSYM: {
// global symbol: name,,NO_SECT,type,0
// Sometimes the N_GSYM value contains the address.
@@ -3668,33 +3665,30 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
is_gsym = true;
sym[sym_idx].SetExternal(true);
- if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O') {
- llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
-
- } else if (symbol_name_ref.starts_with(
- g_objc_v2_prefix_metaclass)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
- }
+ llvm::StringRef symbol_name_ref(symbol_name);
+ if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ demangled_is_synthesized = true;
+
+ } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_metaclass)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
+ type = eSymbolTypeObjCMetaClass;
+ demangled_is_synthesized = true;
+ } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
+ type = eSymbolTypeObjCIVar;
+ demangled_is_synthesized = true;
} else {
if (nlist.n_value != 0)
symbol_section =
section_info.GetSection(nlist.n_sect, nlist.n_value);
type = eSymbolTypeData;
}
- break;
+ } break;
case N_FNAME:
// procedure name (f77 kludge): name,,NO_SECT,0,0
diff --git a/lldb/test/Shell/Expr/TestGlobalSymbolObjCConflict.c b/lldb/test/Shell/Expr/TestGlobalSymbolObjCConflict.c
new file mode 100644
index 0000000000000..da7263648776f
--- /dev/null
+++ b/lldb/test/Shell/Expr/TestGlobalSymbolObjCConflict.c
@@ -0,0 +1,33 @@
+// Tests that LLDB correctly parses global symbols
+// starting with 'O'. On some platforms (e.g., Darwin)
+// C-symbols are prefixed with a '_'. The LLDB Macho-O
+// parses handles Objective-C metadata symbols starting
+// with '_OBJC' specially. This test ensures that we don't
+// lose track of regular global symbols with a '_O' prefix
+// in this.
+
+// RUN: %clang_host -c -g -fno-common %s -o %t.o
+// RUN: %clang_host %t.o -o %t.out
+// RUN: %lldb -b -x %t.out \
+// RUN: -o "b 17" \
+// RUN: -o "run" \
+// RUN: -o "p OglobalVar" \
+// RUN: -o "p Oabc" | FileCheck %s
+
+typedef struct {
+ int a;
+} Oabc_t;
+
+Oabc_t Oabc;
+int OglobalVar;
+
+int main(int argc, const char *argv[]) {
+ Oabc.a = 15;
+ OglobalVar = 10;
+ return OglobalVar + Oabc.a;
+}
+
+// CHECK: (lldb) p OglobalVar
+// CHECK: (int) 10
+// CHECK: (lldb) p Oabc
+// CHECK: (Oabc_t) (a = 15)
>From 9cda8dab674f2ae423d1b9fe503065347e2596aa Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 1 Oct 2025 16:19:15 +0100
Subject: [PATCH 3/3] [lldb][MachO][NFC] Extract ObjC metadata symbol parsing
into helper function
Just a simple de-duplication of the same code. We saw a bug here
recently (https://github.com/llvm/llvm-project/pull/161521). Might as well isolate this all in one place.
rdar://158159242
---
.../ObjectFile/Mach-O/ObjectFileMachO.cpp | 182 ++++++------------
1 file changed, 57 insertions(+), 125 deletions(-)
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 91c93be1b8cfd..b01bba52c5656 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -2067,6 +2067,43 @@ static bool ParseTrieEntries(DataExtractor &data, lldb::offset_t offset,
return true;
}
+static bool
+TryParseV2ObjCMetadataSymbol(const char *&symbol_name,
+ const char *&symbol_name_non_abi_mangled,
+ SymbolType &type) {
+ static constexpr llvm::StringLiteral g_objc_v2_prefix_class("_OBJC_CLASS_$_");
+ static constexpr llvm::StringLiteral g_objc_v2_prefix_metaclass(
+ "_OBJC_METACLASS_$_");
+ static constexpr llvm::StringLiteral g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");
+
+ llvm::StringRef symbol_name_ref(symbol_name);
+ if (symbol_name_ref.empty())
+ return false;
+
+ if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_class.size();
+ type = eSymbolTypeObjCClass;
+ return true;
+ }
+
+ if (symbol_name_ref.starts_with(g_objc_v2_prefix_metaclass)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
+ type = eSymbolTypeObjCMetaClass;
+ return true;
+ }
+
+ if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
+ symbol_name_non_abi_mangled = symbol_name + 1;
+ symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
+ type = eSymbolTypeObjCIVar;
+ return true;
+ }
+
+ return false;
+}
+
static SymbolType GetSymbolType(const char *&symbol_name,
bool &demangled_is_synthesized,
const SectionSP &text_section_sp,
@@ -2094,20 +2131,20 @@ static SymbolType GetSymbolType(const char *&symbol_name,
if (symbol_name) {
llvm::StringRef symbol_name_ref(symbol_name);
if (symbol_name_ref.starts_with("OBJC_")) {
- static const llvm::StringRef g_objc_v2_prefix_class("OBJC_CLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_metaclass(
+ static const llvm::StringRef s_objc_v2_prefix_class("OBJC_CLASS_$_");
+ static const llvm::StringRef s_objc_v2_prefix_metaclass(
"OBJC_METACLASS_$_");
- static const llvm::StringRef g_objc_v2_prefix_ivar("OBJC_IVAR_$_");
- if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
- symbol_name = symbol_name + g_objc_v2_prefix_class.size();
+ static const llvm::StringRef s_objc_v2_prefix_ivar("OBJC_IVAR_$_");
+ if (symbol_name_ref.starts_with(s_objc_v2_prefix_class)) {
+ symbol_name = symbol_name + s_objc_v2_prefix_class.size();
type = eSymbolTypeObjCClass;
demangled_is_synthesized = true;
- } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_metaclass)) {
- symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
+ } else if (symbol_name_ref.starts_with(s_objc_v2_prefix_metaclass)) {
+ symbol_name = symbol_name + s_objc_v2_prefix_metaclass.size();
type = eSymbolTypeObjCMetaClass;
demangled_is_synthesized = true;
- } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
- symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
+ } else if (symbol_name_ref.starts_with(s_objc_v2_prefix_ivar)) {
+ symbol_name = symbol_name + s_objc_v2_prefix_ivar.size();
type = eSymbolTypeObjCIVar;
demangled_is_synthesized = true;
}
@@ -2183,9 +2220,6 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t i;
FileSpecList dylib_files;
- llvm::StringRef g_objc_v2_prefix_class("_OBJC_CLASS_$_");
- llvm::StringRef g_objc_v2_prefix_metaclass("_OBJC_METACLASS_$_");
- llvm::StringRef g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");
UUID image_uuid;
for (i = 0; i < m_header.ncmds; ++i) {
@@ -2805,28 +2839,9 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
is_gsym = true;
sym[sym_idx].SetExternal(true);
- llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.starts_with(
- g_objc_v2_prefix_class)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
-
- } else if (symbol_name_ref.starts_with(
- g_objc_v2_prefix_metaclass)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- } else if (symbol_name_ref.starts_with(
- g_objc_v2_prefix_ivar)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
+ if (TryParseV2ObjCMetadataSymbol(
+ symbol_name, symbol_name_non_abi_mangled,
+ type)) {
demangled_is_synthesized = true;
} else {
if (nlist.n_value != 0)
@@ -3316,49 +3331,10 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
::strstr(symbol_sect_name, "__objc") ==
symbol_sect_name) {
type = eSymbolTypeRuntime;
-
- if (symbol_name) {
- llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.starts_with("_OBJC_")) {
- llvm::StringRef
- g_objc_v2_prefix_class(
- "_OBJC_CLASS_$_");
- llvm::StringRef
- g_objc_v2_prefix_metaclass(
- "_OBJC_METACLASS_$_");
- llvm::StringRef
- g_objc_v2_prefix_ivar("_OBJC_IVAR_$_");
- if (symbol_name_ref.starts_with(
- g_objc_v2_prefix_class)) {
- symbol_name_non_abi_mangled =
- symbol_name + 1;
- symbol_name =
- symbol_name +
- g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
- } else if (
- symbol_name_ref.starts_with(
- g_objc_v2_prefix_metaclass)) {
- symbol_name_non_abi_mangled =
- symbol_name + 1;
- symbol_name =
- symbol_name +
- g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- } else if (symbol_name_ref.starts_with(
- g_objc_v2_prefix_ivar)) {
- symbol_name_non_abi_mangled =
- symbol_name + 1;
- symbol_name =
- symbol_name +
- g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
- }
- }
- }
+ demangled_is_synthesized =
+ TryParseV2ObjCMetadataSymbol(
+ symbol_name,
+ symbol_name_non_abi_mangled, type);
} else if (symbol_sect_name &&
::strstr(symbol_sect_name,
"__gcc_except_tab") ==
@@ -3665,22 +3641,8 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
is_gsym = true;
sym[sym_idx].SetExternal(true);
- llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
-
- } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_metaclass)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- } else if (symbol_name_ref.starts_with(g_objc_v2_prefix_ivar)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name = symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
+ if (TryParseV2ObjCMetadataSymbol(symbol_name,
+ symbol_name_non_abi_mangled, type)) {
demangled_is_synthesized = true;
} else {
if (nlist.n_value != 0)
@@ -4123,39 +4085,9 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
if (symbol_sect_name &&
::strstr(symbol_sect_name, "__objc") == symbol_sect_name) {
type = eSymbolTypeRuntime;
+ demangled_is_synthesized = TryParseV2ObjCMetadataSymbol(
+ symbol_name, symbol_name_non_abi_mangled, type);
- if (symbol_name) {
- llvm::StringRef symbol_name_ref(symbol_name);
- if (symbol_name_ref.starts_with("_OBJC_")) {
- llvm::StringRef g_objc_v2_prefix_class(
- "_OBJC_CLASS_$_");
- llvm::StringRef g_objc_v2_prefix_metaclass(
- "_OBJC_METACLASS_$_");
- llvm::StringRef g_objc_v2_prefix_ivar(
- "_OBJC_IVAR_$_");
- if (symbol_name_ref.starts_with(g_objc_v2_prefix_class)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_class.size();
- type = eSymbolTypeObjCClass;
- demangled_is_synthesized = true;
- } else if (symbol_name_ref.starts_with(
- g_objc_v2_prefix_metaclass)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_metaclass.size();
- type = eSymbolTypeObjCMetaClass;
- demangled_is_synthesized = true;
- } else if (symbol_name_ref.starts_with(
- g_objc_v2_prefix_ivar)) {
- symbol_name_non_abi_mangled = symbol_name + 1;
- symbol_name =
- symbol_name + g_objc_v2_prefix_ivar.size();
- type = eSymbolTypeObjCIVar;
- demangled_is_synthesized = true;
- }
- }
- }
} else if (symbol_sect_name &&
::strstr(symbol_sect_name, "__gcc_except_tab") ==
symbol_sect_name) {
More information about the lldb-commits
mailing list