1 //===-- Decompressor.cpp --------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Object/Decompressor.h"
10 #include "llvm/ADT/StringExtras.h"
11 #include "llvm/BinaryFormat/ELF.h"
12 #include "llvm/Object/ObjectFile.h"
13 #include "llvm/Support/Compression.h"
14 #include "llvm/Support/DataExtractor.h"
15 #include "llvm/Support/Endian.h"
18 using namespace llvm::support::endian
;
19 using namespace object
;
21 Expected
<Decompressor
> Decompressor::create(StringRef Name
, StringRef Data
,
22 bool IsLE
, bool Is64Bit
) {
24 if (Error Err
= D
.consumeCompressedHeader(Is64Bit
, IsLE
))
25 return std::move(Err
);
29 Decompressor::Decompressor(StringRef Data
)
30 : SectionData(Data
), DecompressedSize(0) {}
32 Error
Decompressor::consumeCompressedHeader(bool Is64Bit
, bool IsLittleEndian
) {
34 uint64_t HdrSize
= Is64Bit
? sizeof(Elf64_Chdr
) : sizeof(Elf32_Chdr
);
35 if (SectionData
.size() < HdrSize
)
36 return createError("corrupted compressed section header");
38 DataExtractor
Extractor(SectionData
, IsLittleEndian
, 0);
40 auto ChType
= Extractor
.getUnsigned(&Offset
, Is64Bit
? sizeof(Elf64_Word
)
41 : sizeof(Elf32_Word
));
43 case ELFCOMPRESS_ZLIB
:
44 CompressionType
= DebugCompressionType::Zlib
;
46 case ELFCOMPRESS_ZSTD
:
47 CompressionType
= DebugCompressionType::Zstd
;
50 return createError("unsupported compression type (" + Twine(ChType
) + ")");
52 if (const char *Reason
= llvm::compression::getReasonIfUnsupported(
53 compression::formatFor(CompressionType
)))
54 return createError(Reason
);
56 // Skip Elf64_Chdr::ch_reserved field.
58 Offset
+= sizeof(Elf64_Word
);
60 DecompressedSize
= Extractor
.getUnsigned(
61 &Offset
, Is64Bit
? sizeof(Elf64_Xword
) : sizeof(Elf32_Word
));
62 SectionData
= SectionData
.substr(HdrSize
);
63 return Error::success();
66 Error
Decompressor::decompress(MutableArrayRef
<uint8_t> Output
) {
67 return compression::decompress(CompressionType
,
68 arrayRefFromStringRef(SectionData
),
69 Output
.data(), Output
.size());