Skip to content

Commit 1108fcc

Browse files
committed
v1.2.1
2 parents 7ce084f + a9120ce commit 1108fcc

18 files changed

+1034
-299
lines changed

CMakeLists.txt

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
2-
project(demumble C CXX)
1+
cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR)
2+
project(demumble CXX)
33

44
if (UNIX)
55
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti")
@@ -20,6 +20,7 @@ endif()
2020

2121
if (WIN32)
2222
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:inline /EHs-c- /GR-")
23+
add_definitions(-D_CRT_SECURE_NO_WARNINGS) # The LLVM build sets this.
2324

2425
# This is apparently the simplest way to statically link the CRT in CMake:
2526
string(TOUPPER "${CMAKE_BUILD_TYPE}" build)

README.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,17 @@ symbols (also when running on non-Windows).
6262
$ c++filt '??2@YAPEAX_K@Z'
6363
??2@YAPEAX_K@Z
6464

65-
demumble also has a flag to make it print only things that look like symbols.
66-
For example, print demangled names of all functions defined in a bitcode file:
65+
Optionally print _only_ demangled things: For example, print demangled names of
66+
all functions defined in a bitcode file:
6767

6868
$ grep '^define' bitcode-win.ll | demumble -m | head -1
6969
unsigned int __cdecl v8::RoundUpToPowerOfTwo32(unsigned int)
7070

71+
Optionally print both mangled and demangled names:
72+
73+
$ echo _ZN3fooC1Ev _ZN3fooC2Ev | ./demumble -b
74+
"foo::foo()" (_ZN3fooC1Ev) "foo::foo()" (_ZN3fooC2Ev)
75+
7176
## Build instructions
7277

7378
Use cmake to build: `cmake -G Ninja && ninja`

RELEASING

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Push new release branch:
2-
1. Make sure branches 'master' and 'release' are synced up locally
3-
2. update src/demumble.cc with new version (with ".git"), then
2+
1. make sure branches 'master' and 'release' are synced up locally
3+
2. update demumble.cc with new version (with ".git"), then
44
git commit -am 'mark this 1.0.0.git'
55
3. git checkout release; git merge master
66
4. fix version number in src/version.cc (it will likely conflict in the above)
@@ -9,5 +9,5 @@ Push new release branch:
99
git tag v1.0.0; git push --tags
1010
# Push the 1.0.0.git change on master too:
1111
git checkout master; git push origin master
12-
6. Add binaries to https://github.com/nico/demumble/releases
13-
Build them with `-DCMAKE_BUILD_TYPE=Release`, strip after building.
12+
6. add binaries to https://github.com/nico/demumble/releases
13+
build them with `./dist.py`

demumble.cc

+19-21
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
#include "llvm/Demangle/Demangle.h"
88

9-
const char kDemumbleVersion[] = "1.2.0";
9+
const char kDemumbleVersion[] = "1.2.1";
1010

11-
static void print_help(FILE* out) {
11+
static int print_help(FILE* out) {
1212
fprintf(out,
1313
"usage: demumble [options] [symbols...]\n"
1414
"\n"
@@ -19,17 +19,11 @@ static void print_help(FILE* out) {
1919
" -m only print mangled names that were demangled, omit other output\n"
2020
" -u use unbuffered output\n"
2121
" --version print demumble version (\"%s\")\n", kDemumbleVersion);
22-
}
23-
24-
static bool starts_with(const char* s, const char* prefix) {
25-
return strncmp(s, prefix, strlen(prefix)) == 0;
22+
return out == stdout ? 0 : 1;
2623
}
2724

2825
static void print_demangled(const char* format, const char* s) {
29-
const char* cxa_in = s;
30-
if (starts_with(s, "__Z") || starts_with(s, "____Z"))
31-
cxa_in += 1;
32-
if (char* itanium = llvm::itaniumDemangle(cxa_in, NULL, NULL, NULL)) {
26+
if (char* itanium = llvm::itaniumDemangle(s, NULL, NULL, NULL)) {
3327
printf(format, itanium, s);
3428
free(itanium);
3529
} else if (char* ms = llvm::microsoftDemangle(s, NULL, NULL, NULL)) {
@@ -64,26 +58,30 @@ int main(int argc, char* argv[]) {
6458
enum { kPrintAll, kPrintMatching } print_mode = kPrintAll;
6559
const char* print_format = "%s";
6660
while (argc > 1 && argv[1][0] == '-') {
67-
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
68-
print_help(stdout);
69-
return 0;
70-
} else if (strcmp(argv[1], "-b") == 0) {
71-
print_format = "\"%s\" (%s)";
72-
} else if (strcmp(argv[1], "-m") == 0) {
73-
print_mode = kPrintMatching;
74-
} else if (strcmp(argv[1], "-u") == 0) {
75-
setbuf(stdout, NULL);
61+
if (strcmp(argv[1], "--help") == 0) {
62+
return print_help(stdout);
7663
} else if (strcmp(argv[1], "--version") == 0) {
7764
printf("%s\n", kDemumbleVersion);
7865
return 0;
7966
} else if (strcmp(argv[1], "--") == 0) {
8067
--argc;
8168
++argv;
8269
break;
70+
} else if (argv[1][0] == '-' && argv[1][1] != '-') {
71+
for (int i = 1; i < strlen(argv[1]); ++i)
72+
switch (argv[1][i]) {
73+
case 'b': print_format = "\"%s\" (%s)"; break;
74+
case 'h': return print_help(stdout);
75+
case 'm': print_mode = kPrintMatching; break;
76+
case 'u': setbuf(stdout, NULL); break;
77+
default:
78+
fprintf(stderr, "demumble: unrecognized option `%c' in `%s'\n",
79+
argv[1][i], argv[1]);
80+
return print_help(stderr);
81+
}
8382
} else {
8483
fprintf(stderr, "demumble: unrecognized option `%s'\n", argv[1]);
85-
print_help(stderr);
86-
return 1;
84+
return print_help(stderr);
8785
}
8886
--argc;
8987
++argv;

demumble_test.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
'.invocation function for block in blocksNRVO()\n'),
2424
('demumble -m < .____Z10blocksNRVOv_block_invoke',
2525
'invocation function for block in blocksNRVO()\n'),
26+
('demumble _ZN2zx7channelD4Ev', 'zx::channel::~channel()\n'),
2627
('demumble -- -b', '-b\n'),
2728
('demumble -- -m', '-m\n'),
2829
('demumble -- -h', '-h\n'),
@@ -32,6 +33,10 @@
3233
('demumble -b hello', 'hello\n'),
3334
('demumble -b _Z1fv', '"f()" (_Z1fv)\n'),
3435
('demumble -b < _Z1fv', '"f()" (_Z1fv)\n'),
36+
('demumble -bm < _Z1fv!foo_bar', '"f()" (_Z1fv)\n'),
37+
('demumble -mb < _Z1fv!foo_bar', '"f()" (_Z1fv)\n'),
38+
('demumble --foo < bar', re.compile(".*unrecognized option `--foo'.*")),
39+
('demumble -bx < bar', re.compile(".*unrecognized option `x' in `-bx'.*")),
3540
]
3641

3742
status = 0
@@ -46,7 +51,7 @@
4651
out = p.communicate(input='\n'.join(cmd[cmd.index('<') + 1:]) + '\n')[0]
4752
else:
4853
out = subprocess.check_output(cmd, universal_newlines=True)
49-
if (out != t[1] if isinstance(t[1], str) else t[1].match(out, re.M)):
54+
if (out != t[1] if isinstance(t[1], str) else not t[1].match(out)):
5055
print("`%s`: Expected '%s', got '%s'" % (t[0], t[1], out))
5156
status = 1
5257
print("passed" if status == 0 else "failed")

dist.py

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#!/usr/bin/env python
2+
3+
# Builds demumble for Mac, Linux, Windows. Must run on a Mac.
4+
# Needs a chromium checkout at ~/src/chrome/src that was synced with
5+
# target_os=['win'] to get the Windows toolchain. You must run
6+
# `build/linux/sysroot_scripts/install-sysroot.py --arch amd64` once to
7+
# get the linux toolchain.
8+
9+
# Also needs a GN build of llvm at ~/src/llvm-project/out/gn for llvm-strip
10+
# for stripping the Linux binary.
11+
12+
# Doesn't run tests, so make sure to run `./demumble_test.py` on all 3 platforms
13+
# before running this script.
14+
15+
# After this script finishes successfully, the cwd will contain
16+
# demumble-mac.zip, demumble-linux.zip, demumble-windows.zip which each contain
17+
# a demumble binary built for that OS, ready for releasing (assuming the script
18+
# was run on the release branch).
19+
20+
# https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/CrossCompiling has
21+
# some documentation on cross builds with cmake.
22+
23+
import contextlib
24+
import json
25+
import glob
26+
import os
27+
import subprocess
28+
import sys
29+
30+
crsrc = os.path.join(os.path.expanduser('~'), 'src/chrome/src')
31+
if len(sys.argv) > 1:
32+
crsrc = os.path.abspath(sys.argv[1])
33+
clangcl = crsrc + '/third_party/llvm-build/Release+Asserts/bin/clang-cl'
34+
clangxx = crsrc + '/third_party/llvm-build/Release+Asserts/bin/clang++'
35+
lldlink = crsrc + '/third_party/llvm-build/Release+Asserts/bin/lld-link'
36+
37+
linux_strip = os.path.join(os.path.expanduser('~'),
38+
'src/llvm-project/out/gn/bin/llvm-strip')
39+
40+
cmake = '/Applications/CMake.app/Contents/bin/cmake'
41+
call_cmake = [cmake, '-GNinja', '..', '-DCMAKE_BUILD_TYPE=Release']
42+
43+
44+
@contextlib.contextmanager
45+
def buildir(newdir):
46+
"""Creates newdir if it doesn't exist yet and temporarily sets cwd to it."""
47+
newdir = os.path.join(os.path.dirname(__file__), newdir)
48+
if not os.path.isdir(newdir):
49+
os.mkdir(newdir) # Intentionally not deleted.
50+
prevdir = os.getcwd()
51+
os.chdir(newdir)
52+
try:
53+
yield
54+
finally:
55+
os.chdir(prevdir)
56+
57+
subprocess.check_call(['rm', '-rf', 'buildlinux', 'buildmac', 'buildwin'])
58+
devnull = open(os.devnull,"w")
59+
60+
# Linux.
61+
linux_sysroot = crsrc + '/build/linux/debian_jessie_amd64-sysroot'
62+
cflags = [ '--sysroot', linux_sysroot, '--target=x86_64-linux-gnu', ]
63+
ldflags = ['-fuse-ld=lld'] + cflags
64+
with buildir('buildlinux'):
65+
print 'building linux'
66+
subprocess.check_call(call_cmake + [
67+
'-DCMAKE_CXX_COMPILER=' + clangxx,
68+
'-DCMAKE_CXX_FLAGS=' + ' '.join(cflags),
69+
'-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags),
70+
'-DCMAKE_SYSTEM_NAME=Linux',
71+
], stdout=devnull)
72+
subprocess.check_call(['ninja', 'demumble'])
73+
# FIXME: https://chromium-review.googlesource.com/c/chromium/src/+/1214943
74+
# has a way to build eu-strip on macOS, which is arguably a smaller dep
75+
# than llvm-strip.
76+
subprocess.check_call([linux_strip, 'demumble'])
77+
subprocess.check_call(['zip', '-q9', 'demumble-linux.zip', 'demumble'])
78+
subprocess.check_call(['mv', 'demumble-linux.zip', '..'])
79+
80+
# Mac.
81+
with buildir('buildmac'):
82+
print 'building mac'
83+
subprocess.check_call(call_cmake + [
84+
'-DCMAKE_CXX_COMPILER=' + clangxx,
85+
], stdout=devnull)
86+
subprocess.check_call(['ninja', 'demumble'])
87+
subprocess.check_call(['strip', 'demumble'])
88+
subprocess.check_call(['zip', '-q9', 'demumble-mac.zip', 'demumble'])
89+
subprocess.check_call(['mv', 'demumble-mac.zip', '..'])
90+
91+
# Win.
92+
win_sysroot = glob.glob(
93+
crsrc + '/third_party/depot_tools/win_toolchain/vs_files/*')[0]
94+
win_bindir = win_sysroot + '/win_sdk/bin'
95+
# This json file looks like http://codepad.org/kmfgf0UL
96+
winenv = json.load(open(win_bindir + '/SetEnv.x64.json'))['env']
97+
for k in ['INCLUDE', 'LIB']:
98+
winenv[k] = [os.path.join(*([win_bindir] + e)) for e in winenv[k]]
99+
win_include = ['-imsvc' + i for i in winenv['INCLUDE']]
100+
win_lib = ['/libpath:' + i for i in winenv['LIB']]
101+
cflags = ['--target=x86_64-pc-windows'] + win_include
102+
with buildir('buildwin'):
103+
print 'building windows'
104+
subprocess.check_call(call_cmake + [
105+
'-DCMAKE_CXX_COMPILER=' + clangcl,
106+
'-DCMAKE_CXX_FLAGS=' + ' '.join(cflags),
107+
# Without /manifest:no, cmake creates a default manifest file -- and
108+
# explicitly calls mt.exe (which we don't have in a cross build).
109+
# This also removes a dependency on rc.exe -- without this we'd also
110+
# have to set CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY.
111+
'-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(['/manifest:no'] + win_lib),
112+
'-DCMAKE_LINKER=' + lldlink,
113+
'-DCMAKE_SYSTEM_NAME=Windows',
114+
], stdout=devnull)
115+
subprocess.check_call(['ninja', 'demumble'])
116+
# No stripping on Windows.
117+
subprocess.check_call(['zip', '-q9', 'demumble-win.zip', 'demumble.exe'])
118+
subprocess.check_call(['mv', 'demumble-win.zip', '..'])
119+
120+
# Copy over mac binary and run tests.
121+
print 'running tests (on mac)'
122+
subprocess.check_call(['cp', 'buildmac/demumble', '.'])
123+
subprocess.check_call(['./demumble_test.py'])
124+
125+
# Show zip files.
126+
subprocess.check_call('ls -hl *.zip', shell=True)
127+
subprocess.check_call(['./demumble', '--version'])

0 commit comments

Comments
 (0)