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 <ivanpe@chromium.org>
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
Ian Barkley-Yeung 2022-12-20 13:33:29 -08:00
parent 80430d73ae
commit b14bb95d5d

View File

@ -495,9 +495,42 @@ bool LoadDwarfCFI(const string& dwarf_filename,
google_breakpad::CallFrameInfo::Reporter dwarf_reporter(dwarf_filename, google_breakpad::CallFrameInfo::Reporter dwarf_reporter(dwarf_filename,
section_name); section_name);
google_breakpad::CallFrameInfo parser(cfi, cfi_size, if (!IsCompressedHeader<ElfClass>(section)) {
&byte_reader, &handler, &dwarf_reporter, google_breakpad::CallFrameInfo parser(cfi, cfi_size,
eh_frame); &byte_reader, &handler,
&dwarf_reporter, eh_frame);
parser.Start();
return true;
}
typename ElfClass::Chdr chdr;
uint32_t compression_header_size =
GetCompressionHeader<ElfClass>(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<uint8_t *, uint64_t> 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(); parser.Start();
return true; return true;
} }