LLVM  13.0.0git
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 
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  uint64_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 
76  return Name.startswith(".zdebug");
77 }
78 
80  if (Section.isCompressed())
81  return true;
82 
83  Expected<StringRef> SecNameOrErr = Section.getName();
84  if (SecNameOrErr)
85  return isGnuStyle(*SecNameOrErr);
86 
87  consumeError(SecNameOrErr.takeError());
88  return false;
89 }
90 
92  return (Flags & ELF::SHF_COMPRESSED) || isGnuStyle(Name);
93 }
94 
96  size_t Size = Buffer.size();
97  return zlib::uncompress(SectionData, Buffer.data(), Size);
98 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
Compression.h
llvm::StringRef::startswith
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:289
llvm
This class represents lattice values for constants.
Definition: AllocatorList.h:23
llvm::zlib::uncompress
Error uncompress(StringRef InputBuffer, char *UncompressedBuffer, size_t &UncompressedSize)
Definition: Compression.cpp:63
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:332
llvm::object::createError
static Error createError(const Twine &Err)
Definition: ELF.h:84
llvm::object::Decompressor::decompress
Error decompress(MutableArrayRef< char > Buffer)
Uncompress section data to raw buffer provided.
Definition: Decompressor.cpp:95
llvm::ELF::Elf64_Xword
uint64_t Elf64_Xword
Definition: ELF.h:39
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::object::Decompressor::isCompressed
static bool isCompressed(const object::SectionRef &Section)
Return true if section is compressed, including gnu-styled case.
Definition: Decompressor.cpp:79
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1006
llvm::Data
@ Data
Definition: SIMachineScheduler.h:56
llvm::support::endian::read64be
uint64_t read64be(const void *P)
Definition: Endian.h:385
llvm::ARMBuildAttrs::Section
@ Section
Legacy Tags.
Definition: ARMBuildAttributes.h:78
llvm::StringRef::substr
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:612
llvm::support::endian
Definition: Endian.h:42
ELF.h
llvm::MutableArrayRef
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:305
llvm::createError
static Error createError(const Twine &Err)
Definition: APFloat.cpp:225
llvm::object::SectionRef
This is a value type class that represents a single section in the list of sections in the object fil...
Definition: ObjectFile.h:80
llvm::ELF::Elf64_Word
uint32_t Elf64_Word
Definition: ELF.h:37
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::ELF::Elf32_Word
uint32_t Elf32_Word
Definition: ELF.h:31
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::object::Decompressor::isGnuStyle
static bool isGnuStyle(StringRef Name)
Return true if section name matches gnu style compressed one.
Definition: Decompressor.cpp:75
llvm::zlib::isAvailable
bool isAvailable()
Definition: Compression.cpp:47
llvm::ELF::ELFCOMPRESS_ZLIB
@ ELFCOMPRESS_ZLIB
Definition: ELF.h:1624
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm::MutableArrayRef::data
T * data() const
Definition: ArrayRef.h:352
Decompressor.h
ELFObjectFile.h
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::ELF::SHF_COMPRESSED
@ SHF_COMPRESSED
Definition: ELF.h:955
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
DataExtractor.h
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:557
llvm::DataExtractor
Definition: DataExtractor.h:41
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:163
llvm::StringRef::data
const LLVM_NODISCARD char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:152
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:160
Endian.h
llvm::object::Decompressor
Decompressor helps to handle decompression of compressed sections.
Definition: Decompressor.h:20
llvm::object::Decompressor::isCompressedELFSection
static bool isCompressedELFSection(uint64_t Flags, StringRef Name)
Return true if section is a ELF compressed one.
Definition: Decompressor.cpp:91