diff --git a/src/common/mac/dump_syms.cc b/src/common/mac/dump_syms.cc index c7afb215..1f830312 100644 --- a/src/common/mac/dump_syms.cc +++ b/src/common/mac/dump_syms.cc @@ -441,10 +441,8 @@ bool DumpSymbols::CreateEmptyModule(scoped_ptr& module) { return false; // Create a module to hold the debugging information. - module.reset(new Module(module_name, - "mac", - selected_arch_name, - identifier)); + module.reset(new Module(module_name, "mac", selected_arch_name, identifier, + "", enable_multiple_)); return true; } diff --git a/src/common/mac/dump_syms.h b/src/common/mac/dump_syms.h index d097cfa5..97632ce0 100644 --- a/src/common/mac/dump_syms.h +++ b/src/common/mac/dump_syms.h @@ -53,7 +53,9 @@ namespace google_breakpad { class DumpSymbols { public: - DumpSymbols(SymbolData symbol_data, bool handle_inter_cu_refs) + DumpSymbols(SymbolData symbol_data, + bool handle_inter_cu_refs, + bool enable_multiple = false) : symbol_data_(symbol_data), handle_inter_cu_refs_(handle_inter_cu_refs), object_filename_(), @@ -62,9 +64,9 @@ class DumpSymbols { from_disk_(false), object_files_(), selected_object_file_(), - selected_object_name_() {} - ~DumpSymbols() { - } + selected_object_name_(), + enable_multiple_(enable_multiple) {} + ~DumpSymbols() = default; // Prepare to read debugging information from |filename|. |filename| may be // the name of a fat file, a Mach-O file, or a dSYM bundle containing either @@ -201,6 +203,12 @@ class DumpSymbols { // fat binary, it includes an indication of the particular architecture // within that binary. string selected_object_name_; + + // Whether symbols sharing an address should be collapsed into a single entry + // and marked with an `m` in the output. + // See: https://crbug.com/google-breakpad/751 and docs at + // docs/symbol_files.md#records-3 + bool enable_multiple_; }; } // namespace google_breakpad diff --git a/src/tools/mac/dump_syms/dump_syms_tool.cc b/src/tools/mac/dump_syms/dump_syms_tool.cc index 2ac9e2cc..d0f29ba7 100644 --- a/src/tools/mac/dump_syms/dump_syms_tool.cc +++ b/src/tools/mac/dump_syms/dump_syms_tool.cc @@ -50,8 +50,14 @@ using std::vector; struct Options { Options() - : srcPath(), dsymPath(), arch(), header_only(false), - cfi(true), handle_inter_cu_refs(true), handle_inlines(false) {} + : srcPath(), + dsymPath(), + arch(), + header_only(false), + cfi(true), + handle_inter_cu_refs(true), + handle_inlines(false), + enable_multiple(false) {} string srcPath; string dsymPath; @@ -60,6 +66,7 @@ struct Options { bool cfi; bool handle_inter_cu_refs; bool handle_inlines; + bool enable_multiple; }; static bool StackFrameEntryComparator(const Module::StackFrameEntry* a, @@ -139,7 +146,8 @@ static bool Start(const Options& options) { SymbolData symbol_data = (options.handle_inlines ? INLINES : NO_DATA) | (options.cfi ? CFI : NO_DATA) | SYMBOLS_AND_FILES; - DumpSymbols dump_symbols(symbol_data, options.handle_inter_cu_refs); + DumpSymbols dump_symbols(symbol_data, options.handle_inter_cu_refs, + options.enable_multiple); // For x86_64 binaries, the CFI data is in the __TEXT,__eh_frame of the // Mach-O file, which is not copied into the dSYM. Whereas in i386, the CFI @@ -215,6 +223,9 @@ static void Usage(int argc, const char *argv[]) { fprintf(stderr, "\t-c: Do not generate CFI section\n"); fprintf(stderr, "\t-r: Do not handle inter-compilation unit references\n"); fprintf(stderr, "\t-d: Generate INLINE and INLINE_ORIGIN records\n"); + fprintf(stderr, + "\t-m: Enable writing the optional 'm' field on FUNC " + "and PUBLIC, denoting multiple symbols for the address.\n"); fprintf(stderr, "\t-h: Usage\n"); fprintf(stderr, "\t-?: Usage\n"); } @@ -224,7 +235,7 @@ static void SetupOptions(int argc, const char *argv[], Options *options) { extern int optind; signed char ch; - while ((ch = getopt(argc, (char * const*)argv, "ia:g:crd?h")) != -1) { + while ((ch = getopt(argc, (char* const*)argv, "ia:g:crdm?h")) != -1) { switch (ch) { case 'i': options->header_only = true; @@ -252,6 +263,9 @@ static void SetupOptions(int argc, const char *argv[], Options *options) { case 'd': options->handle_inlines = true; break; + case 'm': + options->enable_multiple = true; + break; case '?': case 'h': Usage(argc, argv);