LLVM  9.0.0svn
Decompressor.cpp
Go to the documentation of this file.
1 //===-- Decompressor.cpp --------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "llvm/BinaryFormat/ELF.h"
14 #include "llvm/Support/Endian.h"
15 
16 using namespace llvm;
17 using namespace llvm::support::endian;
18 using namespace object;
19 
20 Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data,
21  bool IsLE, bool Is64Bit) {
22  if (!zlib::isAvailable())
23  return createError("zlib is not available");
24 
25  Decompressor D(Data);
26  Error Err = isGnuStyle(Name) ? D.consumeCompressedGnuHeader()
27  : D.consumeCompressedZLibHeader(Is64Bit, IsLE);
28  if (Err)
29  return std::move(Err);
30  return D;
31 }
32 
33 Decompressor::Decompressor(StringRef Data)
34  : SectionData(Data), DecompressedSize(0) {}
35 
36 Error Decompressor::consumeCompressedGnuHeader() {
37  if (!SectionData.startswith("ZLIB"))
38  return createError("corrupted compressed section header");
39 
40  SectionData = SectionData.substr(4);
41 
42  // Consume uncompressed section size (big-endian 8 bytes).
43  if (SectionData.size() < 8)
44  return createError("corrupted uncompressed section size");
45  DecompressedSize = read64be(SectionData.data());
46  SectionData = SectionData.substr(8);
47 
48  return Error::success();
49 }
50 
51 Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit,
52  bool IsLittleEndian) {
53  using namespace ELF;
54  uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
55  if (SectionData.size() < HdrSize)
56  return createError("corrupted compressed section header");
57 
58  DataExtractor Extractor(SectionData, IsLittleEndian, 0);
59  uint32_t Offset = 0;
60  if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
61  : sizeof(Elf32_Word)) !=
63  return createError("unsupported compression type");
64 
65  // Skip Elf64_Chdr::ch_reserved field.
66  if (Is64Bit)
67  Offset += sizeof(Elf64_Word);
68 
69  DecompressedSize = Extractor.getUnsigned(
70  &Offset, Is64Bit ? sizeof(Elf64_Xword) : sizeof(Elf32_Word));
71  SectionData = SectionData.substr(HdrSize);
72  return Error::success();
73 }
74 
75 bool Decompressor::isGnuStyle(StringRef Name) {
76  return Name.startswith(".zdebug");
77 }
78 
79 bool Decompressor::isCompressed(const object::SectionRef &Section) {
81  if (Section.getName(Name))
82  return false;
83  return Section.isCompressed() || isGnuStyle(Name);
84 }
85 
86 bool Decompressor::isCompressedELFSection(uint64_t Flags, StringRef Name) {
87  return (Flags & ELF::SHF_COMPRESSED) || isGnuStyle(Name);
88 }
89 
90 Error Decompressor::decompress(MutableArrayRef<char> Buffer) {
91  size_t Size = Buffer.size();
92  return zlib::uncompress(SectionData, Buffer.data(), Size);
93 }
This class represents lattice values for constants.
Definition: AllocatorList.h:23
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:256
uint32_t Elf32_Word
Definition: ELF.h:31
static Error createError(StringRef Err)
Definition: ELF.h:47
uint64_t read64be(const void *P)
Definition: Endian.h:372
uint64_t Elf64_Xword
Definition: ELF.h:39
Decompressor helps to handle decompression of compressed sections.
Definition: Decompressor.h:20
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
bool isCompressed() const
Definition: ObjectFile.h:437
bool isAvailable()
Definition: Compression.cpp:47
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:290
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:148
static ErrorSuccess success()
Create a success value.
Definition: Error.h:326
std::error_code getName(StringRef &Result) const
Definition: ObjectFile.h:413
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
uint64_t getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const
Extract an unsigned integer of size byte_size from *offset_ptr.
uint32_t Size
Definition: Profile.cpp:46
uint32_t Elf64_Word
Definition: ELF.h:37
T * data() const
Definition: ArrayRef.h:328
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Error uncompress(StringRef InputBuffer, char *UncompressedBuffer, size_t &UncompressedSize)
Definition: Compression.cpp:63
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:80