diff --git a/CMakeLists.txt b/CMakeLists.txt index 93c90d2..0b39ba8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,20 +1,27 @@ cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) project(demumble C CXX) -# TODO: Also do this for gcc once gcc 4.9 is common. -if (${UNIX} AND ${CMAKE_GENERATOR} STREQUAL "Ninja" AND - ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color -Wall") -endif() +if (UNIX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -fno-rtti") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") + if (${CMAKE_GENERATOR} STREQUAL "Ninja") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color") + endif() -# 10.9 chosen somewhat arbitrary; it's the first target where clang defaults -# to libc++ and ld64 defaults to stripping __TEXT,__eh_frame. -if (APPLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.9") + # 10.9 chosen somewhat arbitrary; it's the first target where clang defaults + # to libc++ and ld64 defaults to stripping __TEXT,__eh_frame. + if (APPLE) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.9") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-PIC") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie") + endif() endif() -# This is apparently the simplest way to statically link the CRT in CMake: if (WIN32) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:inline /EHs-c- /GR-") + + # This is apparently the simplest way to statically link the CRT in CMake: string(TOUPPER "${CMAKE_BUILD_TYPE}" build) set(flag_var "CMAKE_CXX_FLAGS_${build}") if(${flag_var} MATCHES "/MD") diff --git a/README.md b/README.md index 29f7135..1e6a773 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # demumble -`demumble` demangles both POSIX and Visual Studio symbols. It runs on both +`demumble` demangles both Itanium and Visual Studio symbols. It runs on both POSIX and Windows. $ demumble _Z4funcPci @@ -37,9 +37,11 @@ thing: Smart about filtering: Both c++filt and demumble can work as a stdin filter. demumble only demangles function symbols (which never look like other words), -while c++filt defaults to demangling type names too, which are likely to look -like regular words. demumble does demangle types when they're passed as args: +while c++filt on macOS defaults to demangling type names too, which are likely +to look like regular words. demumble does demangle types when they're passed +as args without requiring the `--types` switch that c++filt needs on Linux: + # on macOS: $ echo 'I like Pi and _Znw' | c++filt I like int* and _Znw $ echo 'I like Pi and _Znw' | demumble @@ -48,6 +50,9 @@ like regular words. demumble does demangle types when they're passed as args: int* $ demumble Pi int* + # on Linux: + $ c++filt Pi + Pi Cross-platform: demumble runs on Windows. demumble can demangle Windows-style symbols (also when running on non-Windows). diff --git a/demumble.cc b/demumble.cc index 61e89d5..9f37890 100644 --- a/demumble.cc +++ b/demumble.cc @@ -6,7 +6,7 @@ #include "llvm/Demangle/Demangle.h" -const char kDemumbleVersion[] = "1.1.0"; +const char kDemumbleVersion[] = "1.2.0"; static void print_help(FILE* out) { fprintf(out, @@ -15,6 +15,7 @@ static void print_help(FILE* out) { "if symbols are unspecified, reads from stdin.\n" "\n" "options:\n" +" -b print both demangled and mangled name\n" " -m only print mangled names that were demangled, omit other output\n" " -u use unbuffered output\n" " --version print demumble version (\"%s\")\n", kDemumbleVersion); @@ -24,15 +25,15 @@ static bool starts_with(const char* s, const char* prefix) { return strncmp(s, prefix, strlen(prefix)) == 0; } -static void print_demangled(const char* s) { +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)) { - printf("%s", itanium); + printf(format, itanium, s); free(itanium); } else if (char* ms = llvm::microsoftDemangle(s, NULL, NULL, NULL)) { - printf("%s", ms); + printf(format, ms, s); free(ms); } else { printf("%s", s); @@ -61,10 +62,13 @@ static bool is_plausible_itanium_prefix(char* s) { static char buf[8192]; 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) { @@ -85,7 +89,7 @@ int main(int argc, char* argv[]) { ++argv; } for (int i = 1; i < argc; ++i) { - print_demangled(argv[i]); + print_demangled(print_format, argv[i]); printf("\n"); } if (argc == 1) { // Read stdin instead. @@ -125,7 +129,7 @@ int main(int argc, char* argv[]) { char tmp = cur[n_sym]; cur[n_sym] = '\0'; - print_demangled(cur); + print_demangled(print_format, cur); need_separator = true; cur[n_sym] = tmp; diff --git a/demumble_test.py b/demumble_test.py index e53d467..7df0ae9 100755 --- a/demumble_test.py +++ b/demumble_test.py @@ -23,11 +23,15 @@ '.invocation function for block in blocksNRVO()\n'), ('demumble -m < .____Z10blocksNRVOv_block_invoke', 'invocation function for block in blocksNRVO()\n'), + ('demumble -- -b', '-b\n'), ('demumble -- -m', '-m\n'), ('demumble -- -h', '-h\n'), ('demumble -h', re.compile('.*usage: demumble.*')), ('demumble --help', re.compile('.*usage: demumble.*')), ('demumble --version', re.compile('.*\..*')), + ('demumble -b hello', 'hello\n'), + ('demumble -b _Z1fv', '"f()" (_Z1fv)\n'), + ('demumble -b < _Z1fv', '"f()" (_Z1fv)\n'), ] status = 0