[Object] Add zstd decompression support to Decompressor
llvm::object::Decompressor is used by many DWARF consumers like llvm-dwarfdump, llvm-dwp, llvm-symbolizer. Add tests to them. The lldb test can be left to D133530. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D134116
This commit is contained in:
parent
41d52c5a7f
commit
0b140d0910
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/Compression.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace llvm {
|
||||
|
@ -35,8 +36,7 @@ public:
|
|||
}
|
||||
|
||||
/// Uncompress section data to raw buffer provided.
|
||||
/// @param Buffer Destination buffer.
|
||||
Error decompress(MutableArrayRef<uint8_t> Buffer);
|
||||
Error decompress(MutableArrayRef<uint8_t> Output);
|
||||
|
||||
/// Return memory buffer size required for decompression.
|
||||
uint64_t getDecompressedSize() { return DecompressedSize; }
|
||||
|
@ -44,10 +44,11 @@ public:
|
|||
private:
|
||||
Decompressor(StringRef Data);
|
||||
|
||||
Error consumeCompressedZLibHeader(bool Is64Bit, bool IsLittleEndian);
|
||||
Error consumeCompressedHeader(bool Is64Bit, bool IsLittleEndian);
|
||||
|
||||
StringRef SectionData;
|
||||
uint64_t DecompressedSize;
|
||||
DebugCompressionType CompressionType = DebugCompressionType::None;
|
||||
};
|
||||
|
||||
} // end namespace object
|
||||
|
|
|
@ -114,6 +114,8 @@ void compress(Params P, ArrayRef<uint8_t> Input,
|
|||
SmallVectorImpl<uint8_t> &Output);
|
||||
|
||||
// Decompress Input. The uncompressed size must be available.
|
||||
Error decompress(DebugCompressionType T, ArrayRef<uint8_t> Input,
|
||||
uint8_t *Output, size_t UncompressedSize);
|
||||
Error decompress(Format F, ArrayRef<uint8_t> Input,
|
||||
SmallVectorImpl<uint8_t> &Output, size_t UncompressedSize);
|
||||
Error decompress(DebugCompressionType T, ArrayRef<uint8_t> Input,
|
||||
|
|
|
@ -19,11 +19,8 @@ using namespace object;
|
|||
|
||||
Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data,
|
||||
bool IsLE, bool Is64Bit) {
|
||||
if (!compression::zlib::isAvailable())
|
||||
return createError("zlib is not available");
|
||||
|
||||
Decompressor D(Data);
|
||||
if (Error Err = D.consumeCompressedZLibHeader(Is64Bit, IsLE))
|
||||
if (Error Err = D.consumeCompressedHeader(Is64Bit, IsLE))
|
||||
return std::move(Err);
|
||||
return D;
|
||||
}
|
||||
|
@ -31,8 +28,7 @@ Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data,
|
|||
Decompressor::Decompressor(StringRef Data)
|
||||
: SectionData(Data), DecompressedSize(0) {}
|
||||
|
||||
Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit,
|
||||
bool IsLittleEndian) {
|
||||
Error Decompressor::consumeCompressedHeader(bool Is64Bit, bool IsLittleEndian) {
|
||||
using namespace ELF;
|
||||
uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
|
||||
if (SectionData.size() < HdrSize)
|
||||
|
@ -40,10 +36,21 @@ Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit,
|
|||
|
||||
DataExtractor Extractor(SectionData, IsLittleEndian, 0);
|
||||
uint64_t Offset = 0;
|
||||
if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
|
||||
: sizeof(Elf32_Word)) !=
|
||||
ELFCOMPRESS_ZLIB)
|
||||
return createError("unsupported compression type");
|
||||
auto ChType = Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
|
||||
: sizeof(Elf32_Word));
|
||||
switch (ChType) {
|
||||
case ELFCOMPRESS_ZLIB:
|
||||
CompressionType = DebugCompressionType::Zlib;
|
||||
break;
|
||||
case ELFCOMPRESS_ZSTD:
|
||||
CompressionType = DebugCompressionType::Zstd;
|
||||
break;
|
||||
default:
|
||||
return createError("unsupported compression type (" + Twine(ChType) + ")");
|
||||
}
|
||||
if (const char *Reason = llvm::compression::getReasonIfUnsupported(
|
||||
compression::formatFor(CompressionType)))
|
||||
return createError(Reason);
|
||||
|
||||
// Skip Elf64_Chdr::ch_reserved field.
|
||||
if (Is64Bit)
|
||||
|
@ -55,8 +62,8 @@ Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit,
|
|||
return Error::success();
|
||||
}
|
||||
|
||||
Error Decompressor::decompress(MutableArrayRef<uint8_t> Buffer) {
|
||||
size_t Size = Buffer.size();
|
||||
return compression::zlib::decompress(arrayRefFromStringRef(SectionData),
|
||||
Buffer.data(), Size);
|
||||
Error Decompressor::decompress(MutableArrayRef<uint8_t> Output) {
|
||||
return compression::decompress(CompressionType,
|
||||
arrayRefFromStringRef(SectionData),
|
||||
Output.data(), Output.size());
|
||||
}
|
||||
|
|
|
@ -55,6 +55,17 @@ void compression::compress(Params P, ArrayRef<uint8_t> Input,
|
|||
}
|
||||
}
|
||||
|
||||
Error compression::decompress(DebugCompressionType T, ArrayRef<uint8_t> Input,
|
||||
uint8_t *Output, size_t UncompressedSize) {
|
||||
switch (formatFor(T)) {
|
||||
case compression::Format::Zlib:
|
||||
return zlib::decompress(Input, Output, UncompressedSize);
|
||||
case compression::Format::Zstd:
|
||||
return zstd::decompress(Input, Output, UncompressedSize);
|
||||
}
|
||||
llvm_unreachable("");
|
||||
}
|
||||
|
||||
Error compression::decompress(compression::Format F, ArrayRef<uint8_t> Input,
|
||||
SmallVectorImpl<uint8_t> &Output,
|
||||
size_t UncompressedSize) {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
; REQUIRES: zstd
|
||||
;; llvm-dwarfdump supports zstd compressed debug sections.
|
||||
|
||||
; RUN: llvm-objcopy --compress-debug-sections=zstd %S/Inputs/dwarfdump-test.elf-x86-64 %t
|
||||
; RUN: llvm-dwarfdump %t | FileCheck %s
|
||||
|
||||
; CHECK: .debug_info contents
|
||||
; CHECK: DW_AT_name ("dwarfdump-test.cc")
|
|
@ -0,0 +1,8 @@
|
|||
# REQUIRES: zstd
|
||||
## llvm-symbolizer supports zstd compressed debug sections.
|
||||
|
||||
# RUN: llvm-objcopy --compress-debug-sections=zstd %S/Inputs/dwarfdump-test.elf-x86-64 %t
|
||||
# RUN: llvm-symbolizer --obj=%t 0x40113f | FileCheck %s
|
||||
|
||||
# CHECK: main
|
||||
# CHECK-NEXT: /tmp/dbginfo{{[/\\]}}dwarfdump-test.cc:16
|
|
@ -0,0 +1,9 @@
|
|||
# REQUIRES: zstd
|
||||
## llvm-dwp supports zstd compressed debug sections.
|
||||
|
||||
# RUN: llvm-objcopy --compress-debug-sections=zstd %p/../Inputs/simple/notypes/a.dwo %t.o
|
||||
# RUN: llvm-dwp %t.o -o %t.dwp
|
||||
|
||||
# CHECK: .debug_info.dwo contents:
|
||||
# CHECK: DW_TAG_compile_unit
|
||||
# CHECK: DW_AT_name {{.*}} "a.cpp"
|
Loading…
Reference in New Issue