LLVM  4.0.0
Decompressor.cpp
Go to the documentation of this file.
1 //===-- Decompressor.cpp --------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
14 #include "llvm/Support/Endian.h"
15 #include "llvm/Support/ELF.h"
16 
17 using namespace llvm;
18 using namespace llvm::support::endian;
19 using namespace object;
20 
22  bool IsLE, bool Is64Bit) {
23  if (!zlib::isAvailable())
24  return createError("zlib is not available");
25 
26  Decompressor D(Data);
27  Error Err = isGnuStyle(Name) ? D.consumeCompressedGnuHeader()
28  : D.consumeCompressedZLibHeader(Is64Bit, IsLE);
29  if (Err)
30  return std::move(Err);
31  return D;
32 }
33 
34 Decompressor::Decompressor(StringRef Data)
35  : SectionData(Data), DecompressedSize(0) {}
36 
37 Error Decompressor::consumeCompressedGnuHeader() {
38  if (!SectionData.startswith("ZLIB"))
39  return createError("corrupted compressed section header");
40 
41  SectionData = SectionData.substr(4);
42 
43  // Consume uncompressed section size (big-endian 8 bytes).
44  if (SectionData.size() < 8)
45  return createError("corrupted uncompressed section size");
46  DecompressedSize = read64be(SectionData.data());
47  SectionData = SectionData.substr(8);
48 
49  return Error::success();
50 }
51 
52 Error Decompressor::consumeCompressedZLibHeader(bool Is64Bit,
53  bool IsLittleEndian) {
54  using namespace ELF;
55  uint64_t HdrSize = Is64Bit ? sizeof(Elf64_Chdr) : sizeof(Elf32_Chdr);
56  if (SectionData.size() < HdrSize)
57  return createError("corrupted compressed section header");
58 
59  DataExtractor Extractor(SectionData, IsLittleEndian, 0);
60  uint32_t Offset = 0;
61  if (Extractor.getUnsigned(&Offset, Is64Bit ? sizeof(Elf64_Word)
62  : sizeof(Elf32_Word)) !=
64  return createError("unsupported compression type");
65 
66  // Skip Elf64_Chdr::ch_reserved field.
67  if (Is64Bit)
68  Offset += sizeof(Elf64_Word);
69 
70  DecompressedSize = Extractor.getUnsigned(
71  &Offset, Is64Bit ? sizeof(Elf64_Xword) : sizeof(Elf32_Word));
72  SectionData = SectionData.substr(HdrSize);
73  return Error::success();
74 }
75 
77  return Name.startswith(".zdebug");
78 }
79 
82  if (Section.getName(Name))
83  return false;
84  return Section.isCompressed() || isGnuStyle(Name);
85 }
86 
88  return (Flags & ELF::SHF_COMPRESSED) || isGnuStyle(Name);
89 }
90 
92  Out.resize(DecompressedSize);
93  return decompress({Out.data(), (size_t)DecompressedSize});
94 }
95 
97  size_t Size = Buffer.size();
98  zlib::Status Status = zlib::uncompress(SectionData, Buffer.data(), Size);
99  if (Status != zlib::StatusOK)
100  return createError("decompression failed");
101  return Error::success();
102 }
static bool isCompressed(const object::SectionRef &Section)
Return true if section is compressed, including gnu-styled case.
static bool isGnuStyle(StringRef Name)
Return true if section name matches gnu style compressed one.
T * data() const
Definition: ArrayRef.h:322
static Error createError(StringRef Err)
Definition: Object/ELF.h:36
uint64_t read64be(const void *P)
Definition: Endian.h:322
Error decompress(SmallString< 32 > &Out)
Resize the buffer and uncompress section data into it.
Decompressor helps to handle decompression of compressed sections.
Definition: Decompressor.h:21
struct fuzzer::@269 Flags
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
Tagged union holding either a T or a Error.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:264
std::error_code getName(StringRef &Result) const
Definition: ObjectFile.h:372
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:135
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:141
uint64_t Elf64_Xword
Definition: Support/ELF.h:42
Status uncompress(StringRef InputBuffer, char *UncompressedBuffer, size_t &UncompressedSize)
Definition: Compression.cpp:65
bool isAvailable()
Definition: Compression.cpp:48
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:283
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:587
uint32_t Offset
static ErrorSuccess success()
Create a success value.
bool isCompressed() const
Definition: ObjectFile.h:392
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition: SmallVector.h:142
uint32_t Elf32_Word
Definition: Support/ELF.h:34
Lightweight error class with error context and mandatory checking.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:125
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
static bool isCompressedELFSection(uint64_t Flags, StringRef Name)
Return true if section is a ELF compressed one.
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:70
static Expected< Decompressor > create(StringRef Name, StringRef Data, bool IsLE, bool Is64Bit)
Create decompressor object.
uint32_t Elf64_Word
Definition: Support/ELF.h:40
void resize(size_type N)
Definition: SmallVector.h:352