From b14bb95d5de268b6231dc8c667fb0f7d73676856 Mon Sep 17 00:00:00 2001 From: Ian Barkley-Yeung Date: Tue, 20 Dec 2022 13:33:29 -0800 Subject: [PATCH] Handle compressed DWARF data in LoadDwarfCFI Emit STACK CFI records even in the presence of clang's "-gz" linker option. Needed for ChromeOS ARM boards' chrome binary. BUG=b:263148951,google-breakpad:874 Fixed: google-breakpad:874 Change-Id: I2fe697a56d3421609128d4e291ab1adc73314864 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/4117692 Reviewed-by: Ivan Penkov Reviewed-by: Joshua Peraza --- src/common/linux/dump_symbols.cc | 39 +++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc index 4915e6ff..b436f765 100644 --- a/src/common/linux/dump_symbols.cc +++ b/src/common/linux/dump_symbols.cc @@ -495,9 +495,42 @@ bool LoadDwarfCFI(const string& dwarf_filename, google_breakpad::CallFrameInfo::Reporter dwarf_reporter(dwarf_filename, section_name); - google_breakpad::CallFrameInfo parser(cfi, cfi_size, - &byte_reader, &handler, &dwarf_reporter, - eh_frame); + if (!IsCompressedHeader(section)) { + google_breakpad::CallFrameInfo parser(cfi, cfi_size, + &byte_reader, &handler, + &dwarf_reporter, eh_frame); + parser.Start(); + return true; + } + + typename ElfClass::Chdr chdr; + uint32_t compression_header_size = + GetCompressionHeader(chdr, cfi, cfi_size); + + if (compression_header_size == 0 || chdr.ch_size == 0) { + fprintf(stderr, "%s: decompression failed at header\n", + dwarf_filename.c_str()); + return false; + } + if (compression_header_size > cfi_size) { + fprintf(stderr, "%s: decompression error, compression_header too large\n", + dwarf_filename.c_str()); + return false; + } + + cfi += compression_header_size; + cfi_size -= compression_header_size; + + std::pair uncompressed = + UncompressSectionContents(cfi, cfi_size, chdr.ch_size); + + if (uncompressed.first == nullptr || uncompressed.second == 0) { + fprintf(stderr, "%s: decompression failed\n", dwarf_filename.c_str()); + return false; + } + google_breakpad::CallFrameInfo parser(uncompressed.first, uncompressed.second, + &byte_reader, &handler, &dwarf_reporter, + eh_frame); parser.Start(); return true; }