LLVM  6.0.0svn
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 
11 #include "llvm/BinaryFormat/ELF.h"
15 #include "llvm/Support/Endian.h"
16 
17 using namespace llvm;
18 using namespace llvm::support::endian;
19 using namespace object;
20 
21 Expected<Decompressor> Decompressor::create(StringRef Name, StringRef Data,
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 
76 bool Decompressor::isGnuStyle(StringRef Name) {
77  return Name.startswith(".zdebug");
78 }
79 
80 bool Decompressor::isCompressed(const object::SectionRef &Section) {
82  if (Section.getName(Name))
83  return false;
84  return Section.isCompressed() || isGnuStyle(Name);
85 }
86 
87 bool Decompressor::isCompressedELFSection(uint64_t Flags, StringRef Name) {
88  return (Flags & ELF::SHF_COMPRESSED) || isGnuStyle(Name);
89 }
90 
91 Error Decompressor::decompress(MutableArrayRef<char> Buffer) {
92  size_t Size = Buffer.size();
93  return zlib::uncompress(SectionData, Buffer.data(), Size);
94 }
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
uint32_t Elf32_Word
Definition: ELF.h:32
static Error createError(StringRef Err)
Definition: ELF.h:47
uint64_t read64be(const void *P)
Definition: Endian.h:373
uint64_t Elf64_Xword
Definition: ELF.h:40
Decompressor helps to handle decompression of compressed sections.
Definition: Decompressor.h:21
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:267
bool isCompressed() const
Definition: ObjectFile.h:422
bool isAvailable()
Definition: Compression.cpp:58
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:291
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
static ErrorSuccess success()
Create a success value.
Definition: Error.h:313
std::error_code getName(StringRef &Result) const
Definition: ObjectFile.h:398
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 Elf64_Word
Definition: ELF.h:38
T * data() const
Definition: ArrayRef.h:329
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Error uncompress(StringRef InputBuffer, char *UncompressedBuffer, size_t &UncompressedSize)
Definition: Compression.cpp:76
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:80