Skip to content

Commit

Permalink
v1.2.1
Browse files Browse the repository at this point in the history
  • Loading branch information
nico committed Jun 24, 2019
2 parents 7ce084f + a9120ce commit 1108fcc
Show file tree
Hide file tree
Showing 18 changed files with 1,034 additions and 299 deletions.
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
project(demumble C CXX)
cmake_minimum_required(VERSION 3.2.0 FATAL_ERROR)
project(demumble CXX)

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

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

# This is apparently the simplest way to statically link the CRT in CMake:
string(TOUPPER "${CMAKE_BUILD_TYPE}" build)
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,17 @@ symbols (also when running on non-Windows).
$ c++filt '??2@YAPEAX_K@Z'
??2@YAPEAX_K@Z

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

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

Optionally print both mangled and demangled names:

$ echo _ZN3fooC1Ev _ZN3fooC2Ev | ./demumble -b
"foo::foo()" (_ZN3fooC1Ev) "foo::foo()" (_ZN3fooC2Ev)

## Build instructions

Use cmake to build: `cmake -G Ninja && ninja`
Expand Down
8 changes: 4 additions & 4 deletions RELEASING
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Push new release branch:
1. Make sure branches 'master' and 'release' are synced up locally
2. update src/demumble.cc with new version (with ".git"), then
1. make sure branches 'master' and 'release' are synced up locally
2. update demumble.cc with new version (with ".git"), then
git commit -am 'mark this 1.0.0.git'
3. git checkout release; git merge master
4. fix version number in src/version.cc (it will likely conflict in the above)
Expand All @@ -9,5 +9,5 @@ Push new release branch:
git tag v1.0.0; git push --tags
# Push the 1.0.0.git change on master too:
git checkout master; git push origin master
6. Add binaries to https://github.com/nico/demumble/releases
Build them with `-DCMAKE_BUILD_TYPE=Release`, strip after building.
6. add binaries to https://github.com/nico/demumble/releases
build them with `./dist.py`
40 changes: 19 additions & 21 deletions demumble.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@

#include "llvm/Demangle/Demangle.h"

const char kDemumbleVersion[] = "1.2.0";
const char kDemumbleVersion[] = "1.2.1";

static void print_help(FILE* out) {
static int print_help(FILE* out) {
fprintf(out,
"usage: demumble [options] [symbols...]\n"
"\n"
Expand All @@ -19,17 +19,11 @@ static void print_help(FILE* out) {
" -m only print mangled names that were demangled, omit other output\n"
" -u use unbuffered output\n"
" --version print demumble version (\"%s\")\n", kDemumbleVersion);
}

static bool starts_with(const char* s, const char* prefix) {
return strncmp(s, prefix, strlen(prefix)) == 0;
return out == stdout ? 0 : 1;
}

static void print_demangled(const char* format, const char* s) {
const char* cxa_in = s;
if (starts_with(s, "__Z") || starts_with(s, "____Z"))
cxa_in += 1;
if (char* itanium = llvm::itaniumDemangle(cxa_in, NULL, NULL, NULL)) {
if (char* itanium = llvm::itaniumDemangle(s, NULL, NULL, NULL)) {
printf(format, itanium, s);
free(itanium);
} else if (char* ms = llvm::microsoftDemangle(s, NULL, NULL, NULL)) {
Expand Down Expand Up @@ -64,26 +58,30 @@ int main(int argc, char* argv[]) {
enum { kPrintAll, kPrintMatching } print_mode = kPrintAll;
const char* print_format = "%s";
while (argc > 1 && argv[1][0] == '-') {
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
print_help(stdout);
return 0;
} else if (strcmp(argv[1], "-b") == 0) {
print_format = "\"%s\" (%s)";
} else if (strcmp(argv[1], "-m") == 0) {
print_mode = kPrintMatching;
} else if (strcmp(argv[1], "-u") == 0) {
setbuf(stdout, NULL);
if (strcmp(argv[1], "--help") == 0) {
return print_help(stdout);
} else if (strcmp(argv[1], "--version") == 0) {
printf("%s\n", kDemumbleVersion);
return 0;
} else if (strcmp(argv[1], "--") == 0) {
--argc;
++argv;
break;
} else if (argv[1][0] == '-' && argv[1][1] != '-') {
for (int i = 1; i < strlen(argv[1]); ++i)
switch (argv[1][i]) {
case 'b': print_format = "\"%s\" (%s)"; break;
case 'h': return print_help(stdout);
case 'm': print_mode = kPrintMatching; break;
case 'u': setbuf(stdout, NULL); break;
default:
fprintf(stderr, "demumble: unrecognized option `%c' in `%s'\n",
argv[1][i], argv[1]);
return print_help(stderr);
}
} else {
fprintf(stderr, "demumble: unrecognized option `%s'\n", argv[1]);
print_help(stderr);
return 1;
return print_help(stderr);
}
--argc;
++argv;
Expand Down
7 changes: 6 additions & 1 deletion demumble_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
'.invocation function for block in blocksNRVO()\n'),
('demumble -m < .____Z10blocksNRVOv_block_invoke',
'invocation function for block in blocksNRVO()\n'),
('demumble _ZN2zx7channelD4Ev', 'zx::channel::~channel()\n'),
('demumble -- -b', '-b\n'),
('demumble -- -m', '-m\n'),
('demumble -- -h', '-h\n'),
Expand All @@ -32,6 +33,10 @@
('demumble -b hello', 'hello\n'),
('demumble -b _Z1fv', '"f()" (_Z1fv)\n'),
('demumble -b < _Z1fv', '"f()" (_Z1fv)\n'),
('demumble -bm < _Z1fv!foo_bar', '"f()" (_Z1fv)\n'),
('demumble -mb < _Z1fv!foo_bar', '"f()" (_Z1fv)\n'),
('demumble --foo < bar', re.compile(".*unrecognized option `--foo'.*")),
('demumble -bx < bar', re.compile(".*unrecognized option `x' in `-bx'.*")),
]

status = 0
Expand All @@ -46,7 +51,7 @@
out = p.communicate(input='\n'.join(cmd[cmd.index('<') + 1:]) + '\n')[0]
else:
out = subprocess.check_output(cmd, universal_newlines=True)
if (out != t[1] if isinstance(t[1], str) else t[1].match(out, re.M)):
if (out != t[1] if isinstance(t[1], str) else not t[1].match(out)):
print("`%s`: Expected '%s', got '%s'" % (t[0], t[1], out))
status = 1
print("passed" if status == 0 else "failed")
Expand Down
127 changes: 127 additions & 0 deletions dist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/usr/bin/env python

# Builds demumble for Mac, Linux, Windows. Must run on a Mac.
# Needs a chromium checkout at ~/src/chrome/src that was synced with
# target_os=['win'] to get the Windows toolchain. You must run
# `build/linux/sysroot_scripts/install-sysroot.py --arch amd64` once to
# get the linux toolchain.

# Also needs a GN build of llvm at ~/src/llvm-project/out/gn for llvm-strip
# for stripping the Linux binary.

# Doesn't run tests, so make sure to run `./demumble_test.py` on all 3 platforms
# before running this script.

# After this script finishes successfully, the cwd will contain
# demumble-mac.zip, demumble-linux.zip, demumble-windows.zip which each contain
# a demumble binary built for that OS, ready for releasing (assuming the script
# was run on the release branch).

# https://gitlab.kitware.com/cmake/community/wikis/doc/cmake/CrossCompiling has
# some documentation on cross builds with cmake.

import contextlib
import json
import glob
import os
import subprocess
import sys

crsrc = os.path.join(os.path.expanduser('~'), 'src/chrome/src')
if len(sys.argv) > 1:
crsrc = os.path.abspath(sys.argv[1])
clangcl = crsrc + '/third_party/llvm-build/Release+Asserts/bin/clang-cl'
clangxx = crsrc + '/third_party/llvm-build/Release+Asserts/bin/clang++'
lldlink = crsrc + '/third_party/llvm-build/Release+Asserts/bin/lld-link'

linux_strip = os.path.join(os.path.expanduser('~'),
'src/llvm-project/out/gn/bin/llvm-strip')

cmake = '/Applications/CMake.app/Contents/bin/cmake'
call_cmake = [cmake, '-GNinja', '..', '-DCMAKE_BUILD_TYPE=Release']


@contextlib.contextmanager
def buildir(newdir):
"""Creates newdir if it doesn't exist yet and temporarily sets cwd to it."""
newdir = os.path.join(os.path.dirname(__file__), newdir)
if not os.path.isdir(newdir):
os.mkdir(newdir) # Intentionally not deleted.
prevdir = os.getcwd()
os.chdir(newdir)
try:
yield
finally:
os.chdir(prevdir)

subprocess.check_call(['rm', '-rf', 'buildlinux', 'buildmac', 'buildwin'])
devnull = open(os.devnull,"w")

# Linux.
linux_sysroot = crsrc + '/build/linux/debian_jessie_amd64-sysroot'
cflags = [ '--sysroot', linux_sysroot, '--target=x86_64-linux-gnu', ]
ldflags = ['-fuse-ld=lld'] + cflags
with buildir('buildlinux'):
print 'building linux'
subprocess.check_call(call_cmake + [
'-DCMAKE_CXX_COMPILER=' + clangxx,
'-DCMAKE_CXX_FLAGS=' + ' '.join(cflags),
'-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags),
'-DCMAKE_SYSTEM_NAME=Linux',
], stdout=devnull)
subprocess.check_call(['ninja', 'demumble'])
# FIXME: https://chromium-review.googlesource.com/c/chromium/src/+/1214943
# has a way to build eu-strip on macOS, which is arguably a smaller dep
# than llvm-strip.
subprocess.check_call([linux_strip, 'demumble'])
subprocess.check_call(['zip', '-q9', 'demumble-linux.zip', 'demumble'])
subprocess.check_call(['mv', 'demumble-linux.zip', '..'])

# Mac.
with buildir('buildmac'):
print 'building mac'
subprocess.check_call(call_cmake + [
'-DCMAKE_CXX_COMPILER=' + clangxx,
], stdout=devnull)
subprocess.check_call(['ninja', 'demumble'])
subprocess.check_call(['strip', 'demumble'])
subprocess.check_call(['zip', '-q9', 'demumble-mac.zip', 'demumble'])
subprocess.check_call(['mv', 'demumble-mac.zip', '..'])

# Win.
win_sysroot = glob.glob(
crsrc + '/third_party/depot_tools/win_toolchain/vs_files/*')[0]
win_bindir = win_sysroot + '/win_sdk/bin'
# This json file looks like http://codepad.org/kmfgf0UL
winenv = json.load(open(win_bindir + '/SetEnv.x64.json'))['env']
for k in ['INCLUDE', 'LIB']:
winenv[k] = [os.path.join(*([win_bindir] + e)) for e in winenv[k]]
win_include = ['-imsvc' + i for i in winenv['INCLUDE']]
win_lib = ['/libpath:' + i for i in winenv['LIB']]
cflags = ['--target=x86_64-pc-windows'] + win_include
with buildir('buildwin'):
print 'building windows'
subprocess.check_call(call_cmake + [
'-DCMAKE_CXX_COMPILER=' + clangcl,
'-DCMAKE_CXX_FLAGS=' + ' '.join(cflags),
# Without /manifest:no, cmake creates a default manifest file -- and
# explicitly calls mt.exe (which we don't have in a cross build).
# This also removes a dependency on rc.exe -- without this we'd also
# have to set CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY.
'-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(['/manifest:no'] + win_lib),
'-DCMAKE_LINKER=' + lldlink,
'-DCMAKE_SYSTEM_NAME=Windows',
], stdout=devnull)
subprocess.check_call(['ninja', 'demumble'])
# No stripping on Windows.
subprocess.check_call(['zip', '-q9', 'demumble-win.zip', 'demumble.exe'])
subprocess.check_call(['mv', 'demumble-win.zip', '..'])

# Copy over mac binary and run tests.
print 'running tests (on mac)'
subprocess.check_call(['cp', 'buildmac/demumble', '.'])
subprocess.check_call(['./demumble_test.py'])

# Show zip files.
subprocess.check_call('ls -hl *.zip', shell=True)
subprocess.check_call(['./demumble', '--version'])
Loading

0 comments on commit 1108fcc

Please sign in to comment.