Skip to content

Commit 88877b5

Browse files
committed
- add dcxxfilt demangling tool
- demangle symbols in disassembly
1 parent cfe0ade commit 88877b5

File tree

8 files changed

+192
-5
lines changed

8 files changed

+192
-5
lines changed

CHANGES

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,3 +742,6 @@ unreleased Version 0.3.42
742742
* add integration into the Visual Studio Performance Wizard
743743
* added project template for console application built with DMD/LDC and x86/x64
744744
* bugzilla 14706: release configurations now enable optimizations and inlining by default
745+
* mago is now the default debug engine for new projects
746+
* demangle D/C++ symbols in disassembly with new tool dcxxfilt that supports both gcc
747+
and MS C++ mangling.

Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ TLB2IDL_EXE = $(BINDIR)\tlb2idl.exe
4848
PIPEDMD_EXE = $(BINDIR)\pipedmd.exe
4949
LARGEADR_EXE= $(BINDIR)\largeadr.exe
5050
FILEMON_DLL = $(BINDIR)\filemonitor.dll
51+
DCXXFILT_EXE= $(BINDIR)\dcxxfilt.exe
5152
VSI2D_EXE = $(BINDIR)\vsi2d.exe
5253
VSI_LIB = $(BINDIR)\vsi.lib
5354
VISUALD = $(BINDIR)\visuald.dll
@@ -157,14 +158,18 @@ cv2pdb:
157158
cd ..\..\cv2pdb\trunk && devenv /Project "dviewhelper" /Build "Release|Win32" src\cv2pdb_vs12.sln
158159
cd ..\..\cv2pdb\trunk && devenv /Project "dumplines" /Build "Release|Win32" src\cv2pdb_vs12.sln
159160

161+
dcxxfilt: $(DCXXFILT_EXE)
162+
$(DCXXFILT_EXE): tools\dcxxfilt.d
163+
cd tools && set CONFIG=Release&& build_dcxxfilt
164+
160165
##################################
161166
# create installer
162167

163168
install: all cpp2d_exe idl2d_exe
164169
cd nsis && "$(NSIS)\makensis" /V1 visuald.nsi
165170
"$(ZIP)" -j ..\downloads\visuald_pdb.zip bin\release\visuald.pdb bin\release\vdserver.pdb
166171

167-
install_vs: prerequisites visuald_vs vdserver cv2pdb dparser vdextension mago install_only
172+
install_vs: prerequisites visuald_vs vdserver cv2pdb dparser vdextension mago dcxxfilt install_only
168173

169174
install_only:
170175
cd nsis && "$(NSIS)\makensis" /V1 visuald.nsi

nsis/visuald.nsi

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ Section "Visual Studio package" SecPackage
186186
${File} ..\bin\${CONFIG}\ vdserver.exe
187187
${File} ..\bin\${CONFIG}\ pipedmd.exe
188188
${File} ..\bin\${CONFIG}\ filemonitor.dll
189+
${File} ..\bin\${CONFIG}\ dcxxfilt.exe
189190
${File} ..\ README.md
190191
${File} ..\ LICENSE_1_0.txt
191192
${File} ..\ CHANGES

tools/build_dcxxfilt.bat

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
@echo off
2+
rem unpack and configure binutils 2.25+
3+
rem don't use spaces in path names!
4+
5+
setlocal
6+
if "%DMDINSTALLDIR%" == "" set DMDINSTALLDIR=m:\s\d\rainers
7+
if "%DMD%" == "" set DMD=%DMDINSTALLDIR%\windows\bin\dmd
8+
if "%BINUTILS%" == "" set BINUTILS=c:\s\cpp\cxxfilt
9+
10+
if "%CONFIG%" == "" set CONFIG=Debug
11+
12+
set OUTDIR=..\bin\%CONFIG%
13+
set LIBIBERTY=%BINUTILS%\libiberty
14+
15+
%DMD% -c -m32mscoff -of%OUTDIR%\dcxxfilt.obj dcxxfilt.d || exit /B 1
16+
17+
set SRC=
18+
set SRC=%SRC% %LIBIBERTY%\d-demangle.c
19+
set SRC=%SRC% %LIBIBERTY%\cp-demangle.c %LIBIBERTY%\cplus-dem.c
20+
set SRC=%SRC% %LIBIBERTY%\xmalloc.c %LIBIBERTY%\xstrdup.c %LIBIBERTY%\xexit.c
21+
set SRC=%SRC% %LIBIBERTY%\safe-ctype.c
22+
set SRC=%SRC% %LIBIBERTY%\alloca.c
23+
24+
set COPT=-I %BINUTILS% -I %BINUTILS%\include -I %BINUTILS%\binutils -DHAVE_CONFIG_H
25+
set LIB=%LIB%;%DMDINSTALLDIR%\lib32
26+
cl /Ox /Fe%OUTDIR%\dcxxfilt.exe /Fo%OUTDIR%\ %COPT% %SRC% %OUTDIR%\dcxxfilt.obj dbghelp.lib

tools/dcxxfilt.d

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
/* Demangler for D/C++ - gcc and MS style mangling
2+
3+
Copyright (C) 2015 Free Software Foundation, Inc.
4+
Written by Rainer Schuetze (r.sagitario@gmx.de)
5+
6+
This file is using part of GNU Binutils, inspired by cxxfilt
7+
8+
This program is free software; you can redistribute it and/or modify
9+
it under the terms of the GNU General Public License as published by
10+
the Free Software Foundation; either version 3 of the License, or (at
11+
your option) any later version.
12+
13+
This program is distributed in the hope that it will be useful,
14+
but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
GNU General Public License for more details.
17+
18+
You should have received a copy of the GNU General Public License
19+
along with GCC; see the file COPYING. If not, write to the Free
20+
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21+
02110-1301, USA. */
22+
23+
import core.demangle;
24+
import core.stdc.stdio;
25+
import core.stdc.stdlib;
26+
import core.stdc.string;
27+
28+
extern(Windows) uint UnDecorateSymbolName(in char* DecoratedName, char* UnDecoratedName,
29+
uint UndecoratedLength, uint Flags);
30+
extern(C) char* dlang_demangle(const char* mangled_name, uint flags);
31+
extern(C) char* cplus_demangle(const char* mangled_name, uint flags);
32+
33+
enum DMGL_PARAMS = (1 << 0); /* Include function args */
34+
enum DMGL_ANSI = (1 << 1); /* Include const, volatile, etc */
35+
enum DMGL_VERBOSE = (1 << 3); /* Include implementation details. */
36+
37+
uint flags = DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE;
38+
char msvc_buffer[32768];
39+
40+
char* msvc_demangle (char *mangled_name)
41+
{
42+
if (UnDecorateSymbolName (mangled_name, msvc_buffer.ptr, msvc_buffer.length, 0) == 0)
43+
return null;
44+
return msvc_buffer.ptr;
45+
}
46+
47+
char* d_demangle (char[] mangled)
48+
{
49+
size_t pos = 0;
50+
string s = decodeDmdString (mangled, pos);
51+
char[] obuf;
52+
if (pos == mangled.length)
53+
obuf = demangle(s, msvc_buffer);
54+
else
55+
obuf = demangle(mangled, msvc_buffer);
56+
if (obuf.ptr != msvc_buffer.ptr)
57+
return null;
58+
msvc_buffer[obuf.length] = 0;
59+
return msvc_buffer.ptr;
60+
}
61+
62+
void print_demangled (char[] mangled)
63+
{
64+
char *result;
65+
char[] initial = mangled;
66+
67+
/* . and $ are sometimes found at the start of function names
68+
in assembler sources in order to distinguish them from other
69+
names (eg register names). So skip them here. */
70+
if (mangled[0] == '.' || mangled[0] == '$')
71+
mangled = mangled[1..$];
72+
73+
if (mangled.length > 1 && mangled[0] == '_' && mangled[1] == 'D')
74+
result = d_demangle (mangled);
75+
else if (mangled.length > 0 && mangled[0] == '?')
76+
result = msvc_demangle (mangled.ptr);
77+
else
78+
result = cplus_demangle (mangled.ptr, flags);
79+
80+
if (result == null)
81+
printf ("%s", initial.ptr);
82+
else
83+
{
84+
if (initial.ptr != mangled.ptr)
85+
putchar (initial[0]);
86+
printf ("%s", result);
87+
if (result != msvc_buffer.ptr)
88+
free (result);
89+
}
90+
}
91+
92+
bool isAlnum(int c)
93+
{
94+
return c <= 'z' && c >= '0' && (c <= '9' || c >= 'a' || (c >= 'A' && c <= 'Z'));
95+
}
96+
97+
int main (char[][] argv)
98+
{
99+
int c;
100+
const char *valid_symbols = "_$.?@";
101+
102+
if (argv.length > 1)
103+
{
104+
foreach(a; argv[1..$])
105+
{
106+
print_demangled(a);
107+
putchar ('\n');
108+
}
109+
return 0;
110+
}
111+
for (;;)
112+
{
113+
static char mbuffer[32767];
114+
uint i = 0;
115+
116+
c = getchar ();
117+
/* Try to read a mangled name. Assume non-ascii characters to be part of the name */
118+
while (c != EOF && (isAlnum (c) || strchr (valid_symbols, c) || c >= 128))
119+
{
120+
if (i >= mbuffer.length - 1)
121+
break;
122+
mbuffer[i++] = cast(char) c;
123+
c = getchar ();
124+
}
125+
126+
if (i > 0)
127+
{
128+
mbuffer[i] = 0;
129+
print_demangled (mbuffer[0..i]);
130+
}
131+
132+
if (c == EOF)
133+
break;
134+
135+
/* Echo the whitespace characters so that the output looks
136+
like the input, only with the mangled names demangled. */
137+
putchar (c);
138+
if (c == '\n')
139+
fflush (stdout);
140+
}
141+
142+
fflush (stdout);
143+
return 0;
144+
}

visuald/config.d

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ class ProjectOptions
260260
string debugworkingdir;
261261
bool debugattach;
262262
string debugremote;
263-
ubyte debugEngine; // 0: mixed, 1: mago
263+
ubyte debugEngine; // 0: mixed, 1: mago, 2: native
264264
bool debugStdOutToOutputWindow;
265265
bool pauseAfterRunning;
266266

@@ -281,6 +281,7 @@ class ProjectOptions
281281
doXGeneration = true;
282282
useStdLibPath = true;
283283
cRuntime = CRuntime.StaticRelease;
284+
debugEngine = 1;
284285

285286
filesToClean = "*.obj;*.cmd;*.build;*.json;*.dep";
286287
setDebug(dbg);
@@ -2829,7 +2830,14 @@ class Config : DisposingComObject,
28292830
GlobalOptions globOpt = Package.GetGlobalOptions();
28302831
string cmd = x64 ? mProjectOptions.compilerDirectories.DisasmCommand64 :
28312832
mscoff ? mProjectOptions.compilerDirectories.DisasmCommand32coff : mProjectOptions.compilerDirectories.DisasmCommand;
2832-
cmd = mProjectOptions.replaceEnvironment(cmd, this, objfile, outfile);
2833+
if(globOpt.demangleError)
2834+
{
2835+
string mangledfile = outfile ~ ".mangled";
2836+
cmd = mProjectOptions.replaceEnvironment(cmd, this, objfile, mangledfile);
2837+
cmd ~= "\nif errorlevel 0 \"" ~ Package.GetGlobalOptions().VisualDInstallDir ~ "dcxxfilt.exe\" < " ~ quoteFilename(mangledfile) ~ " > " ~ quoteFilename(outfile);
2838+
}
2839+
else
2840+
cmd = mProjectOptions.replaceEnvironment(cmd, this, objfile, outfile);
28332841
return cmd;
28342842
}
28352843

visuald/logutil.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ version(test) {
529529

530530
void logCall(...)
531531
{
532-
auto buffer = new char[17 + 1];
532+
auto buffer = new char[32];
533533
SysTime now = Clock.currTime();
534534
uint tid = GetCurrentThreadId();
535535
auto len = sprintf(buffer.ptr, "%02d:%02d:%02d - %04x - ",

visuald/propertypage.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1808,7 +1808,7 @@ class ToolsProperty2Page : GlobalPropertyPage
18081808
AddControl("", mTimeBuilds = new CheckBox(mCanvas, "Show build time"));
18091809
AddControl("", mStopSlnBuild = new CheckBox(mCanvas, "Stop solution build on error"));
18101810
AddHorizontalLine();
1811-
AddControl("", mDemangleError = new CheckBox(mCanvas, "Demangle names in link errors"));
1811+
AddControl("", mDemangleError = new CheckBox(mCanvas, "Demangle names in link errors/disassembly"));
18121812
AddControl("", mOptlinkDeps = new CheckBox(mCanvas, "Monitor linker dependencies"));
18131813
AddHorizontalLine();
18141814
//AddControl("Remove project item", mDeleteFiles =

0 commit comments

Comments
 (0)