Skip to content

Commit 5a02a9a

Browse files
authored
[lldb] Improve identification of Dlang mangled names (#93881)
Reduce false positive identification of C names as Dlang mangled names. This happens when a C function uses the prefix `_D`. The [Dlang ABI](https://dlang.org/spec/abi.html#name_mangling) shows that mangled names have a length immediately following the `_D` prefix. This change checks for a digit after the `_D` prefix, when identifying the mangling scheme of a symbol. This doesn't prevent false positives entirely, but does make it less likely.
1 parent b06e736 commit 5a02a9a

File tree

4 files changed

+36
-2
lines changed

4 files changed

+36
-2
lines changed

lldb/source/Core/Mangled.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "lldb/Utility/Stream.h"
2020
#include "lldb/lldb-enumerations.h"
2121

22+
#include "llvm/ADT/StringExtras.h"
2223
#include "llvm/ADT/StringRef.h"
2324
#include "llvm/Demangle/Demangle.h"
2425
#include "llvm/Support/Compiler.h"
@@ -48,8 +49,14 @@ Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef const name) {
4849
if (name.starts_with("_R"))
4950
return Mangled::eManglingSchemeRustV0;
5051

51-
if (name.starts_with("_D"))
52-
return Mangled::eManglingSchemeD;
52+
if (name.starts_with("_D")) {
53+
// A dlang mangled name begins with `_D`, followed by a numeric length.
54+
// See `SymbolName` and `LName` in
55+
// https://dlang.org/spec/abi.html#name_mangling
56+
llvm::StringRef buf = name.drop_front(2);
57+
if (!buf.empty() && llvm::isDigit(buf.front()))
58+
return Mangled::eManglingSchemeD;
59+
}
5360

5461
if (name.starts_with("_Z"))
5562
return Mangled::eManglingSchemeItanium;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
C_SOURCES := main.c
2+
CFLAGS_EXTRAS := -std=c99
3+
4+
include Makefile.rules
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import lldbsuite.test.lldbutil as lldbutil
2+
from lldbsuite.test.lldbtest import *
3+
4+
5+
class TestCase(TestBase):
6+
def test_functions_having_dlang_mangling_prefix(self):
7+
"""
8+
Ensure C functions with a '_D' prefix alone are not mistakenly treated
9+
as a Dlang mangled name. A proper Dlang mangling will have digits
10+
immediately following the '_D' prefix.
11+
"""
12+
self.build()
13+
_, _, thread, _ = lldbutil.run_to_name_breakpoint(self, "_Dfunction")
14+
symbol = thread.frame[0].symbol
15+
self.assertEqual(symbol.GetDisplayName(), "_Dfunction")
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <stdio.h>
2+
3+
void _Dfunction() {}
4+
5+
int main() {
6+
_Dfunction();
7+
return 0;
8+
}

0 commit comments

Comments
 (0)