-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[lldb][MachO][NFC] Extract ObjC metadata symbol parsing into helper function #161536
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
Merged
Michael137
merged 6 commits into
llvm:main
from
Michael137:lldb/objc-symbol-parsing-refactor
Oct 1, 2025
Merged
[lldb][MachO][NFC] Extract ObjC metadata symbol parsing into helper function #161536
Michael137
merged 6 commits into
llvm:main
from
Michael137:lldb/objc-symbol-parsing-refactor
Oct 1, 2025
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…unction Just a simple de-duplication of the same code. We saw a bug here recently (llvm#161521). Might as well isolate this all in one place. rdar://158159242
@llvm/pr-subscribers-lldb Author: Michael Buch (Michael137) ChangesJust a simple de-duplication of the same code. We saw a bug here rdar://158159242 Full diff: https://github.com/llvm/llvm-project/pull/161536.diff 3 Files Affected:
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index fada1fda2b4bc..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,32 +2839,10 @@ 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;
- }
+ if (TryParseV2ObjCMetadataSymbol(
+ symbol_name, symbol_name_non_abi_mangled,
+ type)) {
+ demangled_is_synthesized = true;
} else {
if (nlist.n_value != 0)
symbol_section = section_info.GetSection(
@@ -3319,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") ==
@@ -3652,7 +3625,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 +3641,16 @@ 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;
- }
+ if (TryParseV2ObjCMetadataSymbol(symbol_name,
+ symbol_name_non_abi_mangled, type)) {
+ 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
@@ -4129,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) {
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)
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
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Michael137
added a commit
to swiftlang/llvm-project
that referenced
this pull request
Oct 1, 2025
…unction (llvm#161536) Just a simple de-duplication of the same code. We saw a bug here recently (llvm#161521). Might as well isolate this all in one place. rdar://158159242 (cherry picked from commit 23e0815)
augusto2112
added a commit
to augusto2112/llvm-project
that referenced
this pull request
Oct 1, 2025
…helper function (llvm#161536)" This reverts commit a561221.
mahesh-attarde
pushed a commit
to mahesh-attarde/llvm-project
that referenced
this pull request
Oct 3, 2025
…unction (llvm#161536) Just a simple de-duplication of the same code. We saw a bug here recently (llvm#161521). Might as well isolate this all in one place. rdar://158159242
mahesh-attarde
pushed a commit
to mahesh-attarde/llvm-project
that referenced
this pull request
Oct 3, 2025
…helper function (llvm#161536)" This reverts commit 23e0815.
Michael137
added a commit
to swiftlang/llvm-project
that referenced
this pull request
Oct 4, 2025
…ng into helper function (llvm#161536)"" This reverts commit 6e4c686.
Michael137
added a commit
to swiftlang/llvm-project
that referenced
this pull request
Oct 4, 2025
…unction (llvm#161536) Just a simple de-duplication of the same code. We saw a bug here recently (llvm#161521). Might as well isolate this all in one place. rdar://158159242 (cherry picked from commit 23e0815)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Just a simple de-duplication of the same code. We saw a bug here
recently (#161521). Might as well isolate this all in one place.
rdar://158159242