From cc7abac08b0c52e6581b9c9c4226816b17a4c26d Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Thu, 8 Dec 2022 18:27:40 +0000 Subject: [PATCH] Add option to enable multiple symbol field in Linux tool Bug: google-breakpad:751 Change-Id: I63a4d652413ef7311da7494fbd8fb816445eb353 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/4089183 Reviewed-by: Mark Mentovai --- src/common/linux/dump_symbols.cc | 14 ++++++++------ src/common/linux/dump_symbols.h | 9 ++++++--- src/tools/linux/dump_syms/dump_syms.cc | 9 ++++++++- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 7e639b0a..4915e6ff 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -1024,7 +1024,8 @@ template bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header, const string& obj_filename, const string& obj_os, - scoped_ptr& module) { + scoped_ptr& module, + bool enable_multiple_field) { PageAllocator allocator; wasteful_vector identifier(&allocator, kDefaultBuildIdSize); if (!FileID::ElfFileIdentifierFromMappedFile(elf_header, identifier)) { @@ -1053,7 +1054,8 @@ bool InitModuleForElfClass(const typename ElfClass::Ehdr* elf_header, // This is just the raw Build ID in hex. string code_id = FileID::ConvertIdentifierToString(identifier); - module.reset(new Module(name, obj_os, architecture, id, code_id)); + module.reset(new Module(name, obj_os, architecture, id, code_id, + enable_multiple_field)); return true; } @@ -1070,8 +1072,8 @@ bool ReadSymbolDataElfClass(const typename ElfClass::Ehdr* elf_header, *out_module = NULL; scoped_ptr module; - if (!InitModuleForElfClass(elf_header, obj_filename, obj_os, - module)) { + if (!InitModuleForElfClass(elf_header, obj_filename, obj_os, module, + options.enable_multiple_field)) { return false; } @@ -1183,14 +1185,14 @@ bool WriteSymbolFileHeader(const string& load_path, if (elfclass == ELFCLASS32) { if (!InitModuleForElfClass( reinterpret_cast(elf_header), obj_file, obj_os, - module)) { + module, /*enable_multiple_field=*/false)) { fprintf(stderr, "Failed to load ELF module: %s\n", obj_file.c_str()); return false; } } else if (elfclass == ELFCLASS64) { if (!InitModuleForElfClass( reinterpret_cast(elf_header), obj_file, obj_os, - module)) { + module, /*enable_multiple_field=*/false)) { fprintf(stderr, "Failed to load ELF module: %s\n", obj_file.c_str()); return false; } diff --git a/src/common/linux/dump_symbols.h b/src/common/linux/dump_symbols.h index 8ac169c9..f1802ecc 100644 --- a/src/common/linux/dump_symbols.h +++ b/src/common/linux/dump_symbols.h @@ -46,13 +46,16 @@ namespace google_breakpad { class Module; struct DumpOptions { - DumpOptions(SymbolData symbol_data, bool handle_inter_cu_refs) + DumpOptions(SymbolData symbol_data, + bool handle_inter_cu_refs, + bool enable_multiple_field) : symbol_data(symbol_data), - handle_inter_cu_refs(handle_inter_cu_refs) { - } + handle_inter_cu_refs(handle_inter_cu_refs), + enable_multiple_field(enable_multiple_field) {} SymbolData symbol_data; bool handle_inter_cu_refs; + bool enable_multiple_field; }; // Find all the debugging information in OBJ_FILE, an ELF executable diff --git a/src/tools/linux/dump_syms/dump_syms.cc b/src/tools/linux/dump_syms/dump_syms.cc index 6e6a6424..8998b3b3 100644 --- a/src/tools/linux/dump_syms/dump_syms.cc +++ b/src/tools/linux/dump_syms/dump_syms.cc @@ -56,6 +56,9 @@ int usage(const char* self) { fprintf(stderr, " -n Use specified name for name of the object\n"); fprintf(stderr, " -o Use specified name for the " "operating system\n"); + fprintf(stderr, " -m Enable writing the optional 'm' field on FUNC" + "and PUBLIC, denoting multiple symbols for " + "the address.\n"); return 1; } @@ -67,6 +70,7 @@ int main(int argc, char** argv) { bool handle_inlines = false; bool handle_inter_cu_refs = true; bool log_to_stderr = false; + bool enable_multiple_field = false; std::string obj_name; const char* obj_os = "Linux"; int arg_index = 1; @@ -96,6 +100,8 @@ int main(int argc, char** argv) { } obj_os = argv[arg_index + 1]; ++arg_index; + } else if (strcmp("-m", argv[arg_index]) == 0) { + enable_multiple_field = true; } else { printf("2.4 %s\n", argv[arg_index]); return usage(argv[0]); @@ -132,7 +138,8 @@ int main(int argc, char** argv) { } else { SymbolData symbol_data = (handle_inlines ? INLINES : NO_DATA) | (cfi ? CFI : NO_DATA) | SYMBOLS_AND_FILES; - google_breakpad::DumpOptions options(symbol_data, handle_inter_cu_refs); + google_breakpad::DumpOptions options(symbol_data, handle_inter_cu_refs, + enable_multiple_field); if (!WriteSymbolFile(binary, obj_name, obj_os, debug_dirs, options, std::cout)) { fprintf(saved_stderr, "Failed to write symbol file.\n");