aboutsummaryrefslogtreecommitdiff
path: root/src/common/linux/dump_symbols.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/linux/dump_symbols.cc')
-rw-r--r--src/common/linux/dump_symbols.cc45
1 files changed, 42 insertions, 3 deletions
diff --git a/src/common/linux/dump_symbols.cc b/src/common/linux/dump_symbols.cc
index 86c948d9..b693fc9e 100644
--- a/src/common/linux/dump_symbols.cc
+++ b/src/common/linux/dump_symbols.cc
@@ -51,6 +51,9 @@
#include <sys/stat.h>
#include <unistd.h>
#include <zlib.h>
+#ifdef HAVE_LIBZSTD
+#include <zstd.h>
+#endif
#include <set>
#include <string>
@@ -108,6 +111,11 @@ using google_breakpad::wasteful_vector;
#define EM_AARCH64 183
#endif
+// Define ZStd compression if host machine does not include this define.
+#ifndef ELFCOMPRESS_ZSTD
+#define ELFCOMPRESS_ZSTD 2
+#endif
+
//
// FDWrapper
//
@@ -305,7 +313,7 @@ uint32_t GetCompressionHeader(
return sizeof (*header);
}
-std::pair<uint8_t *, uint64_t> UncompressSectionContents(
+std::pair<uint8_t *, uint64_t> UncompressZlibSectionContents(
const uint8_t* compressed_buffer, uint64_t compressed_size, uint64_t uncompressed_size) {
z_stream stream;
memset(&stream, 0, sizeof stream);
@@ -334,6 +342,37 @@ std::pair<uint8_t *, uint64_t> UncompressSectionContents(
: std::make_pair(uncompressed_buffer.release(), uncompressed_size);
}
+#ifdef HAVE_LIBZSTD
+std::pair<uint8_t *, uint64_t> UncompressZstdSectionContents(
+ const uint8_t* compressed_buffer, uint64_t compressed_size,uint64_t uncompressed_size) {
+
+ google_breakpad::scoped_array<uint8_t> uncompressed_buffer(new uint8_t[uncompressed_size]);
+ size_t out_size = ZSTD_decompress(uncompressed_buffer.get(), uncompressed_size,
+ compressed_buffer, compressed_size);
+ if (ZSTD_isError(out_size)) {
+ return std::make_pair(nullptr, 0);
+ }
+ assert(out_size == uncompressed_size);
+ return std::make_pair(uncompressed_buffer.release(), uncompressed_size);
+}
+#endif
+
+std::pair<uint8_t *, uint64_t> UncompressSectionContents(
+ uint64_t compression_type, const uint8_t* compressed_buffer,
+ uint64_t compressed_size, uint64_t uncompressed_size) {
+ if (compression_type == ELFCOMPRESS_ZLIB) {
+ return UncompressZlibSectionContents(compressed_buffer, compressed_size, uncompressed_size);
+ }
+
+#ifdef HAVE_LIBZSTD
+ if (compression_type == ELFCOMPRESS_ZSTD) {
+ return UncompressZstdSectionContents(compressed_buffer, compressed_size, uncompressed_size);
+ }
+#endif
+
+ return std::make_pair(nullptr, 0);
+}
+
void StartProcessSplitDwarf(google_breakpad::CompilationUnit* reader,
Module* module,
google_breakpad::Endianness endianness,
@@ -437,7 +476,7 @@ bool LoadDwarf(const string& dwarf_filename,
size -= compression_header_size;
std::pair<uint8_t *, uint64_t> uncompressed =
- UncompressSectionContents(contents, size, chdr.ch_size);
+ UncompressSectionContents(chdr.ch_type, contents, size, chdr.ch_size);
if (uncompressed.first != nullptr && uncompressed.second != 0) {
file_context.AddManagedSectionToSectionMap(name, uncompressed.first, uncompressed.second);
@@ -587,7 +626,7 @@ bool LoadDwarfCFI(const string& dwarf_filename,
cfi_size -= compression_header_size;
std::pair<uint8_t *, uint64_t> uncompressed =
- UncompressSectionContents(cfi, cfi_size, chdr.ch_size);
+ UncompressSectionContents(chdr.ch_type, cfi, cfi_size, chdr.ch_size);
if (uncompressed.first == nullptr || uncompressed.second == 0) {
fprintf(stderr, "%s: decompression failed\n", dwarf_filename.c_str());